fs/archive: wrap states into archive manager
This commit is contained in:
		| @@ -19,6 +19,7 @@ | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| #include "core/hle/service/fs/archive.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/service/sm/sm.h" | ||||
| #include "core/hw/hw.h" | ||||
| @@ -191,6 +192,7 @@ System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) { | ||||
|  | ||||
|     service_manager = std::make_shared<Service::SM::ServiceManager>(); | ||||
|     shared_page_handler = std::make_shared<SharedPage::Handler>(); | ||||
|     archive_manager = std::make_unique<Service::FS::ArchiveManager>(); | ||||
|  | ||||
|     HW::Init(); | ||||
|     Kernel::Init(system_mode); | ||||
| @@ -219,6 +221,14 @@ const Service::SM::ServiceManager& System::ServiceManager() const { | ||||
|     return *service_manager; | ||||
| } | ||||
|  | ||||
| Service::FS::ArchiveManager& System::ArchiveManager() { | ||||
|     return *archive_manager; | ||||
| } | ||||
|  | ||||
| const Service::FS::ArchiveManager& System::ArchiveManager() const { | ||||
|     return *archive_manager; | ||||
| } | ||||
|  | ||||
| void System::RegisterSoftwareKeyboard(std::shared_ptr<Frontend::SoftwareKeyboard> swkbd) { | ||||
|     registered_swkbd = std::move(swkbd); | ||||
| } | ||||
|   | ||||
| @@ -31,6 +31,9 @@ namespace Service { | ||||
| namespace SM { | ||||
| class ServiceManager; | ||||
| } | ||||
| namespace FS { | ||||
| class ArchiveManager; | ||||
| } | ||||
| } // namespace Service | ||||
|  | ||||
| namespace Core { | ||||
| @@ -158,6 +161,12 @@ public: | ||||
|      */ | ||||
|     const Service::SM::ServiceManager& ServiceManager() const; | ||||
|  | ||||
|     /// Gets a reference to the archive manager | ||||
|     Service::FS::ArchiveManager& ArchiveManager(); | ||||
|  | ||||
|     /// Gets a const reference to the archive manager | ||||
|     const Service::FS::ArchiveManager& ArchiveManager() const; | ||||
|  | ||||
|     PerfStats perf_stats; | ||||
|     FrameLimiter frame_limiter; | ||||
|  | ||||
| @@ -230,6 +239,8 @@ private: | ||||
|     /// Shared Page | ||||
|     std::shared_ptr<SharedPage::Handler> shared_page_handler; | ||||
|  | ||||
|     std::unique_ptr<Service::FS::ArchiveManager> archive_manager; | ||||
|  | ||||
|     static System s_instance; | ||||
|  | ||||
|     ResultStatus status = ResultStatus::Success; | ||||
|   | ||||
| @@ -8,9 +8,7 @@ | ||||
| #include <memory> | ||||
| #include <system_error> | ||||
| #include <type_traits> | ||||
| #include <unordered_map> | ||||
| #include <utility> | ||||
| #include <boost/container/flat_map.hpp> | ||||
| #include "common/assert.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/file_util.h" | ||||
| @@ -32,27 +30,13 @@ | ||||
|  | ||||
| namespace Service::FS { | ||||
|  | ||||
| using FileSys::ArchiveBackend; | ||||
| using FileSys::ArchiveFactory; | ||||
|  | ||||
| /** | ||||
|  * Map of registered archives, identified by id code. Once an archive is registered here, it is | ||||
|  * never removed until UnregisterArchiveTypes is called. | ||||
|  */ | ||||
| static boost::container::flat_map<ArchiveIdCode, std::unique_ptr<ArchiveFactory>> id_code_map; | ||||
|  | ||||
| /** | ||||
|  * Map of active archive handles. Values are pointers to the archives in `idcode_map`. | ||||
|  */ | ||||
| static std::unordered_map<ArchiveHandle, std::unique_ptr<ArchiveBackend>> handle_map; | ||||
| static ArchiveHandle next_handle; | ||||
|  | ||||
| static ArchiveBackend* GetArchive(ArchiveHandle handle) { | ||||
| ArchiveBackend* ArchiveManager::GetArchive(ArchiveHandle handle) { | ||||
|     auto itr = handle_map.find(handle); | ||||
|     return (itr == handle_map.end()) ? nullptr : itr->second.get(); | ||||
| } | ||||
|  | ||||
| ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archive_path) { | ||||
| ResultVal<ArchiveHandle> ArchiveManager::OpenArchive(ArchiveIdCode id_code, | ||||
|                                                      FileSys::Path& archive_path) { | ||||
|     LOG_TRACE(Service_FS, "Opening archive with id code 0x{:08X}", static_cast<u32>(id_code)); | ||||
|  | ||||
|     auto itr = id_code_map.find(id_code); | ||||
| @@ -70,7 +54,7 @@ ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archi | ||||
|     return MakeResult<ArchiveHandle>(next_handle++); | ||||
| } | ||||
|  | ||||
| ResultCode CloseArchive(ArchiveHandle handle) { | ||||
| ResultCode ArchiveManager::CloseArchive(ArchiveHandle handle) { | ||||
|     if (handle_map.erase(handle) == 0) | ||||
|         return FileSys::ERR_INVALID_ARCHIVE_HANDLE; | ||||
|     else | ||||
| @@ -79,8 +63,8 @@ ResultCode CloseArchive(ArchiveHandle handle) { | ||||
|  | ||||
| // TODO(yuriks): This might be what the fs:REG service is for. See the Register/Unregister calls in | ||||
| // http://3dbrew.org/wiki/Filesystem_services#ProgramRegistry_service_.22fs:REG.22 | ||||
| ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, | ||||
|                                ArchiveIdCode id_code) { | ||||
| ResultCode ArchiveManager::RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, | ||||
|                                                ArchiveIdCode id_code) { | ||||
|     auto result = id_code_map.emplace(id_code, std::move(factory)); | ||||
|  | ||||
|     bool inserted = result.second; | ||||
| @@ -92,9 +76,9 @@ ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factor | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| ResultVal<std::shared_ptr<File>> OpenFileFromArchive(ArchiveHandle archive_handle, | ||||
|                                                      const FileSys::Path& path, | ||||
|                                                      const FileSys::Mode mode) { | ||||
| ResultVal<std::shared_ptr<File>> ArchiveManager::OpenFileFromArchive(ArchiveHandle archive_handle, | ||||
|                                                                      const FileSys::Path& path, | ||||
|                                                                      const FileSys::Mode mode) { | ||||
|     ArchiveBackend* archive = GetArchive(archive_handle); | ||||
|     if (archive == nullptr) | ||||
|         return FileSys::ERR_INVALID_ARCHIVE_HANDLE; | ||||
| @@ -107,7 +91,8 @@ ResultVal<std::shared_ptr<File>> OpenFileFromArchive(ArchiveHandle archive_handl | ||||
|     return MakeResult<std::shared_ptr<File>>(std::move(file)); | ||||
| } | ||||
|  | ||||
| ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { | ||||
| ResultCode ArchiveManager::DeleteFileFromArchive(ArchiveHandle archive_handle, | ||||
|                                                  const FileSys::Path& path) { | ||||
|     ArchiveBackend* archive = GetArchive(archive_handle); | ||||
|     if (archive == nullptr) | ||||
|         return FileSys::ERR_INVALID_ARCHIVE_HANDLE; | ||||
| @@ -115,10 +100,10 @@ ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Pa | ||||
|     return archive->DeleteFile(path); | ||||
| } | ||||
|  | ||||
| ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, | ||||
|                                      const FileSys::Path& src_path, | ||||
|                                      ArchiveHandle dest_archive_handle, | ||||
|                                      const FileSys::Path& dest_path) { | ||||
| ResultCode ArchiveManager::RenameFileBetweenArchives(ArchiveHandle src_archive_handle, | ||||
|                                                      const FileSys::Path& src_path, | ||||
|                                                      ArchiveHandle dest_archive_handle, | ||||
|                                                      const FileSys::Path& dest_path) { | ||||
|     ArchiveBackend* src_archive = GetArchive(src_archive_handle); | ||||
|     ArchiveBackend* dest_archive = GetArchive(dest_archive_handle); | ||||
|     if (src_archive == nullptr || dest_archive == nullptr) | ||||
| @@ -132,7 +117,8 @@ ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, | ||||
|     } | ||||
| } | ||||
|  | ||||
| ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { | ||||
| ResultCode ArchiveManager::DeleteDirectoryFromArchive(ArchiveHandle archive_handle, | ||||
|                                                       const FileSys::Path& path) { | ||||
|     ArchiveBackend* archive = GetArchive(archive_handle); | ||||
|     if (archive == nullptr) | ||||
|         return FileSys::ERR_INVALID_ARCHIVE_HANDLE; | ||||
| @@ -140,8 +126,8 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy | ||||
|     return archive->DeleteDirectory(path); | ||||
| } | ||||
|  | ||||
| ResultCode DeleteDirectoryRecursivelyFromArchive(ArchiveHandle archive_handle, | ||||
|                                                  const FileSys::Path& path) { | ||||
| ResultCode ArchiveManager::DeleteDirectoryRecursivelyFromArchive(ArchiveHandle archive_handle, | ||||
|                                                                  const FileSys::Path& path) { | ||||
|     ArchiveBackend* archive = GetArchive(archive_handle); | ||||
|     if (archive == nullptr) | ||||
|         return FileSys::ERR_INVALID_ARCHIVE_HANDLE; | ||||
| @@ -149,8 +135,8 @@ ResultCode DeleteDirectoryRecursivelyFromArchive(ArchiveHandle archive_handle, | ||||
|     return archive->DeleteDirectoryRecursively(path); | ||||
| } | ||||
|  | ||||
| ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, | ||||
|                                u64 file_size) { | ||||
| ResultCode ArchiveManager::CreateFileInArchive(ArchiveHandle archive_handle, | ||||
|                                                const FileSys::Path& path, u64 file_size) { | ||||
|     ArchiveBackend* archive = GetArchive(archive_handle); | ||||
|     if (archive == nullptr) | ||||
|         return FileSys::ERR_INVALID_ARCHIVE_HANDLE; | ||||
| @@ -158,7 +144,8 @@ ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path | ||||
|     return archive->CreateFile(path, file_size); | ||||
| } | ||||
|  | ||||
| ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { | ||||
| ResultCode ArchiveManager::CreateDirectoryFromArchive(ArchiveHandle archive_handle, | ||||
|                                                       const FileSys::Path& path) { | ||||
|     ArchiveBackend* archive = GetArchive(archive_handle); | ||||
|     if (archive == nullptr) | ||||
|         return FileSys::ERR_INVALID_ARCHIVE_HANDLE; | ||||
| @@ -166,10 +153,10 @@ ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy | ||||
|     return archive->CreateDirectory(path); | ||||
| } | ||||
|  | ||||
| ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, | ||||
|                                           const FileSys::Path& src_path, | ||||
|                                           ArchiveHandle dest_archive_handle, | ||||
|                                           const FileSys::Path& dest_path) { | ||||
| ResultCode ArchiveManager::RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, | ||||
|                                                           const FileSys::Path& src_path, | ||||
|                                                           ArchiveHandle dest_archive_handle, | ||||
|                                                           const FileSys::Path& dest_path) { | ||||
|     ArchiveBackend* src_archive = GetArchive(src_archive_handle); | ||||
|     ArchiveBackend* dest_archive = GetArchive(dest_archive_handle); | ||||
|     if (src_archive == nullptr || dest_archive == nullptr) | ||||
| @@ -183,8 +170,8 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, | ||||
|     } | ||||
| } | ||||
|  | ||||
| ResultVal<std::shared_ptr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, | ||||
|                                                                const FileSys::Path& path) { | ||||
| ResultVal<std::shared_ptr<Directory>> ArchiveManager::OpenDirectoryFromArchive( | ||||
|     ArchiveHandle archive_handle, const FileSys::Path& path) { | ||||
|     ArchiveBackend* archive = GetArchive(archive_handle); | ||||
|     if (archive == nullptr) | ||||
|         return FileSys::ERR_INVALID_ARCHIVE_HANDLE; | ||||
| @@ -197,15 +184,16 @@ ResultVal<std::shared_ptr<Directory>> OpenDirectoryFromArchive(ArchiveHandle arc | ||||
|     return MakeResult<std::shared_ptr<Directory>>(std::move(directory)); | ||||
| } | ||||
|  | ||||
| ResultVal<u64> GetFreeBytesInArchive(ArchiveHandle archive_handle) { | ||||
| ResultVal<u64> ArchiveManager::GetFreeBytesInArchive(ArchiveHandle archive_handle) { | ||||
|     ArchiveBackend* archive = GetArchive(archive_handle); | ||||
|     if (archive == nullptr) | ||||
|         return FileSys::ERR_INVALID_ARCHIVE_HANDLE; | ||||
|     return MakeResult<u64>(archive->GetFreeBytes()); | ||||
| } | ||||
|  | ||||
| ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, | ||||
|                          const FileSys::Path& path) { | ||||
| ResultCode ArchiveManager::FormatArchive(ArchiveIdCode id_code, | ||||
|                                          const FileSys::ArchiveFormatInfo& format_info, | ||||
|                                          const FileSys::Path& path) { | ||||
|     auto archive_itr = id_code_map.find(id_code); | ||||
|     if (archive_itr == id_code_map.end()) { | ||||
|         return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error | ||||
| @@ -214,8 +202,8 @@ ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo | ||||
|     return archive_itr->second->Format(path, format_info); | ||||
| } | ||||
|  | ||||
| ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code, | ||||
|                                                            FileSys::Path& archive_path) { | ||||
| ResultVal<FileSys::ArchiveFormatInfo> ArchiveManager::GetArchiveFormatInfo( | ||||
|     ArchiveIdCode id_code, FileSys::Path& archive_path) { | ||||
|     auto archive = id_code_map.find(id_code); | ||||
|     if (archive == id_code_map.end()) { | ||||
|         return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error | ||||
| @@ -224,9 +212,9 @@ ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code | ||||
|     return archive->second->GetFormatInfo(archive_path); | ||||
| } | ||||
|  | ||||
| ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, | ||||
|                              const std::vector<u8>& smdh_icon, | ||||
|                              const FileSys::ArchiveFormatInfo& format_info) { | ||||
| ResultCode ArchiveManager::CreateExtSaveData(MediaType media_type, u32 high, u32 low, | ||||
|                                              const std::vector<u8>& smdh_icon, | ||||
|                                              const FileSys::ArchiveFormatInfo& format_info) { | ||||
|     // Construct the binary path to the archive first | ||||
|     FileSys::Path path = | ||||
|         FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low); | ||||
| @@ -248,7 +236,7 @@ ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| ResultCode DeleteExtSaveData(MediaType media_type, u32 high, u32 low) { | ||||
| ResultCode ArchiveManager::DeleteExtSaveData(MediaType media_type, u32 high, u32 low) { | ||||
|     // Construct the binary path to the archive first | ||||
|     FileSys::Path path = | ||||
|         FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low); | ||||
| @@ -272,7 +260,7 @@ ResultCode DeleteExtSaveData(MediaType media_type, u32 high, u32 low) { | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| ResultCode DeleteSystemSaveData(u32 high, u32 low) { | ||||
| ResultCode ArchiveManager::DeleteSystemSaveData(u32 high, u32 low) { | ||||
|     // Construct the binary path to the archive first | ||||
|     FileSys::Path path = FileSys::ConstructSystemSaveDataBinaryPath(high, low); | ||||
|  | ||||
| @@ -284,7 +272,7 @@ ResultCode DeleteSystemSaveData(u32 high, u32 low) { | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| ResultCode CreateSystemSaveData(u32 high, u32 low) { | ||||
| ResultCode ArchiveManager::CreateSystemSaveData(u32 high, u32 low) { | ||||
|     // Construct the binary path to the archive first | ||||
|     FileSys::Path path = FileSys::ConstructSystemSaveDataBinaryPath(high, low); | ||||
|  | ||||
| @@ -296,7 +284,7 @@ ResultCode CreateSystemSaveData(u32 high, u32 low) { | ||||
|     return RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| void RegisterArchiveTypes() { | ||||
| void ArchiveManager::RegisterArchiveTypes() { | ||||
|     // TODO(Subv): Add the other archive types (see here for the known types: | ||||
|     // http://3dbrew.org/wiki/FS:OpenArchive#Archive_idcodes). | ||||
|  | ||||
| @@ -348,7 +336,7 @@ void RegisterArchiveTypes() { | ||||
|     RegisterArchiveType(std::move(selfncch_factory), ArchiveIdCode::SelfNCCH); | ||||
| } | ||||
|  | ||||
| void RegisterSelfNCCH(Loader::AppLoader& app_loader) { | ||||
| void ArchiveManager::RegisterSelfNCCH(Loader::AppLoader& app_loader) { | ||||
|     auto itr = id_code_map.find(ArchiveIdCode::SelfNCCH); | ||||
|     if (itr == id_code_map.end()) { | ||||
|         LOG_ERROR(Service_FS, | ||||
| @@ -360,20 +348,8 @@ void RegisterSelfNCCH(Loader::AppLoader& app_loader) { | ||||
|     factory->Register(app_loader); | ||||
| } | ||||
|  | ||||
| void UnregisterArchiveTypes() { | ||||
|     id_code_map.clear(); | ||||
| } | ||||
|  | ||||
| /// Initialize archives | ||||
| void ArchiveInit() { | ||||
|     next_handle = 1; | ||||
| ArchiveManager::ArchiveManager() { | ||||
|     RegisterArchiveTypes(); | ||||
| } | ||||
|  | ||||
| /// Shutdown archives | ||||
| void ArchiveShutdown() { | ||||
|     handle_map.clear(); | ||||
|     UnregisterArchiveTypes(); | ||||
| } | ||||
|  | ||||
| } // namespace Service::FS | ||||
|   | ||||
| @@ -6,7 +6,9 @@ | ||||
|  | ||||
| #include <memory> | ||||
| #include <string> | ||||
| #include <unordered_map> | ||||
| #include <vector> | ||||
| #include <boost/container/flat_map.hpp> | ||||
| #include "common/common_types.h" | ||||
| #include "core/file_sys/archive_backend.h" | ||||
| #include "core/hle/result.h" | ||||
| @@ -43,196 +45,209 @@ enum class MediaType : u32 { NAND = 0, SDMC = 1, GameCard = 2 }; | ||||
|  | ||||
| typedef u64 ArchiveHandle; | ||||
|  | ||||
| /** | ||||
|  * Opens an archive | ||||
|  * @param id_code IdCode of the archive to open | ||||
|  * @param archive_path Path to the archive, used with Binary paths | ||||
|  * @return Handle to the opened archive | ||||
|  */ | ||||
| ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archive_path); | ||||
| using FileSys::ArchiveBackend; | ||||
| using FileSys::ArchiveFactory; | ||||
|  | ||||
| /** | ||||
|  * Closes an archive | ||||
|  * @param handle Handle to the archive to close | ||||
|  */ | ||||
| ResultCode CloseArchive(ArchiveHandle handle); | ||||
| class ArchiveManager { | ||||
| public: | ||||
|     ArchiveManager(); | ||||
|     /** | ||||
|      * Opens an archive | ||||
|      * @param id_code IdCode of the archive to open | ||||
|      * @param archive_path Path to the archive, used with Binary paths | ||||
|      * @return Handle to the opened archive | ||||
|      */ | ||||
|     ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archive_path); | ||||
|  | ||||
| /** | ||||
|  * Registers an Archive type, instances of which can later be opened using its IdCode. | ||||
|  * @param factory File system backend interface to the archive | ||||
|  * @param id_code Id code used to access this type of archive | ||||
|  */ | ||||
| ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, | ||||
|                                ArchiveIdCode id_code); | ||||
|     /** | ||||
|      * Closes an archive | ||||
|      * @param handle Handle to the archive to close | ||||
|      */ | ||||
|     ResultCode CloseArchive(ArchiveHandle handle); | ||||
|  | ||||
| /** | ||||
|  * Open a File from an Archive | ||||
|  * @param archive_handle Handle to an open Archive object | ||||
|  * @param path Path to the File inside of the Archive | ||||
|  * @param mode Mode under which to open the File | ||||
|  * @return The opened File object | ||||
|  */ | ||||
| ResultVal<std::shared_ptr<File>> OpenFileFromArchive(ArchiveHandle archive_handle, | ||||
|                                                      const FileSys::Path& path, | ||||
|                                                      const FileSys::Mode mode); | ||||
|     /** | ||||
|      * Open a File from an Archive | ||||
|      * @param archive_handle Handle to an open Archive object | ||||
|      * @param path Path to the File inside of the Archive | ||||
|      * @param mode Mode under which to open the File | ||||
|      * @return The opened File object | ||||
|      */ | ||||
|     ResultVal<std::shared_ptr<File>> OpenFileFromArchive(ArchiveHandle archive_handle, | ||||
|                                                          const FileSys::Path& path, | ||||
|                                                          const FileSys::Mode mode); | ||||
|  | ||||
| /** | ||||
|  * Delete a File from an Archive | ||||
|  * @param archive_handle Handle to an open Archive object | ||||
|  * @param path Path to the File inside of the Archive | ||||
|  * @return Whether deletion succeeded | ||||
|  */ | ||||
| ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); | ||||
|     /** | ||||
|      * Delete a File from an Archive | ||||
|      * @param archive_handle Handle to an open Archive object | ||||
|      * @param path Path to the File inside of the Archive | ||||
|      * @return Whether deletion succeeded | ||||
|      */ | ||||
|     ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); | ||||
|  | ||||
| /** | ||||
|  * Rename a File between two Archives | ||||
|  * @param src_archive_handle Handle to the source Archive object | ||||
|  * @param src_path Path to the File inside of the source Archive | ||||
|  * @param dest_archive_handle Handle to the destination Archive object | ||||
|  * @param dest_path Path to the File inside of the destination Archive | ||||
|  * @return Whether rename succeeded | ||||
|  */ | ||||
| ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, | ||||
|                                      const FileSys::Path& src_path, | ||||
|                                      ArchiveHandle dest_archive_handle, | ||||
|                                      const FileSys::Path& dest_path); | ||||
|     /** | ||||
|      * Rename a File between two Archives | ||||
|      * @param src_archive_handle Handle to the source Archive object | ||||
|      * @param src_path Path to the File inside of the source Archive | ||||
|      * @param dest_archive_handle Handle to the destination Archive object | ||||
|      * @param dest_path Path to the File inside of the destination Archive | ||||
|      * @return Whether rename succeeded | ||||
|      */ | ||||
|     ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, | ||||
|                                          const FileSys::Path& src_path, | ||||
|                                          ArchiveHandle dest_archive_handle, | ||||
|                                          const FileSys::Path& dest_path); | ||||
|  | ||||
| /** | ||||
|  * Delete a Directory from an Archive | ||||
|  * @param archive_handle Handle to an open Archive object | ||||
|  * @param path Path to the Directory inside of the Archive | ||||
|  * @return Whether deletion succeeded | ||||
|  */ | ||||
| ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); | ||||
|     /** | ||||
|      * Delete a Directory from an Archive | ||||
|      * @param archive_handle Handle to an open Archive object | ||||
|      * @param path Path to the Directory inside of the Archive | ||||
|      * @return Whether deletion succeeded | ||||
|      */ | ||||
|     ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); | ||||
|  | ||||
| /** | ||||
|  * Delete a Directory and anything under it from an Archive | ||||
|  * @param archive_handle Handle to an open Archive object | ||||
|  * @param path Path to the Directory inside of the Archive | ||||
|  * @return Whether deletion succeeded | ||||
|  */ | ||||
| ResultCode DeleteDirectoryRecursivelyFromArchive(ArchiveHandle archive_handle, | ||||
|                                                  const FileSys::Path& path); | ||||
|     /** | ||||
|      * Delete a Directory and anything under it from an Archive | ||||
|      * @param archive_handle Handle to an open Archive object | ||||
|      * @param path Path to the Directory inside of the Archive | ||||
|      * @return Whether deletion succeeded | ||||
|      */ | ||||
|     ResultCode DeleteDirectoryRecursivelyFromArchive(ArchiveHandle archive_handle, | ||||
|                                                      const FileSys::Path& path); | ||||
|  | ||||
| /** | ||||
|  * Create a File in an Archive | ||||
|  * @param archive_handle Handle to an open Archive object | ||||
|  * @param path Path to the File inside of the Archive | ||||
|  * @param file_size The size of the new file, filled with zeroes | ||||
|  * @return File creation result code | ||||
|  */ | ||||
| ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, | ||||
|                                u64 file_size); | ||||
|     /** | ||||
|      * Create a File in an Archive | ||||
|      * @param archive_handle Handle to an open Archive object | ||||
|      * @param path Path to the File inside of the Archive | ||||
|      * @param file_size The size of the new file, filled with zeroes | ||||
|      * @return File creation result code | ||||
|      */ | ||||
|     ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, | ||||
|                                    u64 file_size); | ||||
|  | ||||
| /** | ||||
|  * Create a Directory from an Archive | ||||
|  * @param archive_handle Handle to an open Archive object | ||||
|  * @param path Path to the Directory inside of the Archive | ||||
|  * @return Whether creation of directory succeeded | ||||
|  */ | ||||
| ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); | ||||
|     /** | ||||
|      * Create a Directory from an Archive | ||||
|      * @param archive_handle Handle to an open Archive object | ||||
|      * @param path Path to the Directory inside of the Archive | ||||
|      * @return Whether creation of directory succeeded | ||||
|      */ | ||||
|     ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); | ||||
|  | ||||
| /** | ||||
|  * Rename a Directory between two Archives | ||||
|  * @param src_archive_handle Handle to the source Archive object | ||||
|  * @param src_path Path to the Directory inside of the source Archive | ||||
|  * @param dest_archive_handle Handle to the destination Archive object | ||||
|  * @param dest_path Path to the Directory inside of the destination Archive | ||||
|  * @return Whether rename succeeded | ||||
|  */ | ||||
| ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, | ||||
|                                           const FileSys::Path& src_path, | ||||
|                                           ArchiveHandle dest_archive_handle, | ||||
|                                           const FileSys::Path& dest_path); | ||||
|     /** | ||||
|      * Rename a Directory between two Archives | ||||
|      * @param src_archive_handle Handle to the source Archive object | ||||
|      * @param src_path Path to the Directory inside of the source Archive | ||||
|      * @param dest_archive_handle Handle to the destination Archive object | ||||
|      * @param dest_path Path to the Directory inside of the destination Archive | ||||
|      * @return Whether rename succeeded | ||||
|      */ | ||||
|     ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, | ||||
|                                               const FileSys::Path& src_path, | ||||
|                                               ArchiveHandle dest_archive_handle, | ||||
|                                               const FileSys::Path& dest_path); | ||||
|  | ||||
| /** | ||||
|  * Open a Directory from an Archive | ||||
|  * @param archive_handle Handle to an open Archive object | ||||
|  * @param path Path to the Directory inside of the Archive | ||||
|  * @return The opened Directory object | ||||
|  */ | ||||
| ResultVal<std::shared_ptr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, | ||||
|                                                                const FileSys::Path& path); | ||||
|     /** | ||||
|      * Open a Directory from an Archive | ||||
|      * @param archive_handle Handle to an open Archive object | ||||
|      * @param path Path to the Directory inside of the Archive | ||||
|      * @return The opened Directory object | ||||
|      */ | ||||
|     ResultVal<std::shared_ptr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, | ||||
|                                                                    const FileSys::Path& path); | ||||
|  | ||||
| /** | ||||
|  * Get the free space in an Archive | ||||
|  * @param archive_handle Handle to an open Archive object | ||||
|  * @return The number of free bytes in the archive | ||||
|  */ | ||||
| ResultVal<u64> GetFreeBytesInArchive(ArchiveHandle archive_handle); | ||||
|     /** | ||||
|      * Get the free space in an Archive | ||||
|      * @param archive_handle Handle to an open Archive object | ||||
|      * @return The number of free bytes in the archive | ||||
|      */ | ||||
|     ResultVal<u64> GetFreeBytesInArchive(ArchiveHandle archive_handle); | ||||
|  | ||||
| /** | ||||
|  * Erases the contents of the physical folder that contains the archive | ||||
|  * identified by the specified id code and path | ||||
|  * @param id_code The id of the archive to format | ||||
|  * @param format_info Format information about the new archive | ||||
|  * @param path The path to the archive, if relevant. | ||||
|  * @return ResultCode 0 on success or the corresponding code on error | ||||
|  */ | ||||
| ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, | ||||
|                          const FileSys::Path& path = FileSys::Path()); | ||||
|     /** | ||||
|      * Erases the contents of the physical folder that contains the archive | ||||
|      * identified by the specified id code and path | ||||
|      * @param id_code The id of the archive to format | ||||
|      * @param format_info Format information about the new archive | ||||
|      * @param path The path to the archive, if relevant. | ||||
|      * @return ResultCode 0 on success or the corresponding code on error | ||||
|      */ | ||||
|     ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, | ||||
|                              const FileSys::Path& path = FileSys::Path()); | ||||
|  | ||||
| /** | ||||
|  * Retrieves the format info about the archive of the specified type and path. | ||||
|  * The format info is supplied by the client code when creating archives. | ||||
|  * @param id_code The id of the archive | ||||
|  * @param archive_path The path of the archive, if relevant | ||||
|  * @return The format info of the archive, or the corresponding error code if failed. | ||||
|  */ | ||||
| ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code, | ||||
|                                                            FileSys::Path& archive_path); | ||||
|     /** | ||||
|      * Retrieves the format info about the archive of the specified type and path. | ||||
|      * The format info is supplied by the client code when creating archives. | ||||
|      * @param id_code The id of the archive | ||||
|      * @param archive_path The path of the archive, if relevant | ||||
|      * @return The format info of the archive, or the corresponding error code if failed. | ||||
|      */ | ||||
|     ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code, | ||||
|                                                                FileSys::Path& archive_path); | ||||
|  | ||||
| /** | ||||
|  * Creates a blank SharedExtSaveData archive for the specified extdata ID | ||||
|  * @param media_type The media type of the archive to create (NAND / SDMC) | ||||
|  * @param high The high word of the extdata id to create | ||||
|  * @param low The low word of the extdata id to create | ||||
|  * @param smdh_icon the SMDH icon for this ExtSaveData | ||||
|  * @param format_info Format information about the new archive | ||||
|  * @return ResultCode 0 on success or the corresponding code on error | ||||
|  */ | ||||
| ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, | ||||
|                              const std::vector<u8>& smdh_icon, | ||||
|                              const FileSys::ArchiveFormatInfo& format_info); | ||||
|     /** | ||||
|      * Creates a blank SharedExtSaveData archive for the specified extdata ID | ||||
|      * @param media_type The media type of the archive to create (NAND / SDMC) | ||||
|      * @param high The high word of the extdata id to create | ||||
|      * @param low The low word of the extdata id to create | ||||
|      * @param smdh_icon the SMDH icon for this ExtSaveData | ||||
|      * @param format_info Format information about the new archive | ||||
|      * @return ResultCode 0 on success or the corresponding code on error | ||||
|      */ | ||||
|     ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, | ||||
|                                  const std::vector<u8>& smdh_icon, | ||||
|                                  const FileSys::ArchiveFormatInfo& format_info); | ||||
|  | ||||
| /** | ||||
|  * Deletes the SharedExtSaveData archive for the specified extdata ID | ||||
|  * @param media_type The media type of the archive to delete (NAND / SDMC) | ||||
|  * @param high The high word of the extdata id to delete | ||||
|  * @param low The low word of the extdata id to delete | ||||
|  * @return ResultCode 0 on success or the corresponding code on error | ||||
|  */ | ||||
| ResultCode DeleteExtSaveData(MediaType media_type, u32 high, u32 low); | ||||
|     /** | ||||
|      * Deletes the SharedExtSaveData archive for the specified extdata ID | ||||
|      * @param media_type The media type of the archive to delete (NAND / SDMC) | ||||
|      * @param high The high word of the extdata id to delete | ||||
|      * @param low The low word of the extdata id to delete | ||||
|      * @return ResultCode 0 on success or the corresponding code on error | ||||
|      */ | ||||
|     ResultCode DeleteExtSaveData(MediaType media_type, u32 high, u32 low); | ||||
|  | ||||
| /** | ||||
|  * Deletes the SystemSaveData archive folder for the specified save data id | ||||
|  * @param high The high word of the SystemSaveData archive to delete | ||||
|  * @param low The low word of the SystemSaveData archive to delete | ||||
|  * @return ResultCode 0 on success or the corresponding code on error | ||||
|  */ | ||||
| ResultCode DeleteSystemSaveData(u32 high, u32 low); | ||||
|     /** | ||||
|      * Deletes the SystemSaveData archive folder for the specified save data id | ||||
|      * @param high The high word of the SystemSaveData archive to delete | ||||
|      * @param low The low word of the SystemSaveData archive to delete | ||||
|      * @return ResultCode 0 on success or the corresponding code on error | ||||
|      */ | ||||
|     ResultCode DeleteSystemSaveData(u32 high, u32 low); | ||||
|  | ||||
| /** | ||||
|  * Creates the SystemSaveData archive folder for the specified save data id | ||||
|  * @param high The high word of the SystemSaveData archive to create | ||||
|  * @param low The low word of the SystemSaveData archive to create | ||||
|  * @return ResultCode 0 on success or the corresponding code on error | ||||
|  */ | ||||
| ResultCode CreateSystemSaveData(u32 high, u32 low); | ||||
|     /** | ||||
|      * Creates the SystemSaveData archive folder for the specified save data id | ||||
|      * @param high The high word of the SystemSaveData archive to create | ||||
|      * @param low The low word of the SystemSaveData archive to create | ||||
|      * @return ResultCode 0 on success or the corresponding code on error | ||||
|      */ | ||||
|     ResultCode CreateSystemSaveData(u32 high, u32 low); | ||||
|  | ||||
| /// Initialize archives | ||||
| void ArchiveInit(); | ||||
|     /// Registers a new NCCH file with the SelfNCCH archive factory | ||||
|     void RegisterSelfNCCH(Loader::AppLoader& app_loader); | ||||
|  | ||||
| /// Shutdown archives | ||||
| void ArchiveShutdown(); | ||||
| private: | ||||
|     /** | ||||
|      * Registers an Archive type, instances of which can later be opened using its IdCode. | ||||
|      * @param factory File system backend interface to the archive | ||||
|      * @param id_code Id code used to access this type of archive | ||||
|      */ | ||||
|     ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, | ||||
|                                    ArchiveIdCode id_code); | ||||
|  | ||||
| /// Registers a new NCCH file with the SelfNCCH archive factory | ||||
| void RegisterSelfNCCH(Loader::AppLoader& app_loader); | ||||
|     /// Register all archive types | ||||
|     void RegisterArchiveTypes(); | ||||
|  | ||||
| /// Register all archive types | ||||
| void RegisterArchiveTypes(); | ||||
|     ArchiveBackend* GetArchive(ArchiveHandle handle); | ||||
|  | ||||
| /// Unregister all archive types | ||||
| void UnregisterArchiveTypes(); | ||||
|     /** | ||||
|      * Map of registered archives, identified by id code. Once an archive is registered here, it is | ||||
|      * never removed until UnregisterArchiveTypes is called. | ||||
|      */ | ||||
|     boost::container::flat_map<ArchiveIdCode, std::unique_ptr<ArchiveFactory>> id_code_map; | ||||
|  | ||||
|     /** | ||||
|      * Map of active archive handles to archive objects | ||||
|      */ | ||||
|     std::unordered_map<ArchiveHandle, std::unique_ptr<ArchiveBackend>> handle_map; | ||||
|     ArchiveHandle next_handle = 1; | ||||
| }; | ||||
|  | ||||
| } // namespace Service::FS | ||||
|   | ||||
| @@ -56,7 +56,7 @@ void FS_USER::OpenFile(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_DEBUG(Service_FS, "path={}, mode={} attrs={}", file_path.DebugStr(), mode.hex, attributes); | ||||
|  | ||||
|     ResultVal<std::shared_ptr<File>> file_res = | ||||
|         OpenFileFromArchive(archive_handle, file_path, mode); | ||||
|         archives.OpenFileFromArchive(archive_handle, file_path, mode); | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||
|     rb.Push(file_res.Code()); | ||||
|     if (file_res.Succeeded()) { | ||||
| @@ -92,7 +92,7 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||
|  | ||||
|     ResultVal<ArchiveHandle> archive_handle = Service::FS::OpenArchive(archive_id, archive_path); | ||||
|     ResultVal<ArchiveHandle> archive_handle = archives.OpenArchive(archive_id, archive_path); | ||||
|     if (archive_handle.Failed()) { | ||||
|         LOG_ERROR(Service_FS, | ||||
|                   "Failed to get a handle for archive archive_id=0x{:08X} archive_path={}", | ||||
| @@ -101,10 +101,10 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { | ||||
|         rb.PushMoveObjects<Kernel::Object>(nullptr); | ||||
|         return; | ||||
|     } | ||||
|     SCOPE_EXIT({ Service::FS::CloseArchive(*archive_handle); }); | ||||
|     SCOPE_EXIT({ archives.CloseArchive(*archive_handle); }); | ||||
|  | ||||
|     ResultVal<std::shared_ptr<File>> file_res = | ||||
|         OpenFileFromArchive(*archive_handle, file_path, mode); | ||||
|         archives.OpenFileFromArchive(*archive_handle, file_path, mode); | ||||
|     rb.Push(file_res.Code()); | ||||
|     if (file_res.Succeeded()) { | ||||
|         std::shared_ptr<File> file = *file_res; | ||||
| @@ -131,7 +131,7 @@ void FS_USER::DeleteFile(Kernel::HLERequestContext& ctx) { | ||||
|               file_path.DebugStr()); | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(DeleteFileFromArchive(archive_handle, file_path)); | ||||
|     rb.Push(archives.DeleteFileFromArchive(archive_handle, file_path)); | ||||
| } | ||||
|  | ||||
| void FS_USER::RenameFile(Kernel::HLERequestContext& ctx) { | ||||
| @@ -158,8 +158,8 @@ void FS_USER::RenameFile(Kernel::HLERequestContext& ctx) { | ||||
|               static_cast<u32>(dest_filename_type), dest_filename_size, dest_file_path.DebugStr()); | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(RenameFileBetweenArchives(src_archive_handle, src_file_path, dest_archive_handle, | ||||
|                                       dest_file_path)); | ||||
|     rb.Push(archives.RenameFileBetweenArchives(src_archive_handle, src_file_path, | ||||
|                                                dest_archive_handle, dest_file_path)); | ||||
| } | ||||
|  | ||||
| void FS_USER::DeleteDirectory(Kernel::HLERequestContext& ctx) { | ||||
| @@ -178,7 +178,7 @@ void FS_USER::DeleteDirectory(Kernel::HLERequestContext& ctx) { | ||||
|               dir_path.DebugStr()); | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(DeleteDirectoryFromArchive(archive_handle, dir_path)); | ||||
|     rb.Push(archives.DeleteDirectoryFromArchive(archive_handle, dir_path)); | ||||
| } | ||||
|  | ||||
| void FS_USER::DeleteDirectoryRecursively(Kernel::HLERequestContext& ctx) { | ||||
| @@ -197,7 +197,7 @@ void FS_USER::DeleteDirectoryRecursively(Kernel::HLERequestContext& ctx) { | ||||
|               dir_path.DebugStr()); | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(DeleteDirectoryRecursivelyFromArchive(archive_handle, dir_path)); | ||||
|     rb.Push(archives.DeleteDirectoryRecursivelyFromArchive(archive_handle, dir_path)); | ||||
| } | ||||
|  | ||||
| void FS_USER::CreateFile(Kernel::HLERequestContext& ctx) { | ||||
| @@ -218,7 +218,7 @@ void FS_USER::CreateFile(Kernel::HLERequestContext& ctx) { | ||||
|               static_cast<u32>(filename_type), attributes, file_size, file_path.DebugStr()); | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(CreateFileInArchive(archive_handle, file_path, file_size)); | ||||
|     rb.Push(archives.CreateFileInArchive(archive_handle, file_path, file_size)); | ||||
| } | ||||
|  | ||||
| void FS_USER::CreateDirectory(Kernel::HLERequestContext& ctx) { | ||||
| @@ -236,7 +236,7 @@ void FS_USER::CreateDirectory(Kernel::HLERequestContext& ctx) { | ||||
|               dir_path.DebugStr()); | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(CreateDirectoryFromArchive(archive_handle, dir_path)); | ||||
|     rb.Push(archives.CreateDirectoryFromArchive(archive_handle, dir_path)); | ||||
| } | ||||
|  | ||||
| void FS_USER::RenameDirectory(Kernel::HLERequestContext& ctx) { | ||||
| @@ -262,8 +262,8 @@ void FS_USER::RenameDirectory(Kernel::HLERequestContext& ctx) { | ||||
|               static_cast<u32>(dest_dirname_type), dest_dirname_size, dest_dir_path.DebugStr()); | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(RenameDirectoryBetweenArchives(src_archive_handle, src_dir_path, dest_archive_handle, | ||||
|                                            dest_dir_path)); | ||||
|     rb.Push(archives.RenameDirectoryBetweenArchives(src_archive_handle, src_dir_path, | ||||
|                                                     dest_archive_handle, dest_dir_path)); | ||||
| } | ||||
|  | ||||
| void FS_USER::OpenDirectory(Kernel::HLERequestContext& ctx) { | ||||
| @@ -281,7 +281,7 @@ void FS_USER::OpenDirectory(Kernel::HLERequestContext& ctx) { | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||
|     ResultVal<std::shared_ptr<Directory>> dir_res = | ||||
|         OpenDirectoryFromArchive(archive_handle, dir_path); | ||||
|         archives.OpenDirectoryFromArchive(archive_handle, dir_path); | ||||
|     rb.Push(dir_res.Code()); | ||||
|     if (dir_res.Succeeded()) { | ||||
|         std::shared_ptr<Directory> directory = *dir_res; | ||||
| @@ -308,7 +308,7 @@ void FS_USER::OpenArchive(Kernel::HLERequestContext& ctx) { | ||||
|               archive_path.DebugStr()); | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(3, 0); | ||||
|     ResultVal<ArchiveHandle> handle = Service::FS::OpenArchive(archive_id, archive_path); | ||||
|     ResultVal<ArchiveHandle> handle = archives.OpenArchive(archive_id, archive_path); | ||||
|     rb.Push(handle.Code()); | ||||
|     if (handle.Succeeded()) { | ||||
|         rb.PushRaw(*handle); | ||||
| @@ -325,7 +325,7 @@ void FS_USER::CloseArchive(Kernel::HLERequestContext& ctx) { | ||||
|     auto archive_handle = rp.PopRaw<ArchiveHandle>(); | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(Service::FS::CloseArchive(archive_handle)); | ||||
|     rb.Push(archives.CloseArchive(archive_handle)); | ||||
| } | ||||
|  | ||||
| void FS_USER::IsSdmcDetected(Kernel::HLERequestContext& ctx) { | ||||
| @@ -384,7 +384,7 @@ void FS_USER::FormatSaveData(Kernel::HLERequestContext& ctx) { | ||||
|     format_info.number_files = number_files; | ||||
|     format_info.total_size = block_size * 512; | ||||
|  | ||||
|     rb.Push(FormatArchive(ArchiveIdCode::SaveData, format_info)); | ||||
|     rb.Push(archives.FormatArchive(ArchiveIdCode::SaveData, format_info)); | ||||
| } | ||||
|  | ||||
| void FS_USER::FormatThisUserSaveData(Kernel::HLERequestContext& ctx) { | ||||
| @@ -403,7 +403,7 @@ void FS_USER::FormatThisUserSaveData(Kernel::HLERequestContext& ctx) { | ||||
|     format_info.total_size = block_size * 512; | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(FormatArchive(ArchiveIdCode::SaveData, format_info)); | ||||
|     rb.Push(archives.FormatArchive(ArchiveIdCode::SaveData, format_info)); | ||||
|  | ||||
|     LOG_TRACE(Service_FS, "called"); | ||||
| } | ||||
| @@ -411,7 +411,7 @@ void FS_USER::FormatThisUserSaveData(Kernel::HLERequestContext& ctx) { | ||||
| void FS_USER::GetFreeBytes(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx, 0x812, 2, 0); | ||||
|     ArchiveHandle archive_handle = rp.PopRaw<ArchiveHandle>(); | ||||
|     ResultVal<u64> bytes_res = GetFreeBytesInArchive(archive_handle); | ||||
|     ResultVal<u64> bytes_res = archives.GetFreeBytesInArchive(archive_handle); | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(3, 0); | ||||
|     rb.Push(bytes_res.Code()); | ||||
| @@ -445,7 +445,7 @@ void FS_USER::CreateExtSaveData(Kernel::HLERequestContext& ctx) { | ||||
|     format_info.total_size = 0; | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||
|     rb.Push(Service::FS::CreateExtSaveData(media_type, save_high, save_low, icon, format_info)); | ||||
|     rb.Push(archives.CreateExtSaveData(media_type, save_high, save_low, icon, format_info)); | ||||
|     rb.PushMappedBuffer(icon_buffer); | ||||
|  | ||||
|     LOG_DEBUG(Service_FS, | ||||
| @@ -462,7 +462,7 @@ void FS_USER::DeleteExtSaveData(Kernel::HLERequestContext& ctx) { | ||||
|     u32 unknown = rp.Pop<u32>(); // TODO(Subv): Figure out what this is | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(Service::FS::DeleteExtSaveData(media_type, save_high, save_low)); | ||||
|     rb.Push(archives.DeleteExtSaveData(media_type, save_high, save_low)); | ||||
|  | ||||
|     LOG_DEBUG(Service_FS, | ||||
|               "called, save_low={:08X} save_high={:08X} media_type={:08X} unknown={:08X}", save_low, | ||||
| @@ -483,7 +483,7 @@ void FS_USER::DeleteSystemSaveData(Kernel::HLERequestContext& ctx) { | ||||
|     u32 savedata_low = rp.Pop<u32>(); | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(Service::FS::DeleteSystemSaveData(savedata_high, savedata_low)); | ||||
|     rb.Push(archives.DeleteSystemSaveData(savedata_high, savedata_low)); | ||||
| } | ||||
|  | ||||
| void FS_USER::CreateSystemSaveData(Kernel::HLERequestContext& ctx) { | ||||
| @@ -506,7 +506,7 @@ void FS_USER::CreateSystemSaveData(Kernel::HLERequestContext& ctx) { | ||||
|         file_buckets, duplicate); | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(Service::FS::CreateSystemSaveData(savedata_high, savedata_low)); | ||||
|     rb.Push(archives.CreateSystemSaveData(savedata_high, savedata_low)); | ||||
| } | ||||
|  | ||||
| void FS_USER::CreateLegacySystemSaveData(Kernel::HLERequestContext& ctx) { | ||||
| @@ -528,7 +528,7 @@ void FS_USER::CreateLegacySystemSaveData(Kernel::HLERequestContext& ctx) { | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     // With this command, the SystemSaveData always has save_high = 0 (Always created in the NAND) | ||||
|     rb.Push(Service::FS::CreateSystemSaveData(0, savedata_id)); | ||||
|     rb.Push(archives.CreateSystemSaveData(0, savedata_id)); | ||||
| } | ||||
|  | ||||
| void FS_USER::InitializeWithSdkVersion(Kernel::HLERequestContext& ctx) { | ||||
| @@ -595,7 +595,7 @@ void FS_USER::GetFormatInfo(Kernel::HLERequestContext& ctx) { | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(5, 0); | ||||
|  | ||||
|     auto format_info = GetArchiveFormatInfo(archive_id, archive_path); | ||||
|     auto format_info = archives.GetArchiveFormatInfo(archive_id, archive_path); | ||||
|     rb.Push(format_info.Code()); | ||||
|     if (format_info.Failed()) { | ||||
|         LOG_ERROR(Service_FS, "Failed to retrieve the format info"); | ||||
| @@ -663,7 +663,7 @@ void FS_USER::ObsoletedCreateExtSaveData(Kernel::HLERequestContext& ctx) { | ||||
|     format_info.total_size = 0; | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||
|     rb.Push(Service::FS::CreateExtSaveData(media_type, save_high, save_low, icon, format_info)); | ||||
|     rb.Push(archives.CreateExtSaveData(media_type, save_high, save_low, icon, format_info)); | ||||
|     rb.PushMappedBuffer(icon_buffer); | ||||
|  | ||||
|     LOG_DEBUG(Service_FS, | ||||
| @@ -678,7 +678,7 @@ void FS_USER::ObsoletedDeleteExtSaveData(Kernel::HLERequestContext& ctx) { | ||||
|     u32 save_low = rp.Pop<u32>(); | ||||
|  | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(Service::FS::DeleteExtSaveData(media_type, 0, save_low)); | ||||
|     rb.Push(archives.DeleteExtSaveData(media_type, 0, save_low)); | ||||
|  | ||||
|     LOG_DEBUG(Service_FS, "called, save_low={:08X} media_type={:08X}", save_low, | ||||
|               static_cast<u32>(media_type)); | ||||
| @@ -736,7 +736,7 @@ void FS_USER::GetSaveDataSecureValue(Kernel::HLERequestContext& ctx) { | ||||
|     rb.Push<u64>(0);      // the secure value | ||||
| } | ||||
|  | ||||
| FS_USER::FS_USER() : ServiceFramework("fs:USER", 30) { | ||||
| FS_USER::FS_USER(ArchiveManager& archives) : ServiceFramework("fs:USER", 30), archives(archives) { | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {0x000100C6, nullptr, "Dummy1"}, | ||||
|         {0x040100C4, nullptr, "Control"}, | ||||
| @@ -855,6 +855,6 @@ FS_USER::FS_USER() : ServiceFramework("fs:USER", 30) { | ||||
|  | ||||
| void InstallInterfaces(Core::System& system) { | ||||
|     auto& service_manager = system.ServiceManager(); | ||||
|     std::make_shared<FS_USER>()->InstallAsService(service_manager); | ||||
|     std::make_shared<FS_USER>(system.ArchiveManager())->InstallAsService(service_manager); | ||||
| } | ||||
| } // namespace Service::FS | ||||
|   | ||||
| @@ -13,9 +13,11 @@ class System; | ||||
|  | ||||
| namespace Service::FS { | ||||
|  | ||||
| class ArchiveManager; | ||||
|  | ||||
| class FS_USER final : public ServiceFramework<FS_USER> { | ||||
| public: | ||||
|     FS_USER(); | ||||
|     explicit FS_USER(ArchiveManager& archives); | ||||
|  | ||||
| private: | ||||
|     void Initialize(Kernel::HLERequestContext& ctx); | ||||
| @@ -519,6 +521,8 @@ private: | ||||
|     void GetSaveDataSecureValue(Kernel::HLERequestContext& ctx); | ||||
|  | ||||
|     u32 priority = -1; ///< For SetPriority and GetPriority service functions | ||||
|  | ||||
|     ArchiveManager& archives; | ||||
| }; | ||||
|  | ||||
| void InstallInterfaces(Core::System& system); | ||||
|   | ||||
| @@ -236,7 +236,6 @@ static bool AttemptLLE(const ServiceModuleInfo& service_module) { | ||||
|  | ||||
| /// Initialize ServiceManager | ||||
| void Init(Core::System& core, std::shared_ptr<SM::ServiceManager>& sm) { | ||||
|     FS::ArchiveInit(); | ||||
|     SM::ServiceManager::InstallInterfaces(sm); | ||||
|  | ||||
|     for (const auto& service_module : service_module_map) { | ||||
| @@ -248,7 +247,6 @@ void Init(Core::System& core, std::shared_ptr<SM::ServiceManager>& sm) { | ||||
|  | ||||
| /// Shutdown ServiceManager | ||||
| void Shutdown() { | ||||
|     FS::ArchiveShutdown(); | ||||
|  | ||||
|     g_kernel_named_ports.clear(); | ||||
|     LOG_DEBUG(Service, "shutdown OK"); | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| #include <algorithm> | ||||
| #include <vector> | ||||
| #include "common/logging/log.h" | ||||
| #include "core/file_sys/archive_selfncch.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/kernel/resource_limit.h" | ||||
| #include "core/hle/service/fs/archive.h" | ||||
| @@ -277,7 +277,7 @@ ResultStatus AppLoader_THREEDSX::Load(Kernel::SharedPtr<Kernel::Process>& proces | ||||
|  | ||||
|     process->Run(48, Kernel::DEFAULT_STACK_SIZE); | ||||
|  | ||||
|     Service::FS::RegisterSelfNCCH(*this); | ||||
|     Core::System::GetInstance().ArchiveManager().RegisterSelfNCCH(*this); | ||||
|  | ||||
|     is_loaded = true; | ||||
|     return ResultStatus::Success; | ||||
|   | ||||
| @@ -14,7 +14,6 @@ | ||||
| #include "common/string_util.h" | ||||
| #include "common/swap.h" | ||||
| #include "core/core.h" | ||||
| #include "core/file_sys/archive_selfncch.h" | ||||
| #include "core/file_sys/ncch_container.h" | ||||
| #include "core/file_sys/title_metadata.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| @@ -185,7 +184,7 @@ ResultStatus AppLoader_NCCH::Load(Kernel::SharedPtr<Kernel::Process>& process) { | ||||
|     if (ResultStatus::Success != result) | ||||
|         return result; | ||||
|  | ||||
|     Service::FS::RegisterSelfNCCH(*this); | ||||
|     Core::System::GetInstance().ArchiveManager().RegisterSelfNCCH(*this); | ||||
|  | ||||
|     ParseRegionLockoutInfo(); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Weiyi Wang
					Weiyi Wang