
* Horizon: Implement arp:r and arp:w services * Fix formatting * Remove HLE arp services * Revert "Remove HLE arp services" This reverts commit c576fcccadb963db56b96bacabd1c1ac7abfb1ab. * Keep LibHac impl since it's used in bcat * Addresses gdkchan's feedback * ArpApi in PrepoIpcServer and remove LmApi * Fix 2 * Fixes ArpApi init * Fix encoding * Update PrepoService.cs * Fix prepo
131 lines
3.8 KiB
C#
131 lines
3.8 KiB
C#
using Ryujinx.Common.Memory;
|
|
using Ryujinx.Horizon.Common;
|
|
using Ryujinx.Horizon.Sdk.Ns;
|
|
using Ryujinx.Horizon.Sdk.Sf.Cmif;
|
|
using Ryujinx.Horizon.Sdk.Sf.Hipc;
|
|
using Ryujinx.Horizon.Sdk.Sm;
|
|
using System;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace Ryujinx.Horizon.Sdk.Arp
|
|
{
|
|
class ArpApi : IDisposable
|
|
{
|
|
private const string ArpRName = "arp:r";
|
|
|
|
private readonly HeapAllocator _allocator;
|
|
private int _sessionHandle;
|
|
|
|
public ArpApi(HeapAllocator allocator)
|
|
{
|
|
_allocator = allocator;
|
|
}
|
|
|
|
private void InitializeArpRService()
|
|
{
|
|
if (_sessionHandle == 0)
|
|
{
|
|
using var smApi = new SmApi();
|
|
|
|
smApi.Initialize();
|
|
smApi.GetServiceHandle(out _sessionHandle, ServiceName.Encode(ArpRName)).AbortOnFailure();
|
|
}
|
|
}
|
|
|
|
public Result GetApplicationInstanceId(out ulong applicationInstanceId, ulong applicationPid)
|
|
{
|
|
Span<byte> data = stackalloc byte[8];
|
|
SpanWriter writer = new(data);
|
|
|
|
writer.Write(applicationPid);
|
|
|
|
InitializeArpRService();
|
|
|
|
Result result = ServiceUtil.SendRequest(out CmifResponse response, _sessionHandle, 3, sendPid: false, data);
|
|
if (result.IsFailure)
|
|
{
|
|
applicationInstanceId = 0;
|
|
|
|
return result;
|
|
}
|
|
|
|
SpanReader reader = new(response.Data);
|
|
|
|
applicationInstanceId = reader.Read<ulong>();
|
|
|
|
return Result.Success;
|
|
}
|
|
|
|
public Result GetApplicationLaunchProperty(out ApplicationLaunchProperty applicationLaunchProperty, ulong applicationInstanceId)
|
|
{
|
|
applicationLaunchProperty = default;
|
|
|
|
Span<byte> data = stackalloc byte[8];
|
|
SpanWriter writer = new(data);
|
|
|
|
writer.Write(applicationInstanceId);
|
|
|
|
InitializeArpRService();
|
|
|
|
Result result = ServiceUtil.SendRequest(out CmifResponse response, _sessionHandle, 0, sendPid: false, data);
|
|
if (result.IsFailure)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
SpanReader reader = new(response.Data);
|
|
|
|
applicationLaunchProperty = reader.Read<ApplicationLaunchProperty>();
|
|
|
|
return Result.Success;
|
|
}
|
|
|
|
public Result GetApplicationControlProperty(out ApplicationControlProperty applicationControlProperty, ulong applicationInstanceId)
|
|
{
|
|
applicationControlProperty = default;
|
|
|
|
Span<byte> data = stackalloc byte[8];
|
|
SpanWriter writer = new(data);
|
|
|
|
writer.Write(applicationInstanceId);
|
|
|
|
ulong bufferSize = (ulong)Unsafe.SizeOf<ApplicationControlProperty>();
|
|
ulong bufferAddress = _allocator.Allocate(bufferSize);
|
|
|
|
InitializeArpRService();
|
|
|
|
Result result = ServiceUtil.SendRequest(
|
|
out CmifResponse response,
|
|
_sessionHandle,
|
|
1,
|
|
sendPid: false,
|
|
data,
|
|
stackalloc[] { HipcBufferFlags.Out | HipcBufferFlags.MapAlias | HipcBufferFlags.FixedSize },
|
|
stackalloc[] { new PointerAndSize(bufferAddress, bufferSize) });
|
|
|
|
if (result.IsFailure)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
applicationControlProperty = HorizonStatic.AddressSpace.Read<ApplicationControlProperty>(bufferAddress);
|
|
|
|
_allocator.Free(bufferAddress, bufferSize);
|
|
|
|
return Result.Success;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_sessionHandle != 0)
|
|
{
|
|
HorizonStatic.Syscall.CloseHandle(_sessionHandle);
|
|
|
|
_sessionHandle = 0;
|
|
}
|
|
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
}
|
|
}
|