From 2934f6c4b2af079d0b326bf916155aeac332ac6b Mon Sep 17 00:00:00 2001 From: Vinicius Rangel Date: Wed, 2 Oct 2024 00:38:18 -0300 Subject: [PATCH] SaveData: implement sceSaveDataTransferringMount (#1191) * SaveData: fix icon overriding * SaveData: implement sceSaveDataTransferringMount --- .../libraries/save_data/save_instance.cpp | 6 ++- src/core/libraries/save_data/save_memory.cpp | 2 +- src/core/libraries/save_data/savedata.cpp | 39 +++++++++++++++---- src/core/libraries/save_data/savedata.h | 4 +- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/core/libraries/save_data/save_instance.cpp b/src/core/libraries/save_data/save_instance.cpp index 2624ca36..1127a545 100644 --- a/src/core/libraries/save_data/save_instance.cpp +++ b/src/core/libraries/save_data/save_instance.cpp @@ -157,7 +157,11 @@ void SaveInstance::SetupAndMount(bool read_only, bool copy_icon, bool ignore_cor 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()); + auto output_icon = GetIconPath(); + if (fs::exists(output_icon)) { + fs::remove(output_icon); + } + fs::copy_file(src_icon, output_icon); } } exists = true; diff --git a/src/core/libraries/save_data/save_memory.cpp b/src/core/libraries/save_data/save_memory.cpp index c4d10561..e9ef5376 100644 --- a/src/core/libraries/save_data/save_memory.cpp +++ b/src/core/libraries/save_data/save_memory.cpp @@ -207,7 +207,7 @@ void SetIcon(void* buf, size_t buf_size) { } else { g_icon_memory.resize(buf_size); std::memcpy(g_icon_memory.data(), buf, buf_size); - IOFile file(g_icon_path, Common::FS::FileAccessMode::Append); + IOFile file(g_icon_path, Common::FS::FileAccessMode::Write); file.Seek(0); file.WriteRaw(g_icon_memory.data(), buf_size); file.Close(); diff --git a/src/core/libraries/save_data/savedata.cpp b/src/core/libraries/save_data/savedata.cpp index da885d97..a2af2f15 100644 --- a/src/core/libraries/save_data/savedata.cpp +++ b/src/core/libraries/save_data/savedata.cpp @@ -262,6 +262,14 @@ struct OrbisSaveDataRestoreBackupData { s32 : 32; }; +struct OrbisSaveDataTransferringMount { + OrbisUserServiceUserId userId; + const OrbisSaveDataTitleId* titleId; + const OrbisSaveDataDirName* dirName; + const OrbisSaveDataFingerprint* fingerprint; + std::array _reserved; +}; + struct OrbisSaveDataDirNameSearchCond { OrbisUserServiceUserId userId; int : 32; @@ -357,7 +365,8 @@ static Error setNotInitializedError() { } static Error saveDataMount(const OrbisSaveDataMount2* mount_info, - OrbisSaveDataMountResult* mount_result) { + OrbisSaveDataMountResult* mount_result, + std::string_view title_id = g_game_serial) { if (mount_info->userId < 0) { return Error::INVALID_LOGIN_USER; @@ -369,8 +378,8 @@ static Error saveDataMount(const OrbisSaveDataMount2* mount_info, // check backup status { - const auto save_path = SaveInstance::MakeDirSavePath(mount_info->userId, g_game_serial, - mount_info->dirName->data); + const auto save_path = + SaveInstance::MakeDirSavePath(mount_info->userId, title_id, mount_info->dirName->data); if (Backup::IsBackupExecutingFor(save_path) && g_fw_ver) { return Error::BACKUP_BUSY; } @@ -409,7 +418,7 @@ static Error saveDataMount(const OrbisSaveDataMount2* mount_info, return Error::MOUNT_FULL; } - SaveInstance save_instance{slot_num, mount_info->userId, g_game_serial, dir_name, + SaveInstance save_instance{slot_num, mount_info->userId, std::string{title_id}, dir_name, (int)mount_info->blocks}; if (save_instance.Mounted()) { @@ -1573,6 +1582,7 @@ Error PS4_SYSV_ABI sceSaveDataSetupSaveDataMemory2(const OrbisSaveDataMemorySetu SaveMemory::SetIcon(nullptr, 0); } } + SaveMemory::TriggerSaveWithoutEvent(); if (g_fw_ver >= ElfInfo::FW_45 && result != nullptr) { result->existedMemorySize = existed_size; } @@ -1646,9 +1656,24 @@ Error PS4_SYSV_ABI sceSaveDataTerminate() { return Error::OK; } -int PS4_SYSV_ABI sceSaveDataTransferringMount() { - LOG_ERROR(Lib_SaveData, "(STUBBED) called"); - return ORBIS_OK; +Error PS4_SYSV_ABI sceSaveDataTransferringMount(const OrbisSaveDataTransferringMount* mount, + OrbisSaveDataMountResult* mountResult) { + LOG_DEBUG(Lib_SaveData, "called"); + if (!g_initialized) { + LOG_INFO(Lib_SaveData, "called without initialize"); + return setNotInitializedError(); + } + if (mount == nullptr || mount->titleId == nullptr || mount->dirName == nullptr) { + LOG_INFO(Lib_SaveData, "called with invalid parameter"); + return Error::PARAMETER; + } + LOG_DEBUG(Lib_SaveData, "called titleId: {}, dirName: {}", mount->titleId->data.to_view(), + mount->dirName->data.to_view()); + OrbisSaveDataMount2 mount_info{}; + mount_info.userId = mount->userId; + mount_info.dirName = mount->dirName; + mount_info.mountMode = OrbisSaveDataMountMode::RDONLY; + return saveDataMount(&mount_info, mountResult, mount->titleId->data.to_string()); } Error PS4_SYSV_ABI sceSaveDataUmount(const OrbisSaveDataMountPoint* mountPoint) { diff --git a/src/core/libraries/save_data/savedata.h b/src/core/libraries/save_data/savedata.h index 13b3dd59..5faf3f2d 100644 --- a/src/core/libraries/save_data/savedata.h +++ b/src/core/libraries/save_data/savedata.h @@ -70,6 +70,7 @@ struct OrbisSaveDataMountInfo; struct OrbisSaveDataMountPoint; struct OrbisSaveDataMountResult; struct OrbisSaveDataRestoreBackupData; +struct OrbisSaveDataTransferringMount; int PS4_SYSV_ABI sceSaveDataAbort(); Error PS4_SYSV_ABI sceSaveDataBackup(const OrbisSaveDataBackup* backup); @@ -174,7 +175,8 @@ int PS4_SYSV_ABI sceSaveDataSupportedFakeBrokenStatus(); int PS4_SYSV_ABI sceSaveDataSyncCloudList(); Error PS4_SYSV_ABI sceSaveDataSyncSaveDataMemory(OrbisSaveDataMemorySync* syncParam); Error PS4_SYSV_ABI sceSaveDataTerminate(); -int PS4_SYSV_ABI sceSaveDataTransferringMount(); +Error PS4_SYSV_ABI sceSaveDataTransferringMount(const OrbisSaveDataTransferringMount* mount, + OrbisSaveDataMountResult* mountResult); Error PS4_SYSV_ABI sceSaveDataUmount(const OrbisSaveDataMountPoint* mountPoint); int PS4_SYSV_ABI sceSaveDataUmountSys(); Error PS4_SYSV_ABI sceSaveDataUmountWithBackup(const OrbisSaveDataMountPoint* mountPoint);