IApplicationFunctions.cs 3.1 KB

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