IApplicationFunctions.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. { 40, NotifyRunning }
  19. };
  20. }
  21. private const uint LaunchParamsMagic = 0xc79497ca;
  22. public long PopLaunchParameter(ServiceCtx Context)
  23. {
  24. //Only the first 0x18 bytes of the Data seems to be actually used.
  25. MakeObject(Context, new IStorage(MakeLaunchParams()));
  26. return 0;
  27. }
  28. public long EnsureSaveData(ServiceCtx Context)
  29. {
  30. long UIdLow = Context.RequestData.ReadInt64();
  31. long UIdHigh = Context.RequestData.ReadInt64();
  32. Logging.Stub(LogClass.ServiceAm, $"UidLow = {UIdLow}, UidHigh = {UIdHigh}");
  33. Context.ResponseData.Write(0L);
  34. return 0;
  35. }
  36. public long GetDesiredLanguage(ServiceCtx Context)
  37. {
  38. Logging.Stub(LogClass.ServiceAm, "LanguageId = 1");
  39. //This is an enumerator where each number is a differnet language.
  40. //0 is Japanese and 1 is English, need to figure out the other codes.
  41. Context.ResponseData.Write(1L);
  42. return 0;
  43. }
  44. public long SetTerminateResult(ServiceCtx Context)
  45. {
  46. int ErrorCode = Context.RequestData.ReadInt32();
  47. int Module = ErrorCode & 0xFF;
  48. int Description = (ErrorCode >> 9) & 0xFFF;
  49. Logging.Info(LogClass.ServiceAm, $"({(ErrorModule)Module}){2000 + Module}-{Description}");
  50. return 0;
  51. }
  52. public long NotifyRunning(ServiceCtx Context)
  53. {
  54. Context.ResponseData.Write(1);
  55. return 0;
  56. }
  57. private byte[] MakeLaunchParams()
  58. {
  59. //Size needs to be at least 0x88 bytes otherwise application errors.
  60. using (MemoryStream MS = new MemoryStream())
  61. {
  62. BinaryWriter Writer = new BinaryWriter(MS);
  63. MS.SetLength(0x88);
  64. Writer.Write(LaunchParamsMagic);
  65. Writer.Write(1); //IsAccountSelected? Only lower 8 bits actually used.
  66. Writer.Write(1L); //User Id Low (note: User Id needs to be != 0)
  67. Writer.Write(0L); //User Id High
  68. return MS.ToArray();
  69. }
  70. }
  71. }
  72. }