From 312eb7e0a1fe0033de08e01aeb0f510129013186 Mon Sep 17 00:00:00 2001 From: Ac_K Date: Mon, 24 Jun 2019 02:44:20 +0200 Subject: [PATCH] friends: INotificationService Implementation of GetEvent According to the RE, the event isn't signaled when handle is returned. ```C long nn::friends::detail::service::NotificationService::GetEvent(long this, uint *output_handle) { long inner_struct_event; int result; if (this->event_created) { inner_struct_event = &this->event_object; } else { inner_struct_event = &this->event_object; result = CreateEvent(&this->event_object, 0, 1); if ( result ) { Assert(); } this->event_created = true; } uint event_handle = nn::os::detail::DetachReadableHandleOfInterProcessEvent(inner_struct_event); *output_handle = event_handle; int unknown = *((char *)output_handle + 4); *((char *)output_handle + 4) = 1; if (unknown) { CloseHandle(*output_handle); } return 0LL; } ``` --- .../Services/Friend/INotificationService.cs | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/Ryujinx.HLE/HOS/Services/Friend/INotificationService.cs b/Ryujinx.HLE/HOS/Services/Friend/INotificationService.cs index 46a5f17c97..0e65ad0f77 100644 --- a/Ryujinx.HLE/HOS/Services/Friend/INotificationService.cs +++ b/Ryujinx.HLE/HOS/Services/Friend/INotificationService.cs @@ -1,5 +1,8 @@ using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Kernel.Common; +using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.Utilities; +using System; using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Services.Friend @@ -8,6 +11,9 @@ namespace Ryujinx.HLE.HOS.Services.Friend { private UInt128 _userId; + private KEvent _notificationEvent; + private int _notificationEventHandle = 0; + private Dictionary _commands; public override IReadOnlyDictionary Commands => _commands; @@ -16,12 +22,29 @@ namespace Ryujinx.HLE.HOS.Services.Friend { _commands = new Dictionary { - //{ 0, GetEvent }, - //{ 1, Pop }, - //{ 2, Clear }, + { 0, GetEvent }, // 2.0.0+ + //{ 1, Pop }, // 2.0.0+ + //{ 2, Clear }, // 2.0.0+ }; _userId = userId; } + + public long GetEvent(ServiceCtx context) + { + if (_notificationEventHandle == 0) + { + _notificationEvent = new KEvent(context.Device.System); + + if (context.Process.HandleTable.GenerateHandle(_notificationEvent.ReadableEvent, out _notificationEventHandle) != KernelResult.Success) + { + throw new InvalidOperationException("Out of handles!"); + } + } + + context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_notificationEventHandle); + + return 0; + } } } \ No newline at end of file