diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/core/file_sys/fs_save_data_types.h | 174 | ||||
| -rw-r--r-- | src/core/file_sys/savedata_factory.cpp | 90 | ||||
| -rw-r--r-- | src/core/file_sys/savedata_factory.h | 68 | ||||
| -rw-r--r-- | src/core/hle/service/am/service/application_functions.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fsp_srv.cpp | 34 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fsp_srv.h | 7 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 10 |
9 files changed, 231 insertions, 168 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e9a98b5d7..66e65476e 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -58,6 +58,7 @@ add_library(core STATIC | |||
| 58 | file_sys/fs_operate_range.h | 58 | file_sys/fs_operate_range.h |
| 59 | file_sys/fs_path.h | 59 | file_sys/fs_path.h |
| 60 | file_sys/fs_path_utility.h | 60 | file_sys/fs_path_utility.h |
| 61 | file_sys/fs_save_data_types.h | ||
| 61 | file_sys/fs_string_util.h | 62 | file_sys/fs_string_util.h |
| 62 | file_sys/fsmitm_romfsbuild.cpp | 63 | file_sys/fsmitm_romfsbuild.cpp |
| 63 | file_sys/fsmitm_romfsbuild.h | 64 | file_sys/fsmitm_romfsbuild.h |
diff --git a/src/core/file_sys/fs_save_data_types.h b/src/core/file_sys/fs_save_data_types.h new file mode 100644 index 000000000..02bbc3294 --- /dev/null +++ b/src/core/file_sys/fs_save_data_types.h | |||
| @@ -0,0 +1,174 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <array> | ||
| 7 | #include "common/common_funcs.h" | ||
| 8 | #include "common/common_types.h" | ||
| 9 | |||
| 10 | namespace FileSys { | ||
| 11 | |||
| 12 | using SaveDataId = u64; | ||
| 13 | using SystemSaveDataId = u64; | ||
| 14 | using SystemBcatSaveDataId = SystemSaveDataId; | ||
| 15 | using ProgramId = u64; | ||
| 16 | |||
| 17 | enum class SaveDataSpaceId : u8 { | ||
| 18 | System = 0, | ||
| 19 | User = 1, | ||
| 20 | SdSystem = 2, | ||
| 21 | Temporary = 3, | ||
| 22 | SdUser = 4, | ||
| 23 | |||
| 24 | ProperSystem = 100, | ||
| 25 | SafeMode = 101, | ||
| 26 | }; | ||
| 27 | |||
| 28 | enum class SaveDataType : u8 { | ||
| 29 | System = 0, | ||
| 30 | Account = 1, | ||
| 31 | Bcat = 2, | ||
| 32 | Device = 3, | ||
| 33 | Temporary = 4, | ||
| 34 | Cache = 5, | ||
| 35 | SystemBcat = 6, | ||
| 36 | }; | ||
| 37 | |||
| 38 | enum class SaveDataRank : u8 { | ||
| 39 | Primary = 0, | ||
| 40 | Secondary = 1, | ||
| 41 | }; | ||
| 42 | |||
| 43 | struct SaveDataSize { | ||
| 44 | u64 normal; | ||
| 45 | u64 journal; | ||
| 46 | }; | ||
| 47 | static_assert(sizeof(SaveDataSize) == 0x10, "SaveDataSize has invalid size."); | ||
| 48 | |||
| 49 | using UserId = u128; | ||
| 50 | static_assert(std::is_trivially_copyable_v<UserId>, "Data type must be trivially copyable."); | ||
| 51 | static_assert(sizeof(UserId) == 0x10, "UserId has invalid size."); | ||
| 52 | |||
| 53 | constexpr inline SystemSaveDataId InvalidSystemSaveDataId = 0; | ||
| 54 | constexpr inline UserId InvalidUserId = {}; | ||
| 55 | |||
| 56 | enum class SaveDataFlags : u32 { | ||
| 57 | None = (0 << 0), | ||
| 58 | KeepAfterResettingSystemSaveData = (1 << 0), | ||
| 59 | KeepAfterRefurbishment = (1 << 1), | ||
| 60 | KeepAfterResettingSystemSaveDataWithoutUserSaveData = (1 << 2), | ||
| 61 | NeedsSecureDelete = (1 << 3), | ||
| 62 | }; | ||
| 63 | |||
| 64 | enum class SaveDataMetaType : u8 { | ||
| 65 | None = 0, | ||
| 66 | Thumbnail = 1, | ||
| 67 | ExtensionContext = 2, | ||
| 68 | }; | ||
| 69 | |||
| 70 | struct SaveDataMetaInfo { | ||
| 71 | u32 size; | ||
| 72 | SaveDataMetaType type; | ||
| 73 | INSERT_PADDING_BYTES(0xB); | ||
| 74 | }; | ||
| 75 | static_assert(std::is_trivially_copyable_v<SaveDataMetaInfo>, | ||
| 76 | "Data type must be trivially copyable."); | ||
| 77 | static_assert(sizeof(SaveDataMetaInfo) == 0x10, "SaveDataMetaInfo has invalid size."); | ||
| 78 | |||
| 79 | struct SaveDataCreationInfo { | ||
| 80 | s64 size; | ||
| 81 | s64 journal_size; | ||
| 82 | s64 block_size; | ||
| 83 | u64 owner_id; | ||
| 84 | u32 flags; | ||
| 85 | SaveDataSpaceId space_id; | ||
| 86 | bool pseudo; | ||
| 87 | INSERT_PADDING_BYTES(0x1A); | ||
| 88 | }; | ||
| 89 | static_assert(std::is_trivially_copyable_v<SaveDataCreationInfo>, | ||
| 90 | "Data type must be trivially copyable."); | ||
| 91 | static_assert(sizeof(SaveDataCreationInfo) == 0x40, "SaveDataCreationInfo has invalid size."); | ||
| 92 | |||
| 93 | struct SaveDataAttribute { | ||
| 94 | ProgramId program_id; | ||
| 95 | UserId user_id; | ||
| 96 | SystemSaveDataId system_save_data_id; | ||
| 97 | SaveDataType type; | ||
| 98 | SaveDataRank rank; | ||
| 99 | u16 index; | ||
| 100 | INSERT_PADDING_BYTES(0x1C); | ||
| 101 | |||
| 102 | static constexpr SaveDataAttribute Make(ProgramId program_id, SaveDataType type, UserId user_id, | ||
| 103 | SystemSaveDataId system_save_data_id, u16 index, | ||
| 104 | SaveDataRank rank) { | ||
| 105 | return { | ||
| 106 | .program_id = program_id, | ||
| 107 | .user_id = user_id, | ||
| 108 | .system_save_data_id = system_save_data_id, | ||
| 109 | .type = type, | ||
| 110 | .rank = rank, | ||
| 111 | .index = index, | ||
| 112 | }; | ||
| 113 | } | ||
| 114 | |||
| 115 | static constexpr SaveDataAttribute Make(ProgramId program_id, SaveDataType type, UserId user_id, | ||
| 116 | SystemSaveDataId system_save_data_id, u16 index) { | ||
| 117 | return Make(program_id, type, user_id, system_save_data_id, index, SaveDataRank::Primary); | ||
| 118 | } | ||
| 119 | |||
| 120 | static constexpr SaveDataAttribute Make(ProgramId program_id, SaveDataType type, UserId user_id, | ||
| 121 | SystemSaveDataId system_save_data_id) { | ||
| 122 | return Make(program_id, type, user_id, system_save_data_id, 0, SaveDataRank::Primary); | ||
| 123 | } | ||
| 124 | |||
| 125 | std::string DebugInfo() const { | ||
| 126 | return fmt::format( | ||
| 127 | "[title_id={:016X}, user_id={:016X}{:016X}, save_id={:016X}, type={:02X}, " | ||
| 128 | "rank={}, index={}]", | ||
| 129 | program_id, user_id[1], user_id[0], system_save_data_id, static_cast<u8>(type), | ||
| 130 | static_cast<u8>(rank), index); | ||
| 131 | } | ||
| 132 | }; | ||
| 133 | static_assert(sizeof(SaveDataAttribute) == 0x40); | ||
| 134 | static_assert(std::is_trivially_destructible<SaveDataAttribute>::value); | ||
| 135 | |||
| 136 | constexpr inline bool operator<(const SaveDataAttribute& lhs, const SaveDataAttribute& rhs) { | ||
| 137 | return std::tie(lhs.program_id, lhs.user_id, lhs.system_save_data_id, lhs.index, lhs.rank) < | ||
| 138 | std::tie(rhs.program_id, rhs.user_id, rhs.system_save_data_id, rhs.index, rhs.rank); | ||
| 139 | } | ||
| 140 | |||
| 141 | constexpr inline bool operator==(const SaveDataAttribute& lhs, const SaveDataAttribute& rhs) { | ||
| 142 | return std::tie(lhs.program_id, lhs.user_id, lhs.system_save_data_id, lhs.type, lhs.rank, | ||
| 143 | lhs.index) == std::tie(rhs.program_id, rhs.user_id, rhs.system_save_data_id, | ||
| 144 | rhs.type, rhs.rank, rhs.index); | ||
| 145 | } | ||
| 146 | |||
| 147 | constexpr inline bool operator!=(const SaveDataAttribute& lhs, const SaveDataAttribute& rhs) { | ||
| 148 | return !(lhs == rhs); | ||
| 149 | } | ||
| 150 | |||
| 151 | struct SaveDataExtraData { | ||
| 152 | SaveDataAttribute attr; | ||
| 153 | u64 owner_id; | ||
| 154 | s64 timestamp; | ||
| 155 | u32 flags; | ||
| 156 | INSERT_PADDING_BYTES(4); | ||
| 157 | s64 available_size; | ||
| 158 | s64 journal_size; | ||
| 159 | s64 commit_id; | ||
| 160 | INSERT_PADDING_BYTES(0x190); | ||
| 161 | }; | ||
| 162 | static_assert(sizeof(SaveDataExtraData) == 0x200, "SaveDataExtraData has invalid size."); | ||
| 163 | static_assert(std::is_trivially_copyable_v<SaveDataExtraData>, | ||
| 164 | "Data type must be trivially copyable."); | ||
| 165 | |||
| 166 | struct HashSalt { | ||
| 167 | static constexpr size_t Size = 32; | ||
| 168 | |||
| 169 | std::array<u8, Size> value; | ||
| 170 | }; | ||
| 171 | static_assert(std::is_trivially_copyable_v<HashSalt>, "Data type must be trivially copyable."); | ||
| 172 | static_assert(sizeof(HashSalt) == HashSalt::Size); | ||
| 173 | |||
| 174 | } // namespace FileSys | ||
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index cbf411a20..106922e04 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp | |||
| @@ -14,48 +14,11 @@ namespace FileSys { | |||
| 14 | 14 | ||
| 15 | namespace { | 15 | namespace { |
| 16 | 16 | ||
| 17 | void PrintSaveDataAttributeWarnings(SaveDataAttribute meta) { | ||
| 18 | if (meta.type == SaveDataType::SystemSaveData || meta.type == SaveDataType::SaveData) { | ||
| 19 | if (meta.zero_1 != 0) { | ||
| 20 | LOG_WARNING(Service_FS, | ||
| 21 | "Possibly incorrect SaveDataAttribute, type is " | ||
| 22 | "SystemSaveData||SaveData but offset 0x28 is non-zero ({:016X}).", | ||
| 23 | meta.zero_1); | ||
| 24 | } | ||
| 25 | if (meta.zero_2 != 0) { | ||
| 26 | LOG_WARNING(Service_FS, | ||
| 27 | "Possibly incorrect SaveDataAttribute, type is " | ||
| 28 | "SystemSaveData||SaveData but offset 0x30 is non-zero ({:016X}).", | ||
| 29 | meta.zero_2); | ||
| 30 | } | ||
| 31 | if (meta.zero_3 != 0) { | ||
| 32 | LOG_WARNING(Service_FS, | ||
| 33 | "Possibly incorrect SaveDataAttribute, type is " | ||
| 34 | "SystemSaveData||SaveData but offset 0x38 is non-zero ({:016X}).", | ||
| 35 | meta.zero_3); | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | if (meta.type == SaveDataType::SystemSaveData && meta.title_id != 0) { | ||
| 40 | LOG_WARNING(Service_FS, | ||
| 41 | "Possibly incorrect SaveDataAttribute, type is SystemSaveData but title_id is " | ||
| 42 | "non-zero ({:016X}).", | ||
| 43 | meta.title_id); | ||
| 44 | } | ||
| 45 | |||
| 46 | if (meta.type == SaveDataType::DeviceSaveData && meta.user_id != u128{0, 0}) { | ||
| 47 | LOG_WARNING(Service_FS, | ||
| 48 | "Possibly incorrect SaveDataAttribute, type is DeviceSaveData but user_id is " | ||
| 49 | "non-zero ({:016X}{:016X})", | ||
| 50 | meta.user_id[1], meta.user_id[0]); | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataAttribute& attr) { | 17 | bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataAttribute& attr) { |
| 55 | return attr.type == SaveDataType::CacheStorage || attr.type == SaveDataType::TemporaryStorage || | 18 | return attr.type == SaveDataType::Cache || attr.type == SaveDataType::Temporary || |
| 56 | (space == SaveDataSpaceId::NandUser && ///< Normal Save Data -- Current Title & User | 19 | (space == SaveDataSpaceId::User && ///< Normal Save Data -- Current Title & User |
| 57 | (attr.type == SaveDataType::SaveData || attr.type == SaveDataType::DeviceSaveData) && | 20 | (attr.type == SaveDataType::Account || attr.type == SaveDataType::Device) && |
| 58 | attr.title_id == 0 && attr.save_id == 0); | 21 | attr.program_id == 0 && attr.system_save_data_id == 0); |
| 59 | } | 22 | } |
| 60 | 23 | ||
| 61 | std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u64 title_id, | 24 | std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u64 title_id, |
| @@ -63,7 +26,7 @@ std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u | |||
| 63 | // Only detect nand user saves. | 26 | // Only detect nand user saves. |
| 64 | const auto space_id_path = [space_id]() -> std::string_view { | 27 | const auto space_id_path = [space_id]() -> std::string_view { |
| 65 | switch (space_id) { | 28 | switch (space_id) { |
| 66 | case SaveDataSpaceId::NandUser: | 29 | case SaveDataSpaceId::User: |
| 67 | return "/user/save"; | 30 | return "/user/save"; |
| 68 | default: | 31 | default: |
| 69 | return ""; | 32 | return ""; |
| @@ -79,9 +42,9 @@ std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u | |||
| 79 | 42 | ||
| 80 | // Only detect account/device saves from the future location. | 43 | // Only detect account/device saves from the future location. |
| 81 | switch (type) { | 44 | switch (type) { |
| 82 | case SaveDataType::SaveData: | 45 | case SaveDataType::Account: |
| 83 | return fmt::format("{}/account/{}/{:016X}/0", space_id_path, uuid.RawString(), title_id); | 46 | return fmt::format("{}/account/{}/{:016X}/0", space_id_path, uuid.RawString(), title_id); |
| 84 | case SaveDataType::DeviceSaveData: | 47 | case SaveDataType::Device: |
| 85 | return fmt::format("{}/device/{:016X}/0", space_id_path, title_id); | 48 | return fmt::format("{}/device/{:016X}/0", space_id_path, title_id); |
| 86 | default: | 49 | default: |
| 87 | return ""; | 50 | return ""; |
| @@ -90,13 +53,6 @@ std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u | |||
| 90 | 53 | ||
| 91 | } // Anonymous namespace | 54 | } // Anonymous namespace |
| 92 | 55 | ||
| 93 | std::string SaveDataAttribute::DebugInfo() const { | ||
| 94 | return fmt::format("[title_id={:016X}, user_id={:016X}{:016X}, save_id={:016X}, type={:02X}, " | ||
| 95 | "rank={}, index={}]", | ||
| 96 | title_id, user_id[1], user_id[0], save_id, static_cast<u8>(type), | ||
| 97 | static_cast<u8>(rank), index); | ||
| 98 | } | ||
| 99 | |||
| 100 | SaveDataFactory::SaveDataFactory(Core::System& system_, ProgramId program_id_, | 56 | SaveDataFactory::SaveDataFactory(Core::System& system_, ProgramId program_id_, |
| 101 | VirtualDir save_directory_) | 57 | VirtualDir save_directory_) |
| 102 | : system{system_}, program_id{program_id_}, dir{std::move(save_directory_)} { | 58 | : system{system_}, program_id{program_id_}, dir{std::move(save_directory_)} { |
| @@ -108,18 +64,16 @@ SaveDataFactory::SaveDataFactory(Core::System& system_, ProgramId program_id_, | |||
| 108 | SaveDataFactory::~SaveDataFactory() = default; | 64 | SaveDataFactory::~SaveDataFactory() = default; |
| 109 | 65 | ||
| 110 | VirtualDir SaveDataFactory::Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const { | 66 | VirtualDir SaveDataFactory::Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const { |
| 111 | PrintSaveDataAttributeWarnings(meta); | 67 | const auto save_directory = GetFullPath(program_id, dir, space, meta.type, meta.program_id, |
| 112 | 68 | meta.user_id, meta.system_save_data_id); | |
| 113 | const auto save_directory = | ||
| 114 | GetFullPath(program_id, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id); | ||
| 115 | 69 | ||
| 116 | return dir->CreateDirectoryRelative(save_directory); | 70 | return dir->CreateDirectoryRelative(save_directory); |
| 117 | } | 71 | } |
| 118 | 72 | ||
| 119 | VirtualDir SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataAttribute& meta) const { | 73 | VirtualDir SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataAttribute& meta) const { |
| 120 | 74 | ||
| 121 | const auto save_directory = | 75 | const auto save_directory = GetFullPath(program_id, dir, space, meta.type, meta.program_id, |
| 122 | GetFullPath(program_id, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id); | 76 | meta.user_id, meta.system_save_data_id); |
| 123 | 77 | ||
| 124 | auto out = dir->GetDirectoryRelative(save_directory); | 78 | auto out = dir->GetDirectoryRelative(save_directory); |
| 125 | 79 | ||
| @@ -136,11 +90,11 @@ VirtualDir SaveDataFactory::GetSaveDataSpaceDirectory(SaveDataSpaceId space) con | |||
| 136 | 90 | ||
| 137 | std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) { | 91 | std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) { |
| 138 | switch (space) { | 92 | switch (space) { |
| 139 | case SaveDataSpaceId::NandSystem: | 93 | case SaveDataSpaceId::System: |
| 140 | return "/system/"; | 94 | return "/system/"; |
| 141 | case SaveDataSpaceId::NandUser: | 95 | case SaveDataSpaceId::User: |
| 142 | return "/user/"; | 96 | return "/user/"; |
| 143 | case SaveDataSpaceId::TemporaryStorage: | 97 | case SaveDataSpaceId::Temporary: |
| 144 | return "/temp/"; | 98 | return "/temp/"; |
| 145 | default: | 99 | default: |
| 146 | ASSERT_MSG(false, "Unrecognized SaveDataSpaceId: {:02X}", static_cast<u8>(space)); | 100 | ASSERT_MSG(false, "Unrecognized SaveDataSpaceId: {:02X}", static_cast<u8>(space)); |
| @@ -153,7 +107,7 @@ std::string SaveDataFactory::GetFullPath(ProgramId program_id, VirtualDir dir, | |||
| 153 | u128 user_id, u64 save_id) { | 107 | u128 user_id, u64 save_id) { |
| 154 | // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should | 108 | // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should |
| 155 | // be interpreted as the title id of the current process. | 109 | // be interpreted as the title id of the current process. |
| 156 | if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) { | 110 | if (type == SaveDataType::Account || type == SaveDataType::Device) { |
| 157 | if (title_id == 0) { | 111 | if (title_id == 0) { |
| 158 | title_id = program_id; | 112 | title_id = program_id; |
| 159 | } | 113 | } |
| @@ -173,16 +127,16 @@ std::string SaveDataFactory::GetFullPath(ProgramId program_id, VirtualDir dir, | |||
| 173 | std::string out = GetSaveDataSpaceIdPath(space); | 127 | std::string out = GetSaveDataSpaceIdPath(space); |
| 174 | 128 | ||
| 175 | switch (type) { | 129 | switch (type) { |
| 176 | case SaveDataType::SystemSaveData: | 130 | case SaveDataType::System: |
| 177 | return fmt::format("{}save/{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]); | 131 | return fmt::format("{}save/{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]); |
| 178 | case SaveDataType::SaveData: | 132 | case SaveDataType::Account: |
| 179 | case SaveDataType::DeviceSaveData: | 133 | case SaveDataType::Device: |
| 180 | return fmt::format("{}save/{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0], | 134 | return fmt::format("{}save/{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0], |
| 181 | title_id); | 135 | title_id); |
| 182 | case SaveDataType::TemporaryStorage: | 136 | case SaveDataType::Temporary: |
| 183 | return fmt::format("{}{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0], | 137 | return fmt::format("{}{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0], |
| 184 | title_id); | 138 | title_id); |
| 185 | case SaveDataType::CacheStorage: | 139 | case SaveDataType::Cache: |
| 186 | return fmt::format("{}save/cache/{:016X}", out, title_id); | 140 | return fmt::format("{}save/cache/{:016X}", out, title_id); |
| 187 | default: | 141 | default: |
| 188 | ASSERT_MSG(false, "Unrecognized SaveDataType: {:02X}", static_cast<u8>(type)); | 142 | ASSERT_MSG(false, "Unrecognized SaveDataType: {:02X}", static_cast<u8>(type)); |
| @@ -202,7 +156,7 @@ std::string SaveDataFactory::GetUserGameSaveDataRoot(u128 user_id, bool future) | |||
| 202 | SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, | 156 | SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, |
| 203 | u128 user_id) const { | 157 | u128 user_id) const { |
| 204 | const auto path = | 158 | const auto path = |
| 205 | GetFullPath(program_id, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0); | 159 | GetFullPath(program_id, dir, SaveDataSpaceId::User, type, title_id, user_id, 0); |
| 206 | const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); | 160 | const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); |
| 207 | 161 | ||
| 208 | const auto size_file = relative_dir->GetFile(GetSaveDataSizeFileName()); | 162 | const auto size_file = relative_dir->GetFile(GetSaveDataSizeFileName()); |
| @@ -221,7 +175,7 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, | |||
| 221 | void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, | 175 | void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, |
| 222 | SaveDataSize new_value) const { | 176 | SaveDataSize new_value) const { |
| 223 | const auto path = | 177 | const auto path = |
| 224 | GetFullPath(program_id, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0); | 178 | GetFullPath(program_id, dir, SaveDataSpaceId::User, type, title_id, user_id, 0); |
| 225 | const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); | 179 | const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); |
| 226 | 180 | ||
| 227 | const auto size_file = relative_dir->CreateFile(GetSaveDataSizeFileName()); | 181 | const auto size_file = relative_dir->CreateFile(GetSaveDataSizeFileName()); |
diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h index 5ab7e4d32..15dd4ec7d 100644 --- a/src/core/file_sys/savedata_factory.h +++ b/src/core/file_sys/savedata_factory.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include "common/common_funcs.h" | 8 | #include "common/common_funcs.h" |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "core/file_sys/fs_save_data_types.h" | ||
| 10 | #include "core/file_sys/vfs/vfs.h" | 11 | #include "core/file_sys/vfs/vfs.h" |
| 11 | #include "core/hle/result.h" | 12 | #include "core/hle/result.h" |
| 12 | 13 | ||
| @@ -16,73 +17,6 @@ class System; | |||
| 16 | 17 | ||
| 17 | namespace FileSys { | 18 | namespace FileSys { |
| 18 | 19 | ||
| 19 | enum class SaveDataSpaceId : u8 { | ||
| 20 | NandSystem = 0, | ||
| 21 | NandUser = 1, | ||
| 22 | SdCardSystem = 2, | ||
| 23 | TemporaryStorage = 3, | ||
| 24 | SdCardUser = 4, | ||
| 25 | ProperSystem = 100, | ||
| 26 | SafeMode = 101, | ||
| 27 | }; | ||
| 28 | |||
| 29 | enum class SaveDataType : u8 { | ||
| 30 | SystemSaveData = 0, | ||
| 31 | SaveData = 1, | ||
| 32 | BcatDeliveryCacheStorage = 2, | ||
| 33 | DeviceSaveData = 3, | ||
| 34 | TemporaryStorage = 4, | ||
| 35 | CacheStorage = 5, | ||
| 36 | SystemBcat = 6, | ||
| 37 | }; | ||
| 38 | |||
| 39 | enum class SaveDataRank : u8 { | ||
| 40 | Primary = 0, | ||
| 41 | Secondary = 1, | ||
| 42 | }; | ||
| 43 | |||
| 44 | enum class SaveDataFlags : u32 { | ||
| 45 | None = (0 << 0), | ||
| 46 | KeepAfterResettingSystemSaveData = (1 << 0), | ||
| 47 | KeepAfterRefurbishment = (1 << 1), | ||
| 48 | KeepAfterResettingSystemSaveDataWithoutUserSaveData = (1 << 2), | ||
| 49 | NeedsSecureDelete = (1 << 3), | ||
| 50 | }; | ||
| 51 | |||
| 52 | struct SaveDataAttribute { | ||
| 53 | u64 title_id; | ||
| 54 | u128 user_id; | ||
| 55 | u64 save_id; | ||
| 56 | SaveDataType type; | ||
| 57 | SaveDataRank rank; | ||
| 58 | u16 index; | ||
| 59 | INSERT_PADDING_BYTES_NOINIT(4); | ||
| 60 | u64 zero_1; | ||
| 61 | u64 zero_2; | ||
| 62 | u64 zero_3; | ||
| 63 | |||
| 64 | std::string DebugInfo() const; | ||
| 65 | }; | ||
| 66 | static_assert(sizeof(SaveDataAttribute) == 0x40, "SaveDataAttribute has incorrect size."); | ||
| 67 | |||
| 68 | struct SaveDataExtraData { | ||
| 69 | SaveDataAttribute attr; | ||
| 70 | u64 owner_id; | ||
| 71 | s64 timestamp; | ||
| 72 | SaveDataFlags flags; | ||
| 73 | INSERT_PADDING_BYTES_NOINIT(4); | ||
| 74 | s64 available_size; | ||
| 75 | s64 journal_size; | ||
| 76 | s64 commit_id; | ||
| 77 | std::array<u8, 0x190> unused; | ||
| 78 | }; | ||
| 79 | static_assert(sizeof(SaveDataExtraData) == 0x200, "SaveDataExtraData has incorrect size."); | ||
| 80 | |||
| 81 | struct SaveDataSize { | ||
| 82 | u64 normal; | ||
| 83 | u64 journal; | ||
| 84 | }; | ||
| 85 | |||
| 86 | constexpr const char* GetSaveDataSizeFileName() { | 20 | constexpr const char* GetSaveDataSizeFileName() { |
| 87 | return ".yuzu_save_size"; | 21 | return ".yuzu_save_size"; |
| 88 | } | 22 | } |
diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp index cb53b07e0..bfccb6b09 100644 --- a/src/core/hle/service/am/service/application_functions.cpp +++ b/src/core/hle/service/am/service/application_functions.cpp | |||
| @@ -123,13 +123,13 @@ Result IApplicationFunctions::EnsureSaveData(Out<u64> out_size, Common::UUID use | |||
| 123 | LOG_INFO(Service_AM, "called, uid={}", user_id.FormattedString()); | 123 | LOG_INFO(Service_AM, "called, uid={}", user_id.FormattedString()); |
| 124 | 124 | ||
| 125 | FileSys::SaveDataAttribute attribute{}; | 125 | FileSys::SaveDataAttribute attribute{}; |
| 126 | attribute.title_id = m_applet->program_id; | 126 | attribute.program_id = m_applet->program_id; |
| 127 | attribute.user_id = user_id.AsU128(); | 127 | attribute.user_id = user_id.AsU128(); |
| 128 | attribute.type = FileSys::SaveDataType::SaveData; | 128 | attribute.type = FileSys::SaveDataType::Account; |
| 129 | 129 | ||
| 130 | FileSys::VirtualDir save_data{}; | 130 | FileSys::VirtualDir save_data{}; |
| 131 | R_TRY(system.GetFileSystemController().OpenSaveDataController()->CreateSaveData( | 131 | R_TRY(system.GetFileSystemController().OpenSaveDataController()->CreateSaveData( |
| 132 | &save_data, FileSys::SaveDataSpaceId::NandUser, attribute)); | 132 | &save_data, FileSys::SaveDataSpaceId::User, attribute)); |
| 133 | 133 | ||
| 134 | *out_size = 0; | 134 | *out_size = 0; |
| 135 | R_SUCCEED(); | 135 | R_SUCCEED(); |
diff --git a/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp b/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp index 0d9b0dcaf..ff823586b 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp +++ b/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp | |||
| @@ -72,7 +72,7 @@ void ISaveDataInfoReader::FindAllSaves(FileSys::SaveDataSpaceId space) { | |||
| 72 | for (const auto& type : save_root->GetSubdirectories()) { | 72 | for (const auto& type : save_root->GetSubdirectories()) { |
| 73 | if (type->GetName() == "save") { | 73 | if (type->GetName() == "save") { |
| 74 | FindNormalSaves(space, type); | 74 | FindNormalSaves(space, type); |
| 75 | } else if (space == FileSys::SaveDataSpaceId::TemporaryStorage) { | 75 | } else if (space == FileSys::SaveDataSpaceId::Temporary) { |
| 76 | FindTemporaryStorageSaves(space, type); | 76 | FindTemporaryStorageSaves(space, type); |
| 77 | } | 77 | } |
| 78 | } | 78 | } |
| @@ -96,7 +96,7 @@ void ISaveDataInfoReader::FindNormalSaves(FileSys::SaveDataSpaceId space, | |||
| 96 | info.emplace_back(SaveDataInfo{ | 96 | info.emplace_back(SaveDataInfo{ |
| 97 | 0, | 97 | 0, |
| 98 | space, | 98 | space, |
| 99 | FileSys::SaveDataType::SystemSaveData, | 99 | FileSys::SaveDataType::System, |
| 100 | {}, | 100 | {}, |
| 101 | user_id_numeric, | 101 | user_id_numeric, |
| 102 | save_id_numeric, | 102 | save_id_numeric, |
| @@ -115,8 +115,7 @@ void ISaveDataInfoReader::FindNormalSaves(FileSys::SaveDataSpaceId space, | |||
| 115 | info.emplace_back(SaveDataInfo{ | 115 | info.emplace_back(SaveDataInfo{ |
| 116 | 0, | 116 | 0, |
| 117 | space, | 117 | space, |
| 118 | device ? FileSys::SaveDataType::DeviceSaveData | 118 | device ? FileSys::SaveDataType::Device : FileSys::SaveDataType::Account, |
| 119 | : FileSys::SaveDataType::SaveData, | ||
| 120 | {}, | 119 | {}, |
| 121 | user_id_numeric, | 120 | user_id_numeric, |
| 122 | save_id_numeric, | 121 | save_id_numeric, |
| @@ -145,7 +144,7 @@ void ISaveDataInfoReader::FindTemporaryStorageSaves(FileSys::SaveDataSpaceId spa | |||
| 145 | info.emplace_back(SaveDataInfo{ | 144 | info.emplace_back(SaveDataInfo{ |
| 146 | 0, | 145 | 0, |
| 147 | space, | 146 | space, |
| 148 | FileSys::SaveDataType::TemporaryStorage, | 147 | FileSys::SaveDataType::Temporary, |
| 149 | {}, | 148 | {}, |
| 150 | user_id_numeric, | 149 | user_id_numeric, |
| 151 | stoull_be(type->GetName()), | 150 | stoull_be(type->GetName()), |
diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp index 2f3b01595..fc67a4713 100644 --- a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp | |||
| @@ -224,23 +224,23 @@ Result FSP_SRV::OpenSdCardFileSystem(OutInterface<IFileSystem> out_interface) { | |||
| 224 | R_SUCCEED(); | 224 | R_SUCCEED(); |
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | Result FSP_SRV::CreateSaveDataFileSystem(std::array<u8, 0x40> save_create_struct, | 227 | Result FSP_SRV::CreateSaveDataFileSystem(FileSys::SaveDataCreationInfo save_create_struct, |
| 228 | FileSys::SaveDataAttribute save_struct, u128 uid) { | 228 | FileSys::SaveDataAttribute save_struct, u128 uid) { |
| 229 | LOG_DEBUG(Service_FS, "called save_struct = {}, uid = {:016X}{:016X}", save_struct.DebugInfo(), | 229 | LOG_DEBUG(Service_FS, "called save_struct = {}, uid = {:016X}{:016X}", save_struct.DebugInfo(), |
| 230 | uid[1], uid[0]); | 230 | uid[1], uid[0]); |
| 231 | 231 | ||
| 232 | FileSys::VirtualDir save_data_dir{}; | 232 | FileSys::VirtualDir save_data_dir{}; |
| 233 | R_RETURN(save_data_controller->CreateSaveData(&save_data_dir, | 233 | R_RETURN(save_data_controller->CreateSaveData(&save_data_dir, FileSys::SaveDataSpaceId::User, |
| 234 | FileSys::SaveDataSpaceId::NandUser, save_struct)); | 234 | save_struct)); |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | Result FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId(std::array<u8, 0x40> save_create_struct, | 237 | Result FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId( |
| 238 | FileSys::SaveDataAttribute save_struct) { | 238 | FileSys::SaveDataCreationInfo save_create_struct, FileSys::SaveDataAttribute save_struct) { |
| 239 | LOG_DEBUG(Service_FS, "called save_struct = {}", save_struct.DebugInfo()); | 239 | LOG_DEBUG(Service_FS, "called save_struct = {}", save_struct.DebugInfo()); |
| 240 | 240 | ||
| 241 | FileSys::VirtualDir save_data_dir{}; | 241 | FileSys::VirtualDir save_data_dir{}; |
| 242 | R_RETURN(save_data_controller->CreateSaveData( | 242 | R_RETURN(save_data_controller->CreateSaveData(&save_data_dir, FileSys::SaveDataSpaceId::System, |
| 243 | &save_data_dir, FileSys::SaveDataSpaceId::NandSystem, save_struct)); | 243 | save_struct)); |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | Result FSP_SRV::OpenSaveDataFileSystem(OutInterface<IFileSystem> out_interface, | 246 | Result FSP_SRV::OpenSaveDataFileSystem(OutInterface<IFileSystem> out_interface, |
| @@ -253,17 +253,17 @@ Result FSP_SRV::OpenSaveDataFileSystem(OutInterface<IFileSystem> out_interface, | |||
| 253 | 253 | ||
| 254 | FileSys::StorageId id{}; | 254 | FileSys::StorageId id{}; |
| 255 | switch (space_id) { | 255 | switch (space_id) { |
| 256 | case FileSys::SaveDataSpaceId::NandUser: | 256 | case FileSys::SaveDataSpaceId::User: |
| 257 | id = FileSys::StorageId::NandUser; | 257 | id = FileSys::StorageId::NandUser; |
| 258 | break; | 258 | break; |
| 259 | case FileSys::SaveDataSpaceId::SdCardSystem: | 259 | case FileSys::SaveDataSpaceId::SdSystem: |
| 260 | case FileSys::SaveDataSpaceId::SdCardUser: | 260 | case FileSys::SaveDataSpaceId::SdUser: |
| 261 | id = FileSys::StorageId::SdCard; | 261 | id = FileSys::StorageId::SdCard; |
| 262 | break; | 262 | break; |
| 263 | case FileSys::SaveDataSpaceId::NandSystem: | 263 | case FileSys::SaveDataSpaceId::System: |
| 264 | id = FileSys::StorageId::NandSystem; | 264 | id = FileSys::StorageId::NandSystem; |
| 265 | break; | 265 | break; |
| 266 | case FileSys::SaveDataSpaceId::TemporaryStorage: | 266 | case FileSys::SaveDataSpaceId::Temporary: |
| 267 | case FileSys::SaveDataSpaceId::ProperSystem: | 267 | case FileSys::SaveDataSpaceId::ProperSystem: |
| 268 | case FileSys::SaveDataSpaceId::SafeMode: | 268 | case FileSys::SaveDataSpaceId::SafeMode: |
| 269 | ASSERT(false); | 269 | ASSERT(false); |
| @@ -302,8 +302,8 @@ Result FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage( | |||
| 302 | OutInterface<ISaveDataInfoReader> out_interface) { | 302 | OutInterface<ISaveDataInfoReader> out_interface) { |
| 303 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 303 | LOG_WARNING(Service_FS, "(STUBBED) called"); |
| 304 | 304 | ||
| 305 | *out_interface = std::make_shared<ISaveDataInfoReader>( | 305 | *out_interface = std::make_shared<ISaveDataInfoReader>(system, save_data_controller, |
| 306 | system, save_data_controller, FileSys::SaveDataSpaceId::TemporaryStorage); | 306 | FileSys::SaveDataSpaceId::Temporary); |
| 307 | 307 | ||
| 308 | R_SUCCEED(); | 308 | R_SUCCEED(); |
| 309 | } | 309 | } |
| @@ -323,11 +323,11 @@ Result FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute( | |||
| 323 | [[maybe_unused]] constexpr auto flags = static_cast<u32>(FileSys::SaveDataFlags::None); | 323 | [[maybe_unused]] constexpr auto flags = static_cast<u32>(FileSys::SaveDataFlags::None); |
| 324 | 324 | ||
| 325 | LOG_WARNING(Service_FS, | 325 | LOG_WARNING(Service_FS, |
| 326 | "(STUBBED) called, flags={}, space_id={}, attribute.title_id={:016X}\n" | 326 | "(STUBBED) called, flags={}, space_id={}, attribute.program_id={:016X}\n" |
| 327 | "attribute.user_id={:016X}{:016X}, attribute.save_id={:016X}\n" | 327 | "attribute.user_id={:016X}{:016X}, attribute.save_id={:016X}\n" |
| 328 | "attribute.type={}, attribute.rank={}, attribute.index={}", | 328 | "attribute.type={}, attribute.rank={}, attribute.index={}", |
| 329 | flags, space_id, attribute.title_id, attribute.user_id[1], attribute.user_id[0], | 329 | flags, space_id, attribute.program_id, attribute.user_id[1], attribute.user_id[0], |
| 330 | attribute.save_id, attribute.type, attribute.rank, attribute.index); | 330 | attribute.system_save_data_id, attribute.type, attribute.rank, attribute.index); |
| 331 | 331 | ||
| 332 | R_SUCCEED(); | 332 | R_SUCCEED(); |
| 333 | } | 333 | } |
diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.h b/src/core/hle/service/filesystem/fsp/fsp_srv.h index 0669c4922..7a29d17c9 100644 --- a/src/core/hle/service/filesystem/fsp/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | #include "core/file_sys/fs_save_data_types.h" | ||
| 7 | #include "core/hle/service/cmif_types.h" | 8 | #include "core/hle/service/cmif_types.h" |
| 8 | #include "core/hle/service/service.h" | 9 | #include "core/hle/service/service.h" |
| 9 | 10 | ||
| @@ -60,10 +61,10 @@ private: | |||
| 60 | Result OpenFileSystemWithPatch(OutInterface<IFileSystem> out_interface, | 61 | Result OpenFileSystemWithPatch(OutInterface<IFileSystem> out_interface, |
| 61 | FileSystemProxyType type, u64 open_program_id); | 62 | FileSystemProxyType type, u64 open_program_id); |
| 62 | Result OpenSdCardFileSystem(OutInterface<IFileSystem> out_interface); | 63 | Result OpenSdCardFileSystem(OutInterface<IFileSystem> out_interface); |
| 63 | Result CreateSaveDataFileSystem(std::array<u8, 0x40> save_create_struct, | 64 | Result CreateSaveDataFileSystem(FileSys::SaveDataCreationInfo save_create_struct, |
| 64 | FileSys::SaveDataAttribute save_struct, u128 uid); | 65 | FileSys::SaveDataAttribute save_struct, u128 uid); |
| 65 | Result CreateSaveDataFileSystemBySystemSaveDataId(std::array<u8, 0x40> save_create_struct, | 66 | Result CreateSaveDataFileSystemBySystemSaveDataId( |
| 66 | FileSys::SaveDataAttribute save_struct); | 67 | FileSys::SaveDataCreationInfo save_create_struct, FileSys::SaveDataAttribute save_struct); |
| 67 | Result OpenSaveDataFileSystem(OutInterface<IFileSystem> out_interface, | 68 | Result OpenSaveDataFileSystem(OutInterface<IFileSystem> out_interface, |
| 68 | FileSys::SaveDataSpaceId space_id, | 69 | FileSys::SaveDataSpaceId space_id, |
| 69 | FileSys::SaveDataAttribute attribute); | 70 | FileSys::SaveDataAttribute attribute); |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 236642fb9..9d63b5935 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -2323,15 +2323,15 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target | |||
| 2323 | ASSERT(user_id); | 2323 | ASSERT(user_id); |
| 2324 | 2324 | ||
| 2325 | const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( | 2325 | const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( |
| 2326 | {}, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser, | 2326 | {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Account, |
| 2327 | FileSys::SaveDataType::SaveData, program_id, user_id->AsU128(), 0); | 2327 | program_id, user_id->AsU128(), 0); |
| 2328 | 2328 | ||
| 2329 | path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path); | 2329 | path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path); |
| 2330 | } else { | 2330 | } else { |
| 2331 | // Device save data | 2331 | // Device save data |
| 2332 | const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath( | 2332 | const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath( |
| 2333 | {}, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser, | 2333 | {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Account, |
| 2334 | FileSys::SaveDataType::SaveData, program_id, {}, 0); | 2334 | program_id, {}, 0); |
| 2335 | 2335 | ||
| 2336 | path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path); | 2336 | path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path); |
| 2337 | } | 2337 | } |
| @@ -2672,7 +2672,7 @@ void GMainWindow::RemoveCacheStorage(u64 program_id) { | |||
| 2672 | vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read); | 2672 | vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read); |
| 2673 | 2673 | ||
| 2674 | const auto cache_storage_path = FileSys::SaveDataFactory::GetFullPath( | 2674 | const auto cache_storage_path = FileSys::SaveDataFactory::GetFullPath( |
| 2675 | {}, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::CacheStorage, | 2675 | {}, vfs_nand_dir, FileSys::SaveDataSpaceId::User, FileSys::SaveDataType::Cache, |
| 2676 | 0 /* program_id */, {}, 0); | 2676 | 0 /* program_id */, {}, 0); |
| 2677 | 2677 | ||
| 2678 | const auto path = Common::FS::ConcatPathSafe(nand_dir, cache_storage_path); | 2678 | const auto path = Common::FS::ConcatPathSafe(nand_dir, cache_storage_path); |