Exemple #1
0
static GameCoin ReadGameCoinData() {
    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);
    if (!archive_result.Succeeded()) {
        LOG_ERROR(Service_PTM, "Could not open the PTM SharedExtSaveData archive!");
        return default_game_coin;
    }

    FileSys::Path gamecoin_path("/gamecoin.dat");
    FileSys::Mode open_mode = {};
    open_mode.read_flag.Assign(1);

    auto gamecoin_result = (*archive_result)->OpenFile(gamecoin_path, open_mode);
    if (!gamecoin_result.Succeeded()) {
        LOG_ERROR(Service_PTM, "Could not open the game coin data file!");
        return default_game_coin;
    }
    u16 result;
    auto gamecoin = std::move(gamecoin_result).Unwrap();
    GameCoin gamecoin_data;
    gamecoin->Read(0, sizeof(GameCoin), reinterpret_cast<u8*>(&gamecoin_data));
    gamecoin->Close();
    return gamecoin_data;
}
Exemple #2
0
static void WriteGameCoinData(GameCoin gamecoin_data) {
    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);
    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());
        // Open it again to get a valid archive now that the folder exists
        archive = extdata_archive_factory.Open(archive_path).Unwrap();
        // Create the game coin file
        archive->CreateFile(gamecoin_path, sizeof(GameCoin));
    } else {
        ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!");
        archive = std::move(archive_result).Unwrap();
    }

    FileSys::Mode open_mode = {};
    open_mode.write_flag.Assign(1);
    // Open the file and write the default gamecoin information
    auto gamecoin_result = archive->OpenFile(gamecoin_path, open_mode);
    if (gamecoin_result.Succeeded()) {
        auto gamecoin = std::move(gamecoin_result).Unwrap();
        gamecoin->Write(0, sizeof(GameCoin), true, reinterpret_cast<const u8*>(&gamecoin_data));
        gamecoin->Close();
    }
}
Exemple #3
0
/**
 * FS_User::OpenArchive service function
 *  Inputs:
 *      1 : Archive ID
 *      2 : Archive low path type
 *      3 : Archive low path size
 *      4 : (LowPathSize << 14) | 2
 *      5 : Archive low path
 *  Outputs:
 *      1 : Result of function, 0 on success, otherwise error code
 *      2 : Archive handle lower word (unused)
 *      3 : Archive handle upper word (same as file handle)
 */
