citra-emu
/
citra-canary
Archived
1
0
Fork 0

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.
This commit is contained in:
Weiyi Wang 2019-02-02 20:14:01 -05:00
parent bad2e084e3
commit a6d9baa05a
24 changed files with 165 additions and 99 deletions

View File

@ -167,24 +167,28 @@ public:
/** /**
* Tries to open the archive of this type with the specified path * Tries to open the archive of this type with the specified path
* @param path Path to the archive * @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. * @return An ArchiveBackend corresponding operating specified archive path.
*/ */
virtual ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) = 0; virtual ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path, u64 program_id) = 0;
/** /**
* Deletes the archive contents and then re-creates the base folder * Deletes the archive contents and then re-creates the base folder
* @param path Path to the archive * @param path Path to the archive
* @param format_info Format information for the new 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 * @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 * Retrieves the format info about the archive with the specified path
* @param path Path to the archive * @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 * @return Format information about the archive or error code
*/ */
virtual ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const = 0; virtual ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const = 0;
}; };
} // namespace FileSys } // namespace FileSys

View File

@ -220,7 +220,8 @@ Path ArchiveFactory_ExtSaveData::GetCorrectedPath(const Path& path) {
return {binary_data}; return {binary_data};
} }
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(const Path& path) { ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(const Path& path,
u64 program_id) {
std::string fullpath = GetExtSaveDataPath(mount_point, GetCorrectedPath(path)) + "user/"; std::string fullpath = GetExtSaveDataPath(mount_point, GetCorrectedPath(path)) + "user/";
if (!FileUtil::Exists(fullpath)) { if (!FileUtil::Exists(fullpath)) {
// TODO(Subv): Verify the archive behavior of SharedExtSaveData compared to ExtSaveData. // TODO(Subv): Verify the archive behavior of SharedExtSaveData compared to ExtSaveData.
@ -236,7 +237,8 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(cons
} }
ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path, 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); auto corrected_path = GetCorrectedPath(path);
// These folders are always created with the ExtSaveData // These folders are always created with the ExtSaveData
@ -258,7 +260,8 @@ ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path,
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
ResultVal<ArchiveFormatInfo> ArchiveFactory_ExtSaveData::GetFormatInfo(const Path& path) const { ResultVal<ArchiveFormatInfo> ArchiveFactory_ExtSaveData::GetFormatInfo(const Path& path,
u64 program_id) const {
std::string metadata_path = GetExtSaveDataPath(mount_point, path) + "metadata"; std::string metadata_path = GetExtSaveDataPath(mount_point, path) + "metadata";
FileUtil::IOFile file(metadata_path, "rb"); FileUtil::IOFile file(metadata_path, "rb");

View File

@ -24,9 +24,10 @@ public:
return "ExtSaveData"; return "ExtSaveData";
} }
ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path, u64 program_id) override;
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info,
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; u64 program_id) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override;
const std::string& GetMountPoint() const { const std::string& GetMountPoint() const {
return mount_point; return mount_point;

View File

@ -269,7 +269,8 @@ bool NCCHFile::SetSize(const u64 size) const {
ArchiveFactory_NCCH::ArchiveFactory_NCCH() {} ArchiveFactory_NCCH::ArchiveFactory_NCCH() {}
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_NCCH::Open(const Path& path) { ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_NCCH::Open(const Path& path,
u64 program_id) {
if (path.GetType() != LowPathType::Binary) { if (path.GetType() != LowPathType::Binary) {
LOG_ERROR(Service_FS, "Path need to be Binary"); LOG_ERROR(Service_FS, "Path need to be Binary");
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
@ -290,14 +291,16 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_NCCH::Open(const Path&
} }
ResultCode ArchiveFactory_NCCH::Format(const Path& 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."); LOG_ERROR(Service_FS, "Attempted to format a NCCH archive.");
// TODO: Verify error code // TODO: Verify error code
return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported,
ErrorLevel::Permanent); ErrorLevel::Permanent);
} }
ResultVal<ArchiveFormatInfo> ArchiveFactory_NCCH::GetFormatInfo(const Path& path) const { ResultVal<ArchiveFormatInfo> ArchiveFactory_NCCH::GetFormatInfo(const Path& path,
u64 program_id) const {
// TODO(Subv): Implement // TODO(Subv): Implement
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
return ResultCode(-1); return ResultCode(-1);

View File

@ -97,9 +97,10 @@ public:
return "NCCH"; return "NCCH";
} }
ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path, u64 program_id) override;
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info,
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; u64 program_id) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override;
}; };
} // namespace FileSys } // namespace FileSys

