IApplicationFunctions.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using Ryujinx.Core.Logging;
  2. using Ryujinx.Core.OsHle.Ipc;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. namespace Ryujinx.Core.OsHle.Services.Am
  6. {
  7. class IApplicationFunctions : IpcService
  8. {
  9. private Dictionary<int, ServiceProcessRequest> m_Commands;
  10. public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
  11. public IApplicationFunctions()
  12. {
  13. m_Commands = new Dictionary<int, ServiceProcessRequest>()
  14. {
  15. { 1, PopLaunchParameter },
  16. { 20, EnsureSaveData },
  17. { 21, GetDesiredLanguage },
  18. { 22, SetTerminateResult },
  19. { 23, GetDisplayVersion },
  20. { 40, NotifyRunning }
  21. };
  22. }
  23. private const uint LaunchParamsMagic = 0xc79497ca;
  24. public long PopLaunchParameter(ServiceCtx Context)
  25. {
  26. //Only the first 0x18 bytes of the Data seems to be actually used.
  27. MakeObject(Context, new IStorage(MakeLaunchParams()));
  28. return 0;
  29. }
  30. public long EnsureSaveData(ServiceCtx Context)
  31. {
  32. long UIdLow = Context.RequestData.ReadInt64();
  33. long UIdHigh = Context.RequestData.ReadInt64();
  34. Context.Ns.Log.PrintStub(LogClass.ServiceAm, "Stubbed.");
  35. Context.ResponseData.Write(0L);
  36. return 0;
  37. }
  38. public long GetDesiredLanguage(ServiceCtx Context)
  39. {
  40. Context.ResponseData.Write(Context.Ns.Os.SystemState.DesiredLanguageCode);
  41. return 0;
  42. }
  43. public long SetTerminateResult(ServiceCtx Context)
  44. {
  45. int ErrorCode = Context.RequestData.ReadInt32();
  46. string Result = GetFormattedErrorCode(ErrorCode);
  47. Context.Ns.Log.PrintInfo(LogClass.ServiceAm, $"Result = 0x{ErrorCode:x8} ({Result}).");
  48. return 0;
  49. }
  50. private string GetFormattedErrorCode(int ErrorCode)
  51. {
  52. int Module = (ErrorCode >> 0) & 0x1ff;
  53. int Description = (ErrorCode >> 9) & 0x1fff;
  54. return $"{(2000 + Module):d4}-{Description:d4}";
  55. }
  56. public long GetDisplayVersion(ServiceCtx Context)
  57. {
  58. //FIXME: Need to check correct version on a switch.
  59. Context.ResponseData.Write(1L);
  60. Context.ResponseData.Write(0L);
  61. return 0;
  62. }
  63. public long NotifyRunning(ServiceCtx Context)
  64. {
  65. Context.ResponseData.Write(1);
  66. return 0;
  67. }
  68. private byte[] MakeLaunchParams()
  69. {
  70. //Size needs to be at least 0x88 bytes otherwise application errors.
  71. using (MemoryStream MS = new MemoryStream())
  72. {
  73. BinaryWriter Writer = new BinaryWriter(MS);
  74. MS.SetLength(0x88);
  75. Writer.Write(LaunchParamsMagic);
  76. Writer.Write(1); //IsAccountSelected? Only lower 8 bits actually used.
  77. Writer.Write(1L); //User Id Low (note: User Id needs to be != 0)
  78. Writer.Write(0L); //User Id High
  79. return MS.ToArray();
  80. }
  81. }
  82. }
  83. }