Horizon: Impl Prepo, Fixes bugs, Clean things (#4220)

* Horizon: Impl Prepo, Fixes bugs, Clean things

* remove ToArray()

* resultCode > status

* Remove old services

* Addresses gdkchan's comments and more cleanup

* Addresses Gdkchan's feedback 2

* Reorganize services, make sure service are loaded before guest

Co-Authored-By: gdkchan <5624669+gdkchan@users.noreply.github.com>

* Create interfaces for lm and sm

Co-authored-by: gdkchan <5624669+gdkchan@users.noreply.github.com>
This commit is contained in:
Ac_K 2023-01-08 13:13:39 +01:00 committed by GitHub
parent 3ffceab1fb
commit 550747eac6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
83 changed files with 1106 additions and 880 deletions

View file

@ -5,16 +5,16 @@ namespace Ryujinx.Horizon.Sm.Impl
struct ServiceInfo
{
public ServiceName Name;
public ulong OwnerProcessId;
public int PortHandle;
public ulong OwnerProcessId;
public int PortHandle;
public void Free()
{
HorizonStatic.Syscall.CloseHandle(PortHandle);
Name = ServiceName.Invalid;
Name = ServiceName.Invalid;
OwnerProcessId = 0L;
PortHandle = 0;
PortHandle = 0;
}
}
}
}

View file

@ -107,8 +107,8 @@ namespace Ryujinx.Horizon.Sm.Impl
return result;
}
freeService.PortHandle = clientPort;
freeService.Name = name;
freeService.PortHandle = clientPort;
freeService.Name = name;
freeService.OwnerProcessId = processId;
return Result.Success;
@ -126,20 +126,19 @@ namespace Ryujinx.Horizon.Sm.Impl
// TODO: Validation with GetProcessInfo etc.
int serviceIndex = GetServiceInfo(name);
if (serviceIndex < 0)
{
return SmResult.NotRegistered;
}
ref var serviceInfo = ref _services[serviceIndex];
if (serviceInfo.OwnerProcessId != processId)
{
return SmResult.NotAllowed;
}
serviceInfo.Free();
return Result.Success;
}
@ -194,4 +193,4 @@ namespace Ryujinx.Horizon.Sm.Impl
return -1;
}
}
}
}

View file

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sm;
namespace Ryujinx.Horizon.Sm.Ipc
{
partial class ManagerService : IManagerService
{
}
}

View file

@ -3,14 +3,14 @@ using Ryujinx.Horizon.Sdk.Sf;
using Ryujinx.Horizon.Sdk.Sm;
using Ryujinx.Horizon.Sm.Impl;
namespace Ryujinx.Horizon.Sm
namespace Ryujinx.Horizon.Sm.Ipc
{
partial class UserService : IServiceObject
partial class UserService : IUserService
{
private readonly ServiceManager _serviceManager;
private ulong _clientProcessId;
private bool _initialized;
private bool _initialized;
public UserService(ServiceManager serviceManager)
{
@ -21,7 +21,7 @@ namespace Ryujinx.Horizon.Sm
public Result Initialize([ClientProcessId] ulong clientProcessId)
{
_clientProcessId = clientProcessId;
_initialized = true;
_initialized = true;
return Result.Success;
}
@ -63,4 +63,4 @@ namespace Ryujinx.Horizon.Sm
return _serviceManager.UnregisterService(_clientProcessId, name);
}
}
}
}

View file

@ -1,8 +0,0 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sm
{
partial class ManagerService : IServiceObject
{
}
}

View file

