summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/am/applets/applet_mii_edit.cpp2
-rw-r--r--src/core/hle/service/mii/mii.cpp563
-rw-r--r--src/core/hle/service/mii/mii.h15
-rw-r--r--src/core/hle/service/set/system_settings_server.cpp3
4 files changed, 171 insertions, 412 deletions
diff --git a/src/core/hle/service/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp
index 50adc7c02..e83e931c5 100644
--- a/src/core/hle/service/am/applets/applet_mii_edit.cpp
+++ b/src/core/hle/service/am/applets/applet_mii_edit.cpp
@@ -59,7 +59,7 @@ void MiiEdit::Initialize() {
59 break; 59 break;
60 } 60 }
61 61
62 manager = system.ServiceManager().GetService<Mii::MiiDBModule>("mii:e")->GetMiiManager(); 62 manager = system.ServiceManager().GetService<Mii::IStaticService>("mii:e")->GetMiiManager();
63 if (manager == nullptr) { 63 if (manager == nullptr) {
64 manager = std::make_shared<Mii::MiiManager>(); 64 manager = std::make_shared<Mii::MiiManager>();
65 } 65 }
diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp
index c28eed926..b4d16fed5 100644
--- a/src/core/hle/service/mii/mii.cpp
+++ b/src/core/hle/service/mii/mii.cpp
@@ -4,15 +4,18 @@
4#include <memory> 4#include <memory>
5 5
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/hle/service/cmif_serialization.h"
7#include "core/hle/service/ipc_helpers.h" 8#include "core/hle/service/ipc_helpers.h"
8#include "core/hle/service/mii/mii.h" 9#include "core/hle/service/mii/mii.h"
9#include "core/hle/service/mii/mii_manager.h" 10#include "core/hle/service/mii/mii_manager.h"
10#include "core/hle/service/mii/mii_result.h" 11#include "core/hle/service/mii/mii_result.h"
11#include "core/hle/service/mii/types/char_info.h" 12#include "core/hle/service/mii/types/char_info.h"
13#include "core/hle/service/mii/types/raw_data.h"
12#include "core/hle/service/mii/types/store_data.h" 14#include "core/hle/service/mii/types/store_data.h"
13#include "core/hle/service/mii/types/ver3_store_data.h" 15#include "core/hle/service/mii/types/ver3_store_data.h"
14#include "core/hle/service/server_manager.h" 16#include "core/hle/service/server_manager.h"
15#include "core/hle/service/service.h" 17#include "core/hle/service/set/system_settings_server.h"
18#include "core/hle/service/sm/sm.h"
16 19
17namespace Service::Mii { 20namespace Service::Mii {
18 21
@@ -24,549 +27,302 @@ public:
24 is_system_} { 27 is_system_} {
25 // clang-format off 28 // clang-format off
26 static const FunctionInfo functions[] = { 29 static const FunctionInfo functions[] = {
27 {0, &IDatabaseService::IsUpdated, "IsUpdated"}, 30 {0, D<&IDatabaseService::IsUpdated>, "IsUpdated"},
28 {1, &IDatabaseService::IsFullDatabase, "IsFullDatabase"}, 31 {1, D<&IDatabaseService::IsFullDatabase>, "IsFullDatabase"},
29 {2, &IDatabaseService::GetCount, "GetCount"}, 32 {2, D<&IDatabaseService::GetCount>, "GetCount"},
30 {3, &IDatabaseService::Get, "Get"}, 33 {3, D<&IDatabaseService::Get>, "Get"},
31 {4, &IDatabaseService::Get1, "Get1"}, 34 {4, D<&IDatabaseService::Get1>, "Get1"},
32 {5, &IDatabaseService::UpdateLatest, "UpdateLatest"}, 35 {5, D<&IDatabaseService::UpdateLatest>, "UpdateLatest"},
33 {6, &IDatabaseService::BuildRandom, "BuildRandom"}, 36 {6, D<&IDatabaseService::BuildRandom>, "BuildRandom"},
34 {7, &IDatabaseService::BuildDefault, "BuildDefault"}, 37 {7, D<&IDatabaseService::BuildDefault>, "BuildDefault"},
35 {8, &IDatabaseService::Get2, "Get2"}, 38 {8, D<&IDatabaseService::Get2>, "Get2"},
36 {9, &IDatabaseService::Get3, "Get3"}, 39 {9, D<&IDatabaseService::Get3>, "Get3"},
37 {10, &IDatabaseService::UpdateLatest1, "UpdateLatest1"}, 40 {10, D<&IDatabaseService::UpdateLatest1>, "UpdateLatest1"},
38 {11, &IDatabaseService::FindIndex, "FindIndex"}, 41 {11, D<&IDatabaseService::FindIndex>, "FindIndex"},
39 {12, &IDatabaseService::Move, "Move"}, 42 {12, D<&IDatabaseService::Move>, "Move"},
40 {13, &IDatabaseService::AddOrReplace, "AddOrReplace"}, 43 {13, D<&IDatabaseService::AddOrReplace>, "AddOrReplace"},
41 {14, &IDatabaseService::Delete, "Delete"}, 44 {14, D<&IDatabaseService::Delete>, "Delete"},
42 {15, &IDatabaseService::DestroyFile, "DestroyFile"}, 45 {15, D<&IDatabaseService::DestroyFile>, "DestroyFile"},
43 {16, &IDatabaseService::DeleteFile, "DeleteFile"}, 46 {16, D<&IDatabaseService::DeleteFile>, "DeleteFile"},
44 {17, &IDatabaseService::Format, "Format"}, 47 {17, D<&IDatabaseService::Format>, "Format"},
45 {18, nullptr, "Import"}, 48 {18, nullptr, "Import"},
46 {19, nullptr, "Export"}, 49 {19, nullptr, "Export"},
47 {20, &IDatabaseService::IsBrokenDatabaseWithClearFlag, "IsBrokenDatabaseWithClearFlag"}, 50 {20, D<&IDatabaseService::IsBrokenDatabaseWithClearFlag>, "IsBrokenDatabaseWithClearFlag"},
48 {21, &IDatabaseService::GetIndex, "GetIndex"}, 51 {21, D<&IDatabaseService::GetIndex>, "GetIndex"},
49 {22, &IDatabaseService::SetInterfaceVersion, "SetInterfaceVersion"}, 52 {22, D<&IDatabaseService::SetInterfaceVersion>, "SetInterfaceVersion"},
50 {23, &IDatabaseService::Convert, "Convert"}, 53 {23, D<&IDatabaseService::Convert>, "Convert"},
51 {24, &IDatabaseService::ConvertCoreDataToCharInfo, "ConvertCoreDataToCharInfo"}, 54 {24, D<&IDatabaseService::ConvertCoreDataToCharInfo>, "ConvertCoreDataToCharInfo"},
52 {25, &IDatabaseService::ConvertCharInfoToCoreData, "ConvertCharInfoToCoreData"}, 55 {25, D<&IDatabaseService::ConvertCharInfoToCoreData>, "ConvertCharInfoToCoreData"},
53 {26, &IDatabaseService::Append, "Append"}, 56 {26, D<&IDatabaseService::Append>, "Append"},
54 }; 57 };
55 // clang-format on 58 // clang-format on
56 59
57 RegisterHandlers(functions); 60 RegisterHandlers(functions);
58 61
62 m_set_sys = system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>(
63 "set:sys", true);
59 manager->Initialize(metadata); 64 manager->Initialize(metadata);
60 } 65 }
61 66
62private: 67private:
63 void IsUpdated(HLERequestContext& ctx) { 68 Result IsUpdated(Out<bool> out_is_updated, SourceFlag source_flag) {
64 IPC::RequestParser rp{ctx};
65 const auto source_flag{rp.PopRaw<SourceFlag>()};
66
67 LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag); 69 LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag);
68 70
69 const bool is_updated = manager->IsUpdated(metadata, source_flag); 71 *out_is_updated = manager->IsUpdated(metadata, source_flag);
70 72
71 IPC::ResponseBuilder rb{ctx, 3}; 73 R_SUCCEED();
72 rb.Push(ResultSuccess);
73 rb.Push<u8>(is_updated);
74 } 74 }
75 75
76 void IsFullDatabase(HLERequestContext& ctx) { 76 Result IsFullDatabase(Out<bool> out_is_full_database) {
77 LOG_DEBUG(Service_Mii, "called"); 77 LOG_DEBUG(Service_Mii, "called");
78 78
79 const bool is_full_database = manager->IsFullDatabase(); 79 *out_is_full_database = manager->IsFullDatabase();
80 80
81 IPC::ResponseBuilder rb{ctx, 3}; 81 R_SUCCEED();
82 rb.Push(ResultSuccess);
83 rb.Push<u8>(is_full_database);
84 } 82 }
85 83
86 void GetCount(HLERequestContext& ctx) { 84 Result GetCount(Out<u32> out_mii_count, SourceFlag source_flag) {
87 IPC::RequestParser rp{ctx}; 85 *out_mii_count = manager->GetCount(metadata, source_flag);
88 const auto source_flag{rp.PopRaw<SourceFlag>()};
89
90 const u32 mii_count = manager->GetCount(metadata, source_flag);
91 86
92 LOG_DEBUG(Service_Mii, "called with source_flag={}, mii_count={}", source_flag, mii_count); 87 LOG_DEBUG(Service_Mii, "called with source_flag={}, mii_count={}", source_flag,
88 *out_mii_count);
93 89
94 IPC::ResponseBuilder rb{ctx, 3}; 90 R_SUCCEED();
95 rb.Push(ResultSuccess);
96 rb.Push(mii_count);
97 } 91 }
98 92
99 void Get(HLERequestContext& ctx) { 93 Result Get(Out<u32> out_mii_count, SourceFlag source_flag,
100 IPC::RequestParser rp{ctx}; 94 OutArray<CharInfoElement, BufferAttr_HipcMapAlias> char_info_element_buffer) {
101 const auto source_flag{rp.PopRaw<SourceFlag>()}; 95 const auto result =
102 const auto output_size{ctx.GetWriteBufferNumElements<CharInfoElement>()}; 96 manager->Get(metadata, char_info_element_buffer, *out_mii_count, source_flag);
103
104 u32 mii_count{};
105 std::vector<CharInfoElement> char_info_elements(output_size);
106 const auto result = manager->Get(metadata, char_info_elements, mii_count, source_flag);
107
108 if (mii_count != 0) {
109 ctx.WriteBuffer(char_info_elements);
110 }
111 97
112 LOG_INFO(Service_Mii, "called with source_flag={}, out_size={}, mii_count={}", source_flag, 98 LOG_INFO(Service_Mii, "called with source_flag={}, mii_count={}", source_flag,
113 output_size, mii_count); 99 *out_mii_count);
114 100
115 IPC::ResponseBuilder rb{ctx, 3}; 101 R_RETURN(result);
116 rb.Push(result);
117 rb.Push(mii_count);
118 } 102 }
119 103
120 void Get1(HLERequestContext& ctx) { 104 Result Get1(Out<u32> out_mii_count, SourceFlag source_flag,
121 IPC::RequestParser rp{ctx}; 105 OutArray<CharInfo, BufferAttr_HipcMapAlias> char_info_buffer) {
122 const auto source_flag{rp.PopRaw<SourceFlag>()}; 106 const auto result = manager->Get(metadata, char_info_buffer, *out_mii_count, source_flag);
123 const auto output_size{ctx.GetWriteBufferNumElements<CharInfo>()};
124 107
125 u32 mii_count{}; 108 LOG_INFO(Service_Mii, "called with source_flag={}, mii_count={}", source_flag,
126 std::vector<CharInfo> char_info(output_size); 109 *out_mii_count);
127 const auto result = manager->Get(metadata, char_info, mii_count, source_flag);
128 110
129 if (mii_count != 0) { 111 R_RETURN(result);
130 ctx.WriteBuffer(char_info);
131 }
132
133 LOG_INFO(Service_Mii, "called with source_flag={}, out_size={}, mii_count={}", source_flag,
134 output_size, mii_count);
135
136 IPC::ResponseBuilder rb{ctx, 3};
137 rb.Push(result);
138 rb.Push(mii_count);
139 } 112 }
140 113
141 void UpdateLatest(HLERequestContext& ctx) { 114 Result UpdateLatest(Out<CharInfo> out_char_info, CharInfo& char_info, SourceFlag source_flag) {
142 IPC::RequestParser rp{ctx};
143 const auto char_info{rp.PopRaw<CharInfo>()};
144 const auto source_flag{rp.PopRaw<SourceFlag>()};
145
146 LOG_INFO(Service_Mii, "called with source_flag={}", source_flag); 115 LOG_INFO(Service_Mii, "called with source_flag={}", source_flag);
147 116
148 CharInfo new_char_info{}; 117 R_RETURN(manager->UpdateLatest(metadata, *out_char_info, char_info, source_flag));
149 const auto result = manager->UpdateLatest(metadata, new_char_info, char_info, source_flag);
150 if (result.IsFailure()) {
151 IPC::ResponseBuilder rb{ctx, 2};
152 rb.Push(result);
153 return;
154 }
155
156 IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)};
157 rb.Push(ResultSuccess);
158 rb.PushRaw(new_char_info);
159 } 118 }
160 119
161 void BuildRandom(HLERequestContext& ctx) { 120 Result BuildRandom(Out<CharInfo> out_char_info, Age age, Gender gender, Race race) {
162 IPC::RequestParser rp{ctx};
163 const auto age{rp.PopRaw<Age>()};
164 const auto gender{rp.PopRaw<Gender>()};
165 const auto race{rp.PopRaw<Race>()};
166
167 LOG_DEBUG(Service_Mii, "called with age={}, gender={}, race={}", age, gender, race); 121 LOG_DEBUG(Service_Mii, "called with age={}, gender={}, race={}", age, gender, race);
168 122
169 if (age > Age::All) { 123 R_UNLESS(age <= Age::All, ResultInvalidArgument);
170 IPC::ResponseBuilder rb{ctx, 2}; 124 R_UNLESS(gender <= Gender::All, ResultInvalidArgument);
171 rb.Push(ResultInvalidArgument); 125 R_UNLESS(race <= Race::All, ResultInvalidArgument);
172 return;
173 }
174
175 if (gender > Gender::All) {
176 IPC::ResponseBuilder rb{ctx, 2};
177 rb.Push(ResultInvalidArgument);
178 return;
179 }
180
181 if (race > Race::All) {
182 IPC::ResponseBuilder rb{ctx, 2};
183 rb.Push(ResultInvalidArgument);
184 return;
185 }
186
187 CharInfo char_info{};
188 manager->BuildRandom(char_info, age, gender, race);
189
190 IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)};
191 rb.Push(ResultSuccess);
192 rb.PushRaw(char_info);
193 }
194 126
195 void BuildDefault(HLERequestContext& ctx) { 127 manager->BuildRandom(*out_char_info, age, gender, race);
196 IPC::RequestParser rp{ctx};
197 const auto index{rp.Pop<u32>()};
198 128
199 LOG_DEBUG(Service_Mii, "called with index={}", index); 129 R_SUCCEED();
130 }
200 131
201 if (index > 5) { 132 Result BuildDefault(Out<CharInfo> out_char_info, s32 index) {
202 IPC::ResponseBuilder rb{ctx, 2}; 133 LOG_DEBUG(Service_Mii, "called with index={}", index);
203 rb.Push(ResultInvalidArgument); 134 R_UNLESS(index < static_cast<s32>(RawData::DefaultMii.size()), ResultInvalidArgument);
204 return;
205 }
206 135
207 CharInfo char_info{}; 136 manager->BuildDefault(*out_char_info, index);
208 manager->BuildDefault(char_info, index);
209 137
210 IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)}; 138 R_SUCCEED();
211 rb.Push(ResultSuccess);
212 rb.PushRaw(char_info);
213 } 139 }
214 140
215 void Get2(HLERequestContext& ctx) { 141 Result Get2(Out<u32> out_mii_count, SourceFlag source_flag,
216 IPC::RequestParser rp{ctx}; 142 OutArray<StoreDataElement, BufferAttr_HipcMapAlias> store_data_element_buffer) {
217 const auto source_flag{rp.PopRaw<SourceFlag>()}; 143 const auto result =
218 const auto output_size{ctx.GetWriteBufferNumElements<StoreDataElement>()}; 144 manager->Get(metadata, store_data_element_buffer, *out_mii_count, source_flag);
219 145
220 u32 mii_count{}; 146 LOG_INFO(Service_Mii, "called with source_flag={}, mii_count={}", source_flag,
221 std::vector<StoreDataElement> store_data_elements(output_size); 147 *out_mii_count);
222 const auto result = manager->Get(metadata, store_data_elements, mii_count, source_flag);
223 148
224 if (mii_count != 0) { 149 R_RETURN(result);
225 ctx.WriteBuffer(store_data_elements);
226 }
227
228 LOG_INFO(Service_Mii, "called with source_flag={}, out_size={}, mii_count={}", source_flag,
229 output_size, mii_count);
230
231 IPC::ResponseBuilder rb{ctx, 3};
232 rb.Push(result);
233 rb.Push(mii_count);
234 } 150 }
235 151
236 void Get3(HLERequestContext& ctx) { 152 Result Get3(Out<u32> out_mii_count, SourceFlag source_flag,
237 IPC::RequestParser rp{ctx}; 153 OutArray<StoreData, BufferAttr_HipcMapAlias> store_data_buffer) {
238 const auto source_flag{rp.PopRaw<SourceFlag>()}; 154 const auto result = manager->Get(metadata, store_data_buffer, *out_mii_count, source_flag);
239 const auto output_size{ctx.GetWriteBufferNumElements<StoreData>()};
240
241 u32 mii_count{};
242 std::vector<StoreData> store_data(output_size);
243 const auto result = manager->Get(metadata, store_data, mii_count, source_flag);
244 155
245 if (mii_count != 0) { 156 LOG_INFO(Service_Mii, "called with source_flag={}, mii_count={}", source_flag,
246 ctx.WriteBuffer(store_data); 157 *out_mii_count);
247 }
248 158
249 LOG_INFO(Service_Mii, "called with source_flag={}, out_size={}, mii_count={}", source_flag, 159 R_RETURN(result);
250 output_size, mii_count);
251
252 IPC::ResponseBuilder rb{ctx, 3};
253 rb.Push(result);
254 rb.Push(mii_count);
255 } 160 }
256 161
257 void UpdateLatest1(HLERequestContext& ctx) { 162 Result UpdateLatest1(Out<StoreData> out_store_data, StoreData& store_data,
258 IPC::RequestParser rp{ctx}; 163 SourceFlag source_flag) {
259 const auto store_data{rp.PopRaw<StoreData>()};
260 const auto source_flag{rp.PopRaw<SourceFlag>()};
261
262 LOG_INFO(Service_Mii, "called with source_flag={}", source_flag); 164 LOG_INFO(Service_Mii, "called with source_flag={}", source_flag);
165 R_UNLESS(is_system, ResultPermissionDenied);
263 166
264 Result result = ResultSuccess; 167 R_RETURN(manager->UpdateLatest(metadata, *out_store_data, store_data, source_flag));
265 if (!is_system) {
266 result = ResultPermissionDenied;
267 }
268
269 StoreData new_store_data{};
270 if (result.IsSuccess()) {
271 result = manager->UpdateLatest(metadata, new_store_data, store_data, source_flag);
272 }
273
274 if (result.IsFailure()) {
275 IPC::ResponseBuilder rb{ctx, 2};
276 rb.Push(result);
277 return;
278 }
279
280 IPC::ResponseBuilder rb{ctx, 2 + sizeof(StoreData) / sizeof(u32)};
281 rb.Push(ResultSuccess);
282 rb.PushRaw<StoreData>(new_store_data);
283 } 168 }
284 169
285 void FindIndex(HLERequestContext& ctx) { 170 Result FindIndex(Out<s32> out_index, Common::UUID create_id, bool is_special) {
286 IPC::RequestParser rp{ctx};
287 const auto create_id{rp.PopRaw<Common::UUID>()};
288 const auto is_special{rp.PopRaw<bool>()};
289
290 LOG_INFO(Service_Mii, "called with create_id={}, is_special={}", 171 LOG_INFO(Service_Mii, "called with create_id={}, is_special={}",
291 create_id.FormattedString(), is_special); 172 create_id.FormattedString(), is_special);
292 173
293 const s32 index = manager->FindIndex(create_id, is_special); 174 *out_index = manager->FindIndex(create_id, is_special);
294 175
295 IPC::ResponseBuilder rb{ctx, 3}; 176 R_SUCCEED();
296 rb.Push(ResultSuccess);
297 rb.Push(index);
298 } 177 }
299 178
300 void Move(HLERequestContext& ctx) { 179 Result Move(Common::UUID create_id, s32 new_index) {
301 IPC::RequestParser rp{ctx};
302 const auto create_id{rp.PopRaw<Common::UUID>()};
303 const auto new_index{rp.PopRaw<s32>()};
304
305 LOG_INFO(Service_Mii, "called with create_id={}, new_index={}", create_id.FormattedString(), 180 LOG_INFO(Service_Mii, "called with create_id={}, new_index={}", create_id.FormattedString(),
306 new_index); 181 new_index);
182 R_UNLESS(is_system, ResultPermissionDenied);
307 183
308 Result result = ResultSuccess; 184 const u32 count = manager->GetCount(metadata, SourceFlag::Database);
309 if (!is_system) {
310 result = ResultPermissionDenied;
311 }
312 185
313 if (result.IsSuccess()) { 186 R_UNLESS(new_index >= 0 && new_index < static_cast<s32>(count), ResultInvalidArgument);
314 const u32 count = manager->GetCount(metadata, SourceFlag::Database);
315 if (new_index < 0 || new_index >= static_cast<s32>(count)) {
316 result = ResultInvalidArgument;
317 }
318 }
319 187
320 if (result.IsSuccess()) { 188 R_RETURN(manager->Move(metadata, new_index, create_id));
321 result = manager->Move(metadata, new_index, create_id);
322 }
323
324 IPC::ResponseBuilder rb{ctx, 2};
325 rb.Push(result);
326 } 189 }
327 190
328 void AddOrReplace(HLERequestContext& ctx) { 191 Result AddOrReplace(StoreData& store_data) {
329 IPC::RequestParser rp{ctx};
330 const auto store_data{rp.PopRaw<StoreData>()};
331
332 LOG_INFO(Service_Mii, "called"); 192 LOG_INFO(Service_Mii, "called");
193 R_UNLESS(is_system, ResultPermissionDenied);
333 194
334 Result result = ResultSuccess; 195 const auto result = manager->AddOrReplace(metadata, store_data);
335
336 if (!is_system) {
337 result = ResultPermissionDenied;
338 }
339 196
340 if (result.IsSuccess()) { 197 R_RETURN(result);
341 result = manager->AddOrReplace(metadata, store_data);
342 }
343
344 IPC::ResponseBuilder rb{ctx, 2};
345 rb.Push(result);
346 } 198 }
347 199
348 void Delete(HLERequestContext& ctx) { 200 Result Delete(Common::UUID create_id) {
349 IPC::RequestParser rp{ctx};
350 const auto create_id{rp.PopRaw<Common::UUID>()};
351
352 LOG_INFO(Service_Mii, "called, create_id={}", create_id.FormattedString()); 201 LOG_INFO(Service_Mii, "called, create_id={}", create_id.FormattedString());
202 R_UNLESS(is_system, ResultPermissionDenied);
353 203
354 Result result = ResultSuccess; 204 R_RETURN(manager->Delete(metadata, create_id));
355
356 if (!is_system) {
357 result = ResultPermissionDenied;
358 }
359
360 if (result.IsSuccess()) {
361 result = manager->Delete(metadata, create_id);
362 }
363
364 IPC::ResponseBuilder rb{ctx, 2};
365 rb.Push(result);
366 } 205 }
367 206
368 void DestroyFile(HLERequestContext& ctx) { 207 Result DestroyFile() {
369 // This calls nn::settings::fwdbg::GetSettingsItemValue("is_db_test_mode_enabled"); 208 bool is_db_test_mode_enabled{};
370 const bool is_db_test_mode_enabled = false; 209 m_set_sys->GetSettingsItemValue(is_db_test_mode_enabled, "mii", "is_db_test_mode_enabled");
371 210
372 LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled); 211 LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled);
212 R_UNLESS(is_db_test_mode_enabled, ResultTestModeOnly);
373 213
374 Result result = ResultSuccess; 214 R_RETURN(manager->DestroyFile(metadata));
375
376 if (!is_db_test_mode_enabled) {
377 result = ResultTestModeOnly;
378 }
379
380 if (result.IsSuccess()) {
381 result = manager->DestroyFile(metadata);
382 }
383
384 IPC::ResponseBuilder rb{ctx, 2};
385 rb.Push(result);
386 } 215 }
387 216
388 void DeleteFile(HLERequestContext& ctx) { 217 Result DeleteFile() {
389 // This calls nn::settings::fwdbg::GetSettingsItemValue("is_db_test_mode_enabled"); 218 bool is_db_test_mode_enabled{};
390 const bool is_db_test_mode_enabled = false; 219 m_set_sys->GetSettingsItemValue(is_db_test_mode_enabled, "mii", "is_db_test_mode_enabled");
391 220
392 LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled); 221 LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled);
222 R_UNLESS(is_db_test_mode_enabled, ResultTestModeOnly);
393 223
394 Result result = ResultSuccess; 224 R_RETURN(manager->DeleteFile());
395
396 if (!is_db_test_mode_enabled) {
397 result = ResultTestModeOnly;
398 }
399
400 if (result.IsSuccess()) {
401 result = manager->DeleteFile();
402 }
403
404 IPC::ResponseBuilder rb{ctx, 2};
405 rb.Push(result);
406 } 225 }
407 226
408 void Format(HLERequestContext& ctx) { 227 Result Format() {
409 // This calls nn::settings::fwdbg::GetSettingsItemValue("is_db_test_mode_enabled"); 228 bool is_db_test_mode_enabled{};
410 const bool is_db_test_mode_enabled = false; 229 m_set_sys->GetSettingsItemValue(is_db_test_mode_enabled, "mii", "is_db_test_mode_enabled");
411 230
412 LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled); 231 LOG_INFO(Service_Mii, "called is_db_test_mode_enabled={}", is_db_test_mode_enabled);
232 R_UNLESS(is_db_test_mode_enabled, ResultTestModeOnly);
413 233
414 Result result = ResultSuccess; 234 R_RETURN(manager->Format(metadata));
415
416 if (!is_db_test_mode_enabled) {
417 result = ResultTestModeOnly;
418 }
419
420 if (result.IsSuccess()) {
421 result = manager->Format(metadata);
422 }
423
424 IPC::ResponseBuilder rb{ctx, 2};
425 rb.Push(result);
426 } 235 }
427 236
428 void IsBrokenDatabaseWithClearFlag(HLERequestContext& ctx) { 237 Result IsBrokenDatabaseWithClearFlag(Out<bool> out_is_broken_with_clear_flag) {
429 LOG_DEBUG(Service_Mii, "called"); 238 LOG_DEBUG(Service_Mii, "called");
239 R_UNLESS(is_system, ResultPermissionDenied);
430 240
431 bool is_broken_with_clear_flag = false; 241 *out_is_broken_with_clear_flag = manager->IsBrokenWithClearFlag(metadata);
432 Result result = ResultSuccess;
433 242
434 if (!is_system) { 243 R_SUCCEED();
435 result = ResultPermissionDenied;
436 }
437
438 if (result.IsSuccess()) {
439 is_broken_with_clear_flag = manager->IsBrokenWithClearFlag(metadata);
440 }
441
442 IPC::ResponseBuilder rb{ctx, 3};
443 rb.Push(result);
444 rb.Push<u8>(is_broken_with_clear_flag);
445 } 244 }
446 245
447 void GetIndex(HLERequestContext& ctx) { 246 Result GetIndex(Out<s32> out_index, CharInfo& char_info) {
448 IPC::RequestParser rp{ctx};
449 const auto info{rp.PopRaw<CharInfo>()};
450
451 LOG_DEBUG(Service_Mii, "called"); 247 LOG_DEBUG(Service_Mii, "called");
452 248
453 s32 index{}; 249 R_RETURN(manager->GetIndex(metadata, char_info, *out_index));
454 const auto result = manager->GetIndex(metadata, info, index);
455
456 IPC::ResponseBuilder rb{ctx, 3};
457 rb.Push(result);
458 rb.Push(index);
459 } 250 }
460 251
461 void SetInterfaceVersion(HLERequestContext& ctx) { 252 Result SetInterfaceVersion(u32 interface_version) {
462 IPC::RequestParser rp{ctx};
463 const auto interface_version{rp.PopRaw<u32>()};
464
465 LOG_INFO(Service_Mii, "called, interface_version={:08X}", interface_version); 253 LOG_INFO(Service_Mii, "called, interface_version={:08X}", interface_version);
466 254
467 manager->SetInterfaceVersion(metadata, interface_version); 255 manager->SetInterfaceVersion(metadata, interface_version);
468 256
469 IPC::ResponseBuilder rb{ctx, 2}; 257 R_SUCCEED();
470 rb.Push(ResultSuccess);
471 } 258 }
472 259
473 void Convert(HLERequestContext& ctx) { 260 Result Convert(Out<CharInfo> out_char_info, Ver3StoreData& mii_v3) {
474 IPC::RequestParser rp{ctx};
475 const auto mii_v3{rp.PopRaw<Ver3StoreData>()};
476
477 LOG_INFO(Service_Mii, "called"); 261 LOG_INFO(Service_Mii, "called");
478 262
479 CharInfo char_info{}; 263 R_RETURN(manager->ConvertV3ToCharInfo(*out_char_info, mii_v3));
480 const auto result = manager->ConvertV3ToCharInfo(char_info, mii_v3);
481
482 IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)};
483 rb.Push(result);
484 rb.PushRaw<CharInfo>(char_info);
485 } 264 }
486 265
487 void ConvertCoreDataToCharInfo(HLERequestContext& ctx) { 266 Result ConvertCoreDataToCharInfo(Out<CharInfo> out_char_info, CoreData& core_data) {
488 IPC::RequestParser rp{ctx};
489 const auto core_data{rp.PopRaw<CoreData>()};
490
491 LOG_INFO(Service_Mii, "called"); 267 LOG_INFO(Service_Mii, "called");
492 268
493 CharInfo char_info{}; 269 R_RETURN(manager->ConvertCoreDataToCharInfo(*out_char_info, core_data));
494 const auto result = manager->ConvertCoreDataToCharInfo(char_info, core_data);
495
496 IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)};
497 rb.Push(result);
498 rb.PushRaw<CharInfo>(char_info);
499 } 270 }
500 271
501 void ConvertCharInfoToCoreData(HLERequestContext& ctx) { 272 Result ConvertCharInfoToCoreData(Out<CoreData> out_core_data, CharInfo& char_info) {
502 IPC::RequestParser rp{ctx};
503 const auto char_info{rp.PopRaw<CharInfo>()};
504
505 LOG_INFO(Service_Mii, "called"); 273 LOG_INFO(Service_Mii, "called");
506 274
507 CoreData core_data{}; 275 R_RETURN(manager->ConvertCharInfoToCoreData(*out_core_data, char_info));
508 const auto result = manager->ConvertCharInfoToCoreData(core_data, char_info);
509
510 IPC::ResponseBuilder rb{ctx, 2 + sizeof(CoreData) / sizeof(u32)};
511 rb.Push(result);
512 rb.PushRaw<CoreData>(core_data);
513 } 276 }
514 277
515 void Append(HLERequestContext& ctx) { 278 Result Append(CharInfo& char_info) {
516 IPC::RequestParser rp{ctx};
517 const auto char_info{rp.PopRaw<CharInfo>()};
518
519 LOG_INFO(Service_Mii, "called"); 279 LOG_INFO(Service_Mii, "called");
520 280
521 const auto result = manager->Append(metadata, char_info); 281 R_RETURN(manager->Append(metadata, char_info));
522
523 IPC::ResponseBuilder rb{ctx, 2};
524 rb.Push(result);
525 } 282 }
526 283
527 std::shared_ptr<MiiManager> manager = nullptr; 284 std::shared_ptr<MiiManager> manager = nullptr;
528 DatabaseSessionMetadata metadata{}; 285 DatabaseSessionMetadata metadata{};
529 bool is_system{}; 286 bool is_system{};
287
288 std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
530}; 289};
531 290
532MiiDBModule::MiiDBModule(Core::System& system_, const char* name_, 291IStaticService::IStaticService(Core::System& system_, const char* name_,
533 std::shared_ptr<MiiManager> mii_manager, bool is_system_) 292 std::shared_ptr<MiiManager> mii_manager, bool is_system_)
534 : ServiceFramework{system_, name_}, manager{mii_manager}, is_system{is_system_} { 293 : ServiceFramework{system_, name_}, manager{mii_manager}, is_system{is_system_} {
535 // clang-format off 294 // clang-format off
536 static const FunctionInfo functions[] = { 295 static const FunctionInfo functions[] = {
537 {0, &MiiDBModule::GetDatabaseService, "GetDatabaseService"}, 296 {0, D<&IStaticService::GetDatabaseService>, "GetDatabaseService"},
538 }; 297 };
539 // clang-format on 298 // clang-format on
540 299
541 RegisterHandlers(functions); 300 RegisterHandlers(functions);
542
543 if (manager == nullptr) {
544 manager = std::make_shared<MiiManager>();
545 }
546} 301}
547 302
548MiiDBModule::~MiiDBModule() = default; 303IStaticService::~IStaticService() = default;
549
550void MiiDBModule::GetDatabaseService(HLERequestContext& ctx) {
551 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
552 rb.Push(ResultSuccess);
553 rb.PushIpcInterface<IDatabaseService>(system, manager, is_system);
554 304
305Result IStaticService::GetDatabaseService(
306 Out<SharedPointer<IDatabaseService>> out_database_service) {
555 LOG_DEBUG(Service_Mii, "called"); 307 LOG_DEBUG(Service_Mii, "called");
308
309 *out_database_service = std::make_shared<IDatabaseService>(system, manager, is_system);
310
311 R_SUCCEED();
556} 312}
557 313
558std::shared_ptr<MiiManager> MiiDBModule::GetMiiManager() { 314std::shared_ptr<MiiManager> IStaticService::GetMiiManager() {
559 return manager; 315 return manager;
560} 316}
561 317
562class MiiImg final : public ServiceFramework<MiiImg> { 318class IImageDatabaseService final : public ServiceFramework<IImageDatabaseService> {
563public: 319public:
564 explicit MiiImg(Core::System& system_) : ServiceFramework{system_, "miiimg"} { 320 explicit IImageDatabaseService(Core::System& system_) : ServiceFramework{system_, "miiimg"} {
565 // clang-format off 321 // clang-format off
566 static const FunctionInfo functions[] = { 322 static const FunctionInfo functions[] = {
567 {0, &MiiImg::Initialize, "Initialize"}, 323 {0, D<&IImageDatabaseService::Initialize>, "Initialize"},
568 {10, nullptr, "Reload"}, 324 {10, nullptr, "Reload"},
569 {11, &MiiImg::GetCount, "GetCount"}, 325 {11, D<&IImageDatabaseService::GetCount>, "GetCount"},
570 {12, nullptr, "IsEmpty"}, 326 {12, nullptr, "IsEmpty"},
571 {13, nullptr, "IsFull"}, 327 {13, nullptr, "IsFull"},
572 {14, nullptr, "GetAttribute"}, 328 {14, nullptr, "GetAttribute"},
@@ -585,31 +341,30 @@ public:
585 } 341 }
586 342
587private: 343private:
588 void Initialize(HLERequestContext& ctx) { 344 Result Initialize() {
589 LOG_INFO(Service_Mii, "called"); 345 LOG_INFO(Service_Mii, "called");
590 346
591 IPC::ResponseBuilder rb{ctx, 2}; 347 R_SUCCEED();
592 rb.Push(ResultSuccess);
593 } 348 }
594 349
595 void GetCount(HLERequestContext& ctx) { 350 Result GetCount(Out<u32> out_count) {
596 LOG_DEBUG(Service_Mii, "called"); 351 LOG_DEBUG(Service_Mii, "called");
597 352
598 IPC::ResponseBuilder rb{ctx, 3}; 353 *out_count = 0;
599 rb.Push(ResultSuccess); 354
600 rb.Push(0); 355 R_SUCCEED();
601 } 356 }
602}; 357};
603 358
604void LoopProcess(Core::System& system) { 359void LoopProcess(Core::System& system) {
605 auto server_manager = std::make_unique<ServerManager>(system); 360 auto server_manager = std::make_unique<ServerManager>(system);
606 std::shared_ptr<MiiManager> manager = nullptr; 361 std::shared_ptr<MiiManager> manager = std::make_shared<MiiManager>();
607 362
608 server_manager->RegisterNamedService( 363 server_manager->RegisterNamedService(
609 "mii:e", std::make_shared<MiiDBModule>(system, "mii:e", manager, true)); 364 "mii:e", std::make_shared<IStaticService>(system, "mii:e", manager, true));
610 server_manager->RegisterNamedService( 365 server_manager->RegisterNamedService(
611 "mii:u", std::make_shared<MiiDBModule>(system, "mii:u", manager, false)); 366 "mii:u", std::make_shared<IStaticService>(system, "mii:u", manager, false));
612 server_manager->RegisterNamedService("miiimg", std::make_shared<MiiImg>(system)); 367 server_manager->RegisterNamedService("miiimg", std::make_shared<IImageDatabaseService>(system));
613 ServerManager::RunServer(std::move(server_manager)); 368 ServerManager::RunServer(std::move(server_manager));
614} 369}
615 370
diff --git a/src/core/hle/service/mii/mii.h b/src/core/hle/service/mii/mii.h
index 9aa4426f6..8683ac1a5 100644
--- a/src/core/hle/service/mii/mii.h
+++ b/src/core/hle/service/mii/mii.h
@@ -3,7 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/service.h" 6#include "core/hle/service/cmif_types.h"
7 7
8namespace Core { 8namespace Core {
9class System; 9class System;
@@ -11,19 +11,20 @@ class System;
11 11
12namespace Service::Mii { 12namespace Service::Mii {
13class MiiManager; 13class MiiManager;
14class IDatabaseService;
14 15
15class MiiDBModule final : public ServiceFramework<MiiDBModule> { 16class IStaticService final : public ServiceFramework<IStaticService> {
16public: 17public:
17 explicit MiiDBModule(Core::System& system_, const char* name_, 18 explicit IStaticService(Core::System& system_, const char* name_,
18 std::shared_ptr<MiiManager> mii_manager, bool is_system_); 19 std::shared_ptr<MiiManager> mii_manager, bool is_system_);
19 ~MiiDBModule() override; 20 ~IStaticService() override;
20 21
21 std::shared_ptr<MiiManager> GetMiiManager(); 22 std::shared_ptr<MiiManager> GetMiiManager();
22 23
23private: 24private:
24 void GetDatabaseService(HLERequestContext& ctx); 25 Result GetDatabaseService(Out<SharedPointer<IDatabaseService>> out_database_service);
25 26
26 std::shared_ptr<MiiManager> manager = nullptr; 27 std::shared_ptr<MiiManager> manager{nullptr};
27 bool is_system{}; 28 bool is_system{};
28}; 29};
29 30
diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp
index f40a1c8f3..cc93a3654 100644
--- a/src/core/hle/service/set/system_settings_server.cpp
+++ b/src/core/hle/service/set/system_settings_server.cpp
@@ -697,6 +697,9 @@ static Settings GetSettings() {
697 ret["hid_debug"]["disabled_features_per_id"] = std::vector<u8>(0xa8); 697 ret["hid_debug"]["disabled_features_per_id"] = std::vector<u8>(0xa8);
698 ret["hid_debug"]["touch_firmware_auto_update_disabled"] = ToBytes(bool{false}); 698 ret["hid_debug"]["touch_firmware_auto_update_disabled"] = ToBytes(bool{false});
699 699
700 // Mii
701 ret["mii"]["is_db_test_mode_enabled"] = ToBytes(bool{false});
702
700 // Settings 703 // Settings
701 ret["settings_debug"]["is_debug_mode_enabled"] = ToBytes(bool{false}); 704 ret["settings_debug"]["is_debug_mode_enabled"] = ToBytes(bool{false});
702 705