View File

@ -64,7 +64,7 @@ ArchiveFactory_OtherSaveDataPermitted::ArchiveFactory_OtherSaveDataPermitted(
: sd_savedata_source(std::move(sd_savedata)) {} : sd_savedata_source(std::move(sd_savedata)) {}
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_OtherSaveDataPermitted::Open( ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_OtherSaveDataPermitted::Open(
const Path& path) { const Path& path, u64 /*client_program_id*/) {
MediaType media_type; MediaType media_type;
u64 program_id; u64 program_id;
CASCADE_RESULT(std::tie(media_type, program_id), ParsePathPermitted(path)); CASCADE_RESULT(std::tie(media_type, program_id), ParsePathPermitted(path));
@ -78,13 +78,13 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_OtherSaveDataPermitted
} }
ResultCode ArchiveFactory_OtherSaveDataPermitted::Format( 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."); LOG_ERROR(Service_FS, "Attempted to format a OtherSaveDataPermitted archive.");
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
ResultVal<ArchiveFormatInfo> ArchiveFactory_OtherSaveDataPermitted::GetFormatInfo( ResultVal<ArchiveFormatInfo> ArchiveFactory_OtherSaveDataPermitted::GetFormatInfo(
const Path& path) const { const Path& path, u64 /*client_program_id*/) const {
MediaType media_type; MediaType media_type;
u64 program_id; u64 program_id;
CASCADE_RESULT(std::tie(media_type, program_id), ParsePathPermitted(path)); 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)) {} : sd_savedata_source(std::move(sd_savedata)) {}
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_OtherSaveDataGeneral::Open( ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_OtherSaveDataGeneral::Open(
const Path& path) { const Path& path, u64 /*client_program_id*/) {
MediaType media_type; MediaType media_type;
u64 program_id; u64 program_id;
CASCADE_RESULT(std::tie(media_type, program_id), ParsePathGeneral(path)); CASCADE_RESULT(std::tie(media_type, program_id), ParsePathGeneral(path));
@ -116,7 +116,7 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_OtherSaveDataGeneral::
} }
ResultCode ArchiveFactory_OtherSaveDataGeneral::Format( 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; MediaType media_type;
u64 program_id; u64 program_id;
CASCADE_RESULT(std::tie(media_type, program_id), ParsePathGeneral(path)); CASCADE_RESULT(std::tie(media_type, program_id), ParsePathGeneral(path));
@ -130,7 +130,7 @@ ResultCode ArchiveFactory_OtherSaveDataGeneral::Format(
} }
ResultVal<ArchiveFormatInfo> ArchiveFactory_OtherSaveDataGeneral::GetFormatInfo( ResultVal<ArchiveFormatInfo> ArchiveFactory_OtherSaveDataGeneral::GetFormatInfo(
const Path& path) const { const Path& path, u64 /*client_program_id*/) const {
MediaType media_type; MediaType media_type;
u64 program_id; u64 program_id;
CASCADE_RESULT(std::tie(media_type, program_id), ParsePathGeneral(path)); CASCADE_RESULT(std::tie(media_type, program_id), ParsePathGeneral(path));

View File

@ -21,9 +21,10 @@ public:
return "OtherSaveDataPermitted"; return "OtherSaveDataPermitted";
} }
ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path, u64 program_id) override;
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info,
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; u64 program_id) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override;
private: private:
std::string mount_point; std::string mount_point;
@ -40,9 +41,10 @@ public:
return "OtherSaveDataGeneral"; return "OtherSaveDataGeneral";
} }
ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path, u64 program_id) override;
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info,
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; u64 program_id) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override;
private: private:
std::string mount_point; std::string mount_point;

