diff options
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/IpcService.cs')
-rw-r--r-- | Ryujinx.HLE/HOS/Services/IpcService.cs | 63 |
1 files changed, 56 insertions, 7 deletions
diff --git a/Ryujinx.HLE/HOS/Services/IpcService.cs b/Ryujinx.HLE/HOS/Services/IpcService.cs index 095e332c..69d461de 100644 --- a/Ryujinx.HLE/HOS/Services/IpcService.cs +++ b/Ryujinx.HLE/HOS/Services/IpcService.cs @@ -11,7 +11,8 @@ namespace Ryujinx.HLE.HOS.Services { abstract class IpcService { - public IReadOnlyDictionary<int, MethodInfo> Commands { get; } + public IReadOnlyDictionary<int, MethodInfo> HipcCommands { get; } + public IReadOnlyDictionary<int, MethodInfo> TipcCommands { get; } public ServerBase Server { get; private set; } @@ -22,11 +23,18 @@ namespace Ryujinx.HLE.HOS.Services public IpcService(ServerBase server = null) { - Commands = Assembly.GetExecutingAssembly().GetTypes() + HipcCommands = Assembly.GetExecutingAssembly().GetTypes() .Where(type => type == GetType()) .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)) - .SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandAttribute)) - .Select(command => (((CommandAttribute)command).Id, methodInfo))) + .SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandHipcAttribute)) + .Select(command => (((CommandHipcAttribute)command).Id, methodInfo))) + .ToDictionary(command => command.Id, command => command.methodInfo); + + TipcCommands = Assembly.GetExecutingAssembly().GetTypes() + .Where(type => type == GetType()) + .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)) + .SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandTipcAttribute)) + .Select(command => (((CommandTipcAttribute)command).Id, methodInfo))) .ToDictionary(command => command.Id, command => command.methodInfo); Server = server; @@ -53,7 +61,7 @@ namespace Ryujinx.HLE.HOS.Services _isDomain = false; } - public void CallMethod(ServiceCtx context) + public void CallHipcMethod(ServiceCtx context) { IpcService service = this; @@ -99,7 +107,7 @@ namespace Ryujinx.HLE.HOS.Services long sfciMagic = context.RequestData.ReadInt64(); int commandId = (int)context.RequestData.ReadInt64(); - bool serviceExists = service.Commands.TryGetValue(commandId, out MethodInfo processRequest); + bool serviceExists = service.HipcCommands.TryGetValue(commandId, out MethodInfo processRequest); if (ServiceConfiguration.IgnoreMissingServices || serviceExists) { @@ -145,7 +153,48 @@ namespace Ryujinx.HLE.HOS.Services { string dbgMessage = $"{service.GetType().FullName}: {commandId}"; - throw new ServiceNotImplementedException(service, context, dbgMessage); + throw new ServiceNotImplementedException(service, context, dbgMessage, false); + } + } + + public void CallTipcMethod(ServiceCtx context) + { + int commandId = (int)context.Request.Type - 0x10; + + bool serviceExists = TipcCommands.TryGetValue(commandId, out MethodInfo processRequest); + + if (ServiceConfiguration.IgnoreMissingServices || serviceExists) + { + ResultCode result = ResultCode.Success; + + context.ResponseData.BaseStream.Seek(0x4, SeekOrigin.Begin); + + if (serviceExists) + { + Logger.Debug?.Print(LogClass.KernelIpc, $"{GetType().Name}: {processRequest.Name}"); + + result = (ResultCode)processRequest.Invoke(this, new object[] { context }); + } + else + { + string serviceName; + + DummyService dummyService = this as DummyService; + + serviceName = (dummyService == null) ? 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, true); } } |