mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-22 04:24:44 +00:00
SaveData: rewrite to implement full functionality
This commit is contained in:
parent
1de295aa94
commit
477bd4ea9d
10 changed files with 1193 additions and 644 deletions
|
@ -232,7 +232,8 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
|||
src/core/libraries/system/msgdialog_ui.cpp
|
||||
src/core/libraries/system/posix.cpp
|
||||
src/core/libraries/system/posix.h
|
||||
src/core/libraries/save_data/error_codes.h
|
||||
src/core/libraries/save_data/save_instance.cpp
|
||||
src/core/libraries/save_data/save_instance.h
|
||||
src/core/libraries/save_data/savedata.cpp
|
||||
src/core/libraries/save_data/savedata.h
|
||||
src/core/libraries/system/savedatadialog.cpp
|
||||
|
|
|
@ -396,4 +396,18 @@ s64 IOFile::Tell() const {
|
|||
return ftello(file);
|
||||
}
|
||||
|
||||
u64 GetDirectorySize(const std::filesystem::path& path) {
|
||||
if (!fs::exists(path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 total = 0;
|
||||
for (const auto& entry : fs::recursive_directory_iterator(path)) {
|
||||
if (fs::is_regular_file(entry.path())) {
|
||||
total += fs::file_size(entry.path());
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
} // namespace Common::FS
|
||||
|
|
|
@ -219,4 +219,6 @@ private:
|
|||
uintptr_t file_mapping = 0;
|
||||
};
|
||||
|
||||
u64 GetDirectorySize(const std::filesystem::path& path);
|
||||
|
||||
} // namespace Common::FS
|
||||
|
|
|
@ -21,6 +21,10 @@ std::string ToLower(std::string_view input) {
|
|||
return str;
|
||||
}
|
||||
|
||||
void ToLowerInPlace(std::string& str) {
|
||||
std::ranges::transform(str, str.begin(), tolower);
|
||||
}
|
||||
|
||||
std::vector<std::string> SplitString(const std::string& str, char delimiter) {
|
||||
std::istringstream iss(str);
|
||||
std::vector<std::string> output(1);
|
||||
|
|
|
@ -12,6 +12,8 @@ namespace Common {
|
|||
/// Make a string lowercase
|
||||
[[nodiscard]] std::string ToLower(std::string_view str);
|
||||
|
||||
void ToLowerInPlace(std::string& str);
|
||||
|
||||
std::vector<std::string> SplitString(const std::string& str, char delimiter);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_PARAMETER = 0x809F0000;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_INITIALIZED = 0x809F0001;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_OUT_OF_MEMORY = 0x809F0002;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_BUSY = 0x809F0003;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_MOUNTED = 0x809F0004;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_NO_PERMISSION = 0x809F0005;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_FINGERPRINT_MISMATCH = 0x809F0006;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_EXISTS = 0x809F0007;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_FOUND = 0x809F0008;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_NO_SPACE_FS = 0x809F000A;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_INTERNAL = 0x809F000B;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_MOUNT_FULL = 0x809F000C;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_BAD_MOUNTED = 0x809F000D;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_FILE_NOT_FOUND = 0x809F000E;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_BROKEN = 0x809F000F;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_INVALID_LOGIN_USER = 0x809F0011;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_MEMORY_NOT_READY = 0x809F0012;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_BACKUP_BUSY = 0x809F0013;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_REGIST_CALLBACK = 0x809F0015;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_BUSY_FOR_SAVING = 0x809F0016;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_LIMITATION_OVER = 0x809F0017;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_EVENT_BUSY = 0x809F0018;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_PARAMSFO_TRANSFER_TITLE_ID_NOT_FOUND = 0x809F0019;
|
224
src/core/libraries/save_data/save_instance.cpp
Normal file
224
src/core/libraries/save_data/save_instance.cpp
Normal file
|
@ -0,0 +1,224 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <magic_enum.hpp>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/config.h"
|
||||
#include "common/path_util.h"
|
||||
#include "common/singleton.h"
|
||||
#include "core/file_sys/fs.h"
|
||||
#include "save_instance.h"
|
||||
|
||||
constexpr u32 OrbisSaveDataBlocksMax = 32768; // 1 GiB
|
||||
constexpr std::string_view sce_sys = "sce_sys"; // system folder inside save
|
||||
constexpr std::string_view max_block_file_name = "max_block.txt";
|
||||
|
||||
static Core::FileSys::MntPoints* g_mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
// clang-format off
|
||||
static const std::unordered_map<std::string, std::string> default_title = {
|
||||
{"ja_JP", "セーブデータ"},
|
||||
{"en", "Saved Data"},
|
||||
{"fr", "Données sauvegardées"},
|
||||
{"es_ES", "Datos guardados"},
|
||||
{"de", "Gespeicherte Daten"},
|
||||
{"it", "Dati salvati"},
|
||||
{"nl", "Opgeslagen data"},
|
||||
{"pt_PT", "Dados guardados"},
|
||||
{"ru", "Сохраненные данные"},
|
||||
{"ko_KR", "저장 데이터"},
|
||||
{"zh_CN", "保存数据"},
|
||||
{"fi", "Tallennetut tiedot"},
|
||||
{"sv_SE", "Sparade data"},
|
||||
{"da_DK", "Gemte data"},
|
||||
{"no_NO", "Lagrede data"},
|
||||
{"pl_PL", "Zapisane dane"},
|
||||
{"pt_BR", "Dados salvos"},
|
||||
{"tr_TR", "Kayıtlı Veriler"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
namespace Libraries::SaveData {
|
||||
|
||||
std::filesystem::path SaveInstance::MakeTitleSavePath(OrbisUserServiceUserId user_id,
|
||||
std::string_view game_serial) {
|
||||
return Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) / std::to_string(user_id) /
|
||||
game_serial;
|
||||
}
|
||||
|
||||
std::filesystem::path SaveInstance::MakeDirSavePath(OrbisUserServiceUserId user_id,
|
||||
std::string_view game_serial,
|
||||
std::string_view dir_name) {
|
||||
return Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) / std::to_string(user_id) /
|
||||
game_serial / dir_name;
|
||||
}
|
||||
int SaveInstance::GetMaxBlocks(const std::filesystem::path& save_path) {
|
||||
Common::FS::IOFile max_blocks_file{save_path / sce_sys / max_block_file_name,
|
||||
Common::FS::FileAccessMode::Read};
|
||||
int max_blocks = 0;
|
||||
if (max_blocks_file.IsOpen()) {
|
||||
max_blocks = std::atoi(max_blocks_file.ReadString(16).c_str());
|
||||
}
|
||||
if (max_blocks <= 0) {
|
||||
max_blocks = OrbisSaveDataBlocksMax;
|
||||
}
|
||||
|
||||
return max_blocks;
|
||||
}
|
||||
|
||||
std::filesystem::path SaveInstance::GetParamSFOPath(const std::filesystem::path& dir_path) {
|
||||
return dir_path / sce_sys / "param.sfo";
|
||||
}
|
||||
|
||||
SaveInstance::SaveInstance(int slot_num, OrbisUserServiceUserId user_id, std::string _game_serial,
|
||||
std::string_view _dir_name, int max_blocks)
|
||||
: slot_num(slot_num), user_id(user_id), game_serial(std::move(_game_serial)),
|
||||
dir_name(_dir_name), max_blocks(max_blocks) {
|
||||
ASSERT(slot_num >= 0 && slot_num < 16);
|
||||
|
||||
save_path = MakeDirSavePath(user_id, game_serial, dir_name);
|
||||
|
||||
const auto sce_sys_path = save_path / sce_sys;
|
||||
param_sfo_path = sce_sys_path / "param.sfo";
|
||||
corrupt_file_path = sce_sys_path / "corrupted";
|
||||
|
||||
this->exists = fs::exists(param_sfo_path);
|
||||
this->mounted = false;
|
||||
}
|
||||
|
||||
SaveInstance::~SaveInstance() {
|
||||
if (mounted) {
|
||||
Umount();
|
||||
}
|
||||
}
|
||||
SaveInstance::SaveInstance(SaveInstance&& other) noexcept {
|
||||
if (this == &other)
|
||||
return;
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
SaveInstance& SaveInstance::operator=(SaveInstance&& other) noexcept {
|
||||
if (this == &other)
|
||||
return *this;
|
||||
slot_num = other.slot_num;
|
||||
user_id = other.user_id;
|
||||
game_serial = std::move(other.game_serial);
|
||||
dir_name = std::move(other.dir_name);
|
||||
save_path = std::move(other.save_path);
|
||||
param_sfo_path = std::move(other.param_sfo_path);
|
||||
corrupt_file_path = std::move(other.corrupt_file_path);
|
||||
corrupt_file = std::move(other.corrupt_file);
|
||||
last_write = other.last_write;
|
||||
param_sfo = std::move(other.param_sfo);
|
||||
mount_point = std::move(other.mount_point);
|
||||
max_blocks = other.max_blocks;
|
||||
exists = other.exists;
|
||||
mounted = other.mounted;
|
||||
read_only = other.read_only;
|
||||
|
||||
other.mounted = false;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SaveInstance::SetupAndMount(bool read_only, bool copy_icon, bool ignore_corrupt) {
|
||||
if (mounted) {
|
||||
UNREACHABLE_MSG("Save instance is already mounted");
|
||||
}
|
||||
this->exists = fs::exists(param_sfo_path); // check again just in case
|
||||
if (!exists) {
|
||||
CreateFiles();
|
||||
if (copy_icon) {
|
||||
const auto& src_icon = g_mnt->GetHostPath("/app0/sce_sys/save_data.png");
|
||||
if (fs::exists(src_icon)) {
|
||||
fs::copy_file(src_icon, GetIconPath());
|
||||
}
|
||||
}
|
||||
exists = true;
|
||||
last_write = std::filesystem::file_time_type::clock::now();
|
||||
} else {
|
||||
if (!ignore_corrupt && fs::exists(corrupt_file_path)) {
|
||||
throw std::filesystem::filesystem_error(
|
||||
"Corrupted save data", corrupt_file_path,
|
||||
std::make_error_code(std::errc::illegal_byte_sequence));
|
||||
}
|
||||
last_write = fs::last_write_time(param_sfo_path);
|
||||
if (!param_sfo.Open(param_sfo_path)) {
|
||||
throw std::filesystem::filesystem_error(
|
||||
"Failed to read param.sfo", param_sfo_path,
|
||||
std::make_error_code(std::errc::illegal_byte_sequence));
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignore_corrupt) {
|
||||
int err = corrupt_file.Open(corrupt_file_path, Common::FS::FileAccessMode::Write);
|
||||
if (err != 0) {
|
||||
throw std::filesystem::filesystem_error(
|
||||
"Failed to open corrupted file", corrupt_file_path,
|
||||
std::make_error_code(std::errc::illegal_byte_sequence));
|
||||
}
|
||||
}
|
||||
|
||||
max_blocks = GetMaxBlocks(save_path);
|
||||
|
||||
mount_point = "/savedata" + std::to_string(slot_num);
|
||||
g_mnt->Mount(save_path, mount_point, read_only);
|
||||
mounted = true;
|
||||
this->read_only = read_only;
|
||||
}
|
||||
|
||||
void SaveInstance::Umount() {
|
||||
if (!mounted) {
|
||||
UNREACHABLE_MSG("Save instance is not mounted");
|
||||
return;
|
||||
}
|
||||
mounted = false;
|
||||
const bool ok = param_sfo.Encode(param_sfo_path);
|
||||
if (!ok) {
|
||||
throw std::filesystem::filesystem_error("Failed to write param.sfo", param_sfo_path,
|
||||
std::make_error_code(std::errc::permission_denied));
|
||||
}
|
||||
last_write = std::filesystem::file_time_type::clock::now();
|
||||
param_sfo = PSF();
|
||||
|
||||
corrupt_file.Close();
|
||||
fs::remove(corrupt_file_path);
|
||||
}
|
||||
|
||||
void SaveInstance::CreateFiles() {
|
||||
const auto sce_sys_dir = save_path / sce_sys;
|
||||
fs::create_directories(sce_sys_dir);
|
||||
|
||||
std::string locale = Config::getEmulatorLanguage();
|
||||
if (!default_title.contains(locale)) {
|
||||
locale = "en";
|
||||
}
|
||||
|
||||
#define P(type, key, ...) param_sfo.Add##type(std::string{key}, __VA_ARGS__)
|
||||
// TODO Link with user service
|
||||
P(Binary, SaveParams::ACCOUNT_ID, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
||||
P(String, SaveParams::MAINTITLE, default_title.at(locale));
|
||||
P(String, SaveParams::SUBTITLE, "");
|
||||
P(String, SaveParams::DETAIL, "");
|
||||
P(String, SaveParams::SAVEDATA_DIRECTORY, dir_name);
|
||||
P(Integer, SaveParams::SAVEDATA_LIST_PARAM, 0);
|
||||
P(String, SaveParams::TITLE_ID, game_serial);
|
||||
#undef P
|
||||
|
||||
const bool ok = param_sfo.Encode(param_sfo_path);
|
||||
if (!ok) {
|
||||
throw std::filesystem::filesystem_error("Failed to write param.sfo", param_sfo_path,
|
||||
std::make_error_code(std::errc::permission_denied));
|
||||
}
|
||||
|
||||
Common::FS::IOFile max_block{sce_sys_dir / max_block_file_name,
|
||||
Common::FS::FileAccessMode::Write};
|
||||
max_block.WriteString(std::to_string(max_blocks == 0 ? OrbisSaveDataBlocksMax : max_blocks));
|
||||
}
|
||||
|
||||
} // namespace Libraries::SaveData
|
129
src/core/libraries/save_data/save_instance.h
Normal file
129
src/core/libraries/save_data/save_instance.h
Normal file
|
@ -0,0 +1,129 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include "core/file_format/psf.h"
|
||||
|
||||
namespace Core::FileSys {
|
||||
class MntPoints;
|
||||
}
|
||||
|
||||
namespace Libraries::SaveData {
|
||||
|
||||
// Used constexpr to easily use as string
|
||||
namespace SaveParams {
|
||||
constexpr std::string_view ACCOUNT_ID = "ACCOUNT_ID";
|
||||
constexpr std::string_view ATTRIBUTE = "ATTRIBUTE";
|
||||
constexpr std::string_view CATEGORY = "CATEGORY";
|
||||
constexpr std::string_view DETAIL = "DETAIL";
|
||||
constexpr std::string_view FORMAT = "FORMAT";
|
||||
constexpr std::string_view MAINTITLE = "MAINTITLE";
|
||||
constexpr std::string_view PARAMS = "PARAMS";
|
||||
constexpr std::string_view SAVEDATA_BLOCKS = "SAVEDATA_BLOCKS";
|
||||
constexpr std::string_view SAVEDATA_DIRECTORY = "SAVEDATA_DIRECTORY";
|
||||
constexpr std::string_view SAVEDATA_LIST_PARAM = "SAVEDATA_LIST_PARAM";
|
||||
constexpr std::string_view SUBTITLE = "SUBTITLE";
|
||||
constexpr std::string_view TITLE_ID = "TITLE_ID";
|
||||
} // namespace SaveParams
|
||||
|
||||
using OrbisUserServiceUserId = s32;
|
||||
|
||||
class SaveInstance {
|
||||
int slot_num{};
|
||||
int user_id{};
|
||||
std::string game_serial;
|
||||
std::string dir_name;
|
||||
|
||||
std::filesystem::path save_path;
|
||||
std::filesystem::path param_sfo_path;
|
||||
std::filesystem::path corrupt_file_path;
|
||||
|
||||
Common::FS::IOFile corrupt_file;
|
||||
|
||||
std::filesystem::file_time_type last_write;
|
||||
PSF param_sfo;
|
||||
std::string mount_point;
|
||||
|
||||
int max_blocks{};
|
||||
bool exists{};
|
||||
bool mounted{};
|
||||
bool read_only{};
|
||||
|
||||
public:
|
||||
// Location of all save data for a title
|
||||
static std::filesystem::path MakeTitleSavePath(OrbisUserServiceUserId user_id,
|
||||
std::string_view game_serial);
|
||||
|
||||
// Location of a specific save data directory
|
||||
static std::filesystem::path MakeDirSavePath(OrbisUserServiceUserId user_id,
|
||||
std::string_view game_serial,
|
||||
std::string_view dir_name);
|
||||
|
||||
static int GetMaxBlocks(const std::filesystem::path& save_path);
|
||||
|
||||
// Get param.sfo path from a dir_path generated by MakeDirSavePath
|
||||
static std::filesystem::path GetParamSFOPath(const std::filesystem::path& dir_path);
|
||||
|
||||
explicit SaveInstance(int slot_num, OrbisUserServiceUserId user_id, std::string game_serial,
|
||||
std::string_view dir_name, int max_blocks = 0);
|
||||
|
||||
~SaveInstance();
|
||||
|
||||
SaveInstance(const SaveInstance& other) = delete;
|
||||
SaveInstance(SaveInstance&& other) noexcept;
|
||||
|
||||
SaveInstance& operator=(const SaveInstance& other) = delete;
|
||||
SaveInstance& operator=(SaveInstance&& other) noexcept;
|
||||
|
||||
void SetupAndMount(bool read_only = false, bool copy_icon = false, bool ignore_corrupt = false);
|
||||
|
||||
void Umount();
|
||||
|
||||
[[nodiscard]] std::filesystem::path GetIconPath() const noexcept {
|
||||
return save_path / "sce_sys" / "icon0.png";
|
||||
}
|
||||
|
||||
[[nodiscard]] bool Exists() const noexcept {
|
||||
return exists;
|
||||
}
|
||||
|
||||
[[nodiscard]] const std::string& GetDirName() const noexcept {
|
||||
return dir_name;
|
||||
}
|
||||
|
||||
[[nodiscard]] const std::filesystem::path& GetSavePath() const noexcept {
|
||||
return save_path;
|
||||
}
|
||||
|
||||
[[nodiscard]] const std::filesystem::file_time_type& GetLastWrite() const noexcept {
|
||||
return last_write;
|
||||
}
|
||||
|
||||
[[nodiscard]] const PSF& GetParamSFO() const noexcept {
|
||||
return param_sfo;
|
||||
}
|
||||
|
||||
[[nodiscard]] PSF& GetParamSFO() noexcept {
|
||||
return param_sfo;
|
||||
}
|
||||
|
||||
[[nodiscard]] const std::string& GetMountPoint() const noexcept {
|
||||
return mount_point;
|
||||
}
|
||||
|
||||
[[nodiscard]] int GetMaxBlocks() const noexcept {
|
||||
return max_blocks;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsReadOnly() const noexcept {
|
||||
return read_only;
|
||||
}
|
||||
|
||||
private:
|
||||
void CreateFiles();
|
||||
};
|
||||
|
||||
} // namespace Libraries::SaveData
|
File diff suppressed because it is too large
Load diff
|
@ -11,83 +11,26 @@ class SymbolsResolver;
|
|||
|
||||
namespace Libraries::SaveData {
|
||||
|
||||
constexpr int ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE =
|
||||
32; // Maximum size for a save data directory name
|
||||
constexpr int ORBIS_SAVE_DATA_MOUNT_POINT_DATA_MAXSIZE = 16; // Maximum size for a mount point name
|
||||
|
||||
struct OrbisSaveDataDirName {
|
||||
char data[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE];
|
||||
};
|
||||
|
||||
struct OrbisSaveDataMount2 {
|
||||
s32 user_id;
|
||||
s32 unk1;
|
||||
const OrbisSaveDataDirName* dir_name;
|
||||
u64 blocks;
|
||||
u32 mount_mode;
|
||||
u8 reserved[32];
|
||||
s32 unk2;
|
||||
};
|
||||
|
||||
struct OrbisSaveDataMountPoint {
|
||||
char data[ORBIS_SAVE_DATA_MOUNT_POINT_DATA_MAXSIZE];
|
||||
};
|
||||
|
||||
struct OrbisSaveDataMountResult {
|
||||
OrbisSaveDataMountPoint mount_point;
|
||||
u64 required_blocks;
|
||||
u32 unused;
|
||||
u32 mount_status;
|
||||
u8 reserved[28];
|
||||
s32 unk1;
|
||||
};
|
||||
|
||||
constexpr int ORBIS_SAVE_DATA_TITLE_ID_DATA_SIZE = 10;
|
||||
struct OrbisSaveDataTitleId {
|
||||
char data[ORBIS_SAVE_DATA_TITLE_ID_DATA_SIZE];
|
||||
char padding[6];
|
||||
};
|
||||
|
||||
constexpr int ORBIS_SAVE_DATA_FINGERPRINT_DATA_SIZE = 65;
|
||||
struct OrbisSaveDataFingerprint {
|
||||
char data[ORBIS_SAVE_DATA_FINGERPRINT_DATA_SIZE];
|
||||
char padding[15];
|
||||
};
|
||||
|
||||
struct OrbisSaveDataMount {
|
||||
s32 user_id;
|
||||
s32 pad;
|
||||
const OrbisSaveDataTitleId* titleId;
|
||||
const OrbisSaveDataDirName* dir_name;
|
||||
const OrbisSaveDataFingerprint* fingerprint;
|
||||
u64 blocks;
|
||||
u32 mount_mode;
|
||||
u8 reserved[32];
|
||||
};
|
||||
enum class Error : u32;
|
||||
enum class OrbisSaveDataParamType : u32;
|
||||
|
||||
typedef u32 OrbisSaveDataParamType;
|
||||
struct OrbisSaveDataDelete;
|
||||
struct OrbisSaveDataIcon;
|
||||
struct OrbisSaveDataMount2;
|
||||
struct OrbisSaveDataMount;
|
||||
struct OrbisSaveDataMountInfo;
|
||||
struct OrbisSaveDataMountPoint;
|
||||
struct OrbisSaveDataMountResult;
|
||||
struct OrbisSaveDataDirNameSearchCond;
|
||||
struct OrbisSaveDataDirNameSearchResult;
|
||||
|
||||
constexpr int ORBIS_SAVE_DATA_TITLE_MAXSIZE = 128;
|
||||
constexpr int ORBIS_SAVE_DATA_SUBTITLE_MAXSIZE = 128;
|
||||
constexpr int ORBIS_SAVE_DATA_DETAIL_MAXSIZE = 1024;
|
||||
struct OrbisSaveDataParam {
|
||||
char title[ORBIS_SAVE_DATA_TITLE_MAXSIZE];
|
||||
char subTitle[ORBIS_SAVE_DATA_SUBTITLE_MAXSIZE];
|
||||
char detail[ORBIS_SAVE_DATA_DETAIL_MAXSIZE];
|
||||
u32 userParam;
|
||||
int : 32;
|
||||
time_t mtime;
|
||||
u8 reserved[32];
|
||||
};
|
||||
|
||||
struct OrbisSaveDataIcon {
|
||||
void* buf;
|
||||
size_t bufSize;
|
||||
size_t dataSize;
|
||||
u8 reserved[32];
|
||||
};
|
||||
|
||||
typedef u32 OrbisSaveDataSaveDataMemoryOption;
|
||||
/*typedef u32 OrbisSaveDataSaveDataMemoryOption;
|
||||
#define ORBIS_SAVE_DATA_MEMORY_OPTION_NONE (0x00000000)
|
||||
#define ORBIS_SAVE_DATA_MEMORY_OPTION_SET_PARAM (0x00000001 << 0)
|
||||
#define ORBIS_SAVE_DATA_MEMORY_OPTION_DOUBLE_BUFFER (0x00000001 << 1)
|
||||
|
@ -162,74 +105,8 @@ struct OrbisSaveDataCheckBackupData {
|
|||
u8 reserved[32];
|
||||
};
|
||||
|
||||
struct OrbisSaveDataMountInfo {
|
||||
u64 blocks;
|
||||
u64 freeBlocks;
|
||||
u8 reserved[32];
|
||||
};
|
||||
|
||||
#define ORBIS_SAVE_DATA_BLOCK_SIZE (32768)
|
||||
#define ORBIS_SAVE_DATA_BLOCKS_MIN2 (96)
|
||||
#define ORBIS_SAVE_DATA_BLOCKS_MAX (32768)
|
||||
|
||||
// savedataMount2 mountModes (ORed values)
|
||||
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY = 1;
|
||||
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_RDWR = 2;
|
||||
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_CREATE = 4;
|
||||
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_DESTRUCT_OFF = 8;
|
||||
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON = 16;
|
||||
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 = 32;
|
||||
typedef struct _OrbisSaveDataEventParam OrbisSaveDataEventParam;
|
||||
|
||||
typedef u32 OrbisSaveDataSortKey;
|
||||
#define ORBIS_SAVE_DATA_SORT_KEY_DIRNAME (0)
|
||||
#define ORBIS_SAVE_DATA_SORT_KEY_USER_PARAM (1)
|
||||
#define ORBIS_SAVE_DATA_SORT_KEY_BLOCKS (2)
|
||||
#define ORBIS_SAVE_DATA_SORT_KEY_MTIME (3)
|
||||
#define ORBIS_SAVE_DATA_SORT_KEY_FREE_BLOCKS (5)
|
||||
|
||||
typedef u32 OrbisSaveDataSortOrder;
|
||||
#define ORBIS_SAVE_DATA_SORT_ORDER_ASCENT (0)
|
||||
#define ORBIS_SAVE_DATA_SORT_ORDER_DESCENT (1)
|
||||
|
||||
struct OrbisSaveDataDirNameSearchCond {
|
||||
s32 userId;
|
||||
int : 32;
|
||||
const OrbisSaveDataTitleId* titleId;
|
||||
const OrbisSaveDataDirName* dirName;
|
||||
OrbisSaveDataSortKey key;
|
||||
OrbisSaveDataSortOrder order;
|
||||
u8 reserved[32];
|
||||
};
|
||||
|
||||
struct OrbisSaveDataSearchInfo {
|
||||
u64 blocks;
|
||||
u64 freeBlocks;
|
||||
u8 reserved[32];
|
||||
};
|
||||
|
||||
struct OrbisSaveDataDirNameSearchResult {
|
||||
u32 hitNum;
|
||||
int : 32;
|
||||
OrbisSaveDataDirName* dirNames;
|
||||
u32 dirNamesNum;
|
||||
u32 setNum;
|
||||
OrbisSaveDataParam* params;
|
||||
OrbisSaveDataSearchInfo* infos;
|
||||
u8 reserved[12];
|
||||
int : 32;
|
||||
};
|
||||
|
||||
struct OrbisSaveDataDelete {
|
||||
s32 userId;
|
||||
int : 32;
|
||||
const OrbisSaveDataTitleId* titleId;
|
||||
const OrbisSaveDataDirName* dirName;
|
||||
u32 unused;
|
||||
u8 reserved[32];
|
||||
int : 32;
|
||||
};
|
||||
|
||||
typedef u32 OrbisSaveDataMemorySyncOption;
|
||||
|
||||
#define SCE_SAVE_DATA_MEMORY_SYNC_OPTION_NONE (0x00000000)
|
||||
|
@ -247,7 +124,7 @@ constexpr int ORBIS_SAVE_DATA_PARAM_TYPE_TITLE = 1;
|
|||
constexpr int ORBIS_SAVE_DATA_PARAM_TYPE_SUB_TITLE = 2;
|
||||
constexpr int ORBIS_SAVE_DATA_PARAM_TYPE_DETAIL = 3;
|
||||
constexpr int ORBIS_SAVE_DATA_PARAM_TYPE_USER_PARAM = 4;
|
||||
constexpr int ORBIS_SAVE_DATA_PARAM_TYPE_MTIME = 5;
|
||||
constexpr int ORBIS_SAVE_DATA_PARAM_TYPE_MTIME = 5;*/
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataAbort();
|
||||
int PS4_SYSV_ABI sceSaveDataBackup();
|
||||
|
@ -255,7 +132,7 @@ int PS4_SYSV_ABI sceSaveDataBindPsnAccount();
|
|||
int PS4_SYSV_ABI sceSaveDataBindPsnAccountForSystemBackup();
|
||||
int PS4_SYSV_ABI sceSaveDataChangeDatabase();
|
||||
int PS4_SYSV_ABI sceSaveDataChangeInternal();
|
||||
int PS4_SYSV_ABI sceSaveDataCheckBackupData(const OrbisSaveDataCheckBackupData* check);
|
||||
int PS4_SYSV_ABI sceSaveDataCheckBackupData(/*const OrbisSaveDataCheckBackupData* check*/);
|
||||
int PS4_SYSV_ABI sceSaveDataCheckBackupDataForCdlg();
|
||||
int PS4_SYSV_ABI sceSaveDataCheckBackupDataInternal();
|
||||
int PS4_SYSV_ABI sceSaveDataCheckCloudData();
|
||||
|
@ -273,13 +150,13 @@ int PS4_SYSV_ABI sceSaveDataDebugCreateSaveDataRoot();
|
|||
int PS4_SYSV_ABI sceSaveDataDebugGetThreadId();
|
||||
int PS4_SYSV_ABI sceSaveDataDebugRemoveSaveDataRoot();
|
||||
int PS4_SYSV_ABI sceSaveDataDebugTarget();
|
||||
int PS4_SYSV_ABI sceSaveDataDelete(const OrbisSaveDataDelete* del);
|
||||
Error PS4_SYSV_ABI sceSaveDataDelete(const OrbisSaveDataDelete* del);
|
||||
int PS4_SYSV_ABI sceSaveDataDelete5();
|
||||
int PS4_SYSV_ABI sceSaveDataDeleteAllUser();
|
||||
int PS4_SYSV_ABI sceSaveDataDeleteCloudData();
|
||||
int PS4_SYSV_ABI sceSaveDataDeleteUser();
|
||||
int PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond* cond,
|
||||
OrbisSaveDataDirNameSearchResult* result);
|
||||
Error PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond* cond,
|
||||
OrbisSaveDataDirNameSearchResult* result);
|
||||
int PS4_SYSV_ABI sceSaveDataDirNameSearchInternal();
|
||||
int PS4_SYSV_ABI sceSaveDataDownload();
|
||||
int PS4_SYSV_ABI sceSaveDataGetAllSize();
|
||||
|
@ -292,37 +169,37 @@ int PS4_SYSV_ABI sceSaveDataGetClientThreadPriority();
|
|||
int PS4_SYSV_ABI sceSaveDataGetCloudQuotaInfo();
|
||||
int PS4_SYSV_ABI sceSaveDataGetDataBaseFilePath();
|
||||
int PS4_SYSV_ABI sceSaveDataGetEventInfo();
|
||||
int PS4_SYSV_ABI sceSaveDataGetEventResult(const OrbisSaveDataEventParam* eventParam,
|
||||
OrbisSaveDataEvent* event);
|
||||
int PS4_SYSV_ABI sceSaveDataGetEventResult(/*const OrbisSaveDataEventParam* eventParam,
|
||||
OrbisSaveDataEvent* event*/);
|
||||
int PS4_SYSV_ABI sceSaveDataGetFormat();
|
||||
int PS4_SYSV_ABI sceSaveDataGetMountedSaveDataCount();
|
||||
int PS4_SYSV_ABI sceSaveDataGetMountInfo(const OrbisSaveDataMountPoint* mountPoint,
|
||||
OrbisSaveDataMountInfo* info);
|
||||
int PS4_SYSV_ABI sceSaveDataGetParam(const OrbisSaveDataMountPoint* mountPoint,
|
||||
const OrbisSaveDataParamType paramType, void* paramBuf,
|
||||
const size_t paramBufSize, size_t* gotSize);
|
||||
Error PS4_SYSV_ABI sceSaveDataGetMountInfo(const OrbisSaveDataMountPoint* mountPoint,
|
||||
OrbisSaveDataMountInfo* info);
|
||||
Error PS4_SYSV_ABI sceSaveDataGetParam(const OrbisSaveDataMountPoint* mountPoint,
|
||||
OrbisSaveDataParamType paramType, void* paramBuf,
|
||||
size_t paramBufSize, size_t* gotSize);
|
||||
int PS4_SYSV_ABI sceSaveDataGetProgress();
|
||||
int PS4_SYSV_ABI sceSaveDataGetSaveDataCount();
|
||||
int PS4_SYSV_ABI sceSaveDataGetSaveDataMemory(const u32 userId, void* buf, const size_t bufSize,
|
||||
const int64_t offset);
|
||||
int PS4_SYSV_ABI sceSaveDataGetSaveDataMemory2(OrbisSaveDataMemoryGet2* getParam);
|
||||
int PS4_SYSV_ABI sceSaveDataGetSaveDataMemory2(/*OrbisSaveDataMemoryGet2* getParam*/);
|
||||
int PS4_SYSV_ABI sceSaveDataGetSaveDataRootDir();
|
||||
int PS4_SYSV_ABI sceSaveDataGetSaveDataRootPath();
|
||||
int PS4_SYSV_ABI sceSaveDataGetSaveDataRootUsbPath();
|
||||
int PS4_SYSV_ABI sceSaveDataGetSavePoint();
|
||||
int PS4_SYSV_ABI sceSaveDataGetUpdatedDataCount();
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize();
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize2();
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize3();
|
||||
Error PS4_SYSV_ABI sceSaveDataInitialize(void*);
|
||||
Error PS4_SYSV_ABI sceSaveDataInitialize2(void*);
|
||||
Error PS4_SYSV_ABI sceSaveDataInitialize3(void*);
|
||||
int PS4_SYSV_ABI sceSaveDataInitializeForCdlg();
|
||||
int PS4_SYSV_ABI sceSaveDataIsDeletingUsbDb();
|
||||
int PS4_SYSV_ABI sceSaveDataIsMounted();
|
||||
int PS4_SYSV_ABI sceSaveDataLoadIcon(const OrbisSaveDataMountPoint* mountPoint,
|
||||
OrbisSaveDataIcon* icon);
|
||||
int PS4_SYSV_ABI sceSaveDataMount(const OrbisSaveDataMount* mount,
|
||||
OrbisSaveDataMountResult* mount_result);
|
||||
s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
|
||||
OrbisSaveDataMountResult* mount_result);
|
||||
Error PS4_SYSV_ABI sceSaveDataLoadIcon(const OrbisSaveDataMountPoint* mountPoint,
|
||||
OrbisSaveDataIcon* icon);
|
||||
Error PS4_SYSV_ABI sceSaveDataMount(const OrbisSaveDataMount* mount,
|
||||
OrbisSaveDataMountResult* mount_result);
|
||||
Error PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
|
||||
OrbisSaveDataMountResult* mount_result);
|
||||
int PS4_SYSV_ABI sceSaveDataMount5();
|
||||
int PS4_SYSV_ABI sceSaveDataMountInternal();
|
||||
int PS4_SYSV_ABI sceSaveDataMountSys();
|
||||
|
@ -332,28 +209,28 @@ int PS4_SYSV_ABI sceSaveDataRegisterEventCallback();
|
|||
int PS4_SYSV_ABI sceSaveDataRestoreBackupData();
|
||||
int PS4_SYSV_ABI sceSaveDataRestoreBackupDataForCdlg();
|
||||
int PS4_SYSV_ABI sceSaveDataRestoreLoadSaveDataMemory();
|
||||
int PS4_SYSV_ABI sceSaveDataSaveIcon(const OrbisSaveDataMountPoint* mountPoint,
|
||||
const OrbisSaveDataIcon* icon);
|
||||
Error PS4_SYSV_ABI sceSaveDataSaveIcon(const OrbisSaveDataMountPoint* mountPoint,
|
||||
const OrbisSaveDataIcon* icon);
|
||||
int PS4_SYSV_ABI sceSaveDataSetAutoUploadSetting();
|
||||
int PS4_SYSV_ABI sceSaveDataSetEventInfo();
|
||||
int PS4_SYSV_ABI sceSaveDataSetParam(const OrbisSaveDataMountPoint* mountPoint,
|
||||
OrbisSaveDataParamType paramType, const void* paramBuf,
|
||||
size_t paramBufSize);
|
||||
Error PS4_SYSV_ABI sceSaveDataSetParam(const OrbisSaveDataMountPoint* mountPoint,
|
||||
OrbisSaveDataParamType paramType, const void* paramBuf,
|
||||
size_t paramBufSize);
|
||||
int PS4_SYSV_ABI sceSaveDataSetSaveDataLibraryUser();
|
||||
int PS4_SYSV_ABI sceSaveDataSetSaveDataMemory(const u32 userId, const void* buf,
|
||||
const size_t bufSize, const int64_t offset);
|
||||
int PS4_SYSV_ABI sceSaveDataSetSaveDataMemory2(const OrbisSaveDataMemorySet2* setParam);
|
||||
int PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory(u32 userId, size_t memorySize,
|
||||
OrbisSaveDataParam* param);
|
||||
int PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory2(const OrbisSaveDataMemorySetup2* setupParam,
|
||||
OrbisSaveDataMemorySetupResult* result);
|
||||
int PS4_SYSV_ABI sceSaveDataSetSaveDataMemory2(/*const OrbisSaveDataMemorySet2* setParam*/);
|
||||
int PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory(/*u32 userId, size_t memorySize,
|
||||
OrbisSaveDataParam* param*/);
|
||||
int PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory2(/*const OrbisSaveDataMemorySetup2* setupParam,
|
||||
OrbisSaveDataMemorySetupResult* result*/);
|
||||
int PS4_SYSV_ABI sceSaveDataShutdownStart();
|
||||
int PS4_SYSV_ABI sceSaveDataSupportedFakeBrokenStatus();
|
||||
int PS4_SYSV_ABI sceSaveDataSyncCloudList();
|
||||
int PS4_SYSV_ABI sceSaveDataSyncSaveDataMemory(OrbisSaveDataMemorySync* syncParam);
|
||||
int PS4_SYSV_ABI sceSaveDataTerminate();
|
||||
int PS4_SYSV_ABI sceSaveDataSyncSaveDataMemory(/*OrbisSaveDataMemorySync* syncParam*/);
|
||||
Error PS4_SYSV_ABI sceSaveDataTerminate();
|
||||
int PS4_SYSV_ABI sceSaveDataTransferringMount();
|
||||
int PS4_SYSV_ABI sceSaveDataUmount(const OrbisSaveDataMountPoint* mountPoint);
|
||||
Error PS4_SYSV_ABI sceSaveDataUmount(const OrbisSaveDataMountPoint* mountPoint);
|
||||
int PS4_SYSV_ABI sceSaveDataUmountSys();
|
||||
int PS4_SYSV_ABI sceSaveDataUmountWithBackup(const OrbisSaveDataMountPoint* mountPoint);
|
||||
int PS4_SYSV_ABI sceSaveDataUnregisterEventCallback();
|
||||
|
|
Loading…
Add table
Reference in a new issue