summaryrefslogtreecommitdiff
path: root/src/core/hle/service/filesystem
diff options
context:
space:
mode:
authorGravatar FearlessTobi2024-02-18 23:02:37 +0100
committerGravatar FearlessTobi2024-02-19 19:06:31 +0100
commit380475af32507cf8fd1a42d470667bce8f0b69c7 (patch)
tree2176dc3a293baadfa0c6e95bd66d70c6ecff9df4 /src/core/hle/service/filesystem
parentMerge pull request #13080 from FearlessTobi/scope-exit (diff)
downloadyuzu-380475af32507cf8fd1a42d470667bce8f0b69c7.tar.gz
yuzu-380475af32507cf8fd1a42d470667bce8f0b69c7.tar.xz
yuzu-380475af32507cf8fd1a42d470667bce8f0b69c7.zip
fsp: Move ISaveDataInfoReader to a seperate file
Diffstat (limited to 'src/core/hle/service/filesystem')
-rw-r--r--src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp162
-rw-r--r--src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h48
-rw-r--r--src/core/hle/service/filesystem/fsp/fsp_srv.cpp167
3 files changed, 212 insertions, 165 deletions
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
new file mode 100644
index 000000000..872377d03
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp
@@ -0,0 +1,162 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/hex_util.h"
5#include "core/file_sys/savedata_factory.h"
6#include "core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h"
7#include "core/hle/service/filesystem/save_data_controller.h"
8#include "core/hle/service/ipc_helpers.h"
9
10namespace Service::FileSystem {
11
12ISaveDataInfoReader::ISaveDataInfoReader(Core::System& system_,
13 std::shared_ptr<SaveDataController> save_data_controller_,
14 FileSys::SaveDataSpaceId space)
15 : ServiceFramework{system_, "ISaveDataInfoReader"},
16 save_data_controller{save_data_controller_} {
17 static const FunctionInfo functions[] = {
18 {0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"},
19 };
20 RegisterHandlers(functions);
21
22 FindAllSaves(space);
23}
24
25ISaveDataInfoReader::~ISaveDataInfoReader() = default;
26
27static u64 stoull_be(std::string_view str) {
28 if (str.size() != 16) {
29 return 0;
30 }
31
32 const auto bytes = Common::HexStringToArray<0x8>(str);
33 u64 out{};
34 std::memcpy(&out, bytes.data(), sizeof(u64));
35
36 return Common::swap64(out);
37}
38
39void ISaveDataInfoReader::ReadSaveDataInfo(HLERequestContext& ctx) {
40 LOG_DEBUG(Service_FS, "called");
41
42 // Calculate how many entries we can fit in the output buffer
43 const u64 count_entries = ctx.GetWriteBufferNumElements<SaveDataInfo>();
44
45 // Cap at total number of entries.
46 const u64 actual_entries = std::min(count_entries, info.size() - next_entry_index);
47
48 // Determine data start and end
49 const auto* begin = reinterpret_cast<u8*>(info.data() + next_entry_index);
50 const auto* end = reinterpret_cast<u8*>(info.data() + next_entry_index + actual_entries);
51 const auto range_size = static_cast<std::size_t>(std::distance(begin, end));
52
53 next_entry_index += actual_entries;
54
55 // Write the data to memory
56 ctx.WriteBuffer(begin, range_size);
57
58 IPC::ResponseBuilder rb{ctx, 4};
59 rb.Push(ResultSuccess);
60 rb.Push<u64>(actual_entries);
61}
62
63void ISaveDataInfoReader::FindAllSaves(FileSys::SaveDataSpaceId space) {
64 FileSys::VirtualDir save_root{};
65 const auto result = save_data_controller->OpenSaveDataSpace(&save_root, space);
66
67 if (result != ResultSuccess || save_root == nullptr) {
68 LOG_ERROR(Service_FS, "The save root for the space_id={:02X} was invalid!", space);
69 return;
70 }
71
72 for (const auto& type : save_root->GetSubdirectories()) {
73 if (type->GetName() == "save") {
74 FindNormalSaves(space, type);
75 } else if (space == FileSys::SaveDataSpaceId::TemporaryStorage) {
76 FindTemporaryStorageSaves(space, type);
77 }
78 }
79}
80
81void ISaveDataInfoReader::FindNormalSaves(FileSys::SaveDataSpaceId space,
82 const FileSys::VirtualDir& type) {
83 for (const auto& save_id : type->GetSubdirectories()) {
84 for (const auto& user_id : save_id->GetSubdirectories()) {
85 // Skip non user id subdirectories
86 if (user_id->GetName().size() != 0x20) {
87 continue;
88 }
89
90 const auto save_id_numeric = stoull_be(save_id->GetName());
91 auto user_id_numeric = Common::HexStringToArray<0x10>(user_id->GetName());
92 std::reverse(user_id_numeric.begin(), user_id_numeric.end());
93
94 if (save_id_numeric != 0) {
95 // System Save Data
96 info.emplace_back(SaveDataInfo{
97 0,
98 space,
99 FileSys::SaveDataType::SystemSaveData,
100 {},
101 user_id_numeric,
102 save_id_numeric,
103 0,
104 user_id->GetSize(),
105 {},
106 {},
107 });
108
109 continue;
110 }
111
112 for (const auto& title_id : user_id->GetSubdirectories()) {
113 const auto device = std::all_of(user_id_numeric.begin(), user_id_numeric.end(),
114 [](u8 val) { return val == 0; });
115 info.emplace_back(SaveDataInfo{
116 0,
117 space,
118 device ? FileSys::SaveDataType::DeviceSaveData
119 : FileSys::SaveDataType::SaveData,
120 {},
121 user_id_numeric,
122 save_id_numeric,
123 stoull_be(title_id->GetName()),
124 title_id->GetSize(),
125 {},
126 {},
127 });
128 }
129 }
130 }
131}
132
133void ISaveDataInfoReader::FindTemporaryStorageSaves(FileSys::SaveDataSpaceId space,
134 const FileSys::VirtualDir& type) {
135 for (const auto& user_id : type->GetSubdirectories()) {
136 // Skip non user id subdirectories
137 if (user_id->GetName().size() != 0x20) {
138 continue;
139 }
140 for (const auto& title_id : user_id->GetSubdirectories()) {
141 if (!title_id->GetFiles().empty() || !title_id->GetSubdirectories().empty()) {
142 auto user_id_numeric = Common::HexStringToArray<0x10>(user_id->GetName());
143 std::reverse(user_id_numeric.begin(), user_id_numeric.end());
144
145 info.emplace_back(SaveDataInfo{
146 0,
147 space,
148 FileSys::SaveDataType::TemporaryStorage,
149 {},
150 user_id_numeric,
151 stoull_be(type->GetName()),
152 stoull_be(title_id->GetName()),
153 title_id->GetSize(),
154 {},
155 {},
156 });
157 }
158 }
159 }
160}
161
162} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h b/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h
new file mode 100644
index 000000000..86e09973b
--- /dev/null
+++ b/src/core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h
@@ -0,0 +1,48 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <vector>
7#include "common/common_types.h"
8#include "core/hle/service/service.h"
9
10namespace Service::FileSystem {
11
12class SaveDataController;
13
14class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> {
15public:
16 explicit ISaveDataInfoReader(Core::System& system_,
17 std::shared_ptr<SaveDataController> save_data_controller_,
18 FileSys::SaveDataSpaceId space);
19 ~ISaveDataInfoReader() override;
20
21 void ReadSaveDataInfo(HLERequestContext& ctx);
22
23private:
24 void FindAllSaves(FileSys::SaveDataSpaceId space);
25 void FindNormalSaves(FileSys::SaveDataSpaceId space, const FileSys::VirtualDir& type);
26 void FindTemporaryStorageSaves(FileSys::SaveDataSpaceId space, const FileSys::VirtualDir& type);
27
28 struct SaveDataInfo {
29 u64_le save_id_unknown;
30 FileSys::SaveDataSpaceId space;
31 FileSys::SaveDataType type;
32 INSERT_PADDING_BYTES_NOINIT(0x6);
33 std::array<u8, 0x10> user_id;
34 u64_le save_id;
35 u64_le title_id;
36 u64_le save_image_size;
37 u16_le index;
38 FileSys::SaveDataRank rank;
39 INSERT_PADDING_BYTES_NOINIT(0x25);
40 };
41 static_assert(sizeof(SaveDataInfo) == 0x60, "SaveDataInfo has incorrect size.");
42
43 std::shared_ptr<SaveDataController> save_data_controller;
44 std::vector<SaveDataInfo> info;
45 u64 next_entry_index = 0;
46};
47
48} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp
index 2d49f30c8..8664ead29 100644
--- a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp
@@ -29,6 +29,7 @@
29#include "core/hle/result.h" 29#include "core/hle/result.h"
30#include "core/hle/service/filesystem/filesystem.h" 30#include "core/hle/service/filesystem/filesystem.h"
31#include "core/hle/service/filesystem/fsp/fs_i_filesystem.h" 31#include "core/hle/service/filesystem/fsp/fs_i_filesystem.h"
32#include "core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h"
32#include "core/hle/service/filesystem/fsp/fs_i_storage.h" 33#include "core/hle/service/filesystem/fsp/fs_i_storage.h"
33#include "core/hle/service/filesystem/fsp/fsp_srv.h" 34#include "core/hle/service/filesystem/fsp/fsp_srv.h"
34#include "core/hle/service/filesystem/romfs_controller.h" 35#include "core/hle/service/filesystem/romfs_controller.h"
@@ -39,6 +40,7 @@
39#include "core/reporter.h" 40#include "core/reporter.h"
40 41
41namespace Service::FileSystem { 42namespace Service::FileSystem {
43
42enum class FileSystemProxyType : u8 { 44enum class FileSystemProxyType : u8 {
43 Code = 0, 45 Code = 0,
44 Rom = 1, 46 Rom = 1,
@@ -51,171 +53,6 @@ enum class FileSystemProxyType : u8 {
51 RegisteredUpdate = 8, 53 RegisteredUpdate = 8,
52}; 54};
53 55
54class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> {
55public:
56 explicit ISaveDataInfoReader(Core::System& system_,
57 std::shared_ptr<SaveDataController> save_data_controller_,
58 FileSys::SaveDataSpaceId space)
59 : ServiceFramework{system_, "ISaveDataInfoReader"}, save_data_controller{
60 save_data_controller_} {
61 static const FunctionInfo functions[] = {
62 {0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"},
63 };
64 RegisterHandlers(functions);
65
66 FindAllSaves(space);
67 }
68
69 void ReadSaveDataInfo(HLERequestContext& ctx) {
70 LOG_DEBUG(Service_FS, "called");
71
72 // Calculate how many entries we can fit in the output buffer
73 const u64 count_entries = ctx.GetWriteBufferNumElements<SaveDataInfo>();
74
75 // Cap at total number of entries.
76 const u64 actual_entries = std::min(count_entries, info.size() - next_entry_index);
77
78 // Determine data start and end
79 const auto* begin = reinterpret_cast<u8*>(info.data() + next_entry_index);
80 const auto* end = reinterpret_cast<u8*>(info.data() + next_entry_index + actual_entries);
81 const auto range_size = static_cast<std::size_t>(std::distance(begin, end));
82
83 next_entry_index += actual_entries;
84
85 // Write the data to memory
86 ctx.WriteBuffer(begin, range_size);
87
88 IPC::ResponseBuilder rb{ctx, 4};
89 rb.Push(ResultSuccess);
90 rb.Push<u64>(actual_entries);
91 }
92
93private:
94 static u64 stoull_be(std::string_view str) {
95 if (str.size() != 16)
96 return 0;
97
98 const auto bytes = Common::HexStringToArray<0x8>(str);
99 u64 out{};
100 std::memcpy(&out, bytes.data(), sizeof(u64));
101
102 return Common::swap64(out);
103 }
104
105 void FindAllSaves(FileSys::SaveDataSpaceId space) {
106 FileSys::VirtualDir save_root{};
107 const auto result = save_data_controller->OpenSaveDataSpace(&save_root, space);
108
109 if (result != ResultSuccess || save_root == nullptr) {
110 LOG_ERROR(Service_FS, "The save root for the space_id={:02X} was invalid!", space);
111 return;
112 }
113
114 for (const auto& type : save_root->GetSubdirectories()) {
115 if (type->GetName() == "save") {
116 for (const auto& save_id : type->GetSubdirectories()) {
117 for (const auto& user_id : save_id->GetSubdirectories()) {
118 // Skip non user id subdirectories
119 if (user_id->GetName().size() != 0x20) {
120 continue;
121 }
122
123 const auto save_id_numeric = stoull_be(save_id->GetName());
124 auto user_id_numeric = Common::HexStringToArray<0x10>(user_id->GetName());
125 std::reverse(user_id_numeric.begin(), user_id_numeric.end());
126
127 if (save_id_numeric != 0) {
128 // System Save Data
129 info.emplace_back(SaveDataInfo{
130 0,
131 space,
132 FileSys::SaveDataType::SystemSaveData,
133 {},
134 user_id_numeric,
135 save_id_numeric,
136 0,
137 user_id->GetSize(),
138 {},
139 {},
140 });
141
142 continue;
143 }
144
145 for (const auto& title_id : user_id->GetSubdirectories()) {
146 const auto device =
147 std::all_of(user_id_numeric.begin(), user_id_numeric.end(),
148 [](u8 val) { return val == 0; });
149 info.emplace_back(SaveDataInfo{
150 0,
151 space,
152 device ? FileSys::SaveDataType::DeviceSaveData
153 : FileSys::SaveDataType::SaveData,
154 {},
155 user_id_numeric,
156 save_id_numeric,
157 stoull_be(title_id->GetName()),
158 title_id->GetSize(),
159 {},
160 {},
161 });
162 }
163 }
164 }
165 } else if (space == FileSys::SaveDataSpaceId::TemporaryStorage) {
166 // Temporary Storage
167 for (const auto& user_id : type->GetSubdirectories()) {
168 // Skip non user id subdirectories
169 if (user_id->GetName().size() != 0x20) {
170 continue;
171 }
172 for (const auto& title_id : user_id->GetSubdirectories()) {
173 if (!title_id->GetFiles().empty() ||
174 !title_id->GetSubdirectories().empty()) {
175 auto user_id_numeric =
176 Common::HexStringToArray<0x10>(user_id->GetName());
177 std::reverse(user_id_numeric.begin(), user_id_numeric.end());
178
179 info.emplace_back(SaveDataInfo{
180 0,
181 space,
182 FileSys::SaveDataType::TemporaryStorage,
183 {},
184 user_id_numeric,
185 stoull_be(type->GetName()),
186 stoull_be(title_id->GetName()),
187 title_id->GetSize(),
188 {},
189 {},
190 });
191 }
192 }
193 }
194 }
195 }
196 }
197
198 struct SaveDataInfo {
199 u64_le save_id_unknown;
200 FileSys::SaveDataSpaceId space;
201 FileSys::SaveDataType type;
202 INSERT_PADDING_BYTES(0x6);
203 std::array<u8, 0x10> user_id;
204 u64_le save_id;
205 u64_le title_id;
206 u64_le save_image_size;
207 u16_le index;
208 FileSys::SaveDataRank rank;
209 INSERT_PADDING_BYTES(0x25);
210 };
211 static_assert(sizeof(SaveDataInfo) == 0x60, "SaveDataInfo has incorrect size.");
212
213 ProcessId process_id = 0;
214 std::shared_ptr<SaveDataController> save_data_controller;
215 std::vector<SaveDataInfo> info;
216 u64 next_entry_index = 0;
217};
218
219FSP_SRV::FSP_SRV(Core::System& system_) 56FSP_SRV::FSP_SRV(Core::System& system_)
220 : ServiceFramework{system_, "fsp-srv"}, fsc{system.GetFileSystemController()}, 57 : ServiceFramework{system_, "fsp-srv"}, fsc{system.GetFileSystemController()},
221 content_provider{system.GetContentProvider()}, reporter{system.GetReporter()} { 58 content_provider{system.GetContentProvider()}, reporter{system.GetReporter()} {