mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-05-23 13:02:08 +00:00
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:
parent
81468c1d25
commit
18dd1be961
178 changed files with 793 additions and 551 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -185,3 +185,6 @@ PublishProfiles/
|
|||
# Ignore distribution build files
|
||||
distribution/macos/temp/
|
||||
distribution/macos/output/
|
||||
|
||||
# MSBuild logs
|
||||
*.binlog
|
||||
|
|
|
|||
6
Directory.Build.targets
Normal file
6
Directory.Build.targets
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<IsTrimmable Condition="'$(IsTrimmable)' == '' AND $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">true</IsTrimmable>
|
||||
<EnableTrimAnalyzer Condition="'$(EnableTrimAnalyzer)' == '' AND $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">true</EnableTrimAnalyzer>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
<PackageVersion Include="DiscordRichPresence" Version="1.6.1.70" />
|
||||
<PackageVersion Include="DynamicData" Version="9.4.31" />
|
||||
<PackageVersion Include="FluentAvaloniaUI" Version="2.5.1" />
|
||||
<PackageVersion Include="Humanizer" Version="2.14.1" />
|
||||
<PackageVersion Include="Humanizer" Version="3.0.1" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
|
||||
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.18.0" />
|
||||
|
|
@ -41,6 +41,7 @@
|
|||
<PackageVersion Include="OpenTK.Audio.OpenAL" Version="4.9.4" />
|
||||
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.9.4" />
|
||||
<PackageVersion Include="Open.NAT.Core" Version="2.1.0.5" />
|
||||
<PackageVersion Include="PolySharp" Version="1.15.0" />
|
||||
<!-- Ryujinx.Audio.OpenAL.Dependencies is from the original project, last updated 12/30/20 -->
|
||||
<!--<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />-->
|
||||
<PackageVersion Include="Ryujinx.Audio.OpenAL" Version="1.25.1" />
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<IsTrimmable>false</IsTrimmable>
|
||||
<EnableTrimAnalyzer>false</EnableTrimAnalyzer>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="PostBuildTarget" AfterTargets="AfterBuild">
|
||||
<Message Text="Running Validation Project" Importance="high" />
|
||||
|
||||
<Exec WorkingDirectory="$(ProjectDir)bin\Debug\$(TargetFramework)\"
|
||||
<Exec WorkingDirectory="$(OutDir)"
|
||||
Command="dotnet Ryujinx.BuildValidationTasks.dll "$(ProjectDir)..\..\\""
|
||||
ConsoleToMsBuild="true"
|
||||
Condition="'$(RuntimeIdentifier)' == ''"
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@ namespace Ryujinx.Common.Logging.Formatters
|
|||
return;
|
||||
}
|
||||
|
||||
#pragma warning disable IL2075 // GetProperties is *probably* fine here, it only really matters what exists anyway
|
||||
PropertyInfo[] props = dynamicObject.GetType().GetProperties();
|
||||
#pragma warning restore IL2075
|
||||
|
||||
sb.Append('{');
|
||||
|
||||
|
|
|
|||
173
src/Ryujinx.HLE.Generators/IpcCommandGenerator.cs
Normal file
173
src/Ryujinx.HLE.Generators/IpcCommandGenerator.cs
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Immutable;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.HLE.Generators
|
||||
{
|
||||
[Generator]
|
||||
public class IpcCommandGenerator : IIncrementalGenerator
|
||||
{
|
||||
private sealed class CommandData : IEquatable<CommandData>
|
||||
{
|
||||
public required string Namespace { get; init; }
|
||||
public required string TypeName { get; init; }
|
||||
public required string MethodName { get; init; }
|
||||
public required ImmutableArray<int> CommandIds { get; init; }
|
||||
|
||||
public bool Equals(CommandData other)
|
||||
{
|
||||
return Namespace == other.Namespace && TypeName == other.TypeName && MethodName == other.MethodName && CommandIds.SequenceEqual(other.CommandIds);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is CommandData other && Equals(other);
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (Namespace != null ? Namespace.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (TypeName != null ? TypeName.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (MethodName != null ? MethodName.GetHashCode() : 0);
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class ServiceData : IEquatable<ServiceData>
|
||||
{
|
||||
public required string Namespace { get; init; }
|
||||
public required string TypeName { get; init; }
|
||||
public required ImmutableArray<CommandData> CmifCommands { get; init; }
|
||||
public required ImmutableArray<CommandData> TipcCommands { get; init; }
|
||||
|
||||
|
||||
public bool Equals(ServiceData other)
|
||||
{
|
||||
return Namespace == other.Namespace && TypeName == other.TypeName && CmifCommands.SequenceEqual(other.CmifCommands) && TipcCommands.SequenceEqual(other.TipcCommands);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is ServiceData other && Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (Namespace != null ? Namespace.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (TypeName != null ? TypeName.GetHashCode() : 0);
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
Func<SyntaxNode, CancellationToken, bool> predicate = (node, _) => node is MethodDeclarationSyntax;
|
||||
Func<GeneratorAttributeSyntaxContext, CancellationToken, CommandData> transform = (ctx, _) =>
|
||||
{
|
||||
var target = (IMethodSymbol)ctx.TargetSymbol;
|
||||
return new CommandData
|
||||
{
|
||||
Namespace = target.ContainingType.ContainingNamespace?.ToDisplayString(),
|
||||
TypeName = target.ContainingType.Name,
|
||||
MethodName = target.Name,
|
||||
CommandIds = ctx.Attributes.Select(attr => (int)attr.ConstructorArguments[0].Value!).ToImmutableArray(),
|
||||
};
|
||||
};
|
||||
IncrementalValuesProvider<CommandData> cmifCommands =
|
||||
context.SyntaxProvider.ForAttributeWithMetadataName("Ryujinx.HLE.HOS.Services.CommandCmifAttribute",
|
||||
predicate,
|
||||
transform
|
||||
);
|
||||
IncrementalValuesProvider<CommandData> tipcCommands =
|
||||
context.SyntaxProvider.ForAttributeWithMetadataName("Ryujinx.HLE.HOS.Services.CommandTipcAttribute",
|
||||
predicate,
|
||||
transform
|
||||
);
|
||||
|
||||
IncrementalValueProvider<(ImmutableArray<CommandData> Left, ImmutableArray<CommandData> Right)> allCommands =
|
||||
cmifCommands.Collect().Combine(tipcCommands.Collect());
|
||||
|
||||
IncrementalValuesProvider<ServiceData> types = allCommands.SelectMany((commands, _) =>
|
||||
{
|
||||
ILookup<(string Namespace, string TypeName), CommandData> cmif = commands.Left.ToLookup(c => (c.Namespace, c.TypeName));
|
||||
ILookup<(string Namespace, string TypeName), CommandData> tipc = commands.Right.ToLookup(c => (c.Namespace, c.TypeName));
|
||||
|
||||
ImmutableArray<ServiceData>.Builder builder = ImmutableArray.CreateBuilder<ServiceData>();
|
||||
|
||||
foreach ((string Namespace, string TypeName) type in cmif.Select(c => c.Key).Union(tipc.Select(t => t.Key)))
|
||||
{
|
||||
builder.Add(new ServiceData
|
||||
{
|
||||
Namespace = type.Namespace,
|
||||
TypeName = type.TypeName,
|
||||
CmifCommands = cmif.Contains(type) ? cmif[type].ToImmutableArray() : [],
|
||||
TipcCommands = tipc.Contains(type) ? tipc[type].ToImmutableArray() : [],
|
||||
});
|
||||
}
|
||||
|
||||
return builder.DrainToImmutable();
|
||||
});
|
||||
|
||||
context.RegisterSourceOutput(types, (ctx, data) =>
|
||||
{
|
||||
var generator = new CodeGenerator();
|
||||
|
||||
generator.AppendLine("using Ryujinx.HLE.HOS;");
|
||||
generator.AppendLine("using RC = global::Ryujinx.HLE.HOS.ResultCode;");
|
||||
|
||||
generator.EnterScope($"namespace {data.Namespace}");
|
||||
generator.EnterScope($"partial class {data.TypeName}");
|
||||
|
||||
if (!data.CmifCommands.IsEmpty)
|
||||
{
|
||||
GenerateCommandMethod("Cmif", data.CmifCommands);
|
||||
}
|
||||
|
||||
if (!data.TipcCommands.IsEmpty)
|
||||
{
|
||||
GenerateCommandMethod("Tipc", data.TipcCommands);
|
||||
}
|
||||
|
||||
generator.LeaveScope();
|
||||
generator.LeaveScope();
|
||||
|
||||
ctx.AddSource($"{data.Namespace}.{data.TypeName}.g.cs", generator.ToString());
|
||||
|
||||
void GenerateCommandMethod(string commandType, ImmutableArray<CommandData> commands)
|
||||
{
|
||||
generator.EnterScope($"protected override RC Invoke{commandType}Method(int id, ServiceCtx context)");
|
||||
generator.EnterScope("switch (id)");
|
||||
foreach (CommandData command in commands)
|
||||
{
|
||||
generator.AppendLine($"case {string.Join(" or ", command.CommandIds)}:");
|
||||
generator.IncreaseIndentation();
|
||||
generator.AppendLine($"LogInvoke(\"{command.MethodName}\");");
|
||||
generator.AppendLine($"return (RC){command.MethodName}(context);");
|
||||
generator.DecreaseIndentation();
|
||||
}
|
||||
generator.AppendLine($"default: return base.Invoke{commandType}Method(id, context);");
|
||||
generator.LeaveScope();
|
||||
generator.LeaveScope();
|
||||
|
||||
generator.EnterScope($"public override int {commandType}CommandIdByMethodName(string name)");
|
||||
generator.EnterScope("return name switch");
|
||||
foreach (CommandData command in commands)
|
||||
{
|
||||
// just return the first command with this name
|
||||
generator.AppendLine($"\"{command.MethodName}\" => {command.CommandIds[0]},");
|
||||
}
|
||||
generator.AppendLine($"_ => base.{commandType}CommandIdByMethodName(name),");
|
||||
generator.LeaveScope(";");
|
||||
generator.LeaveScope();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.HLE.Generators
|
||||
{
|
||||
[Generator]
|
||||
public class IpcServiceGenerator : ISourceGenerator
|
||||
{
|
||||
public void Execute(GeneratorExecutionContext context)
|
||||
{
|
||||
ServiceSyntaxReceiver syntaxReceiver = (ServiceSyntaxReceiver)context.SyntaxReceiver;
|
||||
CodeGenerator generator = new();
|
||||
|
||||
generator.AppendLine("#nullable enable");
|
||||
generator.AppendLine("using System;");
|
||||
generator.EnterScope($"namespace Ryujinx.HLE.HOS.Services.Sm");
|
||||
generator.EnterScope($"partial class IUserInterface");
|
||||
|
||||
generator.EnterScope($"public IpcService? GetServiceInstance(Type type, ServiceCtx context, object? parameter = null)");
|
||||
foreach (ClassDeclarationSyntax className in syntaxReceiver.Types)
|
||||
{
|
||||
if (className.Modifiers.Any(SyntaxKind.AbstractKeyword) || className.Modifiers.Any(SyntaxKind.PrivateKeyword) || !className.AttributeLists.Any(x => x.Attributes.Any(y => y.ToString().StartsWith("Service"))))
|
||||
continue;
|
||||
string name = GetFullName(className, context).Replace("global::", string.Empty);
|
||||
if (!name.StartsWith("Ryujinx.HLE.HOS.Services"))
|
||||
continue;
|
||||
ConstructorDeclarationSyntax[] constructors = className.ChildNodes().Where(x => x.IsKind(SyntaxKind.ConstructorDeclaration)).Select(y => y as ConstructorDeclarationSyntax).ToArray();
|
||||
|
||||
if (!constructors.Any(x => x.ParameterList.Parameters.Count >= 1))
|
||||
continue;
|
||||
|
||||
if (constructors.Where(x => x.ParameterList.Parameters.Count >= 1).FirstOrDefault().ParameterList.Parameters[0].Type.ToString() == "ServiceCtx")
|
||||
{
|
||||
generator.EnterScope($"if (type == typeof({GetFullName(className, context)}))");
|
||||
if (constructors.Any(x => x.ParameterList.Parameters.Count == 2))
|
||||
{
|
||||
TypeSyntax type = constructors.Where(x => x.ParameterList.Parameters.Count == 2).FirstOrDefault().ParameterList.Parameters[1].Type;
|
||||
SemanticModel model = context.Compilation.GetSemanticModel(type.SyntaxTree);
|
||||
INamedTypeSymbol typeSymbol = model.GetSymbolInfo(type).Symbol as INamedTypeSymbol;
|
||||
string fullName = typeSymbol.ToString();
|
||||
generator.EnterScope("if (parameter != null)");
|
||||
generator.AppendLine($"return new {GetFullName(className, context)}(context, ({fullName})parameter);");
|
||||
generator.LeaveScope();
|
||||
}
|
||||
|
||||
if (constructors.Any(x => x.ParameterList.Parameters.Count == 1))
|
||||
{
|
||||
generator.AppendLine($"return new {GetFullName(className, context)}(context);");
|
||||
}
|
||||
|
||||
generator.LeaveScope();
|
||||
}
|
||||
}
|
||||
|
||||
generator.AppendLine("return null;");
|
||||
generator.LeaveScope();
|
||||
|
||||
generator.LeaveScope();
|
||||
generator.LeaveScope();
|
||||
generator.AppendLine("#nullable disable");
|
||||
context.AddSource($"IUserInterface.g.cs", generator.ToString());
|
||||
}
|
||||
|
||||
private string GetFullName(ClassDeclarationSyntax syntaxNode, GeneratorExecutionContext context)
|
||||
{
|
||||
INamedTypeSymbol typeSymbol = context.Compilation.GetSemanticModel(syntaxNode.SyntaxTree).GetDeclaredSymbol(syntaxNode);
|
||||
|
||||
return typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
}
|
||||
|
||||
public void Initialize(GeneratorInitializationContext context)
|
||||
{
|
||||
context.RegisterForSyntaxNotifications(() => new ServiceSyntaxReceiver());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,8 +3,6 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
|
||||
<IsRoslynComponent>true</IsRoslynComponent>
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||
</PropertyGroup>
|
||||
|
|
@ -14,10 +12,14 @@
|
|||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" >
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="PolySharp">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.HLE.Generators
|
||||
{
|
||||
internal class ServiceSyntaxReceiver : ISyntaxReceiver
|
||||
{
|
||||
public HashSet<ClassDeclarationSyntax> Types = [];
|
||||
|
||||
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
|
||||
{
|
||||
if (syntaxNode is ClassDeclarationSyntax classDeclaration)
|
||||
{
|
||||
if (classDeclaration.BaseList == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Types.Add(classDeclaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
93
src/Ryujinx.HLE.Generators/UserServiceGenerator.cs
Normal file
93
src/Ryujinx.HLE.Generators/UserServiceGenerator.cs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.HLE.Generators
|
||||
{
|
||||
[Generator]
|
||||
public sealed class UserServiceGenerator : IIncrementalGenerator
|
||||
{
|
||||
private sealed class ServiceData : IEquatable<ServiceData>
|
||||
{
|
||||
public required string FullName { get; init; }
|
||||
public required IReadOnlyList<(string ServiceName, string ParameterValue)> Instances { get; init; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is ServiceData data && Equals(data);
|
||||
|
||||
public bool Equals(ServiceData other)
|
||||
{
|
||||
return this.FullName == other.FullName && this.Instances.SequenceEqual(other.Instances);
|
||||
}
|
||||
|
||||
public override int GetHashCode() => FullName.GetHashCode();
|
||||
}
|
||||
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
IncrementalValuesProvider<ServiceData> pipeline = context.SyntaxProvider.ForAttributeWithMetadataName("Ryujinx.HLE.HOS.Services.ServiceAttribute",
|
||||
predicate: (node, _) => node is ClassDeclarationSyntax decl && !decl.Modifiers.Any(SyntaxKind.AbstractKeyword) && !decl.Modifiers.Any(SyntaxKind.PrivateKeyword),
|
||||
transform: (ctx, _) =>
|
||||
{
|
||||
var target = (INamedTypeSymbol)ctx.TargetSymbol;
|
||||
IEnumerable<(string, string param)> instances = ctx.Attributes.Select(attr =>
|
||||
{
|
||||
string param = attr.ConstructorArguments is [_, { IsNull: false } arg] ? arg.ToCSharpString() : null;
|
||||
return ((string)attr.ConstructorArguments[0].Value, param);
|
||||
});
|
||||
return new ServiceData
|
||||
{
|
||||
FullName = target.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat),
|
||||
Instances = instances.ToList(),
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
context.RegisterSourceOutput(pipeline.Collect(),
|
||||
(ctx, data) =>
|
||||
{
|
||||
var generator = new CodeGenerator();
|
||||
|
||||
generator.AppendLine("#nullable enable");
|
||||
generator.AppendLine("using System;");
|
||||
generator.EnterScope("namespace Ryujinx.HLE.HOS.Services.Sm");
|
||||
generator.EnterScope("partial class IUserInterface");
|
||||
|
||||
generator.EnterScope("public IpcService? GetServiceInstance(string name, ServiceCtx context)");
|
||||
|
||||
generator.EnterScope("return name switch");
|
||||
|
||||
foreach (ServiceData serviceImpl in data)
|
||||
{
|
||||
foreach ((string ServiceName, string ParameterValue) instance in serviceImpl.Instances)
|
||||
{
|
||||
if (instance.ParameterValue == null)
|
||||
{
|
||||
generator.AppendLine($"\"{instance.ServiceName}\" => new {serviceImpl.FullName}(context),");
|
||||
}
|
||||
else
|
||||
{
|
||||
generator.AppendLine($"\"{instance.ServiceName}\" => new {serviceImpl.FullName}(context, {instance.ParameterValue}),");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generator.AppendLine("_ => null,");
|
||||
|
||||
generator.LeaveScope(";");
|
||||
|
||||
generator.LeaveScope();
|
||||
|
||||
generator.LeaveScope();
|
||||
generator.LeaveScope();
|
||||
|
||||
generator.AppendLine("#nullable disable");
|
||||
|
||||
ctx.AddSource("IUserInterface.g.cs", generator.ToString());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Ryujinx.HLE.Exceptions
|
||||
|
|
@ -17,22 +18,22 @@ namespace Ryujinx.HLE.Exceptions
|
|||
public IpcService Service { get; }
|
||||
public ServiceCtx Context { get; }
|
||||
public IpcMessage Request { get; }
|
||||
private string MethodName { get; }
|
||||
|
||||
public ServiceNotImplementedException(IpcService service, ServiceCtx context)
|
||||
: this(service, context, "The service call is not implemented.") { }
|
||||
|
||||
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message) : base(message)
|
||||
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message = "The service call is not implemented.", [CallerMemberName] string methodName = null) : base(message)
|
||||
{
|
||||
Service = service;
|
||||
Context = context;
|
||||
Request = context.Request;
|
||||
MethodName = methodName;
|
||||
}
|
||||
|
||||
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message, Exception inner) : base(message, inner)
|
||||
public ServiceNotImplementedException(IpcService service, ServiceCtx context, string message, Exception inner, [CallerMemberName] string methodName = null) : base(message, inner)
|
||||
{
|
||||
Service = service;
|
||||
Context = context;
|
||||
Request = context.Request;
|
||||
MethodName = methodName;
|
||||
}
|
||||
|
||||
public override string Message
|
||||
|
|
@ -47,25 +48,12 @@ namespace Ryujinx.HLE.Exceptions
|
|||
{
|
||||
StringBuilder sb = new();
|
||||
|
||||
// Print the IPC command details (service name, command ID, and handler)
|
||||
(Type callingType, MethodBase callingMethod) = WalkStackTrace(new StackTrace(this));
|
||||
int commandId = Request.Type > IpcMessageType.TipcCloseSession
|
||||
? Service.TipcCommandIdByMethodName(MethodName)
|
||||
: Service.CmifCommandIdByMethodName(MethodName);
|
||||
|
||||
if (callingType != null && callingMethod != null)
|
||||
{
|
||||
// If the type is past 0xF, we are using TIPC
|
||||
IReadOnlyDictionary<int, MethodInfo> ipcCommands = Request.Type > IpcMessageType.TipcCloseSession ? Service.TipcCommands : Service.CmifCommands;
|
||||
|
||||
// Find the handler for the method called
|
||||
KeyValuePair<int, MethodInfo> ipcHandler = ipcCommands.FirstOrDefault(x => x.Value == callingMethod);
|
||||
int ipcCommandId = ipcHandler.Key;
|
||||
MethodInfo ipcMethod = ipcHandler.Value;
|
||||
|
||||
if (ipcMethod != null)
|
||||
{
|
||||
sb.AppendLine($"Service Command: {Service.GetType().FullName}: {ipcCommandId} ({ipcMethod.Name})");
|
||||
sb.AppendLine();
|
||||
}
|
||||
}
|
||||
sb.AppendLine($"Service Command: {Service.GetType().FullName}: {commandId} ({MethodName})");
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendLine("Guest Stack Trace:");
|
||||
sb.AppendLine(Context.Thread.GetGuestStackTrace());
|
||||
|
|
@ -137,26 +125,5 @@ namespace Ryujinx.HLE.Exceptions
|
|||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static (Type, MethodBase) WalkStackTrace(StackTrace trace)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
StackFrame frame;
|
||||
|
||||
// Find the IIpcService method that threw this exception
|
||||
while ((frame = trace.GetFrame(i++)) != null)
|
||||
{
|
||||
MethodBase method = frame.GetMethod();
|
||||
Type declType = method.DeclaringType;
|
||||
|
||||
if (typeof(IpcService).IsAssignableFrom(declType))
|
||||
{
|
||||
return (declType, method);
|
||||
}
|
||||
}
|
||||
|
||||
return (null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
|
||||
{
|
||||
class IManagerForApplication : IpcService
|
||||
partial class IManagerForApplication : IpcService
|
||||
{
|
||||
private readonly ManagerServer _managerServer;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
|
||||
{
|
||||
class IManagerForSystemService : IpcService
|
||||
partial class IManagerForSystemService : IpcService
|
||||
{
|
||||
private readonly ManagerServer _managerServer;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
|
||||
{
|
||||
class IProfile : IpcService
|
||||
partial class IProfile : IpcService
|
||||
{
|
||||
private readonly ProfileServer _profileServer;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService
|
||||
{
|
||||
class IProfileEditor : IpcService
|
||||
partial class IProfileEditor : IpcService
|
||||
{
|
||||
private readonly ProfileServer _profileServer;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using System;
|
|||
|
||||
namespace Ryujinx.HLE.HOS.Services.Account.Acc
|
||||
{
|
||||
class IAsyncContext : IpcService
|
||||
partial class IAsyncContext : IpcService
|
||||
{
|
||||
protected AsyncExecution AsyncExecution;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using System;
|
|||
|
||||
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy
|
||||
{
|
||||
class ILibraryAppletSelfAccessor : IpcService
|
||||
partial class ILibraryAppletSelfAccessor : IpcService
|
||||
{
|
||||
private readonly AppletStandalone _appletStandalone = new();
|
||||
|
||||
|
|
|
|||
|
|
@ -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() { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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() { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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() { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ using System;
|
|||
|
||||
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE
|
||||
{
|
||||
class IStorageAccessor : IpcService
|
||||
partial class IStorageAccessor : IpcService
|
||||
{
|
||||
private readonly IStorage _storage;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.Apm
|
||||
{
|
||||
abstract class IManager : IpcService
|
||||
abstract partial class IManager : IpcService
|
||||
{
|
||||
public IManager(ServiceCtx context) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ namespace Ryujinx.HLE.HOS.Services.Apm
|
|||
// NOTE: This service doesn’t 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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.Apm
|
||||
{
|
||||
abstract class ISession : IpcService
|
||||
abstract partial class ISession : IpcService
|
||||
{
|
||||
public ISession(ServiceCtx context) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.Apm
|
||||
{
|
||||
abstract class ISystemManager : IpcService
|
||||
abstract partial class ISystemManager : IpcService
|
||||
{
|
||||
public ISystemManager(ServiceCtx context) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.Caps
|
||||
{
|
||||
[Service("caps:c")]
|
||||
class IAlbumControlService : IpcService
|
||||
partial class IAlbumControlService : IpcService
|
||||
{
|
||||
public IAlbumControlService(ServiceCtx context) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.Hid.HidServer
|
||||
{
|
||||
class IActiveApplicationDeviceList : IpcService
|
||||
partial class IActiveApplicationDeviceList : IpcService
|
||||
{
|
||||
public IActiveApplicationDeviceList() { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using System;
|
|||
|
||||
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
|
||||
{
|
||||
class IRequest : IpcService
|
||||
partial class IRequest : IpcService
|
||||
{
|
||||
private enum RequestState
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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() { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using System;
|
|||
|
||||
namespace Ryujinx.HLE.HOS.Services.Ns.Aoc
|
||||
{
|
||||
class IPurchaseEventManager : IpcService
|
||||
partial class IPurchaseEventManager : IpcService
|
||||
{
|
||||
private readonly KEvent _purchasedEvent;
|
||||
|
||||
|
|
|
|||
|
|
@ -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) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ using LibHac.Ns;
|
|||
|
||||
namespace Ryujinx.HLE.HOS.Services.Ns
|
||||
{
|
||||
class IReadOnlyApplicationControlDataInterface : IpcService
|
||||
partial class IReadOnlyApplicationControlDataInterface : IpcService
|
||||
{
|
||||
public IReadOnlyApplicationControlDataInterface(ServiceCtx context) { }
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue