aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs')
-rw-r--r--Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs115
1 files changed, 115 insertions, 0 deletions
diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs
new file mode 100644
index 00000000..ea2ec650
--- /dev/null
+++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs
@@ -0,0 +1,115 @@
+using Ryujinx.Horizon.Common;
+using Ryujinx.Horizon.Sdk.Sf.Cmif;
+using System;
+
+namespace Ryujinx.Horizon.Sdk.Sf.Hipc
+{
+ partial class HipcManager : IServiceObject
+ {
+ private readonly ServerDomainSessionManager _manager;
+ private readonly ServerSession _session;
+
+ public HipcManager(ServerDomainSessionManager manager, ServerSession session)
+ {
+ _manager = manager;
+ _session = session;
+ }
+
+ [CmifCommand(0)]
+ public Result ConvertCurrentObjectToDomain(out int objectId)
+ {
+ objectId = 0;
+
+ var domain = _manager.Domain.AllocateDomainServiceObject();
+ if (domain == null)
+ {
+ return HipcResult.OutOfDomains;
+ }
+
+ bool succeeded = false;
+
+ try
+ {
+ Span<int> objectIds = stackalloc int[1];
+
+ Result result = domain.ReserveIds(objectIds);
+
+ if (result.IsFailure)
+ {
+ return result;
+ }
+
+ objectId = objectIds[0];
+ succeeded = true;
+ }
+ finally
+ {
+ if (!succeeded)
+ {
+ ServerDomainManager.DestroyDomainServiceObject(domain);
+ }
+ }
+
+ domain.RegisterObject(objectId, _session.ServiceObjectHolder);
+ _session.ServiceObjectHolder = new ServiceObjectHolder(domain);
+
+ return Result.Success;
+ }
+
+ [CmifCommand(1)]
+ public Result CopyFromCurrentDomain([MoveHandle] out int clientHandle, int objectId)
+ {
+ clientHandle = 0;
+
+ if (!(_session.ServiceObjectHolder.ServiceObject is DomainServiceObject domain))
+ {
+ return HipcResult.TargetNotDomain;
+ }
+
+ var obj = domain.GetObject(objectId);
+ if (obj == null)
+ {
+ return HipcResult.DomainObjectNotFound;
+ }
+
+ Api.CreateSession(out int serverHandle, out clientHandle).AbortOnFailure();
+ _manager.RegisterSession(serverHandle, obj).AbortOnFailure();
+
+ return Result.Success;
+ }
+
+ [CmifCommand(2)]
+ public Result CloneCurrentObject([MoveHandle] out int clientHandle)
+ {
+ return CloneCurrentObjectImpl(out clientHandle, _manager);
+ }
+
+ [CmifCommand(3)]
+ public void QueryPointerBufferSize(out ushort size)
+ {
+ size = (ushort)_session.PointerBuffer.Size;
+ }
+
+ [CmifCommand(4)]
+ public Result CloneCurrentObjectEx([MoveHandle] out int clientHandle, uint tag)
+ {
+ return CloneCurrentObjectImpl(out clientHandle, _manager.GetSessionManagerByTag(tag));
+ }
+
+ private Result CloneCurrentObjectImpl(out int clientHandle, ServerSessionManager manager)
+ {
+ clientHandle = 0;
+
+ var clone = _session.ServiceObjectHolder.Clone();
+ if (clone == null)
+ {
+ return HipcResult.DomainObjectNotFound;
+ }
+
+ Api.CreateSession(out int serverHandle, out clientHandle).AbortOnFailure();
+ manager.RegisterSession(serverHandle, clone).AbortOnFailure();
+
+ return Result.Success;
+ }
+ }
+}