Merge pull request #229 from Subv/ensuresavedata_impl
FS: Make EnsureSaveData create the save data if it doesn't already exist.
This commit is contained in:
		
						commit
						80562aaf64
					
				| @ -7,6 +7,7 @@ | ||||
| #include "common/common_types.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "core/file_sys/disk_filesystem.h" | ||||
| #include "core/file_sys/errors.h" | ||||
| 
 | ||||
| namespace FileSys { | ||||
| 
 | ||||
| @ -22,8 +23,7 @@ ResultVal<std::unique_ptr<StorageBackend>> Disk_FileSystem::OpenFile(const std:: | ||||
|     auto file = std::make_shared<FileUtil::IOFile>(full_path, mode == Mode::Read ? "rb" : "wb"); | ||||
| 
 | ||||
|     if (!file->IsOpen()) { | ||||
|         // TODO(Subv): Find out the correct error code.
 | ||||
|         return ResultCode(-1); | ||||
|         return ERROR_PATH_NOT_FOUND; | ||||
|     } | ||||
| 
 | ||||
|     return MakeResult<std::unique_ptr<StorageBackend>>( | ||||
| @ -100,8 +100,7 @@ u64 Disk_FileSystem::GetFreeSpaceSize() const { | ||||
| ResultVal<FileSys::EntryType> Disk_FileSystem::GetEntryType(const std::string& path) const { | ||||
|     std::string full_path = base_directory + path; | ||||
|     if (!FileUtil::Exists(full_path)) { | ||||
|         // TODO(Subv): Find out what this actually means
 | ||||
|         return ResultCode(ErrorModule::FS, 1); | ||||
|         return ERROR_PATH_NOT_FOUND; | ||||
|     } | ||||
| 
 | ||||
|     // TODO(Subv): Find out the EntryType values
 | ||||
|  | ||||
| @ -10,36 +10,17 @@ namespace FileSys { | ||||
| 
 | ||||
| namespace ErrCodes { | ||||
| enum { | ||||
|     RomFSNotFound = 100, | ||||
|     ArchiveNotMounted = 101, | ||||
|     FileNotFound = 112, | ||||
|     PathNotFound = 113, | ||||
|     GameCardNotInserted = 141, | ||||
|     NotFound = 120, | ||||
|     FileAlreadyExists = 180, | ||||
|     DirectoryAlreadyExists = 185, | ||||
|     AlreadyExists = 190, | ||||
|     InvalidOpenFlags = 230, | ||||
|     DirectoryNotEmpty = 240, | ||||
|     NotAFile = 250, | ||||
|     NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive
 | ||||
|     ExeFSSectionNotFound = 567, | ||||
|     CommandNotAllowed = 630, | ||||
|     InvalidReadFlag = 700, | ||||
|     InvalidPath = 702, | ||||
|     WriteBeyondEnd = 705, | ||||
|     UnsupportedOpenFlags = 760, | ||||
|     IncorrectExeFSReadSize = 761, | ||||
|     UnexpectedFileOrDirectory = 770, | ||||
|     NotFound = 1, | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| constexpr ResultCode ERROR_PATH_NOT_FOUND(ErrorModule::FS, ErrCodes::NotFound); | ||||
| 
 | ||||
| // TODO(bunnei): Replace these with correct errors for Switch OS
 | ||||
| constexpr ResultCode ERROR_INVALID_PATH(ResultCode(-1)); | ||||
| constexpr ResultCode ERROR_UNSUPPORTED_OPEN_FLAGS(ResultCode(-1)); | ||||
| constexpr ResultCode ERROR_INVALID_OPEN_FLAGS(ResultCode(-1)); | ||||
| constexpr ResultCode ERROR_FILE_NOT_FOUND(ResultCode(-1)); | ||||
| constexpr ResultCode ERROR_PATH_NOT_FOUND(ResultCode(-1)); | ||||
| constexpr ResultCode ERROR_UNEXPECTED_FILE_OR_DIRECTORY(ResultCode(-1)); | ||||
| constexpr ResultCode ERROR_DIRECTORY_ALREADY_EXISTS(ResultCode(-1)); | ||||
| constexpr ResultCode ERROR_FILE_ALREADY_EXISTS(ResultCode(-1)); | ||||
|  | ||||
| @ -183,10 +183,9 @@ public: | ||||
|     /**
 | ||||
|      * Deletes the archive contents and then re-creates the base folder | ||||
|      * @param path Path to the archive | ||||
|      * @param format_info Format information for the new archive | ||||
|      * @return ResultCode of the operation, 0 on success | ||||
|      */ | ||||
|     virtual ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) = 0; | ||||
|     virtual ResultCode Format(const Path& path) = 0; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Retrieves the format info about the archive with the specified path | ||||
|  | ||||
| @ -23,7 +23,7 @@ ResultVal<std::unique_ptr<FileSystemBackend>> RomFS_Factory::Open(const Path& pa | ||||
|     return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive)); | ||||
| } | ||||
| 
 | ||||
| ResultCode RomFS_Factory::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { | ||||
| ResultCode RomFS_Factory::Format(const Path& path) { | ||||
|     LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str()); | ||||
|     // TODO(bunnei): Find the right error code for this
 | ||||
|     return ResultCode(-1); | ||||
|  | ||||
| @ -23,7 +23,7 @@ public: | ||||
|         return "ArchiveFactory_RomFS"; | ||||
|     } | ||||
|     ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) override; | ||||
|     ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; | ||||
|     ResultCode Format(const Path& path) override; | ||||
|     ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; | ||||
| 
 | ||||
| private: | ||||
|  | ||||
| @ -17,20 +17,26 @@ SaveData_Factory::SaveData_Factory(std::string nand_directory) | ||||
|     : nand_directory(std::move(nand_directory)) {} | ||||
| 
 | ||||
| ResultVal<std::unique_ptr<FileSystemBackend>> SaveData_Factory::Open(const Path& path) { | ||||
|     u64 title_id = Kernel::g_current_process->program_id; | ||||
|     // TODO(Subv): Somehow obtain this value.
 | ||||
|     u32 user = 0; | ||||
|     std::string save_directory = Common::StringFromFormat("%ssave/%016" PRIX64 "/%08X", | ||||
|                                                           nand_directory.c_str(), title_id, user); | ||||
|     std::string save_directory = GetFullPath(); | ||||
|     // Return an error if the save data doesn't actually exist.
 | ||||
|     if (!FileUtil::IsDirectory(save_directory)) { | ||||
|         // TODO(Subv): Find out correct error code.
 | ||||
|         return ResultCode(-1); | ||||
|     } | ||||
| 
 | ||||
|     auto archive = std::make_unique<Disk_FileSystem>(save_directory); | ||||
|     return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive)); | ||||
| } | ||||
| 
 | ||||
| ResultCode SaveData_Factory::Format(const Path& path, | ||||
|                                     const FileSys::ArchiveFormatInfo& format_info) { | ||||
|     LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str()); | ||||
|     // TODO(bunnei): Find the right error code for this
 | ||||
|     return ResultCode(-1); | ||||
| ResultCode SaveData_Factory::Format(const Path& path) { | ||||
|     LOG_WARNING(Service_FS, "Format archive %s", GetName().c_str()); | ||||
|     // Create the save data directory.
 | ||||
|     if (!FileUtil::CreateFullPath(GetFullPath())) { | ||||
|         // TODO(Subv): Find the correct error code.
 | ||||
|         return ResultCode(-1); | ||||
|     } | ||||
| 
 | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| ResultVal<ArchiveFormatInfo> SaveData_Factory::GetFormatInfo(const Path& path) const { | ||||
| @ -39,4 +45,12 @@ ResultVal<ArchiveFormatInfo> SaveData_Factory::GetFormatInfo(const Path& path) c | ||||
|     return ResultCode(-1); | ||||
| } | ||||
| 
 | ||||
| std::string SaveData_Factory::GetFullPath() const { | ||||
|     u64 title_id = Kernel::g_current_process->program_id; | ||||
|     // TODO(Subv): Somehow obtain this value.
 | ||||
|     u32 user = 0; | ||||
|     return Common::StringFromFormat("%ssave/%016" PRIX64 "/%08X/", nand_directory.c_str(), title_id, | ||||
|                                     user); | ||||
| } | ||||
| 
 | ||||
| } // namespace FileSys
 | ||||
|  | ||||
| @ -21,11 +21,13 @@ public: | ||||
|         return "SaveData_Factory"; | ||||
|     } | ||||
|     ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) override; | ||||
|     ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; | ||||
|     ResultCode Format(const Path& path) override; | ||||
|     ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; | ||||
| 
 | ||||
