summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/file_sys/fs_save_data_types.h174
-rw-r--r--src/core/file_sys/savedata_factory.cpp90
-rw-r--r--src/core/file_sys/savedata_factory.h68
-rw-r--r--src/core/hle/service/am/service/application_functions.cpp6
-rw-r--r--src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp9
-rw-r--r--src/core/hle/service/filesystem/fsp/fsp_srv.cpp34
-rw-r--r--src/core/hle/service/filesystem/fsp/fsp_srv.h7
-rw-r--r--src/yuzu/main.cpp10
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
10namespace FileSys {
11
12using SaveDataId = u64;
13using SystemSaveDataId = u64;
14using SystemBcatSaveDataId = SystemSaveDataId;
15using ProgramId = u64;
16
17enum 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
28enum 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
38enum class SaveDataRank : u8 {
39 Primary = 0,
40 Secondary = 1,
41};
42
43struct SaveDataSize {
44 u64 normal;
45 u64 journal;
46};
47static_assert(sizeof(SaveDataSize) == 0x10, "SaveDataSize has invalid size.");
48
49using UserId = u128;
50static_assert(std::is_trivially_copyable_v<UserId>, "Data type must be trivially copyable.");
51static_assert(sizeof(UserId) == 0x10, "UserId has invalid size.");
52
53constexpr inline SystemSaveDataId InvalidSystemSaveDataId = 0;
54constexpr inline UserId InvalidUserId = {};
55
56enum 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
64enum class SaveDataMetaType : u8 {
65 None = 0,
66 Thumbnail = 1,
67 ExtensionContext = 2,
68};
69
70struct SaveDataMetaInfo {
71 u32 size;
72 SaveDataMetaType type;
73 INSERT_PADDING_BYTES(0xB);
74};
75static_assert(std::is_trivially_copyable_v<SaveDataMetaInfo>,
76 "Data type must be trivially copyable.");
77static_assert(sizeof(SaveDataMetaInfo) == 0x10, "SaveDataMetaInfo has invalid size.");
78
79struct 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};
89static_assert(std::is_trivially_copyable_v<SaveDataCreationInfo>,
90 "Data type must be trivially copyable.");
91static_assert(sizeof(SaveDataCreationInfo) == 0x40, "SaveDataCreationInfo has invalid size.");
92
93struct 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};
133static_assert(sizeof(SaveDataAttribute) == 0x40);
134static_assert(std::is_trivially_destructible<SaveDataAttribute>::value);
135
136constexpr 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
141constexpr 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
147constexpr inline bool operator!=(const SaveDataAttribute& lhs, const SaveDataAttribute& rhs) {
148 return !(lhs == rhs);
149}
150
151struct 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};
162static_assert(sizeof(SaveDataExtraData) == 0x200, "SaveDataExtraData has invalid size.");
163static_assert(std::is_trivially_copyable_v<SaveDataExtraData>,
164 "Data type must be trivially copyable.");
165
166struct HashSalt {
167 static constexpr size_t Size = 32;
168
169 std::array<u8, Size> value;
170};
171static_assert(std::is_trivially_copyable_v<HashSalt>, "Data type must be trivially copyable.");
172static_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
15namespace { 15namespace {
16 16
17void 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
54bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataAttribute& attr) { 17bool 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
61std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u64 title_id, 24std::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
93std::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
100SaveDataFactory::SaveDataFactory(Core::System& system_, ProgramId program_id_, 56SaveDataFactory::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_,
108SaveDataFactory::~SaveDataFactory() = default; 64SaveDataFactory::~SaveDataFactory() = default;
109 65
110VirtualDir SaveDataFactory::Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const { 66VirtualDir 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
119VirtualDir SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataAttribute& meta) const { 73VirtualDir 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
137std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) { 91std::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)
202SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, 156SaveDataSize 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,
221void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, 175void 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
17namespace FileSys { 18namespace FileSys {
18 19
19enum 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
29enum 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
39enum class SaveDataRank : u8 {
40 Primary = 0,
41 Secondary = 1,
42};
43
44enum 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
52struct 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};
66static_assert(sizeof(SaveDataAttribute) == 0x40, "SaveDataAttribute has incorrect size.");
67
68struct 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};
79static_assert(sizeof(SaveDataExtraData) == 0x200, "SaveDataExtraData has incorrect size.");
80
81struct SaveDataSize {
82 u64 normal;
83 u64 journal;
84};
85
86constexpr const char* GetSaveDataSizeFileName() { 20constexpr 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
227Result FSP_SRV::CreateSaveDataFileSystem(std::array<u8, 0x40> save_create_struct, 227Result 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
237Result FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId(std::array<u8, 0x40> save_create_struct, 237Result 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
246Result FSP_SRV::OpenSaveDataFileSystem(OutInterface<IFileSystem> out_interface, 246Result 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);