diff --git a/Ryujinx.HLE/HOS/Services/Vi/IApplicationRootService.cs b/Ryujinx.HLE/HOS/Services/Vi/IApplicationRootService.cs index 9fddde577..b4399c584 100644 --- a/Ryujinx.HLE/HOS/Services/Vi/IApplicationRootService.cs +++ b/Ryujinx.HLE/HOS/Services/Vi/IApplicationRootService.cs @@ -16,7 +16,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi if (serviceType != ViServiceType.Application) { - return ResultCode.InvalidRange; + return ResultCode.PermissionDenied; } MakeObject(context, new IApplicationDisplayService(serviceType)); diff --git a/Ryujinx.HLE/HOS/Services/Vi/IManagerRootService.cs b/Ryujinx.HLE/HOS/Services/Vi/IManagerRootService.cs index 6676b629c..7852c613f 100644 --- a/Ryujinx.HLE/HOS/Services/Vi/IManagerRootService.cs +++ b/Ryujinx.HLE/HOS/Services/Vi/IManagerRootService.cs @@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi if (serviceType != ViServiceType.Manager) { - return ResultCode.InvalidRange; + return ResultCode.PermissionDenied; } MakeObject(context, new IApplicationDisplayService(serviceType)); diff --git a/Ryujinx.HLE/HOS/Services/Vi/ISystemRootService.cs b/Ryujinx.HLE/HOS/Services/Vi/ISystemRootService.cs index b63f15c3b..f1122efe8 100644 --- a/Ryujinx.HLE/HOS/Services/Vi/ISystemRootService.cs +++ b/Ryujinx.HLE/HOS/Services/Vi/ISystemRootService.cs @@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi if (serviceType != ViServiceType.System) { - return ResultCode.InvalidRange; + return ResultCode.PermissionDenied; } MakeObject(context, new IApplicationDisplayService(serviceType)); diff --git a/Ryujinx.HLE/HOS/Services/Vi/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Vi/ResultCode.cs index d888e6445..c64339c91 100644 --- a/Ryujinx.HLE/HOS/Services/Vi/ResultCode.cs +++ b/Ryujinx.HLE/HOS/Services/Vi/ResultCode.cs @@ -9,7 +9,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi InvalidArguments = (1 << ErrorCodeShift) | ModuleId, InvalidLayerSize = (4 << ErrorCodeShift) | ModuleId, - InvalidRange = (5 << ErrorCodeShift) | ModuleId, + PermissionDenied = (5 << ErrorCodeShift) | ModuleId, InvalidScalingMode = (6 << ErrorCodeShift) | ModuleId, InvalidValue = (7 << ErrorCodeShift) | ModuleId, AlreadyOpened = (9 << ErrorCodeShift) | ModuleId diff --git a/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs b/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs index 49e6614b2..da55c116b 100644 --- a/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs +++ b/Ryujinx.HLE/HOS/Services/Vi/RootService/IApplicationDisplayService.cs @@ -1,7 +1,6 @@ using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Common.Memory; -using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Applets; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Common; @@ -22,16 +21,21 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService { private readonly ViServiceType _serviceType; - private readonly List _displayInfo; - private readonly Dictionary _openDisplayInfo; + private class DisplayState + { + public int RetrievedEventsCount; + } + + private readonly List _displayInfo; + private readonly Dictionary _openDisplays; private int _vsyncEventHandle; public IApplicationDisplayService(ViServiceType serviceType) { - _serviceType = serviceType; - _displayInfo = new List(); - _openDisplayInfo = new Dictionary(); + _serviceType = serviceType; + _displayInfo = new List(); + _openDisplays = new Dictionary(); void AddDisplayInfo(string name, bool layerLimitEnabled, ulong layerLimitMax, ulong width, ulong height) { @@ -64,7 +68,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService // FIXME: Should be _serviceType != ViServiceType.Application but guests crashes if we do this check. if (_serviceType > ViServiceType.System) { - return ResultCode.InvalidRange; + return ResultCode.PermissionDenied; } MakeObject(context, new HOSBinderDriverServer()); @@ -79,7 +83,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService // FIXME: Should be _serviceType == ViServiceType.System but guests crashes if we do this check. if (_serviceType > ViServiceType.System) { - return ResultCode.InvalidRange; + return ResultCode.PermissionDenied; } MakeObject(context, new ISystemDisplayService(this)); @@ -93,7 +97,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService { if (_serviceType > ViServiceType.System) { - return ResultCode.InvalidRange; + return ResultCode.PermissionDenied; } MakeObject(context, new IManagerDisplayService(this)); @@ -107,7 +111,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService { if (_serviceType > ViServiceType.System) { - return ResultCode.InvalidRange; + return ResultCode.PermissionDenied; } MakeObject(context, new HOSBinderDriverServer()); @@ -174,7 +178,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService return ResultCode.InvalidValue; } - if (!_openDisplayInfo.TryAdd((ulong)displayId, _displayInfo[displayId])) + if (!_openDisplays.TryAdd((ulong)displayId, new DisplayState())) { return ResultCode.AlreadyOpened; } @@ -190,7 +194,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService { ulong displayId = context.RequestData.ReadUInt64(); - if (!_openDisplayInfo.Remove(displayId)) + if (!_openDisplays.Remove(displayId)) { return ResultCode.InvalidValue; } @@ -454,11 +458,16 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService { ulong displayId = context.RequestData.ReadUInt64(); - if (!_openDisplayInfo.ContainsKey(displayId)) + if (!_openDisplays.TryGetValue(displayId, out DisplayState displayState)) { return ResultCode.InvalidValue; } + if (displayState.RetrievedEventsCount > 0) + { + return ResultCode.PermissionDenied; + } + if (_vsyncEventHandle == 0) { if (context.Process.HandleTable.GenerateHandle(context.Device.System.VsyncEvent.ReadableEvent, out _vsyncEventHandle) != KernelResult.Success) @@ -467,6 +476,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService } } + displayState.RetrievedEventsCount++; context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_vsyncEventHandle); return ResultCode.Success;