| private: | ||||
|     std::string nand_directory; | ||||
| 
 | ||||
|     std::string GetFullPath() const; | ||||
| }; | ||||
| 
 | ||||
| } // namespace FileSys
 | ||||
|  | ||||
| @ -2,12 +2,15 @@ | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <cinttypes> | ||||
| #include "core/file_sys/filesystem.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/event.h" | ||||
| #include "core/hle/service/am/am.h" | ||||
| #include "core/hle/service/am/applet_ae.h" | ||||
| #include "core/hle/service/am/applet_oe.h" | ||||
| #include "core/hle/service/apm/apm.h" | ||||
| #include "core/hle/service/filesystem/filesystem.h" | ||||
| #include "core/hle/service/nvflinger/nvflinger.h" | ||||
| 
 | ||||
| namespace Service { | ||||
| @ -416,9 +419,24 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) { | ||||
| } | ||||
| 
 | ||||
| void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service, "(STUBBED) called"); | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     u128 uid = rp.PopRaw<u128>(); | ||||
| 
 | ||||
|     LOG_WARNING(Service, "(STUBBED) called uid = %016" PRIX64 "%016" PRIX64, uid[1], uid[0]); | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 4}; | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
| 
 | ||||
|     FileSys::Path unused; | ||||
|     auto savedata = FileSystem::OpenFileSystem(FileSystem::Type::SaveData, unused); | ||||
|     if (savedata.Failed()) { | ||||
|         // Create the save data and return an error indicating that the operation was performed.
 | ||||
|         FileSystem::FormatFileSystem(FileSystem::Type::SaveData); | ||||
|         // TODO(Subv): Find out the correct error code for this.
 | ||||
|         rb.Push(ResultCode(ErrorModule::FS, 40)); | ||||
|     } else { | ||||
|         rb.Push(RESULT_SUCCESS); | ||||
|     } | ||||
| 
 | ||||
