IDatabaseService.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. using Ryujinx.Common;
  2. using Ryujinx.HLE.HOS.Ipc;
  3. using Ryujinx.HLE.HOS.Services.Mii.Types;
  4. using System;
  5. using System.Runtime.InteropServices;
  6. namespace Ryujinx.HLE.HOS.Services.Mii.StaticService
  7. {
  8. abstract class IDatabaseService : IpcService
  9. {
  10. [CommandHipc(0)]
  11. // IsUpdated(SourceFlag flag) -> bool
  12. public ResultCode IsUpdated(ServiceCtx context)
  13. {
  14. SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32();
  15. context.ResponseData.Write(IsUpdated(flag));
  16. return ResultCode.Success;
  17. }
  18. [CommandHipc(1)]
  19. // IsFullDatabase() -> bool
  20. public ResultCode IsFullDatabase(ServiceCtx context)
  21. {
  22. context.ResponseData.Write(IsFullDatabase());
  23. return ResultCode.Success;
  24. }
  25. [CommandHipc(2)]
  26. // GetCount(SourceFlag flag) -> u32
  27. public ResultCode GetCount(ServiceCtx context)
  28. {
  29. SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32();
  30. context.ResponseData.Write(GetCount(flag));
  31. return ResultCode.Success;
  32. }
  33. [CommandHipc(3)]
  34. // Get(SourceFlag flag) -> (s32 count, buffer<nn::mii::CharInfoRawElement, 6>)
  35. public ResultCode Get(ServiceCtx context)
  36. {
  37. SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32();
  38. IpcBuffDesc outputBuffer = context.Request.ReceiveBuff[0];
  39. Span<CharInfoElement> elementsSpan = CreateSpanFromBuffer<CharInfoElement>(context, outputBuffer, true);
  40. ResultCode result = Get(flag, out int count, elementsSpan);
  41. elementsSpan = elementsSpan.Slice(0, count);
  42. context.ResponseData.Write(count);
  43. WriteSpanToBuffer(context, outputBuffer, elementsSpan);
  44. return result;
  45. }
  46. [CommandHipc(4)]
  47. // Get1(SourceFlag flag) -> (s32 count, buffer<nn::mii::CharInfo, 6>)
  48. public ResultCode Get1(ServiceCtx context)
  49. {
  50. SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32();
  51. IpcBuffDesc outputBuffer = context.Request.ReceiveBuff[0];
  52. Span<CharInfo> elementsSpan = CreateSpanFromBuffer<CharInfo>(context, outputBuffer, true);
  53. ResultCode result = Get1(flag, out int count, elementsSpan);
  54. elementsSpan = elementsSpan.Slice(0, count);
  55. context.ResponseData.Write(count);
  56. WriteSpanToBuffer(context, outputBuffer, elementsSpan);
  57. return result;
  58. }
  59. [CommandHipc(5)]
  60. // UpdateLatest(nn::mii::CharInfo old_char_info, SourceFlag flag) -> nn::mii::CharInfo
  61. public ResultCode UpdateLatest(ServiceCtx context)
  62. {
  63. CharInfo oldCharInfo = context.RequestData.ReadStruct<CharInfo>();
  64. SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32();
  65. ResultCode result = UpdateLatest(oldCharInfo, flag, out CharInfo newCharInfo);
  66. context.ResponseData.WriteStruct(newCharInfo);
  67. return result;
  68. }
  69. [CommandHipc(6)]
  70. // BuildRandom(Age age, Gender gender, Race race) -> nn::mii::CharInfo
  71. public ResultCode BuildRandom(ServiceCtx context)
  72. {
  73. Age age = (Age)context.RequestData.ReadInt32();
  74. Gender gender = (Gender)context.RequestData.ReadInt32();
  75. Race race = (Race)context.RequestData.ReadInt32();
  76. ResultCode result = BuildRandom(age, gender, race, out CharInfo charInfo);
  77. context.ResponseData.WriteStruct(charInfo);
  78. return result;
  79. }
  80. [CommandHipc(7)]
  81. // BuildDefault(u32 index) -> nn::mii::CharInfoRaw
  82. public ResultCode BuildDefault(ServiceCtx context)
  83. {
  84. uint index = context.RequestData.ReadUInt32();
  85. ResultCode result = BuildDefault(index, out CharInfo charInfo);
  86. context.ResponseData.WriteStruct(charInfo);
  87. return result;
  88. }
  89. [CommandHipc(8)]
  90. // Get2(SourceFlag flag) -> (u32 count, buffer<nn::mii::StoreDataElement, 6>)
  91. public ResultCode Get2(ServiceCtx context)
  92. {
  93. SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32();
  94. IpcBuffDesc outputBuffer = context.Request.ReceiveBuff[0];
  95. Span<StoreDataElement> elementsSpan = CreateSpanFromBuffer<StoreDataElement>(context, outputBuffer, true);
  96. ResultCode result = Get2(flag, out int count, elementsSpan);
  97. elementsSpan = elementsSpan.Slice(0, count);
  98. context.ResponseData.Write(count);
  99. WriteSpanToBuffer(context, outputBuffer, elementsSpan);
  100. return result;
  101. }
  102. [CommandHipc(9)]
  103. // Get3(SourceFlag flag) -> (u32 count, buffer<nn::mii::StoreData, 6>)
  104. public ResultCode Get3(ServiceCtx context)
  105. {
  106. SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32();
  107. IpcBuffDesc outputBuffer = context.Request.ReceiveBuff[0];
  108. Span<StoreData> elementsSpan = CreateSpanFromBuffer<StoreData>(context, outputBuffer, true);
  109. ResultCode result = Get3(flag, out int count, elementsSpan);
  110. elementsSpan = elementsSpan.Slice(0, count);
  111. context.ResponseData.Write(count);
  112. WriteSpanToBuffer(context, outputBuffer, elementsSpan);
  113. return result;
  114. }
  115. [CommandHipc(10)]
  116. // UpdateLatest1(nn::mii::StoreData old_store_data, SourceFlag flag) -> nn::mii::StoreData
  117. public ResultCode UpdateLatest1(ServiceCtx context)
  118. {
  119. StoreData oldStoreData = context.RequestData.ReadStruct<StoreData>();
  120. SourceFlag flag = (SourceFlag)context.RequestData.ReadInt32();
  121. ResultCode result = UpdateLatest1(oldStoreData, flag, out StoreData newStoreData);
  122. context.ResponseData.WriteStruct(newStoreData);
  123. return result;
  124. }
  125. [CommandHipc(11)]
  126. // FindIndex(nn::mii::CreateId create_id, bool is_special) -> s32
  127. public ResultCode FindIndex(ServiceCtx context)
  128. {
  129. CreateId createId = context.RequestData.ReadStruct<CreateId>();
  130. bool isSpecial = context.RequestData.ReadBoolean();
  131. ResultCode result = FindIndex(createId, isSpecial, out int index);
  132. context.ResponseData.Write(index);
  133. return result;
  134. }
  135. [CommandHipc(12)]
  136. // Move(nn::mii::CreateId create_id, s32 new_index)
  137. public ResultCode Move(ServiceCtx context)
  138. {
  139. CreateId createId = context.RequestData.ReadStruct<CreateId>();
  140. int newIndex = context.RequestData.ReadInt32();
  141. return Move(createId, newIndex);
  142. }
  143. [CommandHipc(13)]
  144. // AddOrReplace(nn::mii::StoreData store_data)
  145. public ResultCode AddOrReplace(ServiceCtx context)
  146. {
  147. StoreData storeData = context.RequestData.ReadStruct<StoreData>();
  148. return AddOrReplace(storeData);
  149. }
  150. [CommandHipc(14)]
  151. // Delete(nn::mii::CreateId create_id)
  152. public ResultCode Delete(ServiceCtx context)
  153. {
  154. CreateId createId = context.RequestData.ReadStruct<CreateId>();
  155. return Delete(createId);
  156. }
  157. [CommandHipc(15)]
  158. // DestroyFile()
  159. public ResultCode DestroyFile(ServiceCtx context)
  160. {
  161. return DestroyFile();
  162. }
  163. [CommandHipc(16)]
  164. // DeleteFile()
  165. public ResultCode DeleteFile(ServiceCtx context)
  166. {
  167. return DeleteFile();
  168. }
  169. [CommandHipc(17)]
  170. // Format()
  171. public ResultCode Format(ServiceCtx context)
  172. {
  173. return Format();
  174. }
  175. [CommandHipc(18)]
  176. // Import(buffer<bytes, 5>)
  177. public ResultCode Import(ServiceCtx context)
  178. {
  179. ReadOnlySpan<byte> data = CreateByteSpanFromBuffer(context, context.Request.SendBuff[0], false);
  180. return Import(data);
  181. }
  182. [CommandHipc(19)]
  183. // Export() -> buffer<bytes, 6>
  184. public ResultCode Export(ServiceCtx context)
  185. {
  186. IpcBuffDesc outputBuffer = context.Request.ReceiveBuff[0];
  187. Span<byte> data = CreateByteSpanFromBuffer(context, outputBuffer, true);
  188. ResultCode result = Export(data);
  189. context.Memory.Write(outputBuffer.Position, data.ToArray());
  190. return result;
  191. }
  192. [CommandHipc(20)]
  193. // IsBrokenDatabaseWithClearFlag() -> bool
  194. public ResultCode IsBrokenDatabaseWithClearFlag(ServiceCtx context)
  195. {
  196. ResultCode result = IsBrokenDatabaseWithClearFlag(out bool isBrokenDatabase);
  197. context.ResponseData.Write(isBrokenDatabase);
  198. return result;
  199. }
  200. [CommandHipc(21)]
  201. // GetIndex(nn::mii::CharInfo char_info) -> s32
  202. public ResultCode GetIndex(ServiceCtx context)
  203. {
  204. CharInfo charInfo = context.RequestData.ReadStruct<CharInfo>();
  205. ResultCode result = GetIndex(charInfo, out int index);
  206. context.ResponseData.Write(index);
  207. return result;
  208. }
  209. [CommandHipc(22)] // 5.0.0+
  210. // SetInterfaceVersion(u32 version)
  211. public ResultCode SetInterfaceVersion(ServiceCtx context)
  212. {
  213. uint interfaceVersion = context.RequestData.ReadUInt32();
  214. SetInterfaceVersion(interfaceVersion);
  215. return ResultCode.Success;
  216. }
  217. [CommandHipc(23)] // 5.0.0+
  218. // Convert(nn::mii::Ver3StoreData ver3_store_data) -> nn::mii::CharInfo
  219. public ResultCode Convert(ServiceCtx context)
  220. {
  221. Ver3StoreData ver3StoreData = context.RequestData.ReadStruct<Ver3StoreData>();
  222. ResultCode result = Convert(ver3StoreData, out CharInfo charInfo);
  223. context.ResponseData.WriteStruct(charInfo);
  224. return result;
  225. }
  226. [CommandHipc(24)] // 7.0.0+
  227. // ConvertCoreDataToCharInfo(nn::mii::CoreData core_data) -> nn::mii::CharInfo
  228. public ResultCode ConvertCoreDataToCharInfo(ServiceCtx context)
  229. {
  230. CoreData coreData = context.RequestData.ReadStruct<CoreData>();
  231. ResultCode result = ConvertCoreDataToCharInfo(coreData, out CharInfo charInfo);
  232. context.ResponseData.WriteStruct(charInfo);
  233. return result;
  234. }
  235. [CommandHipc(25)] // 7.0.0+
  236. // ConvertCharInfoToCoreData(nn::mii::CharInfo char_info) -> nn::mii::CoreData
  237. public ResultCode ConvertCharInfoToCoreData(ServiceCtx context)
  238. {
  239. CharInfo charInfo = context.RequestData.ReadStruct<CharInfo>();
  240. ResultCode result = ConvertCharInfoToCoreData(charInfo, out CoreData coreData);
  241. context.ResponseData.WriteStruct(coreData);
  242. return result;
  243. }
  244. private Span<byte> CreateByteSpanFromBuffer(ServiceCtx context, IpcBuffDesc ipcBuff, bool isOutput)
  245. {
  246. byte[] rawData;
  247. if (isOutput)
  248. {
  249. rawData = new byte[ipcBuff.Size];
  250. }
  251. else
  252. {
  253. rawData = new byte[ipcBuff.Size];
  254. context.Memory.Read(ipcBuff.Position, rawData);
  255. }
  256. return new Span<byte>(rawData);
  257. }
  258. private Span<T> CreateSpanFromBuffer<T>(ServiceCtx context, IpcBuffDesc ipcBuff, bool isOutput) where T: unmanaged
  259. {
  260. return MemoryMarshal.Cast<byte, T>(CreateByteSpanFromBuffer(context, ipcBuff, isOutput));
  261. }
  262. private void WriteSpanToBuffer<T>(ServiceCtx context, IpcBuffDesc ipcBuff, Span<T> span) where T: unmanaged
  263. {
  264. Span<byte> rawData = MemoryMarshal.Cast<T, byte>(span);
  265. context.Memory.Write(ipcBuff.Position, rawData);
  266. }
  267. protected abstract bool IsUpdated(SourceFlag flag);
  268. protected abstract bool IsFullDatabase();
  269. protected abstract uint GetCount(SourceFlag flag);
  270. protected abstract ResultCode Get(SourceFlag flag, out int count, Span<CharInfoElement> elements);
  271. protected abstract ResultCode Get1(SourceFlag flag, out int count, Span<CharInfo> elements);
  272. protected abstract ResultCode UpdateLatest(CharInfo oldCharInfo, SourceFlag flag, out CharInfo newCharInfo);
  273. protected abstract ResultCode BuildRandom(Age age, Gender gender, Race race, out CharInfo charInfo);
  274. protected abstract ResultCode BuildDefault(uint index, out CharInfo charInfo);
  275. protected abstract ResultCode Get2(SourceFlag flag, out int count, Span<StoreDataElement> elements);
  276. protected abstract ResultCode Get3(SourceFlag flag, out int count, Span<StoreData> elements);
  277. protected abstract ResultCode UpdateLatest1(StoreData oldStoreData, SourceFlag flag, out StoreData newStoreData);
  278. protected abstract ResultCode FindIndex(CreateId createId, bool isSpecial, out int index);
  279. protected abstract ResultCode Move(CreateId createId, int newIndex);
  280. protected abstract ResultCode AddOrReplace(StoreData storeData);
  281. protected abstract ResultCode Delete(CreateId createId);
  282. protected abstract ResultCode DestroyFile();
  283. protected abstract ResultCode DeleteFile();
  284. protected abstract ResultCode Format();
  285. protected abstract ResultCode Import(ReadOnlySpan<byte> data);
  286. protected abstract ResultCode Export(Span<byte> data);
  287. protected abstract ResultCode IsBrokenDatabaseWithClearFlag(out bool isBrokenDatabase);
  288. protected abstract ResultCode GetIndex(CharInfo charInfo, out int index);
  289. protected abstract void SetInterfaceVersion(uint interfaceVersion);
  290. protected abstract ResultCode Convert(Ver3StoreData ver3StoreData, out CharInfo charInfo);
  291. protected abstract ResultCode ConvertCoreDataToCharInfo(CoreData coreData, out CharInfo charInfo);
  292. protected abstract ResultCode ConvertCharInfoToCoreData(CharInfo charInfo, out CoreData coreData);
  293. }
  294. }