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

Merge pull request #4618 from wwylele/fs-clean

FS: pass down program ID for archive operation (cleanup System::GetInstance part 3)
This commit is contained in:
Weiyi Wang 2019-03-04 12:34:54 -05:00 committed by GitHub
commit 9c57b74907
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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

@ -95,9 +95,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);