@ -1,30 +1,34 @@
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Prepo.Types;
using Ryujinx.Horizon.Prepo;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
using Ryujinx.Horizon.Sm.Impl;
using Ryujinx.Horizon.Sm.Types;
namespace Ryujinx.Horizon.Sm
{
public class SmMain
{
private enum PortIndex
{
User,
Manager
}
private const int SmMaxSessionsCount = 64;
private const int SmmMaxSessionsCount = 1;
private const int SmTotalMaxSessionsCount = SmMaxSessionsCount + SmmMaxSessionsCount;
private const int MaxPortsCount = 2;
private readonly ServerManager _serverManager = new ServerManager(null, null, MaxPortsCount, ManagerOptions.Default, 0);
private readonly ServiceManager _serviceManager = new ServiceManager();
private SmServerManager _serverManager;
private readonly ServiceManager _serviceManager = new();
public void Main()
{
HorizonStatic.Syscall.ManageNamedPort(out int smHandle, "sm:", 64).AbortOnFailure();
HorizonStatic.Syscall.ManageNamedPort(out int smHandle, "sm:", SmMaxSessionsCount).AbortOnFailure();
_serverManager.RegisterServer((int)PortIndex.User, smHandle);
_serviceManager.RegisterServiceForSelf(out int smmHandle, ServiceName.Encode("sm:m"), 1).AbortOnFailure();
_serverManager.RegisterServer((int)PortIndex.Manager, smmHandle);
_serverManager = new SmServerManager(_serviceManager, null, null, MaxPortsCount, ManagerOptions.Default, SmTotalMaxSessionsCount);
_serverManager.RegisterServer((int)SmPortIndex.User, smHandle);
_serviceManager.RegisterServiceForSelf(out int smmHandle, ServiceName.Encode("sm:m"), SmmMaxSessionsCount).AbortOnFailure();
_serverManager.RegisterServer((int)SmPortIndex.Manager, smmHandle);
_serverManager.ServiceRequests();
}
}
}
}

View file

@ -6,14 +6,14 @@ namespace Ryujinx.Horizon.Sm
{
private const int ModuleId = 21;
public static Result OutOfProcess => new Result(ModuleId, 1);
public static Result InvalidClient => new Result(ModuleId, 2);
public static Result OutOfSessions => new Result(ModuleId, 3);
public static Result AlreadyRegistered => new Result(ModuleId, 4);
public static Result OutOfServices => new Result(ModuleId, 5);
public static Result InvalidServiceName => new Result(ModuleId, 6);
public static Result NotRegistered => new Result(ModuleId, 7);
public static Result NotAllowed => new Result(ModuleId, 8);
public static Result TooLargeAccessControl => new Result(ModuleId, 9);
public static Result OutOfProcess => new(ModuleId, 1);
public static Result InvalidClient => new(ModuleId, 2);
public static Result OutOfSessions => new(ModuleId, 3);
public static Result AlreadyRegistered => new(ModuleId, 4);
public static Result OutOfServices => new(ModuleId, 5);
public static Result InvalidServiceName => new(ModuleId, 6);
public static Result NotRegistered => new(ModuleId, 7);
public static Result NotAllowed => new(ModuleId, 8);
public static Result TooLargeAccessControl => new(ModuleId, 9);
}
}
}

View file

@ -0,0 +1,30 @@
using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
using Ryujinx.Horizon.Sm.Impl;
using Ryujinx.Horizon.Sm.Ipc;
using Ryujinx.Horizon.Sm.Types;
using System;
namespace Ryujinx.Horizon.Sm
{
class SmServerManager : ServerManager
{
private readonly ServiceManager _serviceManager;
public SmServerManager(ServiceManager serviceManager, HeapAllocator allocator, SmApi sm, int maxPorts, ManagerOptions options, int maxSessions) : base(allocator, sm, maxPorts, options, maxSessions)
{
_serviceManager = serviceManager;
}
protected override Result OnNeedsToAccept(int portIndex, Server server)
{
return (SmPortIndex)portIndex switch
{
SmPortIndex.User => AcceptImpl(server, new UserService(_serviceManager)),
SmPortIndex.Manager => AcceptImpl(server, new ManagerService()),
_ => throw new ArgumentOutOfRangeException(nameof(portIndex)),
};
}
}
}

View file

@ -0,0 +1,8 @@
namespace Ryujinx.Horizon.Sm.Types
{
enum SmPortIndex
{
User,
Manager
}
}