From 4468625080c9388f2fe81a791e8295e6961e96f5 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Thu, 5 Feb 2015 22:32:15 -0200 Subject: FS: Get rid of completely useless Archive class --- src/core/hle/service/fs/archive.cpp | 62 ++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 36 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index ccf132f31..6030e05e0 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -74,18 +74,6 @@ enum class DirectoryCommand : u32 { Close = 0x08020000, }; -class Archive { -public: - Archive(std::unique_ptr&& backend, ArchiveIdCode id_code) - : id_code(id_code), backend(std::move(backend)) { - } - - std::string GetName() const { return "Archive: " + backend->GetName(); } - - ArchiveIdCode id_code; ///< Id code of the archive - std::unique_ptr backend; ///< Archive backend interface -}; - class File : public Kernel::Session { public: File(std::unique_ptr&& backend, const FileSys::Path& path) @@ -244,19 +232,21 @@ public: //////////////////////////////////////////////////////////////////////////////////////////////////// +using FileSys::ArchiveBackend; + /** * Map of registered archives, identified by id code. Once an archive is registered here, it is * never removed until the FS service is shut down. */ -static std::unordered_map> id_code_map; +static std::unordered_map> id_code_map; /** * Map of active archive handles. Values are pointers to the archives in `idcode_map`. */ -static std::unordered_map handle_map; +static std::unordered_map handle_map; static ArchiveHandle next_handle; -static Archive* GetArchive(ArchiveHandle handle) { +static ArchiveBackend* GetArchive(ArchiveHandle handle) { auto itr = handle_map.find(handle); return (itr == handle_map.end()) ? nullptr : itr->second; } @@ -271,7 +261,7 @@ ResultVal OpenArchive(ArchiveIdCode id_code, FileSys::Path& archi ErrorSummary::NotFound, ErrorLevel::Permanent); } - ResultCode res = itr->second->backend->Open(archive_path); + ResultCode res = itr->second->Open(archive_path); if (!res.IsSuccess()) return res; @@ -293,7 +283,7 @@ 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 CreateArchive(std::unique_ptr&& backend, ArchiveIdCode id_code) { - auto result = id_code_map.emplace(id_code, Common::make_unique(std::move(backend), id_code)); + auto result = id_code_map.emplace(id_code, std::move(backend)); bool inserted = result.second; _dbg_assert_msg_(Service_FS, inserted, "Tried to register more than one archive with same id code"); @@ -305,11 +295,11 @@ ResultCode CreateArchive(std::unique_ptr&& backend, Arc ResultVal> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode) { - Archive* archive = GetArchive(archive_handle); + ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; - std::unique_ptr backend = archive->backend->OpenFile(path, mode); + std::unique_ptr backend = archive->OpenFile(path, mode); if (backend == nullptr) { return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Status); @@ -320,11 +310,11 @@ ResultVal> OpenFileFromArchive(ArchiveHandle } ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { - Archive* archive = GetArchive(archive_handle); + ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; - if (archive->backend->DeleteFile(path)) + if (archive->DeleteFile(path)) return RESULT_SUCCESS; return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description ErrorSummary::Canceled, ErrorLevel::Status); @@ -332,13 +322,13 @@ ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Pa ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path) { - Archive* src_archive = GetArchive(src_archive_handle); - Archive* dest_archive = GetArchive(dest_archive_handle); + ArchiveBackend* src_archive = GetArchive(src_archive_handle); + ArchiveBackend* dest_archive = GetArchive(dest_archive_handle); if (src_archive == nullptr || dest_archive == nullptr) return ERR_INVALID_HANDLE; if (src_archive == dest_archive) { - if (src_archive->backend->RenameFile(src_path, dest_path)) + if (src_archive->RenameFile(src_path, dest_path)) return RESULT_SUCCESS; } else { // TODO: Implement renaming across archives @@ -352,30 +342,30 @@ ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const Fil } ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { - Archive* archive = GetArchive(archive_handle); + ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; - if (archive->backend->DeleteDirectory(path)) + if (archive->DeleteDirectory(path)) return RESULT_SUCCESS; return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description ErrorSummary::Canceled, ErrorLevel::Status); } ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size) { - Archive* archive = GetArchive(archive_handle); + ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; - return archive->backend->CreateFile(path, file_size); + return archive->CreateFile(path, file_size); } ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { - Archive* archive = GetArchive(archive_handle); + ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; - if (archive->backend->CreateDirectory(path)) + if (archive->CreateDirectory(path)) return RESULT_SUCCESS; return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description ErrorSummary::Canceled, ErrorLevel::Status); @@ -383,13 +373,13 @@ ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path) { - Archive* src_archive = GetArchive(src_archive_handle); - Archive* dest_archive = GetArchive(dest_archive_handle); + ArchiveBackend* src_archive = GetArchive(src_archive_handle); + ArchiveBackend* dest_archive = GetArchive(dest_archive_handle); if (src_archive == nullptr || dest_archive == nullptr) return ERR_INVALID_HANDLE; if (src_archive == dest_archive) { - if (src_archive->backend->RenameDirectory(src_path, dest_path)) + if (src_archive->RenameDirectory(src_path, dest_path)) return RESULT_SUCCESS; } else { // TODO: Implement renaming across archives @@ -404,11 +394,11 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons ResultVal> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { - Archive* archive = GetArchive(archive_handle); + ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; - std::unique_ptr backend = archive->backend->OpenDirectory(path); + std::unique_ptr backend = archive->OpenDirectory(path); if (backend == nullptr) { return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Permanent); @@ -426,7 +416,7 @@ ResultCode FormatSaveData() { } // Use an empty path, we do not use it when formatting the savedata - return archive_itr->second->backend->Format(FileSys::Path()); + return archive_itr->second->Format(FileSys::Path()); } ResultCode CreateExtSaveData(u32 high, u32 low) { -- cgit v1.2.3 From 3f1a3952d707bce7851652ce54701ca14334f314 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Fri, 6 Feb 2015 11:53:14 -0200 Subject: FS: Allow multiple instances of the same archive type to be open at once --- src/core/hle/service/fs/archive.cpp | 51 +++++++++++++++++++------------------ src/core/hle/service/fs/archive.h | 4 +-- src/core/hle/service/ptm_u.cpp | 9 +++++-- 3 files changed, 35 insertions(+), 29 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 6030e05e0..6c6a59e47 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -5,6 +5,8 @@ #include #include +#include + #include "common/common_types.h" #include "common/file_util.h" #include "common/make_unique.h" @@ -233,22 +235,23 @@ public: //////////////////////////////////////////////////////////////////////////////////////////////////// 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 the FS service is shut down. */ -static std::unordered_map> id_code_map; +static boost::container::flat_map> id_code_map; /** * Map of active archive handles. Values are pointers to the archives in `idcode_map`. */ -static std::unordered_map handle_map; +static std::unordered_map> handle_map; static ArchiveHandle next_handle; static ArchiveBackend* GetArchive(ArchiveHandle handle) { auto itr = handle_map.find(handle); - return (itr == handle_map.end()) ? nullptr : itr->second; + return (itr == handle_map.end()) ? nullptr : itr->second.get(); } ResultVal OpenArchive(ArchiveIdCode id_code, FileSys::Path& archive_path) { @@ -261,15 +264,13 @@ ResultVal OpenArchive(ArchiveIdCode id_code, FileSys::Path& archi ErrorSummary::NotFound, ErrorLevel::Permanent); } - ResultCode res = itr->second->Open(archive_path); - if (!res.IsSuccess()) - return res; + CASCADE_RESULT(std::unique_ptr res, itr->second->Open(archive_path)); // This should never even happen in the first place with 64-bit handles, while (handle_map.count(next_handle) != 0) { ++next_handle; } - handle_map.emplace(next_handle, itr->second.get()); + handle_map.emplace(next_handle, std::move(res)); return MakeResult(next_handle++); } @@ -282,11 +283,11 @@ 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 CreateArchive(std::unique_ptr&& backend, ArchiveIdCode id_code) { - auto result = id_code_map.emplace(id_code, std::move(backend)); +ResultCode RegisterArchiveType(std::unique_ptr&& factory, ArchiveIdCode id_code) { + auto result = id_code_map.emplace(id_code, std::move(factory)); bool inserted = result.second; - _dbg_assert_msg_(Service_FS, inserted, "Tried to register more than one archive with same id code"); + _assert_msg_(Service_FS, inserted, "Tried to register more than one archive with same id code"); auto& archive = result.first->second; LOG_DEBUG(Service_FS, "Registered archive %s with id code 0x%08X", archive->GetName().c_str(), id_code); @@ -450,32 +451,32 @@ void ArchiveInit() { std::string sdmc_directory = FileUtil::GetUserPath(D_SDMC_IDX); std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); - auto sdmc_archive = Common::make_unique(sdmc_directory); - if (sdmc_archive->Initialize()) - CreateArchive(std::move(sdmc_archive), ArchiveIdCode::SDMC); + auto sdmc_factory = Common::make_unique(sdmc_directory); + if (sdmc_factory->Initialize()) + RegisterArchiveType(std::move(sdmc_factory), ArchiveIdCode::SDMC); else LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str()); // Create the SaveData archive - auto savedata_archive = Common::make_unique(sdmc_directory); - CreateArchive(std::move(savedata_archive), ArchiveIdCode::SaveData); + auto savedata_factory = Common::make_unique(sdmc_directory); + RegisterArchiveType(std::move(savedata_factory), ArchiveIdCode::SaveData); - auto extsavedata_archive = Common::make_unique(sdmc_directory, false); - if (extsavedata_archive->Initialize()) - CreateArchive(std::move(extsavedata_archive), ArchiveIdCode::ExtSaveData); + auto extsavedata_factory = Common::make_unique(sdmc_directory, false); + if (extsavedata_factory->Initialize()) + RegisterArchiveType(std::move(extsavedata_factory), ArchiveIdCode::ExtSaveData); else - LOG_ERROR(Service_FS, "Can't instantiate ExtSaveData archive with path %s", extsavedata_archive->GetMountPoint().c_str()); + LOG_ERROR(Service_FS, "Can't instantiate ExtSaveData archive with path %s", extsavedata_factory->GetMountPoint().c_str()); - auto sharedextsavedata_archive = Common::make_unique(nand_directory, true); - if (sharedextsavedata_archive->Initialize()) - CreateArchive(std::move(sharedextsavedata_archive), ArchiveIdCode::SharedExtSaveData); + auto sharedextsavedata_factory = Common::make_unique(nand_directory, true); + if (sharedextsavedata_factory->Initialize()) + RegisterArchiveType(std::move(sharedextsavedata_factory), ArchiveIdCode::SharedExtSaveData); else LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", - sharedextsavedata_archive->GetMountPoint().c_str()); + sharedextsavedata_factory->GetMountPoint().c_str()); // Create the SaveDataCheck archive, basically a small variation of the RomFS archive - auto savedatacheck_archive = Common::make_unique(nand_directory); - CreateArchive(std::move(savedatacheck_archive), ArchiveIdCode::SaveDataCheck); + auto savedatacheck_factory = Common::make_unique(nand_directory); + RegisterArchiveType(std::move(savedatacheck_factory), ArchiveIdCode::SaveDataCheck); } /// Shutdown archives diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index ab5ea4da8..3d9b8a761 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -51,11 +51,11 @@ ResultVal OpenArchive(ArchiveIdCode id_code, FileSys::Path& archi ResultCode CloseArchive(ArchiveHandle handle); /** - * Creates an Archive + * Registers an Archive type, instances of which can later be opened using its IdCode. * @param backend File system backend interface to the archive * @param id_code Id code used to access this type of archive */ -ResultCode CreateArchive(std::unique_ptr&& backend, ArchiveIdCode id_code); +ResultCode RegisterArchiveType(std::unique_ptr&& factory, ArchiveIdCode id_code); /** * Open a File from an Archive diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp index 7b465a348..561849f32 100644 --- a/src/core/hle/service/ptm_u.cpp +++ b/src/core/hle/service/ptm_u.cpp @@ -4,8 +4,9 @@ #include "common/log.h" #include "common/make_unique.h" -#include "core/file_sys/archive_extsavedata.h" + #include "core/hle/hle.h" +#include "core/hle/service/fs/archive.h" #include "core/hle/service/ptm_u.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -28,7 +29,6 @@ struct GameCoin { u8 day; }; static const GameCoin default_game_coin = { 0x4F00, 42, 0, 0, 0, 2014, 12, 29 }; -static std::unique_ptr ptm_shared_extsavedata; static const std::vector ptm_shared_extdata_id = {0, 0, 0, 0, 0x0B, 0, 0, 0xF0, 0, 0, 0, 0}; /// Charge levels used by PTM functions @@ -138,6 +138,10 @@ const Interface::FunctionInfo FunctionTable[] = { Interface::Interface() { Register(FunctionTable); + + // TODO(Subv): This code needs to be updated to not directly create archives and use the + // standard archive.h interfaces. +#if 0 // Create the SharedExtSaveData archive 0xF000000B and the gamecoin.dat file // TODO(Subv): In the future we should use the FS service to query this archive std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); @@ -165,6 +169,7 @@ Interface::Interface() { gamecoin->Close(); } } +#endif } } // namespace -- cgit v1.2.3 From 071663e07423cac6037c72153edafea1efe9da9f Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 7 Feb 2015 13:06:48 -0500 Subject: Archives: Expose the File and Directory classes to HLE --- src/core/hle/service/fs/archive.cpp | 80 +++++++++++++------------------------ src/core/hle/service/fs/archive.h | 34 +++++++++++++++- src/core/hle/service/fs/fs_user.cpp | 6 +-- 3 files changed, 62 insertions(+), 58 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 6c6a59e47..481715f17 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -20,7 +20,6 @@ #include "core/file_sys/archive_sdmc.h" #include "core/file_sys/directory_backend.h" #include "core/hle/service/fs/archive.h" -#include "core/hle/kernel/session.h" #include "core/hle/result.h" // Specializes std::hash for ArchiveIdCode, so that we can use it in std::unordered_map. @@ -76,31 +75,19 @@ enum class DirectoryCommand : u32 { Close = 0x08020000, }; -class File : public Kernel::Session { -public: - File(std::unique_ptr&& backend, const FileSys::Path& path) - : path(path), priority(0), backend(std::move(backend)) { - } - - std::string GetName() const override { return "Path: " + path.DebugStr(); } - - FileSys::Path path; ///< Path of the file - u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means - std::unique_ptr backend; ///< File backend interface - - ResultVal SyncRequest() override { - u32* cmd_buff = Kernel::GetCommandBuffer(); - FileCommand cmd = static_cast(cmd_buff[0]); - switch (cmd) { +ResultVal File::SyncRequest() { + u32* cmd_buff = Kernel::GetCommandBuffer(); + FileCommand cmd = static_cast(cmd_buff[0]); + switch (cmd) { // Read from file... case FileCommand::Read: { - u64 offset = cmd_buff[1] | ((u64) cmd_buff[2]) << 32; - u32 length = cmd_buff[3]; + u64 offset = cmd_buff[1] | ((u64)cmd_buff[2]) << 32; + u32 length = cmd_buff[3]; u32 address = cmd_buff[5]; LOG_TRACE(Service_FS, "Read %s %s: offset=0x%llx length=%d address=0x%x", - GetTypeName().c_str(), GetName().c_str(), offset, length, address); + GetTypeName().c_str(), GetName().c_str(), offset, length, address); cmd_buff[2] = backend->Read(offset, length, Memory::GetPointer(address)); break; } @@ -108,12 +95,12 @@ public: // Write to file... case FileCommand::Write: { - u64 offset = cmd_buff[1] | ((u64) cmd_buff[2]) << 32; - u32 length = cmd_buff[3]; - u32 flush = cmd_buff[4]; + u64 offset = cmd_buff[1] | ((u64)cmd_buff[2]) << 32; + u32 length = cmd_buff[3]; + u32 flush = cmd_buff[4]; u32 address = cmd_buff[6]; LOG_TRACE(Service_FS, "Write %s %s: offset=0x%llx length=%d address=0x%x, flush=0x%x", - GetTypeName().c_str(), GetName().c_str(), offset, length, address, flush); + GetTypeName().c_str(), GetName().c_str(), offset, length, address, flush); cmd_buff[2] = backend->Write(offset, length, flush, Memory::GetPointer(address)); break; } @@ -131,7 +118,7 @@ public: { u64 size = cmd_buff[1] | ((u64)cmd_buff[2] << 32); LOG_TRACE(Service_FS, "SetSize %s %s size=%llu", - GetTypeName().c_str(), GetName().c_str(), size); + GetTypeName().c_str(), GetName().c_str(), size); backend->SetSize(size); break; } @@ -177,27 +164,15 @@ public: ResultCode error = UnimplementedFunction(ErrorModule::FS); cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. return error; - } - cmd_buff[1] = 0; // No error - return MakeResult(false); - } -}; - -class Directory : public Kernel::Session { -public: - Directory(std::unique_ptr&& backend, const FileSys::Path& path) - : path(path), backend(std::move(backend)) { } + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + return MakeResult(false); +} - std::string GetName() const override { return "Directory: " + path.DebugStr(); } - - FileSys::Path path; ///< Path of the directory - std::unique_ptr backend; ///< File backend interface - - ResultVal SyncRequest() override { - u32* cmd_buff = Kernel::GetCommandBuffer(); - DirectoryCommand cmd = static_cast(cmd_buff[0]); - switch (cmd) { +ResultVal Directory::SyncRequest() { + u32* cmd_buff = Kernel::GetCommandBuffer(); + DirectoryCommand cmd = static_cast(cmd_buff[0]); + switch (cmd) { // Read from directory... case DirectoryCommand::Read: @@ -206,7 +181,7 @@ public: u32 address = cmd_buff[3]; auto entries = reinterpret_cast(Memory::GetPointer(address)); LOG_TRACE(Service_FS, "Read %s %s: count=%d", - GetTypeName().c_str(), GetName().c_str(), count); + GetTypeName().c_str(), GetName().c_str(), count); // Number of entries actually read cmd_buff[2] = backend->Read(count, entries); @@ -226,11 +201,10 @@ public: ResultCode error = UnimplementedFunction(ErrorModule::FS); cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. return MakeResult(false); - } - cmd_buff[1] = 0; // No error - return MakeResult(false); } -}; + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + return MakeResult(false); +} //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -294,7 +268,7 @@ ResultCode RegisterArchiveType(std::unique_ptr&& factor return RESULT_SUCCESS; } -ResultVal> OpenFileFromArchive(ArchiveHandle archive_handle, +ResultVal> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode) { ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) @@ -307,7 +281,7 @@ ResultVal> OpenFileFromArchive(ArchiveHandle } auto file = Kernel::SharedPtr(new File(std::move(backend), path)); - return MakeResult>(std::move(file)); + return MakeResult>(std::move(file)); } ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { @@ -393,7 +367,7 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons ErrorSummary::NothingHappened, ErrorLevel::Status); } -ResultVal> OpenDirectoryFromArchive(ArchiveHandle archive_handle, +ResultVal> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) @@ -406,7 +380,7 @@ ResultVal> OpenDirectoryFromArchive(ArchiveHa } auto directory = Kernel::SharedPtr(new Directory(std::move(backend), path)); - return MakeResult>(std::move(directory)); + return MakeResult>(std::move(directory)); } ResultCode FormatSaveData() { diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 3d9b8a761..e27ad7d60 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -8,6 +8,7 @@ #include "core/file_sys/archive_backend.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/session.h" #include "core/hle/result.h" /// The unique system identifier hash, also known as ID0 @@ -36,6 +37,35 @@ enum class ArchiveIdCode : u32 { typedef u64 ArchiveHandle; +class File : public Kernel::Session { +public: + File(std::unique_ptr&& backend, const FileSys::Path& path) + : path(path), priority(0), backend(std::move(backend)) { + } + + std::string GetName() const override { return "Path: " + path.DebugStr(); } + + FileSys::Path path; ///< Path of the file + u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means + std::unique_ptr backend; ///< File backend interface + + ResultVal SyncRequest() override; +}; + +class Directory : public Kernel::Session { +public: + Directory(std::unique_ptr&& backend, const FileSys::Path& path) + : path(path), backend(std::move(backend)) { + } + + std::string GetName() const override { return "Directory: " + path.DebugStr(); } + + FileSys::Path path; ///< Path of the directory + std::unique_ptr backend; ///< File backend interface + + ResultVal SyncRequest() override; +}; + /** * Opens an archive * @param id_code IdCode of the archive to open @@ -64,7 +94,7 @@ ResultCode RegisterArchiveType(std::unique_ptr&& factor * @param mode Mode under which to open the File * @return The opened File object as a Session */ -ResultVal> OpenFileFromArchive(ArchiveHandle archive_handle, +ResultVal> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode); /** @@ -128,7 +158,7 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons * @param path Path to the Directory inside of the Archive * @return The opened Directory object as a Session */ -ResultVal> OpenDirectoryFromArchive(ArchiveHandle archive_handle, +ResultVal> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); /** diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index 94a3a31c8..d57dd042b 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -61,7 +61,7 @@ static void OpenFile(Service::Interface* self) { LOG_DEBUG(Service_FS, "path=%s, mode=%d attrs=%u", file_path.DebugStr().c_str(), mode.hex, attributes); - ResultVal> file_res = OpenFileFromArchive(archive_handle, file_path, mode); + ResultVal> file_res = OpenFileFromArchive(archive_handle, file_path, mode); cmd_buff[1] = file_res.Code().raw; if (file_res.Succeeded()) { cmd_buff[3] = Kernel::g_handle_table.Create(*file_res).MoveFrom(); @@ -117,7 +117,7 @@ static void OpenFileDirectly(Service::Interface* self) { } SCOPE_EXIT({ CloseArchive(*archive_handle); }); - ResultVal> file_res = OpenFileFromArchive(*archive_handle, file_path, mode); + ResultVal> file_res = OpenFileFromArchive(*archive_handle, file_path, mode); cmd_buff[1] = file_res.Code().raw; if (file_res.Succeeded()) { cmd_buff[3] = Kernel::g_handle_table.Create(*file_res).MoveFrom(); @@ -337,7 +337,7 @@ static void OpenDirectory(Service::Interface* self) { LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); - ResultVal> dir_res = OpenDirectoryFromArchive(archive_handle, dir_path); + ResultVal> dir_res = OpenDirectoryFromArchive(archive_handle, dir_path); cmd_buff[1] = dir_res.Code().raw; if (dir_res.Succeeded()) { cmd_buff[3] = Kernel::g_handle_table.Create(*dir_res).MoveFrom(); -- cgit v1.2.3 From 1bbf0567b1889ebd57e3bcdf44b091e0ee18d125 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 7 Feb 2015 13:31:34 -0500 Subject: Archives: Made the Format function more generic. --- src/core/hle/service/fs/archive.cpp | 8 +++----- src/core/hle/service/fs/archive.h | 7 +++++-- src/core/hle/service/fs/fs_user.cpp | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 481715f17..e197d3599 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -383,15 +383,13 @@ ResultVal> OpenDirectoryFromArchive(ArchiveHandle a return MakeResult>(std::move(directory)); } -ResultCode FormatSaveData() { - // Do not create the archive again if it already exists - auto archive_itr = id_code_map.find(ArchiveIdCode::SaveData); +ResultCode FormatArchive(ArchiveIdCode id_code, 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 } - // Use an empty path, we do not use it when formatting the savedata - return archive_itr->second->Format(FileSys::Path()); + return archive_itr->second->Format(path); } ResultCode CreateExtSaveData(u32 high, u32 low) { diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index e27ad7d60..c490327d0 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -162,10 +162,13 @@ ResultVal> OpenDirectoryFromArchive(ArchiveHandle a const FileSys::Path& path); /** - * Creates a blank SaveData archive. + * 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 path The path to the archive, if relevant. * @return ResultCode 0 on success or the corresponding code on error */ -ResultCode FormatSaveData(); +ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::Path& path = FileSys::Path()); /** * Creates a blank SharedExtSaveData archive for the specified extdata ID diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index d57dd042b..71ee4ff55 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -468,7 +468,7 @@ static void FormatSaveData(Service::Interface* self) { return; } - cmd_buff[1] = FormatSaveData().raw; + cmd_buff[1] = FormatArchive(ArchiveIdCode::SaveData).raw; } /** @@ -484,7 +484,7 @@ static void FormatThisUserSaveData(Service::Interface* self) { // TODO(Subv): Find out what the inputs and outputs of this function are - cmd_buff[1] = FormatSaveData().raw; + cmd_buff[1] = FormatArchive(ArchiveIdCode::SaveData).raw; } static void CreateExtSaveData(Service::Interface* self) { -- cgit v1.2.3 From 0d2b6dd6566b6718c806181c1f1c3bcdcede86ae Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 7 Feb 2015 13:31:51 -0500 Subject: PTM: Fixed a problem with the gamecoin PTM file. --- src/core/hle/service/ptm_u.cpp | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp index 561849f32..7c8d9ce8c 100644 --- a/src/core/hle/service/ptm_u.cpp +++ b/src/core/hle/service/ptm_u.cpp @@ -139,37 +139,29 @@ const Interface::FunctionInfo FunctionTable[] = { Interface::Interface() { Register(FunctionTable); - // TODO(Subv): This code needs to be updated to not directly create archives and use the - // standard archive.h interfaces. -#if 0 - // Create the SharedExtSaveData archive 0xF000000B and the gamecoin.dat file - // TODO(Subv): In the future we should use the FS service to query this archive - std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); - ptm_shared_extsavedata = Common::make_unique(nand_directory, true); - if (!ptm_shared_extsavedata->Initialize()) { - LOG_CRITICAL(Service_PTM, "Could not initialize SharedExtSaveData archive for the PTM:U service"); - return; - } + // Open the SharedExtSaveData archive 0xF000000B and the gamecoin.dat file FileSys::Path archive_path(ptm_shared_extdata_id); - ResultCode result = ptm_shared_extsavedata->Open(archive_path); + auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); // If the archive didn't exist, create the files inside - if (result.description == ErrorDescription::FS_NotFormatted) { - // Format the archive to clear the directories - ptm_shared_extsavedata->Format(archive_path); + if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) { + // Format the archive to create the directories + Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); // Open it again to get a valid archive now that the folder exists - ptm_shared_extsavedata->Open(archive_path); + archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); + _assert_msg_(Service_PTM, archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!"); + FileSys::Path gamecoin_path("gamecoin.dat"); FileSys::Mode open_mode = {}; open_mode.write_flag = 1; open_mode.create_flag = 1; // Open the file and write the default gamecoin information - auto gamecoin = ptm_shared_extsavedata->OpenFile(gamecoin_path, open_mode); - if (gamecoin != nullptr) { - gamecoin->Write(0, sizeof(GameCoin), 1, reinterpret_cast(&default_game_coin)); - gamecoin->Close(); + auto gamecoin_result = Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode); + if (gamecoin_result.Succeeded()) { + auto gamecoin = gamecoin_result.MoveFrom(); + gamecoin->backend->Write(0, sizeof(GameCoin), 1, reinterpret_cast(&default_game_coin)); + gamecoin->backend->Close(); } } -#endif } } // namespace -- cgit v1.2.3