2023-01-04 14:15:45 -08:00
|
|
|
|
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;
|
|
|
|
|
|
2023-01-08 04:13:39 -08:00
|
|
|
|
if (_session.ServiceObjectHolder.ServiceObject is not DomainServiceObject domain)
|
2023-01-04 14:15:45 -08:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-08 04:13:39 -08:00
|
|
|
|
}
|