static void OpenArchive(Service::Interface* self) {
    u32* cmd_buff = Service::GetCommandBuffer();

    auto archive_id       = static_cast<FileSys::Archive::IdCode>(cmd_buff[1]);
    auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[2]);
    u32 archivename_size  = cmd_buff[3];
    u32 archivename_ptr   = cmd_buff[5];
    FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr);

    DEBUG_LOG(KERNEL, "archive_path=%s", archive_path.DebugStr().c_str());

    if (archive_path.GetType() != FileSys::Empty) {
        ERROR_LOG(KERNEL, "archive LowPath type other than empty is currently unsupported");
        cmd_buff[1] = UnimplementedFunction(ErrorModule::FS).raw;
        return;
    }

    ResultVal<Handle> handle = Kernel::OpenArchive(archive_id);
    cmd_buff[1] = handle.Code().raw;
    if (handle.Succeeded()) {
        // cmd_buff[2] isn't used according to 3dmoo's implementation.
        cmd_buff[3] = *handle;
    } else {
        ERROR_LOG(KERNEL, "failed to get a handle for archive");
    }

    DEBUG_LOG(KERNEL, "called");
}
Exemple #4
0
void Init() {
    AddService(new PTM_Play_Interface);
    AddService(new PTM_Sysm_Interface);
    AddService(new PTM_U_Interface);

    shell_open = true;
    battery_is_charging = true;

    // Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't exist
    FileSys::Path archive_path(ptm_shared_extdata_id);
    auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
    // If the archive didn't exist, create the files inside
    if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) {
        // Format the archive to create the directories
        Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
        // Open it again to get a valid archive now that the folder exists
        archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
        ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!");

        FileSys::Path gamecoin_path("gamecoin.dat");
        FileSys::Mode open_mode = {};
        open_mode.write_flag = 1;
        open_mode.create_flag = 1;
        // Open the file and write the default gamecoin information
        auto gamecoin_result = Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode);
        if (gamecoin_result.Succeeded()) {
            auto gamecoin = gamecoin_result.MoveFrom();
            gamecoin->backend->Write(0, sizeof(GameCoin), 1, reinterpret_cast<const u8*>(&default_game_coin));
            gamecoin->backend->Close();
        }
    }
}
Exemple #5
0
Module::Module() {
    // Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't
    // exist
    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);
    // If the archive didn't exist, write the default game coin file
    if (archive_result.Code() == FileSys::ERR_NOT_FORMATTED) {
        WriteGameCoinData(default_game_coin);
    }
}
Exemple #6
0
/**
 * FS_User::OpenFileDirectly service function
 *  Inputs:
 *      1 : Transaction
 *      2 : Archive ID
 *      3 : Archive low path type
 *      4 : Archive low path size
 *      5 : File low path type
 *      6 : File low path size
 *      7 : Flags
 *      8 : Attributes
 *      9 : (ArchiveLowPathSize << 14) | 0x802
 *      10 : Archive low path
 *      11 : (FileLowPathSize << 14) | 2
 *      12 : File low path
 *  Outputs:
 *      1 : Result of function, 0 on success, otherwise error code
 *      3 : File handle
 */
static void OpenFileDirectly(Service::Interface* self) {
    u32* cmd_buff = Service::GetCommandBuffer();

    auto archive_id       = static_cast<FileSys::Archive::IdCode>(cmd_buff[2]);
    auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[3]);
    u32 archivename_size  = cmd_buff[4];
    auto filename_type    = static_cast<FileSys::LowPathType>(cmd_buff[5]);
    u32 filename_size     = cmd_buff[6];
    FileSys::Mode mode; mode.hex = cmd_buff[7];
    u32 attributes        = cmd_buff[8]; // TODO(Link Mauve): do something with those attributes.
    u32 archivename_ptr   = cmd_buff[10];
    u32 filename_ptr      = cmd_buff[12];
    FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr);
    FileSys::Path file_path(filename_type, filename_size, filename_ptr);

    DEBUG_LOG(KERNEL, "archive_path=%s file_path=%s, mode=%u attributes=%d",
              archive_path.DebugStr().c_str(), file_path.DebugStr().c_str(), mode.hex, attributes);

    if (archive_path.GetType() != FileSys::Empty) {
        ERROR_LOG(KERNEL, "archive LowPath type other than empty is currently unsupported");
        cmd_buff[1] = UnimplementedFunction(ErrorModule::FS).raw;
        return;
    }

    // TODO(Link Mauve): Check if we should even get a handle for the archive, and don't leak it
    // TODO(yuriks): Why is there all this duplicate (and seemingly useless) code up here?
    ResultVal<Handle> archive_handle = Kernel::OpenArchive(archive_id);
    cmd_buff[1] = archive_handle.Code().raw;
    if (archive_handle.Failed()) {
        ERROR_LOG(KERNEL, "failed to get a handle for archive");
        return;
    }
    // cmd_buff[2] isn't used according to 3dmoo's implementation.
    cmd_buff[3] = *archive_handle;

    ResultVal<Handle> handle = Kernel::OpenFileFromArchive(*archive_handle, file_path, mode);
    cmd_buff[1] = handle.Code().raw;
    if (handle.Succeeded()) {
        cmd_buff[3] = *handle;
    } else {
        ERROR_LOG(KERNEL, "failed to get a handle for file %s", file_path.DebugStr().c_str());
    }

    DEBUG_LOG(KERNEL, "called");
}