IpcHandler.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. using ChocolArm64.Memory;
  2. using Ryujinx.HLE.OsHle.Handles;
  3. using System;
  4. using System.IO;
  5. namespace Ryujinx.HLE.OsHle.Ipc
  6. {
  7. static class IpcHandler
  8. {
  9. public static long IpcCall(
  10. Switch Ns,
  11. Process Process,
  12. AMemory Memory,
  13. KSession Session,
  14. IpcMessage Request,
  15. long CmdPtr)
  16. {
  17. IpcMessage Response = new IpcMessage();
  18. using (MemoryStream Raw = new MemoryStream(Request.RawData))
  19. {
  20. BinaryReader ReqReader = new BinaryReader(Raw);
  21. if (Request.Type == IpcMessageType.Request)
  22. {
  23. Response.Type = IpcMessageType.Response;
  24. using (MemoryStream ResMS = new MemoryStream())
  25. {
  26. BinaryWriter ResWriter = new BinaryWriter(ResMS);
  27. ServiceCtx Context = new ServiceCtx(
  28. Ns,
  29. Process,
  30. Memory,
  31. Session,
  32. Request,
  33. Response,
  34. ReqReader,
  35. ResWriter);
  36. Session.Service.CallMethod(Context);
  37. Response.RawData = ResMS.ToArray();
  38. }
  39. }
  40. else if (Request.Type == IpcMessageType.Control)
  41. {
  42. long Magic = ReqReader.ReadInt64();
  43. long CmdId = ReqReader.ReadInt64();
  44. switch (CmdId)
  45. {
  46. case 0:
  47. {
  48. Request = FillResponse(Response, 0, Session.Service.ConvertToDomain());
  49. break;
  50. }
  51. case 3:
  52. {
  53. Request = FillResponse(Response, 0, 0x500);
  54. break;
  55. }
  56. //TODO: Whats the difference between IpcDuplicateSession/Ex?
  57. case 2:
  58. case 4:
  59. {
  60. int Unknown = ReqReader.ReadInt32();
  61. int Handle = Process.HandleTable.OpenHandle(Session);
  62. Response.HandleDesc = IpcHandleDesc.MakeMove(Handle);
  63. Request = FillResponse(Response, 0);
  64. break;
  65. }
  66. default: throw new NotImplementedException(CmdId.ToString());
  67. }
  68. }
  69. else if (Request.Type == IpcMessageType.CloseSession)
  70. {
  71. //TODO
  72. }
  73. else
  74. {
  75. throw new NotImplementedException(Request.Type.ToString());
  76. }
  77. Memory.WriteBytes(CmdPtr, Response.GetBytes(CmdPtr));
  78. }
  79. return 0;
  80. }
  81. private static IpcMessage FillResponse(IpcMessage Response, long Result, params int[] Values)
  82. {
  83. using (MemoryStream MS = new MemoryStream())
  84. {
  85. BinaryWriter Writer = new BinaryWriter(MS);
  86. foreach (int Value in Values)
  87. {
  88. Writer.Write(Value);
  89. }
  90. return FillResponse(Response, Result, MS.ToArray());
  91. }
  92. }
  93. private static IpcMessage FillResponse(IpcMessage Response, long Result, byte[] Data = null)
  94. {
  95. Response.Type = IpcMessageType.Response;
  96. using (MemoryStream MS = new MemoryStream())
  97. {
  98. BinaryWriter Writer = new BinaryWriter(MS);
  99. Writer.Write(IpcMagic.Sfco);
  100. Writer.Write(Result);
  101. if (Data != null)
  102. {
  103. Writer.Write(Data);
  104. }
  105. Response.RawData = MS.ToArray();
  106. }
  107. return Response;
  108. }
  109. }
  110. }