Fix reading not existing savedata

This commit is contained in:
mailwl 2025-05-16 10:18:42 +03:00
parent aeb4536988
commit d5a4413d60
5 changed files with 48 additions and 35 deletions

View File

@ -409,6 +409,7 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
src/core/libraries/save_data/save_memory.h src/core/libraries/save_data/save_memory.h
src/core/libraries/save_data/savedata.cpp src/core/libraries/save_data/savedata.cpp
src/core/libraries/save_data/savedata.h src/core/libraries/save_data/savedata.h
src/core/libraries/save_data/savedata_error.h
src/core/libraries/save_data/dialog/savedatadialog.cpp src/core/libraries/save_data/dialog/savedatadialog.cpp
src/core/libraries/save_data/dialog/savedatadialog.h src/core/libraries/save_data/dialog/savedatadialog.h
src/core/libraries/save_data/dialog/savedatadialog_ui.cpp src/core/libraries/save_data/dialog/savedatadialog_ui.cpp

View File

@ -10,15 +10,14 @@
#include <utility> #include <utility>
#include <fmt/format.h> #include <fmt/format.h>
#include <core/libraries/system/msgdialog_ui.h>
#include "common/assert.h"
#include "common/elf_info.h" #include "common/elf_info.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/path_util.h" #include "common/path_util.h"
#include "common/singleton.h" #include "common/singleton.h"
#include "common/thread.h" #include "common/thread.h"
#include "core/file_sys/fs.h" #include "core/file_sys/fs.h"
#include "core/libraries/save_data/savedata_error.h"
#include "core/libraries/system/msgdialog_ui.h"
#include "save_instance.h" #include "save_instance.h"
using Common::FS::IOFile; using Common::FS::IOFile;
@ -35,7 +34,7 @@ namespace Libraries::SaveData::SaveMemory {
static Core::FileSys::MntPoints* g_mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance(); static Core::FileSys::MntPoints* g_mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
struct SlotData { struct SlotData {
OrbisUserServiceUserId user_id; OrbisUserServiceUserId user_id{};
std::string game_serial; std::string game_serial;
std::filesystem::path folder_path; std::filesystem::path folder_path;
PSF sfo; PSF sfo;
@ -191,23 +190,25 @@ void SaveSFO(u32 slot_id) {
} }
} }
void ReadMemory(u32 slot_id, void* buf, size_t buf_size, int64_t offset) { Error ReadMemory(u32 slot_id, void* buf, size_t buf_size, int64_t offset) {
std::lock_guard lk{g_slot_mtx}; std::lock_guard lk{g_slot_mtx};
auto& data = g_attached_slots[slot_id]; auto& data = g_attached_slots[slot_id];
auto& memory = data.memory_cache; auto& memory = data.memory_cache;
if (memory.empty()) { // Load file if (memory.empty()) { // Load file
IOFile f{data.folder_path / FilenameSaveDataMemory, Common::FS::FileAccessMode::Read}; IOFile f{data.folder_path / FilenameSaveDataMemory, Common::FS::FileAccessMode::Read};
if (f.IsOpen()) { if (!f.IsOpen()) {
memory.resize(f.GetSize()); return Error::NOT_FOUND;
f.Seek(0);
f.ReadSpan(std::span{memory});
} }
memory.resize(f.GetSize());
f.Seek(0);
f.ReadSpan(std::span{memory});
} }
s64 read_size = buf_size; s64 read_size = buf_size;
if (read_size + offset > memory.size()) { if (read_size + offset > memory.size()) {
read_size = memory.size() - offset; read_size = memory.size() - offset;
} }
std::memcpy(buf, memory.data() + offset, read_size); std::memcpy(buf, memory.data() + offset, read_size);
return Error::OK;
} }
void WriteMemory(u32 slot_id, void* buf, size_t buf_size, int64_t offset) { void WriteMemory(u32 slot_id, void* buf, size_t buf_size, int64_t offset) {

View File

@ -4,13 +4,14 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include "save_backup.h" #include "core/libraries/save_data/save_backup.h"
class PSF; class PSF;
namespace Libraries::SaveData { namespace Libraries::SaveData {
using OrbisUserServiceUserId = s32; using OrbisUserServiceUserId = s32;
} enum class Error : u32;
} // namespace Libraries::SaveData
namespace Libraries::SaveData::SaveMemory { namespace Libraries::SaveData::SaveMemory {
@ -36,7 +37,7 @@ void SetIcon(u32 slot_id, void* buf = nullptr, size_t buf_size = 0);
// Save now or wait for the background thread to save // Save now or wait for the background thread to save
void SaveSFO(u32 slot_id); void SaveSFO(u32 slot_id);
void ReadMemory(u32 slot_id, void* buf, size_t buf_size, int64_t offset); Error ReadMemory(u32 slot_id, void* buf, size_t buf_size, int64_t offset);
void WriteMemory(u32 slot_id, void* buf, size_t buf_size, int64_t offset); void WriteMemory(u32 slot_id, void* buf, size_t buf_size, int64_t offset);

View File

@ -5,7 +5,6 @@
#include <thread> #include <thread>
#include <vector> #include <vector>
#include <core/libraries/system/msgdialog_ui.h>
#include <magic_enum/magic_enum.hpp> #include <magic_enum/magic_enum.hpp>
#include "common/assert.h" #include "common/assert.h"
@ -20,7 +19,9 @@
#include "core/libraries/error_codes.h" #include "core/libraries/error_codes.h"
#include "core/libraries/libs.h" #include "core/libraries/libs.h"
#include "core/libraries/save_data/savedata.h" #include "core/libraries/save_data/savedata.h"
#include "core/libraries/save_data/savedata_error.h"
#include "core/libraries/system/msgdialog.h" #include "core/libraries/system/msgdialog.h"
#include "core/libraries/system/msgdialog_ui.h"
#include "save_backup.h" #include "save_backup.h"
#include "save_instance.h" #include "save_instance.h"
#include "save_memory.h" #include "save_memory.h"
@ -33,27 +34,6 @@ using Common::ElfInfo;
namespace Libraries::SaveData { namespace Libraries::SaveData {
enum class Error : u32 {
OK = 0,
USER_SERVICE_NOT_INITIALIZED = 0x80960002,
PARAMETER = 0x809F0000,
NOT_INITIALIZED = 0x809F0001,
OUT_OF_MEMORY = 0x809F0002,
BUSY = 0x809F0003,
NOT_MOUNTED = 0x809F0004,
EXISTS = 0x809F0007,
NOT_FOUND = 0x809F0008,
NO_SPACE_FS = 0x809F000A,
INTERNAL = 0x809F000B,
MOUNT_FULL = 0x809F000C,
BAD_MOUNTED = 0x809F000D,
BROKEN = 0x809F000F,
INVALID_LOGIN_USER = 0x809F0011,
MEMORY_NOT_READY = 0x809F0012,
BACKUP_BUSY = 0x809F0013,
BUSY_FOR_SAVING = 0x809F0016,
};
enum class OrbisSaveDataSaveDataMemoryOption : u32 { enum class OrbisSaveDataSaveDataMemoryOption : u32 {
NONE = 0, NONE = 0,
SET_PARAM = 1 << 0, SET_PARAM = 1 << 0,
@ -1159,7 +1139,10 @@ Error PS4_SYSV_ABI sceSaveDataGetSaveDataMemory2(OrbisSaveDataMemoryGet2* getPar
LOG_DEBUG(Lib_SaveData, "called"); LOG_DEBUG(Lib_SaveData, "called");
auto data = getParam->data; auto data = getParam->data;
if (data != nullptr) { if (data != nullptr) {
SaveMemory::ReadMemory(slot_id, data->buf, data->bufSize, data->offset); auto result = SaveMemory::ReadMemory(slot_id, data->buf, data->bufSize, data->offset);
if (Error::OK != result) {
return result;
}
} }
auto param = getParam->param; auto param = getParam->param;
if (param != nullptr) { if (param != nullptr) {

View File

@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
namespace Libraries::SaveData {
enum class Error : u32 {
OK = 0,
USER_SERVICE_NOT_INITIALIZED = 0x80960002,
PARAMETER = 0x809F0000,
NOT_INITIALIZED = 0x809F0001,
OUT_OF_MEMORY = 0x809F0002,
BUSY = 0x809F0003,
NOT_MOUNTED = 0x809F0004,
EXISTS = 0x809F0007,
NOT_FOUND = 0x809F0008,
NO_SPACE_FS = 0x809F000A,
INTERNAL = 0x809F000B,
MOUNT_FULL = 0x809F000C,
BAD_MOUNTED = 0x809F000D,
BROKEN = 0x809F000F,
INVALID_LOGIN_USER = 0x809F0011,
MEMORY_NOT_READY = 0x809F0012,
BACKUP_BUSY = 0x809F0013,
BUSY_FOR_SAVING = 0x809F0016,
};
} // namespace Libraries::SaveData