Enable full trimming

Enables full trimming for Ryujinx, and in doing so removes many usages of reflection, namely:

IUserService no longer uses reflection to find possible service types, and now has a generated switch based on name

Ryujinx.HLE.HOS.Tamper no longer uses dynamic to do operations, now using INumber<T> and friends

Cmif and Tipc commands in Ryujinx.HLE.HOS.Services no longer get resolved via reflection and are now done via generated virtual methods

Fix things broken by trimming (profile panel, DiscordRPC)
This commit is contained in:
Aaron Robinson
2025-11-19 00:32:38 -06:00
committed by KeatonTheBot
parent 32ee806070
commit c76f65904d
181 changed files with 794 additions and 552 deletions

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
{
class IManagerForApplication : IpcService
partial class IManagerForApplication : IpcService
{
private readonly ManagerServer _managerServer;

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
{
class IManagerForSystemService : IpcService
partial class IManagerForSystemService : IpcService
{
private readonly ManagerServer _managerServer;

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
{
class IProfile : IpcService
partial class IProfile : IpcService
{
private readonly ProfileServer _profileServer;

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
{
class IProfileEditor : IpcService
partial class IProfileEditor : IpcService
{
private readonly ProfileServer _profileServer;

View File

@@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc.AccountService;
namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
[Service("acc:su", AccountServiceFlag.Administrator)] // Max Sessions: 8
class IAccountServiceForAdministrator : IpcService
partial class IAccountServiceForAdministrator : IpcService
{
private readonly ApplicationServiceServer _applicationServiceServer;

View File

@@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Arp;
namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
[Service("acc:u0", AccountServiceFlag.Application)] // Max Sessions: 4
class IAccountServiceForApplication : IpcService
partial class IAccountServiceForApplication : IpcService
{
private readonly ApplicationServiceServer _applicationServiceServer;

View File

@@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc.AccountService;
namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
[Service("acc:u1", AccountServiceFlag.SystemService)] // Max Sessions: 16
class IAccountServiceForSystemService : IpcService
partial class IAccountServiceForSystemService : IpcService
{
private readonly ApplicationServiceServer _applicationServiceServer;

View File

@@ -5,7 +5,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
class IAsyncContext : IpcService
partial class IAsyncContext : IpcService
{
protected AsyncExecution AsyncExecution;

View File

@@ -2,7 +2,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc.AsyncContext;
namespace Ryujinx.HLE.HOS.Services.Account.Acc
{
class IAsyncNetworkServiceLicenseKindContext : IAsyncContext
partial class IAsyncNetworkServiceLicenseKindContext : IAsyncContext
{
private readonly NetworkServiceLicenseKind? _serviceLicenseKind;

View File

@@ -3,6 +3,6 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
[Service("acc:aa", AccountServiceFlag.BaasAccessTokenAccessor)] // Max Sessions: 4
class IBaasAccessTokenAccessor : IpcService
{
public IBaasAccessTokenAccessor(ServiceCtx context) { }
public IBaasAccessTokenAccessor(ServiceCtx context, AccountServiceFlag serviceFlag) { }
}
}

View File

@@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemA
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService
{
class ILibraryAppletProxy : IpcService
partial class ILibraryAppletProxy : IpcService
{
private readonly ulong _pid;

View File

@@ -2,7 +2,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemA
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService
{
class ISystemAppletProxy : IpcService
partial class ISystemAppletProxy : IpcService
{
private readonly ulong _pid;

View File

@@ -9,7 +9,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletCreator
{
class ILibraryAppletAccessor : DisposableIpcService
partial class ILibraryAppletAccessor : DisposableIpcService
{
private readonly KernelContext _kernelContext;

View File

@@ -3,7 +3,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy
{
class ILibraryAppletSelfAccessor : IpcService
partial class ILibraryAppletSelfAccessor : IpcService
{
private readonly AppletStandalone _appletStandalone = new();

View File

@@ -2,7 +2,7 @@ using Ryujinx.Common;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy
{
class IProcessWindingController : IpcService
partial class IProcessWindingController : IpcService
{
public IProcessWindingController() { }

View File

@@ -2,7 +2,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class IAudioController : IpcService
partial class IAudioController : IpcService
{
public IAudioController() { }

View File

@@ -10,7 +10,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class ICommonStateGetter : DisposableIpcService
partial class ICommonStateGetter : DisposableIpcService
{
private readonly ServiceCtx _context;

View File

@@ -6,7 +6,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class IDisplayController : IpcService
partial class IDisplayController : IpcService
{
private readonly KTransferMemory _transferMem;
private bool _lastApplicationCaptureBufferAcquired;

View File

@@ -6,7 +6,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class IHomeMenuFunctions : IpcService
partial class IHomeMenuFunctions : IpcService
{
private readonly KEvent _channelEvent;
private int _channelEventHandle;

View File

@@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Library
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class ILibraryAppletCreator : IpcService
partial class ILibraryAppletCreator : IpcService
{
public ILibraryAppletCreator() { }

View File

@@ -8,7 +8,7 @@ using System.Threading;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class ISelfController : IpcService
partial class ISelfController : IpcService
{
private readonly ulong _pid;

View File

@@ -2,7 +2,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
class IWindowController : IpcService
partial class IWindowController : IpcService
{
private readonly ulong _pid;

View File

@@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE
{
[Service("appletAE")]
class IAllSystemAppletProxiesService : IpcService
partial class IAllSystemAppletProxiesService : IpcService
{
public IAllSystemAppletProxiesService(ServiceCtx context) { }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE
{
class IStorage : IpcService
partial class IStorage : IpcService
{
public bool IsReadOnly { get; private set; }
public byte[] Data { get; private set; }

View File

@@ -2,7 +2,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE
{
class IStorageAccessor : IpcService
partial class IStorageAccessor : IpcService
{
private readonly IStorage _storage;

View File

@@ -22,7 +22,7 @@ using ApplicationId = LibHac.Ncm.ApplicationId;
namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy
{
class IApplicationFunctions : IpcService
partial class IApplicationFunctions : IpcService
{
private long _defaultSaveDataSize = 200000000;
private long _defaultJournalSaveDataSize = 200000000;

View File

@@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationPr
namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService
{
class IApplicationProxy : IpcService
partial class IApplicationProxy : IpcService
{
private readonly ulong _pid;

View File

@@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService;
namespace Ryujinx.HLE.HOS.Services.Am
{
[Service("appletOE")]
class IApplicationProxyService : IpcService
partial class IApplicationProxyService : IpcService
{
public IApplicationProxyService(ServiceCtx context) { }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Apm
{
abstract class IManager : IpcService
abstract partial class IManager : IpcService
{
public IManager(ServiceCtx context) { }

View File

@@ -3,7 +3,7 @@ namespace Ryujinx.HLE.HOS.Services.Apm
// NOTE: This service doesnt exist anymore after firmware 7.0.1. But some outdated homebrew still uses it.
[Service("apm:p")] // 1.0.0-7.0.1
class IManagerPrivileged : IpcService
partial class IManagerPrivileged : IpcService
{
public IManagerPrivileged(ServiceCtx context) { }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Apm
{
abstract class ISession : IpcService
abstract partial class ISession : IpcService
{
public ISession(ServiceCtx context) { }

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Apm
{
abstract class ISystemManager : IpcService
abstract partial class ISystemManager : IpcService
{
public ISystemManager(ServiceCtx context) { }

View File

@@ -8,7 +8,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Bluetooth
{
[Service("btdrv")]
class IBluetoothDriver : IpcService
partial class IBluetoothDriver : IpcService
{
#pragma warning disable CS0414, IDE0052 // Remove unread private member
private string _unknownLowEnergy;

View File

@@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Settings;
namespace Ryujinx.HLE.HOS.Services.Bluetooth
{
[Service("bt")]
class IBluetoothUser : IpcService
partial class IBluetoothUser : IpcService
{
public IBluetoothUser(ServiceCtx context) { }

View File

@@ -5,7 +5,7 @@ using Ryujinx.Horizon.Common;
namespace Ryujinx.HLE.HOS.Services.BluetoothManager.BtmUser
{
class IBtmUserCore : IpcService
partial class IBtmUserCore : IpcService
{
public KEvent _bleScanEvent;
public int _bleScanEventHandle;

View File

@@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.BluetoothManager.BtmUser;
namespace Ryujinx.HLE.HOS.Services.BluetoothManager
{
[Service("btm:u")] // 5.0.0+
class IBtmUser : IpcService
partial class IBtmUser : IpcService
{
public IBtmUser(ServiceCtx context) { }

View File

@@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Caps.Types;
namespace Ryujinx.HLE.HOS.Services.Caps
{
[Service("caps:u")]
class IAlbumApplicationService : IpcService
partial class IAlbumApplicationService : IpcService
{
public IAlbumApplicationService(ServiceCtx context) { }

View File

@@ -1,7 +1,7 @@
namespace Ryujinx.HLE.HOS.Services.Caps
{
[Service("caps:c")]
class IAlbumControlService : IpcService
partial class IAlbumControlService : IpcService
{
public IAlbumControlService(ServiceCtx context) { }

View File

@@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Caps.Types;
namespace Ryujinx.HLE.HOS.Services.Caps
{
[Service("caps:su")] // 6.0.0+
class IScreenShotApplicationService : IpcService
partial class IScreenShotApplicationService : IpcService
{
public IScreenShotApplicationService(ServiceCtx context) { }

View File

@@ -4,7 +4,7 @@ using Ryujinx.Horizon.Common;
namespace Ryujinx.HLE.HOS.Services.Ectx
{
class IContextRegistrar : DisposableIpcService
partial class IContextRegistrar : DisposableIpcService
{
public IContextRegistrar(ServiceCtx context) { }

View File

@@ -1,7 +1,7 @@
namespace Ryujinx.HLE.HOS.Services.Ectx
{
[Service("ectx:aw")] // 11.0.0+
class IWriterForApplication : IpcService
partial class IWriterForApplication : IpcService
{
public IWriterForApplication(ServiceCtx context) { }

View File

@@ -7,7 +7,7 @@ using System.Text;
namespace Ryujinx.HLE.HOS.Services.Fatal
{
[Service("fatal:u")]
class IService : IpcService
partial class IService : IpcService
{
public IService(ServiceCtx context) { }

View File

@@ -5,7 +5,7 @@ using Ryujinx.Memory;
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
class IDirectory : DisposableIpcService
partial class IDirectory : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.IDirectory> _baseDirectory;

View File

@@ -7,7 +7,7 @@ using Ryujinx.Memory;
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
class IFile : DisposableIpcService
partial class IFile : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.IFile> _baseFile;

View File

@@ -7,7 +7,7 @@ using Path = LibHac.FsSrv.Sf.Path;
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
class IFileSystem : DisposableIpcService
partial class IFileSystem : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.IFileSystem> _fileSystem;

View File

@@ -10,7 +10,7 @@ using System.Threading;
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
{
class IStorage : DisposableIpcService
partial class IStorage : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.IStorage> _baseStorage;

View File

@@ -5,7 +5,7 @@ using GameCardHandle = System.UInt32;
namespace Ryujinx.HLE.HOS.Services.Fs
{
class IDeviceOperator : DisposableIpcService
partial class IDeviceOperator : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.IDeviceOperator> _baseOperator;

View File

@@ -25,7 +25,7 @@ using IStorage = LibHac.FsSrv.Sf.IStorage;
namespace Ryujinx.HLE.HOS.Services.Fs
{
[Service("fsp-srv")]
class IFileSystemProxy : DisposableIpcService
partial class IFileSystemProxy : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.IFileSystemProxy> _baseFileSystemProxy;
private ulong _pid;

View File

@@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy;
namespace Ryujinx.HLE.HOS.Services.Fs
{
class IMultiCommitManager : DisposableIpcService // 6.0.0+
partial class IMultiCommitManager : DisposableIpcService // 6.0.0+
{
private SharedRef<LibHac.FsSrv.Sf.IMultiCommitManager> _baseCommitManager;

View File

@@ -5,7 +5,7 @@ using Ryujinx.Memory;
namespace Ryujinx.HLE.HOS.Services.Fs
{
class ISaveDataInfoReader : DisposableIpcService
partial class ISaveDataInfoReader : DisposableIpcService
{
private SharedRef<LibHac.FsSrv.Sf.ISaveDataInfoReader> _baseReader;

View File

@@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Hid.HidServer
{
class IActiveApplicationDeviceList : IpcService
partial class IActiveApplicationDeviceList : IpcService
{
public IActiveApplicationDeviceList() { }

View File

@@ -5,7 +5,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Hid.HidServer
{
class IAppletResource : IpcService
partial class IAppletResource : IpcService
{
private readonly KSharedMemory _hidSharedMem;
private int _hidSharedMemHandle;

View File

@@ -13,7 +13,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Hid
{
[Service("hid")]
class IHidServer : IpcService
partial class IHidServer : IpcService
{
private readonly KEvent _xpadIdEvent;
private readonly KEvent _palmaOperationCompleteEvent;

View File

@@ -5,7 +5,7 @@ using Ryujinx.HLE.HOS.Services.Hid.Types;
namespace Ryujinx.HLE.HOS.Services.Hid
{
[Service("hid:sys")]
class IHidSystemServer : IpcService
partial class IHidSystemServer : IpcService
{
public IHidSystemServer(ServiceCtx context) { }

View File

@@ -4,7 +4,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Hid
{
[Service("hidbus")]
class IHidbusServer : IpcService
partial class IHidbusServer : IpcService
{
public IHidbusServer(ServiceCtx context) { }

View File

@@ -9,7 +9,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Hid.Irs
{
[Service("irs")]
class IIrSensorServer : IpcService
partial class IIrSensorServer : IpcService
{
private int _irsensorSharedMemoryHandle = 0;

View File

@@ -13,9 +13,6 @@ namespace Ryujinx.HLE.HOS.Services
{
abstract class IpcService
{
public IReadOnlyDictionary<int, MethodInfo> CmifCommands { get; }
public IReadOnlyDictionary<int, MethodInfo> TipcCommands { get; }
public ServerBase Server { get; private set; }
private IpcService _parent;
@@ -23,46 +20,8 @@ namespace Ryujinx.HLE.HOS.Services
private int _selfId;
private bool _isDomain;
// cache array so we don't recreate it all the time
private object[] _parameters = [null];
public IpcService(ServerBase server = null, bool registerTipc = false)
public IpcService(ServerBase server = null)
{
Stopwatch sw = Stopwatch.StartNew();
CmifCommands = GetType()
.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)
.SelectMany(methodInfo => methodInfo.GetCustomAttributes<CommandCmifAttribute>()
.Select(command => (command.Id, methodInfo)))
.ToDictionary(command => command.Id, command => command.methodInfo);
sw.Stop();
Logger.Debug?.Print(
LogClass.Emulation,
$"{CmifCommands.Count} Cmif commands loaded in {sw.ElapsedTicks} ticks ({Stopwatch.Frequency} tps).",
GetType().AsPrettyString()
);
if (registerTipc)
{
sw.Start();
TipcCommands = GetType()
.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)
.SelectMany(methodInfo => methodInfo.GetCustomAttributes<CommandTipcAttribute>()
.Select(command => (command.Id, methodInfo)))
.ToDictionary(command => command.Id, command => command.methodInfo);
sw.Stop();
Logger.Debug?.Print(
LogClass.Emulation,
$"{TipcCommands.Count} Tipc commands loaded in {sw.ElapsedTicks} ticks ({Stopwatch.Frequency} tps).",
GetType().AsPrettyString()
);
}
Server = server;
_parent = this;
@@ -87,6 +46,49 @@ namespace Ryujinx.HLE.HOS.Services
_isDomain = false;
}
protected virtual ResultCode InvokeCmifMethod(int id, ServiceCtx context)
{
if (!context.Device.Configuration.IgnoreMissingServices)
{
string dbgMessage = $"{this.GetType().FullName}: {id}";
throw new ServiceNotImplementedException(this, context, dbgMessage);
}
string serviceName = (this is not DummyService dummyService)
? this.GetType().FullName
: dummyService.ServiceName;
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {id} ignored");
return ResultCode.Success;
}
public virtual int CmifCommandIdByMethodName(string name) => -1;
protected virtual ResultCode InvokeTipcMethod(int id, ServiceCtx context)
{
if (!context.Device.Configuration.IgnoreMissingServices)
{
string dbgMessage = $"{this.GetType().FullName}: {id}";
throw new ServiceNotImplementedException(this, context, dbgMessage);
}
string serviceName = (this is not DummyService dummyService)
? this.GetType().FullName
: dummyService.ServiceName;
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {id} ignored");
return ResultCode.Success;
}
public virtual int TipcCommandIdByMethodName(string name) => -1;
protected void LogInvoke(string name)
=> Logger.Trace?.Print(LogClass.KernelIpc, $"{this.GetType().Name}: {name}");
public void CallCmifMethod(ServiceCtx context)
{
IpcService service = this;
@@ -137,93 +139,39 @@ namespace Ryujinx.HLE.HOS.Services
#pragma warning restore IDE0059
int commandId = (int)context.RequestData.ReadInt64();
bool serviceExists = service.CmifCommands.TryGetValue(commandId, out MethodInfo processRequest);
context.ResponseData.BaseStream.Seek(_isDomain ? 0x20 : 0x10, SeekOrigin.Begin);
if (context.Device.Configuration.IgnoreMissingServices || serviceExists)
ResultCode result = service.InvokeCmifMethod(commandId, context);
if (_isDomain)
{
ResultCode result = ResultCode.Success;
context.ResponseData.BaseStream.Seek(_isDomain ? 0x20 : 0x10, SeekOrigin.Begin);
if (serviceExists)
foreach (int id in context.Response.ObjectIds)
{
Logger.Trace?.Print(LogClass.KernelIpc, $"{service.GetType().Name}: {processRequest.Name}");
_parameters[0] = context;
result = (ResultCode)processRequest.Invoke(service, _parameters);
}
else
{
string serviceName = (service is not DummyService dummyService) ? service.GetType().FullName : dummyService.ServiceName;
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {commandId} ignored");
context.ResponseData.Write(id);
}
if (_isDomain)
{
foreach (int id in context.Response.ObjectIds)
{
context.ResponseData.Write(id);
}
context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
context.ResponseData.Write(context.Response.ObjectIds.Count);
}
context.ResponseData.BaseStream.Seek(_isDomain ? 0x10 : 0, SeekOrigin.Begin);
context.ResponseData.Write(IpcMagic.Sfco);
context.ResponseData.Write((long)result);
context.ResponseData.Write(context.Response.ObjectIds.Count);
}
else
{
string dbgMessage = $"{service.GetType().FullName}: {commandId}";
throw new ServiceNotImplementedException(service, context, dbgMessage);
}
context.ResponseData.BaseStream.Seek(_isDomain ? 0x10 : 0, SeekOrigin.Begin);
context.ResponseData.Write(IpcMagic.Sfco);
context.ResponseData.Write((long)result);
}
public void CallTipcMethod(ServiceCtx context)
{
int commandId = (int)context.Request.Type - 0x10;
bool serviceExists = TipcCommands.TryGetValue(commandId, out MethodInfo processRequest);
context.ResponseData.BaseStream.Seek(0x4, SeekOrigin.Begin);
if (context.Device.Configuration.IgnoreMissingServices || serviceExists)
{
ResultCode result = ResultCode.Success;
ResultCode result = InvokeTipcMethod(commandId, context);
context.ResponseData.BaseStream.Seek(0x4, SeekOrigin.Begin);
context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
if (serviceExists)
{
Logger.Debug?.Print(LogClass.KernelIpc, $"{GetType().Name}: {processRequest.Name}");
_parameters[0] = context;
result = (ResultCode)processRequest.Invoke(this, _parameters);
}
else
{
string serviceName;
serviceName = (this is not DummyService dummyService) ? GetType().FullName : dummyService.ServiceName;
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {commandId} ignored");
}
context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin);
context.ResponseData.Write((uint)result);
}
else
{
string dbgMessage = $"{GetType().FullName}: {commandId}";
throw new ServiceNotImplementedException(this, context, dbgMessage);
}
context.ResponseData.Write((uint)result);
}
protected void MakeObject(ServiceCtx context, IpcService obj)

View File

@@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator;
namespace Ryujinx.HLE.HOS.Services.Ldn
{
[Service("ldn:u")]
class IUserServiceCreator : IpcService
partial class IUserServiceCreator : IpcService
{
public IUserServiceCreator(ServiceCtx context) : base(context.Device.System.LdnServer) { }

View File

@@ -2,7 +2,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.Lp2p
{
[Service("lp2p:app")] // 9.0.0+
[Service("lp2p:sys")] // 9.0.0+
class IServiceCreator : IpcService
partial class IServiceCreator : IpcService
{
public IServiceCreator(ServiceCtx context) { }

View File

@@ -2,7 +2,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Ldn.Lp2p
{
class ISfService : IpcService
partial class ISfService : IpcService
{
public ISfService(ServiceCtx context) { }

View File

@@ -6,7 +6,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Ldn.Lp2p
{
class ISfServiceMonitor : IpcService
partial class ISfServiceMonitor : IpcService
{
private readonly KEvent _stateChangeEvent;
private readonly KEvent _jointEvent;

View File

@@ -2,7 +2,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
{
class IClientProcessMonitor : DisposableIpcService
partial class IClientProcessMonitor : DisposableIpcService
{
public IClientProcessMonitor(ServiceCtx context) { }

View File

@@ -23,7 +23,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
{
class IUserLocalCommunicationService : IpcService, IDisposable
partial class IUserLocalCommunicationService : IpcService, IDisposable
{
public INetworkClient NetworkClient { get; private set; }

View File

@@ -3,7 +3,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Mii
{
[Service("miiimg")] // 5.0.0+
class IImageDatabaseService : IpcService
partial class IImageDatabaseService : IpcService
{
private uint _imageCount;
private bool _isDirty;

View File

@@ -6,7 +6,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii
{
[Service("mii:e", true)]
[Service("mii:u", false)]
class IStaticService : IpcService
partial class IStaticService : IpcService
{
private readonly DatabaseImpl _databaseImpl;

View File

@@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Mii.StaticService
{
abstract class IDatabaseService : IpcService
abstract partial class IDatabaseService : IpcService
{
[CommandCmif(0)]
// IsUpdated(SourceFlag flag) -> bool

View File

@@ -6,7 +6,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc;
namespace Ryujinx.HLE.HOS.Services.Mnpp
{
[Service("mnpp:app")] // 13.0.0+
class IServiceForApplication : IpcService
partial class IServiceForApplication : IpcService
{
public IServiceForApplication(ServiceCtx context) { }

View File

@@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager;
namespace Ryujinx.HLE.HOS.Services.Ncm.Lr
{
[Service("lr")]
class ILocationResolverManager : IpcService
partial class ILocationResolverManager : IpcService
{
public ILocationResolverManager(ServiceCtx context) { }

View File

@@ -6,7 +6,7 @@ using static Ryujinx.HLE.Utilities.StringUtils;
namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
{
class ILocationResolver : IpcService
partial class ILocationResolver : IpcService
{
private readonly StorageId _storageId;

View File

@@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.NfcManager;
namespace Ryujinx.HLE.HOS.Services.Nfc
{
[Service("nfc:sys")]
class ISystemManager : IpcService
partial class ISystemManager : IpcService
{
public ISystemManager(ServiceCtx context) { }

View File

@@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.NfcManager;
namespace Ryujinx.HLE.HOS.Services.Nfc
{
[Service("nfc:user")]
class IUserManager : IpcService
partial class IUserManager : IpcService
{
public IUserManager(ServiceCtx context) { }

View File

@@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.Mifare.MifareManager;
namespace Ryujinx.HLE.HOS.Services.Nfc.Mifare
{
[Service("nfc:mf:u")]
class IUserManager : IpcService
partial class IUserManager : IpcService
{
public IUserManager(ServiceCtx context) { }

View File

@@ -14,7 +14,7 @@ using System.Threading.Tasks;
namespace Ryujinx.HLE.HOS.Services.Nfc.Mifare.MifareManager
{
class IMifare : IpcService
partial class IMifare : IpcService
{
private State _state;

View File

@@ -2,7 +2,7 @@ using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Nfc.NfcManager
{
class INfc : IpcService
partial class INfc : IpcService
{
private readonly NfcPermissionLevel _permissionLevel;
private State _state;

View File

@@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager;
namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
{
[Service("nfp:dbg")]
class IAmManager : IpcService
partial class IAmManager : IpcService
{
public IAmManager(ServiceCtx context) { }

View File

@@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager;
namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
{
[Service("nfp:sys")]
class ISystemManager : IpcService
partial class ISystemManager : IpcService
{
public ISystemManager(ServiceCtx context) { }

View File

@@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager;
namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
{
[Service("nfp:user")]
class IUserManager : IpcService
partial class IUserManager : IpcService
{
public IUserManager(ServiceCtx context) { }

View File

@@ -16,7 +16,7 @@ using System.Threading.Tasks;
namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
{
class INfp : IpcService
partial class INfp : IpcService
{
#pragma warning disable IDE0052 // Remove unread private member
private ulong _appletResourceUserId;

View File

@@ -1,7 +1,7 @@
namespace Ryujinx.HLE.HOS.Services.Ngct
{
[Service("ngct:u")] // 9.0.0+
class IService : IpcService
partial class IService : IpcService
{
public IService(ServiceCtx context) { }

View File

@@ -1,7 +1,7 @@
namespace Ryujinx.HLE.HOS.Services.Ngct
{
[Service("ngct:s")] // 9.0.0+
class IServiceWithManagementApi : IpcService
partial class IServiceWithManagementApi : IpcService
{
public IServiceWithManagementApi(ServiceCtx context) { }

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm
[Service("nifm:a")] // Max sessions: 2
[Service("nifm:s")] // Max sessions: 16
[Service("nifm:u")] // Max sessions: 5
class IStaticService : IpcService
partial class IStaticService : IpcService
{
public IStaticService(ServiceCtx context) { }

View File

@@ -10,7 +10,7 @@ using System.Runtime.CompilerServices;
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
{
class IGeneralService : DisposableIpcService
partial class IGeneralService : DisposableIpcService
{
private readonly GeneralServiceDetail _generalServiceDetail;

View File

@@ -6,7 +6,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
{
class IRequest : IpcService
partial class IRequest : IpcService
{
private enum RequestState
{

View File

@@ -3,7 +3,7 @@ using Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceA
namespace Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface
{
class IShopServiceAccessServer : IpcService
partial class IShopServiceAccessServer : IpcService
{
public IShopServiceAccessServer() { }

View File

@@ -6,7 +6,7 @@ using Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface;
namespace Ryujinx.HLE.HOS.Services.Nim
{
[Service("nim:eca")] // 5.0.0+
class IShopServiceAccessServerInterface : IpcService
partial class IShopServiceAccessServerInterface : IpcService
{
public IShopServiceAccessServerInterface(ServiceCtx context) { }

View File

@@ -7,7 +7,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceAccessServer
{
class IShopServiceAccessor : IpcService
partial class IShopServiceAccessor : IpcService
{
private readonly KEvent _event;

View File

@@ -4,7 +4,7 @@ using Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService;
namespace Ryujinx.HLE.HOS.Services.Nim.Ntc
{
[Service("ntc")]
class IStaticService : IpcService
partial class IStaticService : IpcService
{
public IStaticService(ServiceCtx context) { }

View File

@@ -6,7 +6,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService
{
class IEnsureNetworkClockAvailabilityService : IpcService
partial class IEnsureNetworkClockAvailabilityService : IpcService
{
private readonly KEvent _finishNotificationEvent;
private ResultCode _taskResultCode;

View File

@@ -8,7 +8,7 @@ using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Ns.Aoc
{
[Service("aoc:u")]
class IAddOnContentManager : IpcService
partial class IAddOnContentManager : IpcService
{
private readonly KEvent _addOnContentListChangedEvent;
private int _addOnContentListChangedEventHandle;

View File

@@ -6,7 +6,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Ns.Aoc
{
class IPurchaseEventManager : IpcService
partial class IPurchaseEventManager : IpcService
{
private readonly KEvent _purchasedEvent;

View File

@@ -4,7 +4,7 @@ using Ryujinx.Common.Utilities;
namespace Ryujinx.HLE.HOS.Services.Ns
{
[Service("ns:am")]
class IApplicationManagerInterface : IpcService
partial class IApplicationManagerInterface : IpcService
{
public IApplicationManagerInterface(ServiceCtx context) { }

View File

@@ -3,7 +3,7 @@ using LibHac.Ns;
namespace Ryujinx.HLE.HOS.Services.Ns
{
class IReadOnlyApplicationControlDataInterface : IpcService
partial class IReadOnlyApplicationControlDataInterface : IpcService
{
public IReadOnlyApplicationControlDataInterface(ServiceCtx context) { }

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns
[Service("ns:rid")]
[Service("ns:rt")]
[Service("ns:web")]
class IServiceGetterInterface : IpcService
partial class IServiceGetterInterface : IpcService
{
public IServiceGetterInterface(ServiceCtx context) { }

View File

@@ -24,7 +24,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv
[Service("nvdrv:a")]
[Service("nvdrv:s")]
[Service("nvdrv:t")]
class INvDrvServices : IpcService
partial class INvDrvServices : IpcService
{
private static readonly List<string> _deviceFileDebugRegistry =
[
@@ -32,20 +32,20 @@ namespace Ryujinx.HLE.HOS.Services.Nv
"/dev/nvhost-prof-gpu"
];
private static readonly Dictionary<string, Type> _deviceFileRegistry = new()
private static readonly Dictionary<string, Func<ServiceCtx, IVirtualMemoryManager, ulong, NvDeviceFile>> _deviceFileRegistry = new()
{
{ "/dev/nvmap", typeof(NvMapDeviceFile) },
{ "/dev/nvhost-ctrl", typeof(NvHostCtrlDeviceFile) },
{ "/dev/nvhost-ctrl-gpu", typeof(NvHostCtrlGpuDeviceFile) },
{ "/dev/nvhost-as-gpu", typeof(NvHostAsGpuDeviceFile) },
{ "/dev/nvhost-gpu", typeof(NvHostGpuDeviceFile) },
//{ "/dev/nvhost-msenc", typeof(NvHostChannelDeviceFile) },
{ "/dev/nvhost-nvdec", typeof(NvHostChannelDeviceFile) },
//{ "/dev/nvhost-nvjpg", typeof(NvHostChannelDeviceFile) },
{ "/dev/nvhost-vic", typeof(NvHostChannelDeviceFile) },
//{ "/dev/nvhost-display", typeof(NvHostChannelDeviceFile) },
{ "/dev/nvhost-dbg-gpu", typeof(NvHostDbgGpuDeviceFile) },
{ "/dev/nvhost-prof-gpu", typeof(NvHostProfGpuDeviceFile) },
{ "/dev/nvmap", (ctx, mem, owner) => new NvMapDeviceFile(ctx, mem, owner) },
{ "/dev/nvhost-ctrl", (ctx, mem, owner) => new NvHostCtrlDeviceFile(ctx, mem, owner) },
{ "/dev/nvhost-ctrl-gpu", (ctx, mem, owner) => new NvHostCtrlGpuDeviceFile(ctx, mem, owner) },
{ "/dev/nvhost-as-gpu", (ctx, mem, owner) => new NvHostAsGpuDeviceFile(ctx, mem, owner) },
{ "/dev/nvhost-gpu", (ctx, mem, owner) => new NvHostGpuDeviceFile(ctx, mem, owner) },
//{ "/dev/nvhost-msenc", (ctx, mem, owner) => new NvHostChannelDeviceFile(ctx, mem, owner) },
{ "/dev/nvhost-nvdec", (ctx, mem, owner) => new NvHostChannelDeviceFile(ctx, mem, owner) },
//{ "/dev/nvhost-nvjpg", (ctx, mem, owner) => new NvHostChannelDeviceFile(ctx, mem, owner) },
{ "/dev/nvhost-vic", (ctx, mem, owner) => new NvHostChannelDeviceFile(ctx, mem, owner) },
//{ "/dev/nvhost-display", (ctx, mem, owner) => new NvHostChannelDeviceFile(ctx, mem, owner) },
{ "/dev/nvhost-dbg-gpu", (ctx, mem, owner) => new NvHostDbgGpuDeviceFile(ctx, mem, owner) },
{ "/dev/nvhost-prof-gpu", (ctx, mem, owner) => new NvHostProfGpuDeviceFile(ctx, mem, owner) },
};
private static readonly ArrayPool<byte> _byteArrayPool = ArrayPool<byte>.Create();
@@ -78,12 +78,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv
return NvResult.NotSupported;
}
if (_deviceFileRegistry.TryGetValue(path, out Type deviceFileClass))
if (_deviceFileRegistry.TryGetValue(path, out Func<ServiceCtx, IVirtualMemoryManager, ulong, NvDeviceFile> deviceFileFactory))
{
ConstructorInfo constructor = deviceFileClass.GetConstructor([typeof(ServiceCtx), typeof(IVirtualMemoryManager), typeof(ulong)
]);
NvDeviceFile deviceFile = (NvDeviceFile)constructor.Invoke([context, _clientMemory, _owner]);
NvDeviceFile deviceFile = deviceFileFactory(context, _clientMemory, _owner);
deviceFile.Path = path;

View File

@@ -6,7 +6,7 @@ using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Olsc
{
[Service("olsc:u")] // 10.0.0+
class IOlscServiceForApplication : IpcService
partial class IOlscServiceForApplication : IpcService
{
private bool _initialized;
private Dictionary<UserId, bool> _saveDataBackupSettingDatabase;

View File

@@ -6,7 +6,7 @@ namespace Ryujinx.HLE.HOS.Services.Pctl
[Service("pctl:a", 0x83BE)]
[Service("pctl:r", 0x8040)]
[Service("pctl:s", 0x838E)]
class IParentalControlServiceFactory : IpcService
partial class IParentalControlServiceFactory : IpcService
{
private readonly int _permissionFlag;

View File

@@ -5,7 +5,7 @@ using static LibHac.Ns.ApplicationControlProperty;
namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory
{
class IParentalControlService : IpcService
partial class IParentalControlService : IpcService
{
private readonly ulong _pid;
private readonly int _permissionFlag;

View File

@@ -3,7 +3,7 @@ using System;
namespace Ryujinx.HLE.HOS.Services.Pcv.Bpc
{
[Service("bpc:r")] // 1.0.0 - 8.1.0
class IRtcManager : IpcService
partial class IRtcManager : IpcService
{
public IRtcManager(ServiceCtx context) { }

View File

@@ -4,7 +4,7 @@ using System.Linq;
namespace Ryujinx.HLE.HOS.Services.Pcv.Clkrst.ClkrstManager
{
class IClkrstSession : IpcService
partial class IClkrstSession : IpcService
{
private readonly DeviceCode _deviceCode;
#pragma warning disable IDE0052 // Remove unread private member

View File

@@ -8,7 +8,7 @@ namespace Ryujinx.HLE.HOS.Services.Pcv.Clkrst
{
[Service("clkrst")] // 8.0.0+
[Service("clkrst:i")] // 8.0.0+
class IClkrstManager : IpcService
partial class IClkrstManager : IpcService
{
private int _moduleStateTableEventHandle = 0;

Some files were not shown because too many files have changed in this diff Show More