IpcHandler.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. using ChocolArm64.Memory;
  2. using Ryujinx.OsHle.Handles;
  3. using Ryujinx.OsHle.Objects;
  4. using Ryujinx.OsHle.Services;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. namespace Ryujinx.OsHle.Ipc
  9. {
  10. static class IpcHandler
  11. {
  12. private delegate long ServiceProcessRequest(ServiceCtx Context);
  13. private static Dictionary<(string, int), ServiceProcessRequest> ServiceCmds =
  14. new Dictionary<(string, int), ServiceProcessRequest>()
  15. {
  16. { ( "acc:u0", 3), Service.AccU0ListOpenUsers },
  17. { ( "acc:u0", 5), Service.AccU0GetProfile },
  18. { ( "acc:u0", 100), Service.AccU0InitializeApplicationInfo },
  19. { ( "acc:u0", 101), Service.AccU0GetBaasAccountManagerForApplication },
  20. { ( "apm", 0), Service.ApmOpenSession },
  21. { ( "appletOE", 0), Service.AppletOpenApplicationProxy },
  22. { ( "audout:u", 0), Service.AudOutListAudioOuts },
  23. { ( "audout:u", 1), Service.AudOutOpenAudioOut },
  24. { ( "audren:u", 0), Service.AudRenOpenAudioRenderer },
  25. { ( "audren:u", 1), Service.AudRenGetAudioRendererWorkBufferSize },
  26. { ( "friend:a", 0), Service.FriendCreateFriendService },
  27. { ( "fsp-srv", 1), Service.FspSrvInitialize },
  28. { ( "fsp-srv", 51), Service.FspSrvMountSaveData },
  29. { ( "fsp-srv", 200), Service.FspSrvOpenDataStorageByCurrentProcess },
  30. { ( "fsp-srv", 203), Service.FspSrvOpenRomStorage },
  31. { ( "fsp-srv", 1005), Service.FspSrvGetGlobalAccessLogMode },
  32. { ( "hid", 0), Service.HidCreateAppletResource },
  33. { ( "hid", 11), Service.HidActivateTouchScreen },
  34. { ( "hid", 100), Service.HidSetSupportedNpadStyleSet },
  35. { ( "hid", 102), Service.HidSetSupportedNpadIdType },
  36. { ( "hid", 103), Service.HidActivateNpad },
  37. { ( "hid", 120), Service.HidSetNpadJoyHoldType },
  38. { ( "lm", 0), Service.LmInitialize },
  39. { ( "nvdrv", 0), Service.NvDrvOpen },
  40. { ( "nvdrv", 1), Service.NvDrvIoctl },
  41. { ( "nvdrv", 2), Service.NvDrvClose },
  42. { ( "nvdrv", 3), Service.NvDrvInitialize },
  43. { ( "nvdrv", 4), Service.NvDrvQueryEvent },
  44. { ( "nvdrv:a", 0), Service.NvDrvOpen },
  45. { ( "nvdrv:a", 1), Service.NvDrvIoctl },
  46. { ( "nvdrv:a", 2), Service.NvDrvClose },
  47. { ( "nvdrv:a", 3), Service.NvDrvInitialize },
  48. { ( "nvdrv:a", 4), Service.NvDrvQueryEvent },
  49. { ( "pctl:a", 0), Service.PctlCreateService },
  50. { ( "pl:u", 1), Service.PlGetLoadState },
  51. { ( "pl:u", 2), Service.PlGetFontSize },
  52. { ( "pl:u", 3), Service.PlGetSharedMemoryAddressOffset },
  53. { ( "pl:u", 4), Service.PlGetSharedMemoryNativeHandle },
  54. { ( "set", 1), Service.SetGetAvailableLanguageCodes },
  55. { ( "sm:", 0), Service.SmInitialize },
  56. { ( "sm:", 1), Service.SmGetService },
  57. { ( "time:u", 0), Service.TimeGetStandardUserSystemClock },
  58. { ( "time:u", 1), Service.TimeGetStandardNetworkSystemClock },
  59. { ( "time:u", 2), Service.TimeGetStandardSteadyClock },
  60. { ( "time:u", 3), Service.TimeGetTimeZoneService },
  61. { ( "time:s", 0), Service.TimeGetStandardUserSystemClock },
  62. { ( "time:s", 1), Service.TimeGetStandardNetworkSystemClock },
  63. { ( "time:s", 2), Service.TimeGetStandardSteadyClock },
  64. { ( "time:s", 3), Service.TimeGetTimeZoneService },
  65. { ( "vi:m", 2), Service.ViGetDisplayService },
  66. };
  67. private static Dictionary<(Type, int), ServiceProcessRequest> ObjectCmds =
  68. new Dictionary<(Type, int), ServiceProcessRequest>()
  69. {
  70. //IManagerForApplication
  71. { (typeof(AccIManagerForApplication), 0), AccIManagerForApplication.CheckAvailability },
  72. { (typeof(AccIManagerForApplication), 1), AccIManagerForApplication.GetAccountId },
  73. //IProfile
  74. { (typeof(AccIProfile), 1), AccIProfile.GetBase },
  75. //IApplicationFunctions
  76. { (typeof(AmIApplicationFunctions), 1), AmIApplicationFunctions.PopLaunchParameter },
  77. { (typeof(AmIApplicationFunctions), 20), AmIApplicationFunctions.EnsureSaveData },
  78. { (typeof(AmIApplicationFunctions), 21), AmIApplicationFunctions.GetDesiredLanguage },
  79. //IApplicationProxy
  80. { (typeof(AmIApplicationProxy), 0), AmIApplicationProxy.GetCommonStateGetter },
  81. { (typeof(AmIApplicationProxy), 1), AmIApplicationProxy.GetSelfController },
  82. { (typeof(AmIApplicationProxy), 2), AmIApplicationProxy.GetWindowController },
  83. { (typeof(AmIApplicationProxy), 3), AmIApplicationProxy.GetAudioController },
  84. { (typeof(AmIApplicationProxy), 4), AmIApplicationProxy.GetDisplayController },
  85. { (typeof(AmIApplicationProxy), 11), AmIApplicationProxy.GetLibraryAppletCreator },
  86. { (typeof(AmIApplicationProxy), 20), AmIApplicationProxy.GetApplicationFunctions },
  87. { (typeof(AmIApplicationProxy), 1000), AmIApplicationProxy.GetDebugFunctions },
  88. //ICommonStateGetter
  89. { (typeof(AmICommonStateGetter), 0), AmICommonStateGetter.GetEventHandle },
  90. { (typeof(AmICommonStateGetter), 1), AmICommonStateGetter.ReceiveMessage },
  91. { (typeof(AmICommonStateGetter), 5), AmICommonStateGetter.GetOperationMode },
  92. { (typeof(AmICommonStateGetter), 6), AmICommonStateGetter.GetPerformanceMode },
  93. { (typeof(AmICommonStateGetter), 9), AmICommonStateGetter.GetCurrentFocusState },
  94. //ISelfController
  95. { (typeof(AmISelfController), 11), AmISelfController.SetOperationModeChangedNotification },
  96. { (typeof(AmISelfController), 12), AmISelfController.SetPerformanceModeChangedNotification },
  97. { (typeof(AmISelfController), 13), AmISelfController.SetFocusHandlingMode },
  98. //IStorage
  99. { (typeof(AmIStorage), 0), AmIStorage.Open },
  100. //IStorageAccessor
  101. { (typeof(AmIStorageAccessor), 0), AmIStorageAccessor.GetSize },
  102. { (typeof(AmIStorageAccessor), 11), AmIStorageAccessor.Read },
  103. //IWindowController
  104. { (typeof(AmIWindowController), 1), AmIWindowController.GetAppletResourceUserId },
  105. { (typeof(AmIWindowController), 10), AmIWindowController.AcquireForegroundRights },
  106. //ISession
  107. { (typeof(ApmISession), 0), ApmISession.SetPerformanceConfiguration },
  108. //IAudioRenderer
  109. { (typeof(AudIAudioRenderer), 4), AudIAudioRenderer.RequestUpdateAudioRenderer },
  110. { (typeof(AudIAudioRenderer), 5), AudIAudioRenderer.StartAudioRenderer },
  111. { (typeof(AudIAudioRenderer), 7), AudIAudioRenderer.QuerySystemEvent },
  112. //IFile
  113. { (typeof(FspSrvIFile), 0), FspSrvIFile.Read },
  114. { (typeof(FspSrvIFile), 1), FspSrvIFile.Write },
  115. //IFileSystem
  116. { (typeof(FspSrvIFileSystem), 7), FspSrvIFileSystem.GetEntryType },
  117. { (typeof(FspSrvIFileSystem), 8), FspSrvIFileSystem.OpenFile },
  118. { (typeof(FspSrvIFileSystem), 10), FspSrvIFileSystem.Commit },
  119. //IStorage
  120. { (typeof(FspSrvIStorage), 0), FspSrvIStorage.Read },
  121. //IAppletResource
  122. { (typeof(HidIAppletResource), 0), HidIAppletResource.GetSharedMemoryHandle },
  123. //ISystemClock
  124. { (typeof(TimeISystemClock), 0), TimeISystemClock.GetCurrentTime },
  125. //IApplicationDisplayService
  126. { (typeof(ViIApplicationDisplayService), 100), ViIApplicationDisplayService.GetRelayService },
  127. { (typeof(ViIApplicationDisplayService), 101), ViIApplicationDisplayService.GetSystemDisplayService },
  128. { (typeof(ViIApplicationDisplayService), 102), ViIApplicationDisplayService.GetManagerDisplayService },
  129. { (typeof(ViIApplicationDisplayService), 1010), ViIApplicationDisplayService.OpenDisplay },
  130. { (typeof(ViIApplicationDisplayService), 2020), ViIApplicationDisplayService.OpenLayer },
  131. { (typeof(ViIApplicationDisplayService), 2030), ViIApplicationDisplayService.CreateStrayLayer },
  132. { (typeof(ViIApplicationDisplayService), 2101), ViIApplicationDisplayService.SetLayerScalingMode },
  133. { (typeof(ViIApplicationDisplayService), 5202), ViIApplicationDisplayService.GetDisplayVSyncEvent },
  134. //IHOSBinderDriver
  135. { (typeof(ViIHOSBinderDriver), 0), ViIHOSBinderDriver.TransactParcel },
  136. { (typeof(ViIHOSBinderDriver), 1), ViIHOSBinderDriver.AdjustRefcount },
  137. { (typeof(ViIHOSBinderDriver), 2), ViIHOSBinderDriver.GetNativeHandle },
  138. //IManagerDisplayService
  139. { (typeof(ViIManagerDisplayService), 2010), ViIManagerDisplayService.CreateManagedLayer },
  140. { (typeof(ViIManagerDisplayService), 6000), ViIManagerDisplayService.AddToLayerStack },
  141. //ISystemDisplayService
  142. { (typeof(ViISystemDisplayService), 2205), ViISystemDisplayService.SetLayerZ },
  143. };
  144. private const long SfciMagic = 'S' << 0 | 'F' << 8 | 'C' << 16 | 'I' << 24;
  145. private const long SfcoMagic = 'S' << 0 | 'F' << 8 | 'C' << 16 | 'O' << 24;
  146. public static void ProcessRequest(
  147. Switch Ns,
  148. AMemory Memory,
  149. HSession Session,
  150. IpcMessage Request,
  151. long CmdPtr,
  152. int HndId)
  153. {
  154. IpcMessage Response = new IpcMessage(Request.IsDomain);
  155. using (MemoryStream Raw = new MemoryStream(Request.RawData))
  156. {
  157. BinaryReader ReqReader = new BinaryReader(Raw);
  158. if (Request.Type == IpcMessageType.Request)
  159. {
  160. string ServiceName = Session.ServiceName;
  161. ServiceProcessRequest ProcReq = null;
  162. bool IgnoreNullPR = false;
  163. if (Session is HDomain Dom)
  164. {
  165. if (Request.DomCmd == IpcDomCmd.SendMsg)
  166. {
  167. long Magic = ReqReader.ReadInt64();
  168. int CmdId = (int)ReqReader.ReadInt64();
  169. object Obj = Dom.GetObject(Request.DomObjId);
  170. if (Obj is HDomain)
  171. {
  172. ServiceCmds.TryGetValue((ServiceName, CmdId), out ProcReq);
  173. }
  174. else if (Obj != null)
  175. {
  176. ObjectCmds.TryGetValue((Obj.GetType(), CmdId), out ProcReq);
  177. }
  178. }
  179. else if (Request.DomCmd == IpcDomCmd.DeleteObj)
  180. {
  181. Dom.DeleteObject(Request.DomObjId);
  182. Response = FillResponse(Response, 0);
  183. IgnoreNullPR = true;
  184. }
  185. }
  186. else
  187. {
  188. long Magic = ReqReader.ReadInt64();
  189. int CmdId = (int)ReqReader.ReadInt64();
  190. if (Session is HSessionObj)
  191. {
  192. object Obj = ((HSessionObj)Session).Obj;
  193. ObjectCmds.TryGetValue((Obj.GetType(), CmdId), out ProcReq);
  194. }
  195. else
  196. {
  197. ServiceCmds.TryGetValue((ServiceName, CmdId), out ProcReq);
  198. }
  199. }
  200. if (ProcReq != null)
  201. {
  202. using (MemoryStream ResMS = new MemoryStream())
  203. {
  204. BinaryWriter ResWriter = new BinaryWriter(ResMS);
  205. ServiceCtx Context = new ServiceCtx(
  206. Ns,
  207. Memory,
  208. Session,
  209. Request,
  210. Response,
  211. ReqReader,
  212. ResWriter);
  213. long Result = ProcReq(Context);
  214. Response = FillResponse(Response, Result, ResMS.ToArray());
  215. }
  216. }
  217. else if (!IgnoreNullPR)
  218. {
  219. throw new NotImplementedException(ServiceName);
  220. }
  221. }
  222. else if (Request.Type == IpcMessageType.Control)
  223. {
  224. long Magic = ReqReader.ReadInt64();
  225. long CmdId = ReqReader.ReadInt64();
  226. switch (CmdId)
  227. {
  228. case 0: Request = IpcConvertSessionToDomain(Ns, Session, Response, HndId); break;
  229. case 3: Request = IpcQueryBufferPointerSize(Response); break;
  230. case 4: Request = IpcDuplicateSessionEx(Ns, Session, Response, ReqReader); break;
  231. default: throw new NotImplementedException(CmdId.ToString());
  232. }
  233. }
  234. else if (Request.Type == IpcMessageType.Unknown2)
  235. {
  236. //TODO
  237. }
  238. else
  239. {
  240. throw new NotImplementedException(Request.Type.ToString());
  241. }
  242. AMemoryHelper.WriteBytes(Memory, CmdPtr, Response.GetBytes(CmdPtr));
  243. }
  244. }
  245. private static IpcMessage IpcConvertSessionToDomain(
  246. Switch Ns,
  247. HSession Session,
  248. IpcMessage Response,
  249. int HndId)
  250. {
  251. HDomain Dom = new HDomain(Session);
  252. Ns.Os.Handles.ReplaceData(HndId, Dom);
  253. return FillResponse(Response, 0, Dom.GenertateObjectId(Dom));
  254. }
  255. private static IpcMessage IpcDuplicateSessionEx(
  256. Switch Ns,
  257. HSession Session,
  258. IpcMessage Response,
  259. BinaryReader ReqReader)
  260. {
  261. int Unknown = ReqReader.ReadInt32();
  262. int Handle = Ns.Os.Handles.GenerateId(Session);
  263. Response.HandleDesc = IpcHandleDesc.MakeMove(Handle);
  264. return FillResponse(Response, 0);
  265. }
  266. private static IpcMessage IpcQueryBufferPointerSize(IpcMessage Response)
  267. {
  268. return FillResponse(Response, 0, 0x500);
  269. }
  270. private static IpcMessage FillResponse(IpcMessage Response, long Result, params int[] Values)
  271. {
  272. using (MemoryStream MS = new MemoryStream())
  273. {
  274. BinaryWriter Writer = new BinaryWriter(MS);
  275. foreach (int Value in Values)
  276. {
  277. Writer.Write(Value);
  278. }
  279. return FillResponse(Response, Result, MS.ToArray());
  280. }
  281. }
  282. private static IpcMessage FillResponse(IpcMessage Response, long Result, byte[] Data = null)
  283. {
  284. Response.Type = IpcMessageType.Response;
  285. using (MemoryStream MS = new MemoryStream())
  286. {
  287. BinaryWriter Writer = new BinaryWriter(MS);
  288. Writer.Write(SfcoMagic);
  289. Writer.Write(Result);
  290. if (Data != null)
  291. {
  292. Writer.Write(Data);
  293. }
  294. Response.RawData = MS.ToArray();
  295. }
  296. return Response;
  297. }
  298. }
  299. }