aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAc_K <Acoustik666@gmail.com>2019-06-27 14:05:30 +0200
committerThomas Guillemard <me@thog.eu>2019-06-27 14:05:30 +0200
commit36f62cbe72d16c94f0c87fa1712ffff314ab080a (patch)
tree94ca51fc21bb640a03b68e783a2396a2b8e2d022
parentdb21621bb681ee6d85f81fd04d7ea286b0742ca7 (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.cs7
-rw-r--r--Ryujinx.HLE/HOS/Services/Friend/INotificationService.cs29
-rw-r--r--Ryujinx.HLE/HOS/Services/Friend/IServiceCreator.cs9
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
+}