diff options
author | Ac_K <Acoustik666@gmail.com> | 2019-06-27 14:05:30 +0200 |
---|---|---|
committer | Thomas Guillemard <me@thog.eu> | 2019-06-27 14:05:30 +0200 |
commit | 36f62cbe72d16c94f0c87fa1712ffff314ab080a (patch) | |
tree | 94ca51fc21bb640a03b68e783a2396a2b8e2d022 | |
parent | db21621bb681ee6d85f81fd04d7ea286b0742ca7 (diff) |
friends: INotificationService Implementation of GetEvent (#710)
* 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;
}
```
Co-Authored-By: Thomas Guillemard <me@thog.eu>
-rw-r--r-- | Ryujinx.HLE/HOS/Services/Friend/FriendErr.cs | 7 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Services/Friend/INotificationService.cs | 29 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Services/Friend/IServiceCreator.cs | 9 |
3 files changed, 41 insertions, 4 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Friend/FriendErr.cs b/Ryujinx.HLE/HOS/Services/Friend/FriendErr.cs new file mode 100644 index 00000000..5ee2a706 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Friend/FriendErr.cs @@ -0,0 +1,7 @@ +namespace Ryujinx.HLE.HOS.Services.Friend +{ + static class FriendErr + { + public const int InvalidArgument = 2; + } +} diff --git a/Ryujinx.HLE/HOS/Services/Friend/INotificationService.cs b/Ryujinx.HLE/HOS/Services/Friend/INotificationService.cs index 46a5f17c..8b684e6b 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<int, ServiceProcessRequest> _commands; public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands; @@ -16,12 +22,29 @@ namespace Ryujinx.HLE.HOS.Services.Friend { _commands = new Dictionary<int, ServiceProcessRequest> { - //{ 0, GetEvent }, - //{ 1, Pop }, - //{ 2, Clear }, + { 0, GetEvent }, // 2.0.0+ + //{ 1, Clear }, // 2.0.0+ + //{ 2, Pop }, // 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 diff --git a/Ryujinx.HLE/HOS/Services/Friend/IServiceCreator.cs b/Ryujinx.HLE/HOS/Services/Friend/IServiceCreator.cs index 2464cb53..81281dc2 100644 --- a/Ryujinx.HLE/HOS/Services/Friend/IServiceCreator.cs +++ b/Ryujinx.HLE/HOS/Services/Friend/IServiceCreator.cs @@ -2,6 +2,8 @@ using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.Utilities; using System.Collections.Generic; +using static Ryujinx.HLE.HOS.ErrorCode; + namespace Ryujinx.HLE.HOS.Services.Friend { class IServiceCreator : IpcService @@ -33,6 +35,11 @@ namespace Ryujinx.HLE.HOS.Services.Friend { UInt128 userId = new UInt128(context.RequestData.ReadBytes(0x10)); + if (userId.IsNull) + { + return MakeError(ErrorModule.Friends, FriendErr.InvalidArgument); + } + MakeObject(context, new INotificationService(userId)); return 0; @@ -46,4 +53,4 @@ namespace Ryujinx.HLE.HOS.Services.Friend return 0; } } -}
\ No newline at end of file +} |