IStaticService.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. using Ryujinx.HLE.HOS.Ipc;
  2. using Ryujinx.HLE.HOS.Kernel.Common;
  3. using Ryujinx.HLE.HOS.Services.Time.Clock;
  4. using System;
  5. namespace Ryujinx.HLE.HOS.Services.Time
  6. {
  7. [Service("time:a", TimePermissions.Applet)]
  8. [Service("time:s", TimePermissions.System)]
  9. [Service("time:u", TimePermissions.User)]
  10. class IStaticService : IpcService
  11. {
  12. private TimePermissions _permissions;
  13. private int _timeSharedMemoryNativeHandle = 0;
  14. private static readonly DateTime StartupDate = DateTime.UtcNow;
  15. public IStaticService(ServiceCtx context, TimePermissions permissions)
  16. {
  17. _permissions = permissions;
  18. }
  19. [Command(0)]
  20. // GetStandardUserSystemClock() -> object<nn::timesrv::detail::service::ISystemClock>
  21. public ResultCode GetStandardUserSystemClock(ServiceCtx context)
  22. {
  23. MakeObject(context, new ISystemClock(StandardUserSystemClockCore.Instance, (_permissions & TimePermissions.UserSystemClockWritableMask) != 0));
  24. return ResultCode.Success;
  25. }
  26. [Command(1)]
  27. // GetStandardNetworkSystemClock() -> object<nn::timesrv::detail::service::ISystemClock>
  28. public ResultCode GetStandardNetworkSystemClock(ServiceCtx context)
  29. {
  30. MakeObject(context, new ISystemClock(StandardNetworkSystemClockCore.Instance, (_permissions & TimePermissions.NetworkSystemClockWritableMask) != 0));
  31. return ResultCode.Success;
  32. }
  33. [Command(2)]
  34. // GetStandardSteadyClock() -> object<nn::timesrv::detail::service::ISteadyClock>
  35. public ResultCode GetStandardSteadyClock(ServiceCtx context)
  36. {
  37. MakeObject(context, new ISteadyClock());
  38. return ResultCode.Success;
  39. }
  40. [Command(3)]
  41. // GetTimeZoneService() -> object<nn::timesrv::detail::service::ITimeZoneService>
  42. public ResultCode GetTimeZoneService(ServiceCtx context)
  43. {
  44. MakeObject(context, new ITimeZoneService());
  45. return ResultCode.Success;
  46. }
  47. [Command(4)]
  48. // GetStandardLocalSystemClock() -> object<nn::timesrv::detail::service::ISystemClock>
  49. public ResultCode GetStandardLocalSystemClock(ServiceCtx context)
  50. {
  51. MakeObject(context, new ISystemClock(StandardLocalSystemClockCore.Instance, (_permissions & TimePermissions.LocalSystemClockWritableMask) != 0));
  52. return ResultCode.Success;
  53. }
  54. [Command(20)] // 6.0.0+
  55. // GetSharedMemoryNativeHandle() -> handle<copy>
  56. public ResultCode GetSharedMemoryNativeHandle(ServiceCtx context)
  57. {
  58. if (_timeSharedMemoryNativeHandle == 0)
  59. {
  60. if (context.Process.HandleTable.GenerateHandle(context.Device.System.TimeSharedMem, out _timeSharedMemoryNativeHandle) != KernelResult.Success)
  61. {
  62. throw new InvalidOperationException("Out of handles!");
  63. }
  64. }
  65. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_timeSharedMemoryNativeHandle);
  66. return ResultCode.Success;
  67. }
  68. [Command(100)]
  69. // IsStandardUserSystemClockAutomaticCorrectionEnabled() -> bool
  70. public ResultCode IsStandardUserSystemClockAutomaticCorrectionEnabled(ServiceCtx context)
  71. {
  72. context.ResponseData.Write(StandardUserSystemClockCore.Instance.IsAutomaticCorrectionEnabled());
  73. return ResultCode.Success;
  74. }
  75. [Command(101)]
  76. // SetStandardUserSystemClockAutomaticCorrectionEnabled(b8)
  77. public ResultCode SetStandardUserSystemClockAutomaticCorrectionEnabled(ServiceCtx context)
  78. {
  79. if ((_permissions & TimePermissions.UserSystemClockWritableMask) == 0)
  80. {
  81. return ResultCode.PermissionDenied;
  82. }
  83. bool autoCorrectionEnabled = context.RequestData.ReadBoolean();
  84. return StandardUserSystemClockCore.Instance.SetAutomaticCorrectionEnabled(context.Thread, autoCorrectionEnabled);
  85. }
  86. [Command(200)] // 3.0.0+
  87. // IsStandardNetworkSystemClockAccuracySufficient() -> bool
  88. public ResultCode IsStandardNetworkSystemClockAccuracySufficient(ServiceCtx context)
  89. {
  90. context.ResponseData.Write(StandardNetworkSystemClockCore.Instance.IsStandardNetworkSystemClockAccuracySufficient(context.Thread));
  91. return ResultCode.Success;
  92. }
  93. [Command(300)] // 4.0.0+
  94. // CalculateMonotonicSystemClockBaseTimePoint(nn::time::SystemClockContext) -> u64
  95. public ResultCode CalculateMonotonicSystemClockBaseTimePoint(ServiceCtx context)
  96. {
  97. // TODO: reimplement this
  98. long timeOffset = (long)(DateTime.UtcNow - StartupDate).TotalSeconds;
  99. long systemClockContextEpoch = context.RequestData.ReadInt64();
  100. context.ResponseData.Write(timeOffset + systemClockContextEpoch);
  101. return ResultCode.Success;
  102. }
  103. }
  104. }