diff --git a/Ryujinx.HLE/HOS/Services/Time/IStaticService.cs b/Ryujinx.HLE/HOS/Services/Time/IStaticService.cs index a5d2f42b07..f188a6c1e9 100644 --- a/Ryujinx.HLE/HOS/Services/Time/IStaticService.cs +++ b/Ryujinx.HLE/HOS/Services/Time/IStaticService.cs @@ -5,22 +5,40 @@ using System; namespace Ryujinx.HLE.HOS.Services.Time { - [Service("time:a")] - [Service("time:s")] - [Service("time:u")] + [Flags] + enum TimePermissions + { + LocalSystemClockWritableMask = 0x1, + UserSystemClockWritableMask = 0x2, + NetworkSystemClockWritableMask = 0x4, + UnknwonPermissionMask = 0x8, + + User = 0, + Applet = LocalSystemClockWritableMask | UserSystemClockWritableMask | UnknwonPermissionMask, + System = NetworkSystemClockWritableMask + } + + [Service("time:a", TimePermissions.Applet)] + [Service("time:s", TimePermissions.System)] + [Service("time:u", TimePermissions.User)] class IStaticService : IpcService { + private TimePermissions _permissions; + private int _timeSharedMemoryNativeHandle = 0; private static readonly DateTime StartupDate = DateTime.UtcNow; - public IStaticService(ServiceCtx context) { } + public IStaticService(ServiceCtx context, TimePermissions permissions) + { + _permissions = permissions; + } [Command(0)] // GetStandardUserSystemClock() -> object public ResultCode GetStandardUserSystemClock(ServiceCtx context) { - MakeObject(context, new ISystemClock(StandardUserSystemClockCore.Instance)); + MakeObject(context, new ISystemClock(StandardUserSystemClockCore.Instance, (_permissions & TimePermissions.UserSystemClockWritableMask) != 0)); return ResultCode.Success; } @@ -29,7 +47,7 @@ namespace Ryujinx.HLE.HOS.Services.Time // GetStandardNetworkSystemClock() -> object public ResultCode GetStandardNetworkSystemClock(ServiceCtx context) { - MakeObject(context, new ISystemClock(StandardNetworkSystemClockCore.Instance)); + MakeObject(context, new ISystemClock(StandardNetworkSystemClockCore.Instance, (_permissions & TimePermissions.NetworkSystemClockWritableMask) != 0)); return ResultCode.Success; } @@ -56,7 +74,7 @@ namespace Ryujinx.HLE.HOS.Services.Time // GetStandardLocalSystemClock() -> object public ResultCode GetStandardLocalSystemClock(ServiceCtx context) { - MakeObject(context, new ISystemClock(StandardLocalSystemClockCore.Instance)); + MakeObject(context, new ISystemClock(StandardLocalSystemClockCore.Instance, (_permissions & TimePermissions.LocalSystemClockWritableMask) != 0)); return ResultCode.Success; } @@ -91,6 +109,11 @@ namespace Ryujinx.HLE.HOS.Services.Time // SetStandardUserSystemClockAutomaticCorrectionEnabled(b8) public ResultCode SetStandardUserSystemClockAutomaticCorrectionEnabled(ServiceCtx context) { + if ((_permissions & TimePermissions.UserSystemClockWritableMask) == 0) + { + return ResultCode.PermissionDenied; + } + bool autoCorrectionEnabled = context.RequestData.ReadBoolean(); return StandardUserSystemClockCore.Instance.SetAutomaticCorrectionEnabled(context.Thread, autoCorrectionEnabled); diff --git a/Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs b/Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs index 62e10da952..c9a3a05c91 100644 --- a/Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs +++ b/Ryujinx.HLE/HOS/Services/Time/ISystemClock.cs @@ -6,10 +6,12 @@ namespace Ryujinx.HLE.HOS.Services.Time class ISystemClock : IpcService { private SystemClockCore _clockCore; + private bool _writePermission; - public ISystemClock(SystemClockCore clockCore) + public ISystemClock(SystemClockCore clockCore, bool writePermission) { - _clockCore = clockCore; + _clockCore = clockCore; + _writePermission = writePermission; } [Command(0)] @@ -43,6 +45,11 @@ namespace Ryujinx.HLE.HOS.Services.Time // SetCurrentTime(nn::time::PosixTime) public ResultCode SetCurrentTime(ServiceCtx context) { + if (!_writePermission) + { + return ResultCode.PermissionDenied; + } + ulong posixTime = context.RequestData.ReadUInt64(); SteadyClockCore steadyClockCore = _clockCore.GetSteadyClockCore(); @@ -83,6 +90,11 @@ namespace Ryujinx.HLE.HOS.Services.Time // SetSystemClockContext(nn::time::SystemClockContext) public ResultCode SetSystemClockContext(ServiceCtx context) { + if (!_writePermission) + { + return ResultCode.PermissionDenied; + } + SystemClockContext clockContext = context.RequestData.ReadStruct(); ResultCode result = _clockCore.SetSystemClockContext(clockContext); diff --git a/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs index f9c324b68f..ed7130f364 100644 --- a/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs +++ b/Ryujinx.HLE/HOS/Services/Time/ResultCode.cs @@ -7,6 +7,7 @@ Success = 0, + PermissionDenied = (1 << ErrorCodeShift) | ModuleId, TimeMismatch = (102 << ErrorCodeShift) | ModuleId, TimeNotFound = (200 << ErrorCodeShift) | ModuleId, Overflow = (201 << ErrorCodeShift) | ModuleId,