|     rb.Push<u64>(0); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -43,6 +43,19 @@ ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, | ||||
|     return itr->second->Open(path); | ||||
| } | ||||
| 
 | ||||
| ResultCode FormatFileSystem(Type type) { | ||||
|     LOG_TRACE(Service_FS, "Formatting FileSystem with type=%d", type); | ||||
| 
 | ||||
|     auto itr = filesystem_map.find(type); | ||||
|     if (itr == filesystem_map.end()) { | ||||
|         // TODO(bunnei): Find a better error code for this
 | ||||
|         return ResultCode(-1); | ||||
|     } | ||||
| 
 | ||||
|     FileSys::Path unused; | ||||
|     return itr->second->Format(unused); | ||||
| } | ||||
| 
 | ||||
| void RegisterFileSystems() { | ||||
|     filesystem_map.clear(); | ||||
| 
 | ||||
|  | ||||
| @ -44,6 +44,13 @@ ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& fact | ||||
| ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type, | ||||
|                                                                       FileSys::Path& path); | ||||
| 
 | ||||
| /**
 | ||||
|  * Formats a file system | ||||
|  * @param type Type of the file system to format | ||||
|  * @return ResultCode of the operation | ||||
|  */ | ||||
| ResultCode FormatFileSystem(Type type); | ||||
| 
 | ||||
| /// Registers all Filesystem services with the specified service manager.
 | ||||
| void InstallInterfaces(SM::ServiceManager& service_manager); | ||||
| 
 | ||||
|  | ||||
| @ -245,6 +245,7 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {1, &FSP_SRV::Initalize, "Initalize"}, | ||||
|         {18, &FSP_SRV::MountSdCard, "MountSdCard"}, | ||||
|         {22, &FSP_SRV::CreateSaveData, "CreateSaveData"}, | ||||
|         {51, &FSP_SRV::MountSaveData, "MountSaveData"}, | ||||
|         {200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"}, | ||||
|         {202, nullptr, "OpenDataStorageByDataId"}, | ||||
| @ -279,6 +280,19 @@ void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
| } | ||||
| 
 | ||||
| void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
| 
 | ||||
|     auto save_struct = rp.PopRaw<std::array<u8, 0x40>>(); | ||||
|     auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>(); | ||||
|     u128 uid = rp.PopRaw<u128>(); | ||||
| 
 | ||||
|     LOG_WARNING(Service_FS, "(STUBBED) called uid = %016" PRIX64 "%016" PRIX64, uid[1], uid[0]); | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
| } | ||||
| 
 | ||||
| void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_FS, "(STUBBED) called"); | ||||
| 
 | ||||
|  | ||||
| @ -24,6 +24,7 @@ private: | ||||
| 
 | ||||
|     void Initalize(Kernel::HLERequestContext& ctx); | ||||
|     void MountSdCard(Kernel::HLERequestContext& ctx); | ||||
|     void CreateSaveData(Kernel::HLERequestContext& ctx); | ||||
|     void MountSaveData(Kernel::HLERequestContext& ctx); | ||||
|     void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); | ||||
|     void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei