From a6d9baa05ad83c41f5c6ee2674db5dcfac7facd6 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Sat, 2 Feb 2019 20:14:01 -0500 Subject: [PATCH] FS: pass down program ID for archive operation To eliminate System::GetInstance usage. Archive type like SelfNCCH and SaveData changes the actual reference path for different client, so archive backend interface should accept client information from the service interface. Currently we only pass the program ID as the client information. --- src/core/file_sys/archive_backend.h | 10 +++-- src/core/file_sys/archive_extsavedata.cpp | 9 +++-- src/core/file_sys/archive_extsavedata.h | 7 ++-- src/core/file_sys/archive_ncch.cpp | 9 +++-- src/core/file_sys/archive_ncch.h | 7 ++-- src/core/file_sys/archive_other_savedata.cpp | 12 +++--- src/core/file_sys/archive_other_savedata.h | 14 ++++--- src/core/file_sys/archive_savedata.cpp | 18 ++++----- src/core/file_sys/archive_savedata.h | 7 ++-- src/core/file_sys/archive_sdmc.cpp | 9 +++-- src/core/file_sys/archive_sdmc.h | 7 ++-- src/core/file_sys/archive_sdmcwriteonly.cpp | 9 +++-- src/core/file_sys/archive_sdmcwriteonly.h | 7 ++-- src/core/file_sys/archive_selfncch.cpp | 12 +++--- src/core/file_sys/archive_selfncch.h | 7 ++-- src/core/file_sys/archive_systemsavedata.cpp | 9 +++-- src/core/file_sys/archive_systemsavedata.h | 7 ++-- src/core/hle/service/cecd/cecd.cpp | 6 +-- src/core/hle/service/cfg/cfg.cpp | 6 +-- src/core/hle/service/fs/archive.cpp | 18 +++++---- src/core/hle/service/fs/archive.h | 14 +++++-- src/core/hle/service/fs/fs_user.cpp | 39 +++++++++++++++----- src/core/hle/service/fs/fs_user.h | 11 +++++- src/core/hle/service/ptm/ptm.cpp | 10 ++--- 24 files changed, 165 insertions(+), 99 deletions(-) diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index a425a383f6..1a57e12d30 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -167,24 +167,28 @@ public: /** * Tries to open the archive of this type with the specified path * @param path Path to the archive + * @param program_id the program ID of the client that requests the operation * @return An ArchiveBackend corresponding operating specified archive path. */ - virtual ResultVal> Open(const Path& path) = 0; + virtual ResultVal> Open(const Path& path, u64 program_id) = 0; /** * 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 + * @param program_id the program ID of the client that requests the operation * @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, const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) = 0; /** * Retrieves the format info about the archive with the specified path * @param path Path to the archive + * @param program_id the program ID of the client that requests the operation * @return Format information about the archive or error code */ - virtual ResultVal GetFormatInfo(const Path& path) const = 0; + virtual ResultVal GetFormatInfo(const Path& path, u64 program_id) const = 0; }; } // namespace FileSys diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index e1de76f875..2839483f56 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -220,7 +220,8 @@ Path ArchiveFactory_ExtSaveData::GetCorrectedPath(const Path& path) { return {binary_data}; } -ResultVal> ArchiveFactory_ExtSaveData::Open(const Path& path) { +ResultVal> ArchiveFactory_ExtSaveData::Open(const Path& path, + u64 program_id) { std::string fullpath = GetExtSaveDataPath(mount_point, GetCorrectedPath(path)) + "user/"; if (!FileUtil::Exists(fullpath)) { // TODO(Subv): Verify the archive behavior of SharedExtSaveData compared to ExtSaveData. @@ -236,7 +237,8 @@ ResultVal> ArchiveFactory_ExtSaveData::Open(cons } ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path, - const FileSys::ArchiveFormatInfo& format_info) { + const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) { auto corrected_path = GetCorrectedPath(path); // These folders are always created with the ExtSaveData @@ -258,7 +260,8 @@ ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path, return RESULT_SUCCESS; } -ResultVal ArchiveFactory_ExtSaveData::GetFormatInfo(const Path& path) const { +ResultVal ArchiveFactory_ExtSaveData::GetFormatInfo(const Path& path, + u64 program_id) const { std::string metadata_path = GetExtSaveDataPath(mount_point, path) + "metadata"; FileUtil::IOFile file(metadata_path, "rb"); diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index 46d849d33c..7dc345c847 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h @@ -24,9 +24,10 @@ public: return "ExtSaveData"; } - ResultVal> Open(const Path& path) override; - ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; - ResultVal GetFormatInfo(const Path& path) const override; + ResultVal> Open(const Path& path, u64 program_id) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) override; + ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; const std::string& GetMountPoint() const { return mount_point; diff --git a/src/core/file_sys/archive_ncch.cpp b/src/core/file_sys/archive_ncch.cpp index 9c563d38c7..4aeaf8fcae 100644 --- a/src/core/file_sys/archive_ncch.cpp +++ b/src/core/file_sys/archive_ncch.cpp @@ -269,7 +269,8 @@ bool NCCHFile::SetSize(const u64 size) const { ArchiveFactory_NCCH::ArchiveFactory_NCCH() {} -ResultVal> ArchiveFactory_NCCH::Open(const Path& path) { +ResultVal> ArchiveFactory_NCCH::Open(const Path& path, + u64 program_id) { if (path.GetType() != LowPathType::Binary) { LOG_ERROR(Service_FS, "Path need to be Binary"); return ERROR_INVALID_PATH; @@ -290,14 +291,16 @@ ResultVal> ArchiveFactory_NCCH::Open(const Path& } ResultCode ArchiveFactory_NCCH::Format(const Path& path, - const FileSys::ArchiveFormatInfo& format_info) { + const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) { LOG_ERROR(Service_FS, "Attempted to format a NCCH archive."); // TODO: Verify error code return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); } -ResultVal ArchiveFactory_NCCH::GetFormatInfo(const Path& path) const { +ResultVal ArchiveFactory_NCCH::GetFormatInfo(const Path& path, + u64 program_id) const { // TODO(Subv): Implement LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); return ResultCode(-1); diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index 864b569f25..7d352ea092 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -97,9 +97,10 @@ public: return "NCCH"; } - ResultVal> Open(const Path& path) override; - ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; - ResultVal GetFormatInfo(const Path& path) const override; + ResultVal> Open(const Path& path, u64 program_id) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) override; + ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; }; } // namespace FileSys diff --git a/src/core/file_sys/archive_other_savedata.cpp b/src/core/file_sys/archive_other_savedata.cpp index 9655c66500..1c3b071ba8 100644 --- a/src/core/file_sys/archive_other_savedata.cpp +++ b/src/core/file_sys/archive_other_savedata.cpp @@ -64,7 +64,7 @@ ArchiveFactory_OtherSaveDataPermitted::ArchiveFactory_OtherSaveDataPermitted( : sd_savedata_source(std::move(sd_savedata)) {} ResultVal> ArchiveFactory_OtherSaveDataPermitted::Open( - const Path& path) { + const Path& path, u64 /*client_program_id*/) { MediaType media_type; u64 program_id; CASCADE_RESULT(std::tie(media_type, program_id), ParsePathPermitted(path)); @@ -78,13 +78,13 @@ ResultVal> ArchiveFactory_OtherSaveDataPermitted } ResultCode ArchiveFactory_OtherSaveDataPermitted::Format( - const Path& path, const FileSys::ArchiveFormatInfo& format_info) { + const Path& path, const FileSys::ArchiveFormatInfo& format_info, u64 program_id) { LOG_ERROR(Service_FS, "Attempted to format a OtherSaveDataPermitted archive."); return ERROR_INVALID_PATH; } ResultVal ArchiveFactory_OtherSaveDataPermitted::GetFormatInfo( - const Path& path) const { + const Path& path, u64 /*client_program_id*/) const { MediaType media_type; u64 program_id; CASCADE_RESULT(std::tie(media_type, program_id), ParsePathPermitted(path)); @@ -102,7 +102,7 @@ ArchiveFactory_OtherSaveDataGeneral::ArchiveFactory_OtherSaveDataGeneral( : sd_savedata_source(std::move(sd_savedata)) {} ResultVal> ArchiveFactory_OtherSaveDataGeneral::Open( - const Path& path) { + const Path& path, u64 /*client_program_id*/) { MediaType media_type; u64 program_id; CASCADE_RESULT(std::tie(media_type, program_id), ParsePathGeneral(path)); @@ -116,7 +116,7 @@ ResultVal> ArchiveFactory_OtherSaveDataGeneral:: } ResultCode ArchiveFactory_OtherSaveDataGeneral::Format( - const Path& path, const FileSys::ArchiveFormatInfo& format_info) { + const Path& path, const FileSys::ArchiveFormatInfo& format_info, u64 /*client_program_id*/) { MediaType media_type; u64 program_id; CASCADE_RESULT(std::tie(media_type, program_id), ParsePathGeneral(path)); @@ -130,7 +130,7 @@ ResultCode ArchiveFactory_OtherSaveDataGeneral::Format( } ResultVal ArchiveFactory_OtherSaveDataGeneral::GetFormatInfo( - const Path& path) const { + const Path& path, u64 /*client_program_id*/) const { MediaType media_type; u64 program_id; CASCADE_RESULT(std::tie(media_type, program_id), ParsePathGeneral(path)); diff --git a/src/core/file_sys/archive_other_savedata.h b/src/core/file_sys/archive_other_savedata.h index d807251581..e3e8f83c33 100644 --- a/src/core/file_sys/archive_other_savedata.h +++ b/src/core/file_sys/archive_other_savedata.h @@ -21,9 +21,10 @@ public: return "OtherSaveDataPermitted"; } - ResultVal> Open(const Path& path) override; - ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; - ResultVal GetFormatInfo(const Path& path) const override; + ResultVal> Open(const Path& path, u64 program_id) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) override; + ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; private: std::string mount_point; @@ -40,9 +41,10 @@ public: return "OtherSaveDataGeneral"; } - ResultVal> Open(const Path& path) override; - ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; - ResultVal GetFormatInfo(const Path& path) const override; + ResultVal> Open(const Path& path, u64 program_id) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) override; + ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; private: std::string mount_point; diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp index 6e518af8b1..c1046e2f56 100644 --- a/src/core/file_sys/archive_savedata.cpp +++ b/src/core/file_sys/archive_savedata.cpp @@ -16,20 +16,20 @@ ArchiveFactory_SaveData::ArchiveFactory_SaveData( std::shared_ptr sd_savedata) : sd_savedata_source(std::move(sd_savedata)) {} -ResultVal> ArchiveFactory_SaveData::Open(const Path& path) { - return sd_savedata_source->Open( - Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id); +ResultVal> ArchiveFactory_SaveData::Open(const Path& path, + u64 program_id) { + return sd_savedata_source->Open(program_id); } ResultCode ArchiveFactory_SaveData::Format(const Path& path, - const FileSys::ArchiveFormatInfo& format_info) { - return sd_savedata_source->Format( - Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id, format_info); + const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) { + return sd_savedata_source->Format(program_id, format_info); } -ResultVal ArchiveFactory_SaveData::GetFormatInfo(const Path& path) const { - return sd_savedata_source->GetFormatInfo( - Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id); +ResultVal ArchiveFactory_SaveData::GetFormatInfo(const Path& path, + u64 program_id) const { + return sd_savedata_source->GetFormatInfo(program_id); } } // namespace FileSys diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 41aa6f1899..591a3b900c 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h @@ -20,10 +20,11 @@ public: return "SaveData"; } - ResultVal> Open(const Path& path) override; - ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; + ResultVal> Open(const Path& path, u64 program_id) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) override; - ResultVal GetFormatInfo(const Path& path) const override; + ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; private: std::string mount_point; diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index d6f3935eb9..cff4cd3959 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -376,18 +376,21 @@ bool ArchiveFactory_SDMC::Initialize() { return true; } -ResultVal> ArchiveFactory_SDMC::Open(const Path& path) { +ResultVal> ArchiveFactory_SDMC::Open(const Path& path, + u64 program_id) { auto archive = std::make_unique(sdmc_directory); return MakeResult>(std::move(archive)); } ResultCode ArchiveFactory_SDMC::Format(const Path& path, - const FileSys::ArchiveFormatInfo& format_info) { + const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) { // This is kind of an undesirable operation, so let's just ignore it. :) return RESULT_SUCCESS; } -ResultVal ArchiveFactory_SDMC::GetFormatInfo(const Path& path) const { +ResultVal ArchiveFactory_SDMC::GetFormatInfo(const Path& path, + u64 program_id) const { // TODO(Subv): Implement LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); return ResultCode(-1); diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index f6c70bfccb..637d4dc16b 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -55,9 +55,10 @@ public: return "SDMC"; } - ResultVal> Open(const Path& path) override; - ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; - ResultVal GetFormatInfo(const Path& path) const override; + ResultVal> Open(const Path& path, u64 program_id) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) override; + ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; private: std::string sdmc_directory; diff --git a/src/core/file_sys/archive_sdmcwriteonly.cpp b/src/core/file_sys/archive_sdmcwriteonly.cpp index a1f5a416c7..b9534f12d3 100644 --- a/src/core/file_sys/archive_sdmcwriteonly.cpp +++ b/src/core/file_sys/archive_sdmcwriteonly.cpp @@ -49,19 +49,22 @@ bool ArchiveFactory_SDMCWriteOnly::Initialize() { return true; } -ResultVal> ArchiveFactory_SDMCWriteOnly::Open(const Path& path) { +ResultVal> ArchiveFactory_SDMCWriteOnly::Open(const Path& path, + u64 program_id) { auto archive = std::make_unique(sdmc_directory); return MakeResult>(std::move(archive)); } ResultCode ArchiveFactory_SDMCWriteOnly::Format(const Path& path, - const FileSys::ArchiveFormatInfo& format_info) { + const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) { // TODO(wwylele): hwtest this LOG_ERROR(Service_FS, "Attempted to format a SDMC write-only archive."); return ResultCode(-1); } -ResultVal ArchiveFactory_SDMCWriteOnly::GetFormatInfo(const Path& path) const { +ResultVal ArchiveFactory_SDMCWriteOnly::GetFormatInfo(const Path& path, + u64 program_id) const { // TODO(Subv): Implement LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); return ResultCode(-1); diff --git a/src/core/file_sys/archive_sdmcwriteonly.h b/src/core/file_sys/archive_sdmcwriteonly.h index 9cd38d96f7..050fc19c8d 100644 --- a/src/core/file_sys/archive_sdmcwriteonly.h +++ b/src/core/file_sys/archive_sdmcwriteonly.h @@ -46,9 +46,10 @@ public: return "SDMCWriteOnly"; } - ResultVal> Open(const Path& path) override; - ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; - ResultVal GetFormatInfo(const Path& path) const override; + ResultVal> Open(const Path& path, u64 program_id) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) override; + ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; private: std::string sdmc_directory; diff --git a/src/core/file_sys/archive_selfncch.cpp b/src/core/file_sys/archive_selfncch.cpp index dc2c61666d..0f8dd80651 100644 --- a/src/core/file_sys/archive_selfncch.cpp +++ b/src/core/file_sys/archive_selfncch.cpp @@ -278,18 +278,20 @@ void ArchiveFactory_SelfNCCH::Register(Loader::AppLoader& app_loader) { data.banner = std::make_shared>(std::move(buffer)); } -ResultVal> ArchiveFactory_SelfNCCH::Open(const Path& path) { - auto archive = std::make_unique( - ncch_data[Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id]); +ResultVal> ArchiveFactory_SelfNCCH::Open(const Path& path, + u64 program_id) { + auto archive = std::make_unique(ncch_data[program_id]); return MakeResult>(std::move(archive)); } -ResultCode ArchiveFactory_SelfNCCH::Format(const Path&, const FileSys::ArchiveFormatInfo&) { +ResultCode ArchiveFactory_SelfNCCH::Format(const Path&, const FileSys::ArchiveFormatInfo&, + u64 program_id) { LOG_ERROR(Service_FS, "Attempted to format a SelfNCCH archive."); return ERROR_INVALID_PATH; } -ResultVal ArchiveFactory_SelfNCCH::GetFormatInfo(const Path&) const { +ResultVal ArchiveFactory_SelfNCCH::GetFormatInfo(const Path&, + u64 program_id) const { LOG_ERROR(Service_FS, "Attempted to get format info of a SelfNCCH archive"); return ERROR_INVALID_PATH; } diff --git a/src/core/file_sys/archive_selfncch.h b/src/core/file_sys/archive_selfncch.h index 245691a5dc..779e7e75ab 100644 --- a/src/core/file_sys/archive_selfncch.h +++ b/src/core/file_sys/archive_selfncch.h @@ -37,9 +37,10 @@ public: std::string GetName() const override { return "SelfNCCH"; } - ResultVal> Open(const Path& path) override; - ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; - ResultVal GetFormatInfo(const Path& path) const override; + ResultVal> Open(const Path& path, u64 program_id) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) override; + ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; private: /// Mapping of ProgramId -> NCCHData diff --git a/src/core/file_sys/archive_systemsavedata.cpp b/src/core/file_sys/archive_systemsavedata.cpp index 9e823c3324..cef42e5611 100644 --- a/src/core/file_sys/archive_systemsavedata.cpp +++ b/src/core/file_sys/archive_systemsavedata.cpp @@ -52,7 +52,8 @@ Path ConstructSystemSaveDataBinaryPath(u32 high, u32 low) { ArchiveFactory_SystemSaveData::ArchiveFactory_SystemSaveData(const std::string& nand_path) : base_path(GetSystemSaveDataContainerPath(nand_path)) {} -ResultVal> ArchiveFactory_SystemSaveData::Open(const Path& path) { +ResultVal> ArchiveFactory_SystemSaveData::Open(const Path& path, + u64 program_id) { std::string fullpath = GetSystemSaveDataPath(base_path, path); if (!FileUtil::Exists(fullpath)) { // TODO(Subv): Check error code, this one is probably wrong @@ -63,14 +64,16 @@ ResultVal> ArchiveFactory_SystemSaveData::Open(c } ResultCode ArchiveFactory_SystemSaveData::Format(const Path& path, - const FileSys::ArchiveFormatInfo& format_info) { + const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) { std::string fullpath = GetSystemSaveDataPath(base_path, path); FileUtil::DeleteDirRecursively(fullpath); FileUtil::CreateFullPath(fullpath); return RESULT_SUCCESS; } -ResultVal ArchiveFactory_SystemSaveData::GetFormatInfo(const Path& path) const { +ResultVal ArchiveFactory_SystemSaveData::GetFormatInfo(const Path& path, + u64 program_id) const { // TODO(Subv): Implement LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); return ResultCode(-1); diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h index 52eb6c6309..e72ecce3a1 100644 --- a/src/core/file_sys/archive_systemsavedata.h +++ b/src/core/file_sys/archive_systemsavedata.h @@ -20,9 +20,10 @@ class ArchiveFactory_SystemSaveData final : public ArchiveFactory { public: explicit ArchiveFactory_SystemSaveData(const std::string& mount_point); - ResultVal> Open(const Path& path) override; - ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; - ResultVal GetFormatInfo(const Path& path) const override; + ResultVal> Open(const Path& path, u64 program_id) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) override; + ResultVal GetFormatInfo(const Path& path, u64 program_id) const override; std::string GetName() const override { return "SystemSaveData"; diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index df217d76e2..85f3e50ce5 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -1362,7 +1362,7 @@ Module::Module(Core::System& system) : system(system) { // Open the SystemSaveData archive 0x00010026 FileSys::Path archive_path(cecd_system_savedata_id); - auto archive_result = systemsavedata_factory.Open(archive_path); + auto archive_result = systemsavedata_factory.Open(archive_path, 0); // If the archive didn't exist, create the files inside if (archive_result.Code() != FileSys::ERR_NOT_FORMATTED) { @@ -1370,10 +1370,10 @@ Module::Module(Core::System& system) : system(system) { cecd_system_save_data_archive = std::move(archive_result).Unwrap(); } else { // Format the archive to create the directories - systemsavedata_factory.Format(archive_path, FileSys::ArchiveFormatInfo()); + systemsavedata_factory.Format(archive_path, FileSys::ArchiveFormatInfo(), 0); // Open it again to get a valid archive now that the folder exists - cecd_system_save_data_archive = systemsavedata_factory.Open(archive_path).Unwrap(); + cecd_system_save_data_archive = systemsavedata_factory.Open(archive_path, 0).Unwrap(); /// Now that the archive is formatted, we need to create the root CEC directory, /// eventlog.dat, and CEC/MBoxList____ diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 8c6859bb39..dba0002576 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -531,15 +531,15 @@ ResultCode Module::LoadConfigNANDSaveFile() { // Open the SystemSaveData archive 0x00010017 FileSys::Path archive_path(cfg_system_savedata_id); - auto archive_result = systemsavedata_factory.Open(archive_path); + auto archive_result = systemsavedata_factory.Open(archive_path, 0); // If the archive didn't exist, create the files inside if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) { // Format the archive to create the directories - systemsavedata_factory.Format(archive_path, FileSys::ArchiveFormatInfo()); + systemsavedata_factory.Format(archive_path, FileSys::ArchiveFormatInfo(), 0); // Open it again to get a valid archive now that the folder exists - cfg_system_save_data_archive = systemsavedata_factory.Open(archive_path).Unwrap(); + cfg_system_save_data_archive = systemsavedata_factory.Open(archive_path, 0).Unwrap(); } else { ASSERT_MSG(archive_result.Succeeded(), "Could not open the CFG SystemSaveData archive!"); diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 4322f66531..184c319f07 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -36,7 +36,7 @@ ArchiveBackend* ArchiveManager::GetArchive(ArchiveHandle handle) { } ResultVal ArchiveManager::OpenArchive(ArchiveIdCode id_code, - FileSys::Path& archive_path) { + FileSys::Path& archive_path, u64 program_id) { LOG_TRACE(Service_FS, "Opening archive with id code 0x{:08X}", static_cast(id_code)); auto itr = id_code_map.find(id_code); @@ -44,7 +44,8 @@ ResultVal ArchiveManager::OpenArchive(ArchiveIdCode id_code, return FileSys::ERROR_NOT_FOUND; } - CASCADE_RESULT(std::unique_ptr res, itr->second->Open(archive_path)); + CASCADE_RESULT(std::unique_ptr res, + itr->second->Open(archive_path, program_id)); // This should never even happen in the first place with 64-bit handles, while (handle_map.count(next_handle) != 0) { @@ -193,28 +194,29 @@ ResultVal ArchiveManager::GetFreeBytesInArchive(ArchiveHandle archive_handl ResultCode ArchiveManager::FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, - const FileSys::Path& path) { + const FileSys::Path& path, u64 program_id) { 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 } - return archive_itr->second->Format(path, format_info); + return archive_itr->second->Format(path, format_info, program_id); } ResultVal ArchiveManager::GetArchiveFormatInfo( - ArchiveIdCode id_code, FileSys::Path& archive_path) { + ArchiveIdCode id_code, FileSys::Path& archive_path, u64 program_id) { auto archive = id_code_map.find(id_code); if (archive == id_code_map.end()) { return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error } - return archive->second->GetFormatInfo(archive_path); + return archive->second->GetFormatInfo(archive_path, program_id); } ResultCode ArchiveManager::CreateExtSaveData(MediaType media_type, u32 high, u32 low, const std::vector& smdh_icon, - const FileSys::ArchiveFormatInfo& format_info) { + const FileSys::ArchiveFormatInfo& format_info, + u64 program_id) { // Construct the binary path to the archive first FileSys::Path path = FileSys::ConstructExtDataBinaryPath(static_cast(media_type), high, low); @@ -228,7 +230,7 @@ ResultCode ArchiveManager::CreateExtSaveData(MediaType media_type, u32 high, u32 auto ext_savedata = static_cast(archive->second.get()); - ResultCode result = ext_savedata->Format(path, format_info); + ResultCode result = ext_savedata->Format(path, format_info, program_id); if (result.IsError()) return result; diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index f335f650dc..c1dd2bd1b4 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -60,9 +60,11 @@ public: * Opens an archive * @param id_code IdCode of the archive to open * @param archive_path Path to the archive, used with Binary paths + * @param program_id the program ID of the client that requests the operation * @return Handle to the opened archive */ - ResultVal OpenArchive(ArchiveIdCode id_code, FileSys::Path& archive_path); + ResultVal OpenArchive(ArchiveIdCode id_code, FileSys::Path& archive_path, + u64 program_id); /** * Closes an archive @@ -172,20 +174,23 @@ public: * @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. + * @param program_id the program ID of the client that requests the operation * @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()); + const FileSys::Path& path, u64 program_id); /** * 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 + * @param program_id the program ID of the client that requests the operation * @return The format info of the archive, or the corresponding error code if failed. */ ResultVal GetArchiveFormatInfo(ArchiveIdCode id_code, - FileSys::Path& archive_path); + FileSys::Path& archive_path, + u64 program_id); /** * Creates a blank SharedExtSaveData archive for the specified extdata ID @@ -194,11 +199,12 @@ public: * @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 + * @param program_id the program ID of the client that requests the operation * @return ResultCode 0 on success or the corresponding code on error */ ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, const std::vector& smdh_icon, - const FileSys::ArchiveFormatInfo& format_info); + const FileSys::ArchiveFormatInfo& format_info, u64 program_id); /** * Deletes the 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 f9b883fe7c..bbcc2e6fd3 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -35,7 +35,10 @@ namespace Service::FS { void FS_USER::Initialize(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x0801, 0, 2); - rp.PopPID(); + u32 pid = rp.PopPID(); + + ClientSlot* slot = GetSessionData(ctx.Session()); + slot->program_id = system.Kernel().GetProcessById(pid)->codeset->program_id; IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(RESULT_SUCCESS); @@ -93,7 +96,10 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); - ResultVal archive_handle = archives.OpenArchive(archive_id, archive_path); + ClientSlot* slot = GetSessionData(ctx.Session()); + + ResultVal archive_handle = + archives.OpenArchive(archive_id, archive_path, slot->program_id); if (archive_handle.Failed()) { LOG_ERROR(Service_FS, "Failed to get a handle for archive archive_id=0x{:08X} archive_path={}", @@ -309,7 +315,9 @@ void FS_USER::OpenArchive(Kernel::HLERequestContext& ctx) { archive_path.DebugStr()); IPC::RequestBuilder rb = rp.MakeBuilder(3, 0); - ResultVal handle = archives.OpenArchive(archive_id, archive_path); + ClientSlot* slot = GetSessionData(ctx.Session()); + ResultVal handle = + archives.OpenArchive(archive_id, archive_path, slot->program_id); rb.Push(handle.Code()); if (handle.Succeeded()) { rb.PushRaw(*handle); @@ -385,7 +393,9 @@ void FS_USER::FormatSaveData(Kernel::HLERequestContext& ctx) { format_info.number_files = number_files; format_info.total_size = block_size * 512; - rb.Push(archives.FormatArchive(ArchiveIdCode::SaveData, format_info)); + ClientSlot* slot = GetSessionData(ctx.Session()); + rb.Push(archives.FormatArchive(ArchiveIdCode::SaveData, format_info, archive_path, + slot->program_id)); } void FS_USER::FormatThisUserSaveData(Kernel::HLERequestContext& ctx) { @@ -404,7 +414,9 @@ void FS_USER::FormatThisUserSaveData(Kernel::HLERequestContext& ctx) { format_info.total_size = block_size * 512; IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); - rb.Push(archives.FormatArchive(ArchiveIdCode::SaveData, format_info)); + ClientSlot* slot = GetSessionData(ctx.Session()); + rb.Push(archives.FormatArchive(ArchiveIdCode::SaveData, format_info, FileSys::Path(), + slot->program_id)); LOG_TRACE(Service_FS, "called"); } @@ -446,7 +458,9 @@ void FS_USER::CreateExtSaveData(Kernel::HLERequestContext& ctx) { format_info.total_size = 0; IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); - rb.Push(archives.CreateExtSaveData(media_type, save_high, save_low, icon, format_info)); + ClientSlot* slot = GetSessionData(ctx.Session()); + rb.Push(archives.CreateExtSaveData(media_type, save_high, save_low, icon, format_info, + slot->program_id)); rb.PushMappedBuffer(icon_buffer); LOG_DEBUG(Service_FS, @@ -535,7 +549,10 @@ void FS_USER::CreateLegacySystemSaveData(Kernel::HLERequestContext& ctx) { void FS_USER::InitializeWithSdkVersion(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x861, 1, 2); const u32 version = rp.Pop(); - rp.PopPID(); + u32 pid = rp.PopPID(); + + ClientSlot* slot = GetSessionData(ctx.Session()); + slot->program_id = system.Kernel().GetProcessById(pid)->codeset->program_id; LOG_WARNING(Service_FS, "(STUBBED) called, version: 0x{:08X}", version); @@ -595,8 +612,8 @@ void FS_USER::GetFormatInfo(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_FS, "archive_path={}", archive_path.DebugStr()); IPC::RequestBuilder rb = rp.MakeBuilder(5, 0); - - auto format_info = archives.GetArchiveFormatInfo(archive_id, archive_path); + ClientSlot* slot = GetSessionData(ctx.Session()); + auto format_info = archives.GetArchiveFormatInfo(archive_id, archive_path, slot->program_id); rb.Push(format_info.Code()); if (format_info.Failed()) { LOG_ERROR(Service_FS, "Failed to retrieve the format info"); @@ -664,7 +681,9 @@ void FS_USER::ObsoletedCreateExtSaveData(Kernel::HLERequestContext& ctx) { format_info.total_size = 0; IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); - rb.Push(archives.CreateExtSaveData(media_type, save_high, save_low, icon, format_info)); + ClientSlot* slot = GetSessionData(ctx.Session()); + rb.Push(archives.CreateExtSaveData(media_type, save_high, save_low, icon, format_info, + slot->program_id)); rb.PushMappedBuffer(icon_buffer); LOG_DEBUG(Service_FS, diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h index 90c0ed7ecf..97b45714b2 100644 --- a/src/core/hle/service/fs/fs_user.h +++ b/src/core/hle/service/fs/fs_user.h @@ -15,7 +15,16 @@ namespace Service::FS { class ArchiveManager; -class FS_USER final : public ServiceFramework { +struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase { + // We retrieves program ID for client process on FS::Initialize(WithSDKVersion) + // Real 3DS matches program ID and process ID based on data registered by loader via fs:REG, so + // theoretically the program ID for FS client and for process codeset can mismatch if the loader + // behaviour is modified. Since we don't emulate fs:REG mechanism, we assume the program ID is + // the same as codeset ID and fetch from there directly. + u64 program_id = 0; +}; + +class FS_USER final : public ServiceFramework { public: explicit FS_USER(Core::System& system); diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp index 8d6dc6cad5..9ba14d4079 100644 --- a/src/core/hle/service/ptm/ptm.cpp +++ b/src/core/hle/service/ptm/ptm.cpp @@ -143,16 +143,16 @@ static void WriteGameCoinData(GameCoin gamecoin_data) { FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true); FileSys::Path archive_path(ptm_shared_extdata_id); - auto archive_result = extdata_archive_factory.Open(archive_path); + auto archive_result = extdata_archive_factory.Open(archive_path, 0); std::unique_ptr archive; FileSys::Path gamecoin_path("/gamecoin.dat"); // If the archive didn't exist, create the files inside if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) { // Format the archive to create the directories - extdata_archive_factory.Format(archive_path, FileSys::ArchiveFormatInfo()); + extdata_archive_factory.Format(archive_path, FileSys::ArchiveFormatInfo(), 0); // Open it again to get a valid archive now that the folder exists - archive = extdata_archive_factory.Open(archive_path).Unwrap(); + archive = extdata_archive_factory.Open(archive_path, 0).Unwrap(); // Create the game coin file archive->CreateFile(gamecoin_path, sizeof(GameCoin)); } else { @@ -176,7 +176,7 @@ static GameCoin ReadGameCoinData() { FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true); FileSys::Path archive_path(ptm_shared_extdata_id); - auto archive_result = extdata_archive_factory.Open(archive_path); + auto archive_result = extdata_archive_factory.Open(archive_path, 0); if (!archive_result.Succeeded()) { LOG_ERROR(Service_PTM, "Could not open the PTM SharedExtSaveData archive!"); return default_game_coin; @@ -205,7 +205,7 @@ Module::Module() { std::string nand_directory = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir); FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true); FileSys::Path archive_path(ptm_shared_extdata_id); - auto archive_result = extdata_archive_factory.Open(archive_path); + auto archive_result = extdata_archive_factory.Open(archive_path, 0); // If the archive didn't exist, write the default game coin file if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) { WriteGameCoinData(default_game_coin);