View File

@ -16,20 +16,20 @@ ArchiveFactory_SaveData::ArchiveFactory_SaveData(
std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata) std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata)
: sd_savedata_source(std::move(sd_savedata)) {} : sd_savedata_source(std::move(sd_savedata)) {}
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const Path& path) { ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const Path& path,
return sd_savedata_source->Open( u64 program_id) {
Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id); return sd_savedata_source->Open(program_id);
} }
ResultCode ArchiveFactory_SaveData::Format(const Path& path, ResultCode ArchiveFactory_SaveData::Format(const Path& path,
const FileSys::ArchiveFormatInfo& format_info) { const FileSys::ArchiveFormatInfo& format_info,
return sd_savedata_source->Format( u64 program_id) {
Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id, format_info); return sd_savedata_source->Format(program_id, format_info);
} }
ResultVal<ArchiveFormatInfo> ArchiveFactory_SaveData::GetFormatInfo(const Path& path) const { ResultVal<ArchiveFormatInfo> ArchiveFactory_SaveData::GetFormatInfo(const Path& path,
return sd_savedata_source->GetFormatInfo( u64 program_id) const {
Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id); return sd_savedata_source->GetFormatInfo(program_id);
} }
} // namespace FileSys } // namespace FileSys

View File

@ -20,10 +20,11 @@ public:
return "SaveData"; return "SaveData";
} }
ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path, u64 program_id) override;
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info,
u64 program_id) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override;
private: private:
std::string mount_point; std::string mount_point;

View File

@ -376,18 +376,21 @@ bool ArchiveFactory_SDMC::Initialize() {
return true; return true;
} }
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMC::Open(const Path& path) { ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMC::Open(const Path& path,
u64 program_id) {
auto archive = std::make_unique<SDMCArchive>(sdmc_directory); auto archive = std::make_unique<SDMCArchive>(sdmc_directory);
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
} }
ResultCode ArchiveFactory_SDMC::Format(const Path& path, 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. :) // This is kind of an undesirable operation, so let's just ignore it. :)
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
ResultVal<ArchiveFormatInfo> ArchiveFactory_SDMC::GetFormatInfo(const Path& path) const { ResultVal<ArchiveFormatInfo> ArchiveFactory_SDMC::GetFormatInfo(const Path& path,
u64 program_id) const {
// TODO(Subv): Implement // TODO(Subv): Implement
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
return ResultCode(-1); return ResultCode(-1);

View File

@ -55,9 +55,10 @@ public:
return "SDMC"; return "SDMC";
} }
ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path, u64 program_id) override;
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info,
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; u64 program_id) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override;
private: private:
std::string sdmc_directory; std::string sdmc_directory;

View File

@ -49,19 +49,22 @@ bool ArchiveFactory_SDMCWriteOnly::Initialize() {
return true; return true;
} }
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMCWriteOnly::Open(const Path& path) { ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMCWriteOnly::Open(const Path& path,
u64 program_id) {
auto archive = std::make_unique<SDMCWriteOnlyArchive>(sdmc_directory); auto archive = std::make_unique<SDMCWriteOnlyArchive>(sdmc_directory);
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
} }
ResultCode ArchiveFactory_SDMCWriteOnly::Format(const Path& path, ResultCode ArchiveFactory_SDMCWriteOnly::Format(const Path& path,
const FileSys::ArchiveFormatInfo& format_info) { const FileSys::ArchiveFormatInfo& format_info,
u64 program_id) {
// TODO(wwylele): hwtest this // TODO(wwylele): hwtest this
LOG_ERROR(Service_FS, "Attempted to format a SDMC write-only archive."); LOG_ERROR(Service_FS, "Attempted to format a SDMC write-only archive.");
return ResultCode(-1); return ResultCode(-1);
} }
ResultVal<ArchiveFormatInfo> ArchiveFactory_SDMCWriteOnly::GetFormatInfo(const Path& path) const { ResultVal<ArchiveFormatInfo> ArchiveFactory_SDMCWriteOnly::GetFormatInfo(const Path& path,
u64 program_id) const {
// TODO(Subv): Implement // TODO(Subv): Implement
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
return ResultCode(-1); return ResultCode(-1);

View File

@ -46,9 +46,10 @@ public:
return "SDMCWriteOnly"; return "SDMCWriteOnly";
} }
ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path, u64 program_id) override;
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info,
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; u64 program_id) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override;
private: private:
std::string sdmc_directory; std::string sdmc_directory;

