From 69bfe075b5c3f6b17ce269950d1f8c9aab18e2de Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 17 Jul 2018 15:42:15 -0400 Subject: General Filesystem and Save Data Fixes (#670) --- src/core/file_sys/savedata_factory.cpp | 95 ++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 22 deletions(-) (limited to 'src/core/file_sys/savedata_factory.cpp') diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index f3aa213af..3ad37b28c 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -12,11 +12,49 @@ namespace FileSys { -SaveData_Factory::SaveData_Factory(std::string nand_directory) +std::string SaveDataDescriptor::DebugInfo() { + return fmt::format("[type={:02X}, title_id={:016X}, user_id={:016X}{:016X}, save_id={:016X}]", + static_cast(type), title_id, user_id[1], user_id[0], save_id); +} + +SaveDataFactory::SaveDataFactory(std::string nand_directory) : nand_directory(std::move(nand_directory)) {} -ResultVal> SaveData_Factory::Open(const Path& path) { - std::string save_directory = GetFullPath(); +ResultVal> SaveDataFactory::Open(SaveDataSpaceId space, + SaveDataDescriptor meta) { + if (meta.type == SaveDataType::SystemSaveData || meta.type == SaveDataType::SaveData) { + if (meta.zero_1 != 0) { + LOG_WARNING(Service_FS, + "Possibly incorrect SaveDataDescriptor, type is " + "SystemSaveData||SaveData but offset 0x28 is non-zero ({:016X}).", + meta.zero_1); + } + if (meta.zero_2 != 0) { + LOG_WARNING(Service_FS, + "Possibly incorrect SaveDataDescriptor, type is " + "SystemSaveData||SaveData but offset 0x30 is non-zero ({:016X}).", + meta.zero_2); + } + if (meta.zero_3 != 0) { + LOG_WARNING(Service_FS, + "Possibly incorrect SaveDataDescriptor, type is " + "SystemSaveData||SaveData but offset 0x38 is non-zero ({:016X}).", + meta.zero_3); + } + } + + if (meta.type == SaveDataType::SystemSaveData && meta.title_id != 0) { + LOG_WARNING(Service_FS, + "Possibly incorrect SaveDataDescriptor, type is SystemSaveData but title_id is " + "non-zero ({:016X}).", + meta.title_id); + } + + std::string save_directory = + GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id); + + // TODO(DarkLordZach): Try to not create when opening, there are dedicated create save methods. + // But, user_ids don't match so this works for now. if (!FileUtil::Exists(save_directory)) { // TODO(bunnei): This is a work-around to always create a save data directory if it does not @@ -26,6 +64,12 @@ ResultVal> SaveData_Factory::Open(const Path& FileUtil::CreateFullPath(save_directory); } + // TODO(DarkLordZach): For some reason, CreateFullPath doesn't create the last bit. Should be + // fixed with VFS. + if (!FileUtil::IsDirectory(save_directory)) { + FileUtil::CreateDir(save_directory); + } + // Return an error if the save data doesn't actually exist. if (!FileUtil::IsDirectory(save_directory)) { // TODO(Subv): Find out correct error code. @@ -36,28 +80,35 @@ ResultVal> SaveData_Factory::Open(const Path& return MakeResult>(std::move(archive)); } -ResultCode SaveData_Factory::Format(const Path& path) { - LOG_WARNING(Service_FS, "Format archive {}", GetName()); - // Create the save data directory. - if (!FileUtil::CreateFullPath(GetFullPath())) { - // TODO(Subv): Find the correct error code. - return ResultCode(-1); - } +std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, + u128 user_id, u64 save_id) const { + // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should + // be interpreted as the title id of the current process. + if (type == SaveDataType::SaveData && title_id == 0) + title_id = Core::CurrentProcess()->program_id; - return RESULT_SUCCESS; -} + std::string prefix; -ResultVal SaveData_Factory::GetFormatInfo(const Path& path) const { - LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName()); - // TODO(bunnei): Find the right error code for this - return ResultCode(-1); -} + switch (space) { + case SaveDataSpaceId::NandSystem: + prefix = nand_directory + "system/save/"; + break; + case SaveDataSpaceId::NandUser: + prefix = nand_directory + "user/save/"; + break; + default: + ASSERT_MSG(false, "Unrecognized SaveDataSpaceId: {:02X}", static_cast(space)); + } -std::string SaveData_Factory::GetFullPath() const { - u64 title_id = Core::CurrentProcess()->program_id; - // TODO(Subv): Somehow obtain this value. - u32 user = 0; - return fmt::format("{}save/{:016X}/{:08X}/", nand_directory, title_id, user); + switch (type) { + case SaveDataType::SystemSaveData: + return fmt::format("{}{:016X}/{:016X}{:016X}", prefix, save_id, user_id[1], user_id[0]); + case SaveDataType::SaveData: + return fmt::format("{}{:016X}/{:016X}{:016X}/{:016X}", prefix, 0, user_id[1], user_id[0], + title_id); + default: + ASSERT_MSG(false, "Unrecognized SaveDataType: {:02X}", static_cast(type)); + } } } // namespace FileSys -- cgit v1.2.3