mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-11-04 07:38:47 +00:00 
			
		
		
		
	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:
		
						commit
						9c57b74907
					
				
					 24 changed files with 165 additions and 99 deletions
				
			
		| 
						 | 
				
			
			@ -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____
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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!");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ ArchiveBackend* ArchiveManager::GetArchive(ArchiveHandle handle) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
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));
 | 
			
		||||
 | 
			
		||||
    auto itr = id_code_map.find(id_code);
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +44,8 @@ ResultVal<ArchiveHandle> ArchiveManager::OpenArchive(ArchiveIdCode id_code,
 | 
			
		|||
        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,
 | 
			
		||||
    while (handle_map.count(next_handle) != 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -193,28 +194,29 @@ ResultVal<u64> 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<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);
 | 
			
		||||
    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<u8>& 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<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());
 | 
			
		||||
 | 
			
		||||
    ResultCode result = ext_savedata->Format(path, format_info);
 | 
			
		||||
    ResultCode result = ext_savedata->Format(path, format_info, program_id);
 | 
			
		||||
    if (result.IsError())
 | 
			
		||||
        return result;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<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
 | 
			
		||||
| 
						 | 
				
			
			@ -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<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
 | 
			
		||||
| 
						 | 
				
			
			@ -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<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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<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()) {
 | 
			
		||||
        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<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());
 | 
			
		||||
    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<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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,16 @@ namespace Service::FS {
 | 
			
		|||
 | 
			
		||||
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:
 | 
			
		||||
    explicit FS_USER(Core::System& system);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<FileSys::ArchiveBackend> 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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue