diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index a425a383f..1a57e12d3 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 e1de76f87..2839483f5 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 46d849d33..7dc345c84 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 9c563d38c..4aeaf8fca 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 864b569f2..7d352ea09 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 9655c6650..1c3b071ba 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 d80725158..e3e8f83c3 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 6e518af8b..c1046e2f5 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 41aa6f189..591a3b900 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 d6f3935eb..cff4cd395 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 f6c70bfcc..637d4dc16 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 a1f5a416c..b9534f12d 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 9cd38d96f..050fc19c8 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 dc2c61666..0f8dd8065 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 245691a5d..779e7e75a 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 9e823c332..cef42e561 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 52eb6c630..e72ecce3a 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 df217d76e..85f3e50ce 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 8c6859bb3..dba000257 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 4322f6653..184c319f0 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 f335f650d..c1dd2bd1b 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 f9b883fe7..bbcc2e6fd 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 90c0ed7ec..97b45714b 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 8d6dc6cad..9ba14d407 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);