View File

@ -278,18 +278,20 @@ void ArchiveFactory_SelfNCCH::Register(Loader::AppLoader& app_loader) {
data.banner = std::make_shared<std::vector<u8>>(std::move(buffer)); data.banner = std::make_shared<std::vector<u8>>(std::move(buffer));
} }
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SelfNCCH::Open(const Path& path) { ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SelfNCCH::Open(const Path& path,
auto archive = std::make_unique<SelfNCCHArchive>( u64 program_id) {
ncch_data[Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id]); auto archive = std::make_unique<SelfNCCHArchive>(ncch_data[program_id]);
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); return MakeResult<std::unique_ptr<ArchiveBackend>>(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."); LOG_ERROR(Service_FS, "Attempted to format a SelfNCCH archive.");
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
ResultVal<ArchiveFormatInfo> ArchiveFactory_SelfNCCH::GetFormatInfo(const Path&) const { ResultVal<ArchiveFormatInfo> ArchiveFactory_SelfNCCH::GetFormatInfo(const Path&,
u64 program_id) const {
LOG_ERROR(Service_FS, "Attempted to get format info of a SelfNCCH archive"); LOG_ERROR(Service_FS, "Attempted to get format info of a SelfNCCH archive");
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }

View File

@ -37,9 +37,10 @@ public:
std::string GetName() const override { std::string GetName() const override {
return "SelfNCCH"; return "SelfNCCH";
} }
ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path, u64 program_id) override;
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info,
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; u64 program_id) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override;
private: private:
/// Mapping of ProgramId -> NCCHData /// Mapping of ProgramId -> NCCHData

View File

@ -52,7 +52,8 @@ Path ConstructSystemSaveDataBinaryPath(u32 high, u32 low) {
ArchiveFactory_SystemSaveData::ArchiveFactory_SystemSaveData(const std::string& nand_path) ArchiveFactory_SystemSaveData::ArchiveFactory_SystemSaveData(const std::string& nand_path)
: base_path(GetSystemSaveDataContainerPath(nand_path)) {} : base_path(GetSystemSaveDataContainerPath(nand_path)) {}
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SystemSaveData::Open(const Path& path) { ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SystemSaveData::Open(const Path& path,
u64 program_id) {
std::string fullpath = GetSystemSaveDataPath(base_path, path); std::string fullpath = GetSystemSaveDataPath(base_path, path);
if (!FileUtil::Exists(fullpath)) { if (!FileUtil::Exists(fullpath)) {
// TODO(Subv): Check error code, this one is probably wrong // TODO(Subv): Check error code, this one is probably wrong
@ -63,14 +64,16 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SystemSaveData::Open(c
} }
ResultCode ArchiveFactory_SystemSaveData::Format(const Path& path, 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); std::string fullpath = GetSystemSaveDataPath(base_path, path);
FileUtil::DeleteDirRecursively(fullpath); FileUtil::DeleteDirRecursively(fullpath);
FileUtil::CreateFullPath(fullpath); FileUtil::CreateFullPath(fullpath);
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
ResultVal<ArchiveFormatInfo> ArchiveFactory_SystemSaveData::GetFormatInfo(const Path& path) const { ResultVal<ArchiveFormatInfo> ArchiveFactory_SystemSaveData::GetFormatInfo(const Path& path,
u64 program_id) const {
// TODO(Subv): Implement // TODO(Subv): Implement
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
return ResultCode(-1); return ResultCode(-1);

View File

@ -20,9 +20,10 @@ class ArchiveFactory_SystemSaveData final : public ArchiveFactory {
public: public:
explicit ArchiveFactory_SystemSaveData(const std::string& mount_point); explicit ArchiveFactory_SystemSaveData(const std::string& mount_point);
ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path, u64 program_id) override;
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info,
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; u64 program_id) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const override;
std::string GetName() const override { std::string GetName() const override {
return "SystemSaveData"; return "SystemSaveData";

View File

@ -1362,7 +1362,7 @@ Module::Module(Core::System& system) : system(system) {
// Open the SystemSaveData archive 0x00010026 // Open the SystemSaveData archive 0x00010026
FileSys::Path archive_path(cecd_system_savedata_id); 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 the archive didn't exist, create the files inside
if (archive_result.Code() != FileSys::ERR_NOT_FORMATTED) { 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(); cecd_system_save_data_archive = std::move(archive_result).Unwrap();
} else { } else {
// Format the archive to create the directories // 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 // 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, /// Now that the archive is formatted, we need to create the root CEC directory,
/// eventlog.dat, and CEC/MBoxList____ /// eventlog.dat, and CEC/MBoxList____

View File

@ -531,15 +531,15 @@ ResultCode Module::LoadConfigNANDSaveFile() {
// Open the SystemSaveData archive 0x00010017 // Open the SystemSaveData archive 0x00010017
FileSys::Path archive_path(cfg_system_savedata_id); 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 the archive didn't exist, create the files inside
if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) { if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) {
// Format the archive to create the directories // 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 // 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 { } else {
ASSERT_MSG(archive_result.Succeeded(), "Could not open the CFG SystemSaveData archive!"); ASSERT_MSG(archive_result.Succeeded(), "Could not open the CFG SystemSaveData archive!");

View File

@ -36,7 +36,7 @@ ArchiveBackend* ArchiveManager::GetArchive(ArchiveHandle handle) {
} }
ResultVal<ArchiveHandle> ArchiveManager::OpenArchive(ArchiveIdCode id_code, ResultVal<ArchiveHandle> 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<u32>(id_code)); LOG_TRACE(Service_FS, "Opening archive with id code 0x{:08X}", static_cast<u32>(id_code));
auto itr = id_code_map.find(id_code); auto itr = id_code_map.find(id_code);
@ -44,7 +44,8 @@ ResultVal<ArchiveHandle> ArchiveManager::OpenArchive(ArchiveIdCode id_code,
return FileSys::ERROR_NOT_FOUND; return FileSys::ERROR_NOT_FOUND;
} }
CASCADE_RESULT(std::unique_ptr<ArchiveBackend> res, itr->second->Open(archive_path)); CASCADE_RESULT(std::unique_ptr<ArchiveBackend> res,
itr->second->Open(archive_path, program_id));
// This should never even happen in the first place with 64-bit handles, // This should never even happen in the first place with 64-bit handles,
while (handle_map.count(next_handle) != 0) { while (handle_map.count(next_handle) != 0) {
@ -193,28 +194,29 @@ ResultVal<u64> ArchiveManager::GetFreeBytesInArchive(ArchiveHandle archive_handl
ResultCode ArchiveManager::FormatArchive(ArchiveIdCode id_code, ResultCode ArchiveManager::FormatArchive(ArchiveIdCode id_code,
const FileSys::ArchiveFormatInfo& format_info, 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); auto archive_itr = id_code_map.find(id_code);
if (archive_itr == id_code_map.end()) { if (archive_itr == id_code_map.end()) {
return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error 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<FileSys::ArchiveFormatInfo> ArchiveManager::GetArchiveFormatInfo( ResultVal<FileSys::ArchiveFormatInfo> 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); auto archive = id_code_map.find(id_code);
if (archive == id_code_map.end()) { if (archive == id_code_map.end()) {
return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error 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, ResultCode ArchiveManager::CreateExtSaveData(MediaType media_type, u32 high, u32 low,
const std::vector<u8>& smdh_icon, const std::vector<u8>& smdh_icon,
const FileSys::ArchiveFormatInfo& format_info) { const FileSys::ArchiveFormatInfo& format_info,
u64 program_id) {
// Construct the binary path to the archive first // Construct the binary path to the archive first
FileSys::Path path = FileSys::Path path =
FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low); FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low);
@ -228,7 +230,7 @@ ResultCode ArchiveManager::CreateExtSaveData(MediaType media_type, u32 high, u32
auto ext_savedata = static_cast<FileSys::ArchiveFactory_ExtSaveData*>(archive->second.get()); auto ext_savedata = static_cast<FileSys::ArchiveFactory_ExtSaveData*>(archive->second.get());
ResultCode result = ext_savedata->Format(path, format_info); ResultCode result = ext_savedata->Format(path, format_info, program_id);
if (result.IsError()) if (result.IsError())
return result; return result;

View File

@ -60,9 +60,11 @@ public:
* Opens an archive * Opens an archive
* @param id_code IdCode of the archive to open * @param id_code IdCode of the archive to open
* @param archive_path Path to the archive, used with Binary paths * @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 * @return Handle to the opened archive
*/ */
ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archive_path); ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archive_path,
u64 program_id);
/** /**
* Closes an archive * Closes an archive
@ -172,20 +174,23 @@ public:
* @param id_code The id of the archive to format * @param id_code The id of the archive to format
* @param format_info Format information about the new archive * @param format_info Format information about the new archive
* @param path The path to the archive, if relevant. * @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 * @return ResultCode 0 on success or the corresponding code on error
*/ */
ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, 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. * 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. * The format info is supplied by the client code when creating archives.
* @param id_code The id of the archive * @param id_code The id of the archive
* @param archive_path The path of the archive, if relevant * @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. * @return The format info of the archive, or the corresponding error code if failed.
*/ */
ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code, ResultVal<FileSys::ArchiveFormatInfo> 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 * 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 low The low word of the extdata id to create
* @param smdh_icon the SMDH icon for this ExtSaveData * @param smdh_icon the SMDH icon for this ExtSaveData
* @param format_info Format information about the new archive * @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 * @return ResultCode 0 on success or the corresponding code on error
*/ */
ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low,
const std::vector<u8>& smdh_icon, const std::vector<u8>& smdh_icon,
const FileSys::ArchiveFormatInfo& format_info); const FileSys::ArchiveFormatInfo& format_info, u64 program_id);
/** /**
* Deletes the SharedExtSaveData archive for the specified extdata ID * Deletes the SharedExtSaveData archive for the specified extdata ID

View File

@ -35,7 +35,10 @@ namespace Service::FS {
void FS_USER::Initialize(Kernel::HLERequestContext& ctx) { void FS_USER::Initialize(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x0801, 0, 2); 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); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
@ -93,7 +96,10 @@ void FS_USER::OpenFileDirectly(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
ResultVal<ArchiveHandle> archive_handle = archives.OpenArchive(archive_id, archive_path); ClientSlot* slot = GetSessionData(ctx.Session());
ResultVal<ArchiveHandle> archive_handle =
archives.OpenArchive(archive_id, archive_path, slot->program_id);
if (archive_handle.Failed()) { if (archive_handle.Failed()) {
LOG_ERROR(Service_FS, LOG_ERROR(Service_FS,
"Failed to get a handle for archive archive_id=0x{:08X} archive_path={}", "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()); archive_path.DebugStr());
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0); IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
ResultVal<ArchiveHandle> handle = archives.OpenArchive(archive_id, archive_path); ClientSlot* slot = GetSessionData(ctx.Session());
ResultVal<ArchiveHandle> handle =
archives.OpenArchive(archive_id, archive_path, slot->program_id);
rb.Push(handle.Code()); rb.Push(handle.Code());
if (handle.Succeeded()) { if (handle.Succeeded()) {
rb.PushRaw(*handle); rb.PushRaw(*handle);
@ -385,7 +393,9 @@ void FS_USER::FormatSaveData(Kernel::HLERequestContext& ctx) {
format_info.number_files = number_files; format_info.number_files = number_files;
format_info.total_size = block_size * 512; 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) { 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; format_info.total_size = block_size * 512;
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); 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"); LOG_TRACE(Service_FS, "called");
} }
@ -446,7 +458,9 @@ void FS_USER::CreateExtSaveData(Kernel::HLERequestContext& ctx) {
format_info.total_size = 0; format_info.total_size = 0;
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); 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); rb.PushMappedBuffer(icon_buffer);
LOG_DEBUG(Service_FS, LOG_DEBUG(Service_FS,
@ -535,7 +549,10 @@ void FS_USER::CreateLegacySystemSaveData(Kernel::HLERequestContext& ctx) {
void FS_USER::InitializeWithSdkVersion(Kernel::HLERequestContext& ctx) { void FS_USER::InitializeWithSdkVersion(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x861, 1, 2); IPC::RequestParser rp(ctx, 0x861, 1, 2);
const u32 version = rp.Pop<u32>(); const u32 version = rp.Pop<u32>();
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); 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()); LOG_DEBUG(Service_FS, "archive_path={}", archive_path.DebugStr());
IPC::RequestBuilder rb = rp.MakeBuilder(5, 0); IPC::RequestBuilder rb = rp.MakeBuilder(5, 0);
ClientSlot* slot = GetSessionData(ctx.Session());
auto format_info = archives.GetArchiveFormatInfo(archive_id, archive_path); auto format_info = archives.GetArchiveFormatInfo(archive_id, archive_path, slot->program_id);
rb.Push(format_info.Code()); rb.Push(format_info.Code());
if (format_info.Failed()) { if (format_info.Failed()) {
LOG_ERROR(Service_FS, "Failed to retrieve the format info"); 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; format_info.total_size = 0;
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); 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); rb.PushMappedBuffer(icon_buffer);
LOG_DEBUG(Service_FS, LOG_DEBUG(Service_FS,

View File

@ -15,7 +15,16 @@ namespace Service::FS {
class ArchiveManager; class ArchiveManager;
class FS_USER final : public ServiceFramework<FS_USER> { 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<FS_USER, ClientSlot> {
public: public:
explicit FS_USER(Core::System& system); explicit FS_USER(Core::System& system);

View File

@ -143,16 +143,16 @@ static void WriteGameCoinData(GameCoin gamecoin_data) {
FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true); FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true);
FileSys::Path archive_path(ptm_shared_extdata_id); 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<FileSys::ArchiveBackend> archive; std::unique_ptr<FileSys::ArchiveBackend> archive;
FileSys::Path gamecoin_path("/gamecoin.dat"); FileSys::Path gamecoin_path("/gamecoin.dat");
// If the archive didn't exist, create the files inside // If the archive didn't exist, create the files inside
if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) { if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) {
// Format the archive to create the directories // 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 // 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 // Create the game coin file
archive->CreateFile(gamecoin_path, sizeof(GameCoin)); archive->CreateFile(gamecoin_path, sizeof(GameCoin));
} else { } else {
@ -176,7 +176,7 @@ static GameCoin ReadGameCoinData() {
FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true); FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true);
FileSys::Path archive_path(ptm_shared_extdata_id); 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()) { if (!archive_result.Succeeded()) {
LOG_ERROR(Service_PTM, "Could not open the PTM SharedExtSaveData archive!"); LOG_ERROR(Service_PTM, "Could not open the PTM SharedExtSaveData archive!");
return default_game_coin; return default_game_coin;
@ -205,7 +205,7 @@ Module::Module() {
std::string nand_directory = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir); std::string nand_directory = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true); FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true);
FileSys::Path archive_path(ptm_shared_extdata_id); 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 the archive didn't exist, write the default game coin file
if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) { if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) {
WriteGameCoinData(default_game_coin); WriteGameCoinData(default_game_coin);