citra-emu
/
citra-canary
Archived
1
0
Fork 0

HLE/FS: Always use 0x48000 as the high dword when opening the SharedExtData archive

The FS module overrides whatever value was in the saveid high dword with 0x48000 when trying to open the archive.

This fixes the problem where the Home Menu would create a few SharedExtData archives with 0x48000 as the saveid high, but then try to open them with 0 as the high value and fail.
This commit is contained in:
Subv 2017-12-09 00:16:51 -05:00
parent 040006fa6b
commit 37cb18358b
2 changed files with 36 additions and 4 deletions

View File

@ -131,6 +131,14 @@ public:
} }
}; };
struct ExtSaveDataArchivePath {
u32_le media_type;
u32_le save_low;
u32_le save_high;
};
static_assert(sizeof(ExtSaveDataArchivePath) == 12, "Incorrect path size");
std::string GetExtSaveDataPath(const std::string& mount_point, const Path& path) { std::string GetExtSaveDataPath(const std::string& mount_point, const Path& path) {
std::vector<u8> vec_data = path.AsBinary(); std::vector<u8> vec_data = path.AsBinary();
const u32* data = reinterpret_cast<const u32*>(vec_data.data()); const u32* data = reinterpret_cast<const u32*>(vec_data.data());
@ -183,8 +191,27 @@ bool ArchiveFactory_ExtSaveData::Initialize() {
return true; return true;
} }
Path ArchiveFactory_ExtSaveData::GetCorrectedPath(const Path& path) {
if (!shared)
return path;
static constexpr u32 SharedExtDataHigh = 0x48000;
ExtSaveDataArchivePath new_path;
std::memcpy(&new_path, path.AsBinary().data(), sizeof(new_path));
// The FS module overwrites the high value of the saveid when dealing with the SharedExtSaveData
// archive.
new_path.save_high = SharedExtDataHigh;
std::vector<u8> binary_data(sizeof(new_path));
std::memcpy(binary_data.data(), &new_path, binary_data.size());
return {binary_data};
}
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(const Path& path) { ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(const Path& path) {
std::string fullpath = GetExtSaveDataPath(mount_point, path) + "user/"; std::string fullpath = GetExtSaveDataPath(mount_point, GetCorrectedPath(path)) + "user/";
if (!FileUtil::Exists(fullpath)) { if (!FileUtil::Exists(fullpath)) {
// TODO(Subv): Verify the archive behavior of SharedExtSaveData compared to ExtSaveData. // TODO(Subv): Verify the archive behavior of SharedExtSaveData compared to ExtSaveData.
// ExtSaveData seems to return FS_NotFound (120) when the archive doesn't exist. // ExtSaveData seems to return FS_NotFound (120) when the archive doesn't exist.
@ -200,14 +227,16 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(cons
ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path, ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path,
const FileSys::ArchiveFormatInfo& format_info) { const FileSys::ArchiveFormatInfo& format_info) {
auto corrected_path = GetCorrectedPath(path);
// These folders are always created with the ExtSaveData // These folders are always created with the ExtSaveData
std::string user_path = GetExtSaveDataPath(mount_point, path) + "user/"; std::string user_path = GetExtSaveDataPath(mount_point, corrected_path) + "user/";
std::string boss_path = GetExtSaveDataPath(mount_point, path) + "boss/"; std::string boss_path = GetExtSaveDataPath(mount_point, corrected_path) + "boss/";
FileUtil::CreateFullPath(user_path); FileUtil::CreateFullPath(user_path);
FileUtil::CreateFullPath(boss_path); FileUtil::CreateFullPath(boss_path);
// Write the format metadata // Write the format metadata
std::string metadata_path = GetExtSaveDataPath(mount_point, path) + "metadata"; std::string metadata_path = GetExtSaveDataPath(mount_point, corrected_path) + "metadata";
FileUtil::IOFile file(metadata_path, "wb"); FileUtil::IOFile file(metadata_path, "wb");
if (!file.IsOpen()) { if (!file.IsOpen()) {

View File

@ -56,6 +56,9 @@ private:
* See GetExtSaveDataPath for the code that extracts this data from an archive path. * See GetExtSaveDataPath for the code that extracts this data from an archive path.
*/ */
std::string mount_point; std::string mount_point;
/// Returns a path with the correct SaveIdHigh value for Shared extdata paths.
Path GetCorrectedPath(const Path& path);
}; };
/** /**