[Ryujinx.Horizon] Address dotnet-format issues (#5381)

* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Address dotnet format CA1822 warnings

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Revert formatting changes for while and for-loops

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Add trailing commas and fix formatting issues

* Convert if-else chain to switch block

* Address review feedback
This commit is contained in:
TSRBerry 2023-07-01 12:42:10 +02:00 committed by GitHub
parent 801b71a128
commit 02b5c7ea89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
105 changed files with 617 additions and 637 deletions

View file

@ -1,5 +1,4 @@
using Ryujinx.Horizon.Bcat.Ipc; using Ryujinx.Horizon.Bcat.Types;
using Ryujinx.Horizon.Bcat.Types;
using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm; using Ryujinx.Horizon.Sdk.Sm;
@ -29,10 +28,12 @@ namespace Ryujinx.Horizon.Bcat
_serverManager = new BcatServerManager(allocator, _sm, MaxPortsCount, _bcatManagerOptions, BcatTotalMaxSessionsCount); _serverManager = new BcatServerManager(allocator, _sm, MaxPortsCount, _bcatManagerOptions, BcatTotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterServer((int)BcatPortIndex.Admin, ServiceName.Encode("bcat:a"), BcatMaxSessionsCount); _serverManager.RegisterServer((int)BcatPortIndex.Admin, ServiceName.Encode("bcat:a"), BcatMaxSessionsCount);
_serverManager.RegisterServer((int)BcatPortIndex.Manager, ServiceName.Encode("bcat:m"), BcatMaxSessionsCount); _serverManager.RegisterServer((int)BcatPortIndex.Manager, ServiceName.Encode("bcat:m"), BcatMaxSessionsCount);
_serverManager.RegisterServer((int)BcatPortIndex.User, ServiceName.Encode("bcat:u"), BcatMaxSessionsCount); _serverManager.RegisterServer((int)BcatPortIndex.User, ServiceName.Encode("bcat:u"), BcatMaxSessionsCount);
_serverManager.RegisterServer((int)BcatPortIndex.System, ServiceName.Encode("bcat:s"), BcatMaxSessionsCount); _serverManager.RegisterServer((int)BcatPortIndex.System, ServiceName.Encode("bcat:s"), BcatMaxSessionsCount);
#pragma warning restore IDE0055
} }
public void ServiceRequests() public void ServiceRequests()

View file

@ -1,11 +1,4 @@
using Ryujinx.Horizon.LogManager; namespace Ryujinx.Horizon.Bcat
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ryujinx.Horizon.Bcat
{ {
internal class BcatMain : IService internal class BcatMain : IService
{ {

View file

@ -17,11 +17,11 @@ namespace Ryujinx.Horizon.Bcat
{ {
return (BcatPortIndex)portIndex switch return (BcatPortIndex)portIndex switch
{ {
BcatPortIndex.Admin => AcceptImpl(server, new ServiceCreator("bcat:a", BcatServicePermissionLevel.Admin)), BcatPortIndex.Admin => AcceptImpl(server, new ServiceCreator("bcat:a", BcatServicePermissionLevel.Admin)),
BcatPortIndex.Manager => AcceptImpl(server, new ServiceCreator("bcat:m", BcatServicePermissionLevel.Manager)), BcatPortIndex.Manager => AcceptImpl(server, new ServiceCreator("bcat:m", BcatServicePermissionLevel.Manager)),
BcatPortIndex.User => AcceptImpl(server, new ServiceCreator("bcat:u", BcatServicePermissionLevel.User)), BcatPortIndex.User => AcceptImpl(server, new ServiceCreator("bcat:u", BcatServicePermissionLevel.User)),
BcatPortIndex.System => AcceptImpl(server, new ServiceCreator("bcat:s", BcatServicePermissionLevel.System)), BcatPortIndex.System => AcceptImpl(server, new ServiceCreator("bcat:s", BcatServicePermissionLevel.System)),
_ => throw new ArgumentOutOfRangeException(nameof(portIndex)), _ => throw new ArgumentOutOfRangeException(nameof(portIndex)),
}; };
} }
} }

View file

@ -7,12 +7,7 @@ namespace Ryujinx.Horizon.Bcat.Ipc
{ {
partial class BcatService : IBcatService partial class BcatService : IBcatService
{ {
private readonly BcatServicePermissionLevel _permissionLevel; public BcatService(BcatServicePermissionLevel permissionLevel) { }
public BcatService(BcatServicePermissionLevel permissionLevel)
{
_permissionLevel = permissionLevel;
}
[CmifCommand(10100)] [CmifCommand(10100)]
public Result RequestSyncDeliveryCache(out IDeliveryCacheProgressService deliveryCacheProgressService) public Result RequestSyncDeliveryCache(out IDeliveryCacheProgressService deliveryCacheProgressService)

View file

@ -26,7 +26,7 @@ namespace Ryujinx.Horizon.Bcat.Ipc
} }
[CmifCommand(1)] [CmifCommand(1)]
public Result Read(out int entriesRead, [Buffer(Sdk.Sf.Hipc.HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span<DeliveryCacheDirectoryEntry> entriesBuffer) public Result Read(out int entriesRead, [Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span<DeliveryCacheDirectoryEntry> entriesBuffer)
{ {
return _libHacService.Get.Read(out entriesRead, entriesBuffer).ToHorizonResult(); return _libHacService.Get.Read(out entriesRead, entriesBuffer).ToHorizonResult();
} }

View file

@ -39,7 +39,7 @@ namespace Ryujinx.Horizon.Bcat.Ipc
deliveryCacheProgressImpl = new DeliveryCacheProgressImpl deliveryCacheProgressImpl = new DeliveryCacheProgressImpl
{ {
State = DeliveryCacheProgressImpl.Status.Done, State = DeliveryCacheProgressImpl.Status.Done,
Result = 0 Result = 0,
}; };
Logger.Stub?.PrintStub(LogClass.ServiceBcat); Logger.Stub?.PrintStub(LogClass.ServiceBcat);

View file

@ -8,11 +8,11 @@ namespace Ryujinx.Horizon.Bcat.Ipc.Types
public enum Status public enum Status
{ {
// TODO: determine other values // TODO: determine other values
Done = 9 Done = 9,
} }
public Status State; public Status State;
public uint Result; public uint Result;
// TODO: reverse the rest of the structure // TODO: reverse the rest of the structure
} }
} }

View file

@ -5,6 +5,6 @@
Admin, Admin,
Manager, Manager,
User, User,
System System,
} }
} }

View file

@ -2,9 +2,9 @@
{ {
enum BcatServicePermissionLevel enum BcatServicePermissionLevel
{ {
Admin = -1, Admin = -1,
User = 1, User = 1,
System = 2, System = 2,
Manager = 6 Manager = 6,
} }
} }

View file

@ -9,15 +9,15 @@ namespace Ryujinx.Horizon
{ {
private const ulong InvalidAddress = ulong.MaxValue; private const ulong InvalidAddress = ulong.MaxValue;
private struct Range : IComparable<Range> private readonly struct Range : IComparable<Range>
{ {
public ulong Offset { get; } public ulong Offset { get; }
public ulong Size { get; } public ulong Size { get; }
public Range(ulong offset, ulong size) public Range(ulong offset, ulong size)
{ {
Offset = offset; Offset = offset;
Size = size; Size = size;
} }
public int CompareTo(Range other) public int CompareTo(Range other)
@ -31,7 +31,7 @@ namespace Ryujinx.Horizon
public HeapAllocator() public HeapAllocator()
{ {
_freeRanges = new List<Range>(); _freeRanges = new List<Range>();
_currentHeapSize = 0; _currentHeapSize = 0;
} }
@ -70,8 +70,8 @@ namespace Ryujinx.Horizon
var range = _freeRanges[i]; var range = _freeRanges[i];
ulong alignedOffset = BitUtils.AlignUp(range.Offset, alignment); ulong alignedOffset = BitUtils.AlignUp(range.Offset, alignment);
ulong sizeDelta = alignedOffset - range.Offset; ulong sizeDelta = alignedOffset - range.Offset;
ulong usableSize = range.Size - sizeDelta; ulong usableSize = range.Size - sizeDelta;
if (sizeDelta < range.Size && usableSize >= size) if (sizeDelta < range.Size && usableSize >= size)
{ {
@ -82,7 +82,7 @@ namespace Ryujinx.Horizon
InsertFreeRange(range.Offset, sizeDelta); InsertFreeRange(range.Offset, sizeDelta);
} }
ulong endOffset = range.Offset + range.Size; ulong endOffset = range.Offset + range.Size;
ulong remainingSize = endOffset - (alignedOffset + size); ulong remainingSize = endOffset - (alignedOffset + size);
if (remainingSize != 0) if (remainingSize != 0)
{ {

View file

@ -2,18 +2,18 @@ using LibHac;
namespace Ryujinx.Horizon namespace Ryujinx.Horizon
{ {
public struct HorizonOptions public readonly struct HorizonOptions
{ {
public bool IgnoreMissingServices { get; } public bool IgnoreMissingServices { get; }
public bool ThrowOnInvalidCommandIds { get; } public bool ThrowOnInvalidCommandIds { get; }
public HorizonClient BcatClient { get; } public HorizonClient BcatClient { get; }
public HorizonOptions(bool ignoreMissingServices, HorizonClient bcatClient) public HorizonOptions(bool ignoreMissingServices, HorizonClient bcatClient)
{ {
IgnoreMissingServices = ignoreMissingServices; IgnoreMissingServices = ignoreMissingServices;
ThrowOnInvalidCommandIds = true; ThrowOnInvalidCommandIds = true;
BcatClient = bcatClient; BcatClient = bcatClient;
} }
} }
} }

View file

@ -21,24 +21,24 @@ namespace Ryujinx.Horizon
[ThreadStatic] [ThreadStatic]
private static int _threadHandle; private static int _threadHandle;
public static HorizonOptions Options => _options; public static HorizonOptions Options => _options;
public static ISyscallApi Syscall => _syscall; public static ISyscallApi Syscall => _syscall;
public static IVirtualMemoryManager AddressSpace => _addressSpace; public static IVirtualMemoryManager AddressSpace => _addressSpace;
public static IThreadContext ThreadContext => _threadContext; public static IThreadContext ThreadContext => _threadContext;
public static int CurrentThreadHandle => _threadHandle; public static int CurrentThreadHandle => _threadHandle;
public static void Register( public static void Register(
HorizonOptions options, HorizonOptions options,
ISyscallApi syscallApi, ISyscallApi syscallApi,
IVirtualMemoryManager addressSpace, IVirtualMemoryManager addressSpace,
IThreadContext threadContext, IThreadContext threadContext,
int threadHandle) int threadHandle)
{ {
_options = options; _options = options;
_syscall = syscallApi; _syscall = syscallApi;
_addressSpace = addressSpace; _addressSpace = addressSpace;
_threadContext = threadContext; _threadContext = threadContext;
_threadHandle = threadHandle; _threadHandle = threadHandle;
} }
} }
} }

View file

@ -95,74 +95,52 @@ namespace Ryujinx.Horizon.LogManager.Ipc
LogDataChunkKey key = (LogDataChunkKey)type; LogDataChunkKey key = (LogDataChunkKey)type;
if (key == LogDataChunkKey.Start) switch (key)
{ {
reader.Skip(size); case LogDataChunkKey.Start:
reader.Skip(size);
continue; continue;
} case LogDataChunkKey.Stop:
else if (key == LogDataChunkKey.Stop) break;
{ case LogDataChunkKey.Line when !reader.TryRead(out _logPacket.Line):
break; case LogDataChunkKey.DropCount when !reader.TryRead(out _logPacket.DropCount):
} case LogDataChunkKey.Time when !reader.TryRead(out _logPacket.Time):
else if (key == LogDataChunkKey.Line)
{
if (!reader.TryRead<int>(out _logPacket.Line))
{
return true; return true;
} case LogDataChunkKey.Message:
}
else if (key == LogDataChunkKey.DropCount)
{
if (!reader.TryRead<long>(out _logPacket.DropCount))
{
return true;
}
}
else if (key == LogDataChunkKey.Time)
{
if (!reader.TryRead<long>(out _logPacket.Time))
{
return true;
}
}
else if (key == LogDataChunkKey.Message)
{
string text = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
if (isHeadPacket && isTailPacket)
{
_logPacket.Message = text;
}
else
{
_logPacket.Message += text;
if (_logPacket.Message.Length >= MessageLengthLimit)
{ {
isTailPacket = true; string text = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
if (isHeadPacket && isTailPacket)
{
_logPacket.Message = text;
}
else
{
_logPacket.Message += text;
if (_logPacket.Message.Length >= MessageLengthLimit)
{
isTailPacket = true;
}
}
break;
} }
} case LogDataChunkKey.Filename:
} _logPacket.Filename = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
else if (key == LogDataChunkKey.Filename) break;
{ case LogDataChunkKey.Function:
_logPacket.Filename = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd(); _logPacket.Function = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
} break;
else if (key == LogDataChunkKey.Function) case LogDataChunkKey.Module:
{ _logPacket.Module = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
_logPacket.Function = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd(); break;
} case LogDataChunkKey.Thread:
else if (key == LogDataChunkKey.Module) _logPacket.Thread = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
{ break;
_logPacket.Module = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd(); case LogDataChunkKey.ProgramName:
} _logPacket.ProgramName = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
else if (key == LogDataChunkKey.Thread) break;
{
_logPacket.Thread = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
}
else if (key == LogDataChunkKey.ProgramName)
{
_logPacket.ProgramName = Encoding.UTF8.GetString(reader.GetSpanSafe(size)).TrimEnd();
} }
} }
@ -177,7 +155,7 @@ namespace Ryujinx.Horizon.LogManager.Ipc
do do
{ {
if (!reader.TryRead<byte>(out encoded)) if (!reader.TryRead(out encoded))
{ {
return false; return false;
} }

View file

@ -9,13 +9,13 @@ namespace Ryujinx.Horizon.LogManager
private const int LogMaxSessionsCount = 42; private const int LogMaxSessionsCount = 42;
private const int PointerBufferSize = 0x400; private const int PointerBufferSize = 0x400;
private const int MaxDomains = 31; private const int MaxDomains = 31;
private const int MaxDomainObjects = 61; private const int MaxDomainObjects = 61;
private const int MaxPortsCount = 1; private const int MaxPortsCount = 1;
private static readonly ManagerOptions _logManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); private static readonly ManagerOptions _logManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm; private SmApi _sm;
private ServerManager _serverManager; private ServerManager _serverManager;
public void Initialize() public void Initialize()

View file

@ -5,15 +5,15 @@ namespace Ryujinx.Horizon.LogManager.Types
{ {
struct LogPacket struct LogPacket
{ {
public string Message; public string Message;
public int Line; public int Line;
public string Filename; public string Filename;
public string Function; public string Function;
public string Module; public string Module;
public string Thread; public string Thread;
public long DropCount; public long DropCount;
public long Time; public long Time;
public string ProgramName; public string ProgramName;
public LogSeverity Severity; public LogSeverity Severity;
public override string ToString() public override string ToString()

View file

@ -10,6 +10,7 @@ using Ryujinx.Horizon.Sdk.Sf;
using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Sf.Hipc;
using System; using System;
using System.Text; using System.Text;
using ApplicationId = Ryujinx.Horizon.Sdk.Ncm.ApplicationId;
namespace Ryujinx.Horizon.Prepo.Ipc namespace Ryujinx.Horizon.Prepo.Ipc
{ {
@ -18,14 +19,14 @@ namespace Ryujinx.Horizon.Prepo.Ipc
enum PlayReportKind enum PlayReportKind
{ {
Normal, Normal,
System System,
} }
private readonly PrepoServicePermissionLevel _permissionLevel; private readonly PrepoServicePermissionLevel _permissionLevel;
private ulong _systemSessionId; private ulong _systemSessionId;
private bool _immediateTransmissionEnabled = false; private bool _immediateTransmissionEnabled;
private bool _userAgreementCheckEnabled = true; private bool _userAgreementCheckEnabled = true;
public PrepoService(PrepoServicePermissionLevel permissionLevel) public PrepoService(PrepoServicePermissionLevel permissionLevel)
{ {
@ -107,7 +108,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
} }
[CmifCommand(20100)] [CmifCommand(20100)]
public Result SaveSystemReport([Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, Sdk.Ncm.ApplicationId applicationId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer) public Result SaveSystemReport([Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, ApplicationId applicationId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer)
{ {
if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0) if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0)
{ {
@ -118,7 +119,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
} }
[CmifCommand(20101)] [CmifCommand(20101)]
public Result SaveSystemReportWithUser(Uid userId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, Sdk.Ncm.ApplicationId applicationId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer) public Result SaveSystemReportWithUser(Uid userId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.Pointer)] ReadOnlySpan<byte> gameRoomBuffer, ApplicationId applicationId, [Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan<byte> reportBuffer)
{ {
if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0) if ((_permissionLevel & PrepoServicePermissionLevel.System) != 0)
{ {
@ -164,7 +165,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
return PrepoResult.PermissionDenied; return PrepoResult.PermissionDenied;
} }
private static Result ProcessPlayReport(PlayReportKind playReportKind, ReadOnlySpan<byte> gameRoomBuffer, ReadOnlySpan<byte> reportBuffer, ulong pid, Uid userId, bool withUserId = false, Sdk.Ncm.ApplicationId applicationId = default) private static Result ProcessPlayReport(PlayReportKind playReportKind, ReadOnlySpan<byte> gameRoomBuffer, ReadOnlySpan<byte> reportBuffer, ulong pid, Uid userId, bool withUserId = false, ApplicationId applicationId = default)
{ {
if (withUserId) if (withUserId)
{ {
@ -191,7 +192,7 @@ namespace Ryujinx.Horizon.Prepo.Ipc
return PrepoResult.InvalidBufferSize; return PrepoResult.InvalidBufferSize;
} }
StringBuilder builder = new(); StringBuilder builder = new();
MessagePackObject deserializedReport = MessagePackSerializer.UnpackMessagePackObject(reportBuffer.ToArray()); MessagePackObject deserializedReport = MessagePackSerializer.UnpackMessagePackObject(reportBuffer.ToArray());
builder.AppendLine(); builder.AppendLine();

View file

@ -6,13 +6,13 @@ namespace Ryujinx.Horizon.Prepo
{ {
class PrepoIpcServer class PrepoIpcServer
{ {
private const int PrepoMaxSessionsCount = 12; private const int PrepoMaxSessionsCount = 12;
private const int PrepoTotalMaxSessionsCount = PrepoMaxSessionsCount * 6; private const int PrepoTotalMaxSessionsCount = PrepoMaxSessionsCount * 6;
private const int PointerBufferSize = 0x80; private const int PointerBufferSize = 0x80;
private const int MaxDomains = 64; private const int MaxDomains = 64;
private const int MaxDomainObjects = 16; private const int MaxDomainObjects = 16;
private const int MaxPortsCount = 6; private const int MaxPortsCount = 6;
private static readonly ManagerOptions _prepoManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); private static readonly ManagerOptions _prepoManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
@ -28,12 +28,14 @@ namespace Ryujinx.Horizon.Prepo
_serverManager = new PrepoServerManager(allocator, _sm, MaxPortsCount, _prepoManagerOptions, PrepoTotalMaxSessionsCount); _serverManager = new PrepoServerManager(allocator, _sm, MaxPortsCount, _prepoManagerOptions, PrepoTotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterServer((int)PrepoPortIndex.Admin, ServiceName.Encode("prepo:a"), PrepoMaxSessionsCount); // 1.0.0-5.1.0 _serverManager.RegisterServer((int)PrepoPortIndex.Admin, ServiceName.Encode("prepo:a"), PrepoMaxSessionsCount); // 1.0.0-5.1.0
_serverManager.RegisterServer((int)PrepoPortIndex.Admin2, ServiceName.Encode("prepo:a2"), PrepoMaxSessionsCount); // 6.0.0+ _serverManager.RegisterServer((int)PrepoPortIndex.Admin2, ServiceName.Encode("prepo:a2"), PrepoMaxSessionsCount); // 6.0.0+
_serverManager.RegisterServer((int)PrepoPortIndex.Manager, ServiceName.Encode("prepo:m"), PrepoMaxSessionsCount); _serverManager.RegisterServer((int)PrepoPortIndex.Manager, ServiceName.Encode("prepo:m"), PrepoMaxSessionsCount);
_serverManager.RegisterServer((int)PrepoPortIndex.User, ServiceName.Encode("prepo:u"), PrepoMaxSessionsCount); _serverManager.RegisterServer((int)PrepoPortIndex.User, ServiceName.Encode("prepo:u"), PrepoMaxSessionsCount);
_serverManager.RegisterServer((int)PrepoPortIndex.System, ServiceName.Encode("prepo:s"), PrepoMaxSessionsCount); _serverManager.RegisterServer((int)PrepoPortIndex.System, ServiceName.Encode("prepo:s"), PrepoMaxSessionsCount);
_serverManager.RegisterServer((int)PrepoPortIndex.Debug, ServiceName.Encode("prepo:d"), PrepoMaxSessionsCount); // 1.0.0 _serverManager.RegisterServer((int)PrepoPortIndex.Debug, ServiceName.Encode("prepo:d"), PrepoMaxSessionsCount); // 1.0.0
#pragma warning restore IDE0055
} }
public void ServiceRequests() public void ServiceRequests()

View file

@ -6,10 +6,12 @@ namespace Ryujinx.Horizon.Prepo
{ {
private const int ModuleId = 129; private const int ModuleId = 129;
#pragma warning disable IDE0055 // Disable formatting
public static Result InvalidArgument => new(ModuleId, 1); public static Result InvalidArgument => new(ModuleId, 1);
public static Result InvalidState => new(ModuleId, 5); public static Result InvalidState => new(ModuleId, 5);
public static Result InvalidBufferSize => new(ModuleId, 9); public static Result InvalidBufferSize => new(ModuleId, 9);
public static Result PermissionDenied => new(ModuleId, 90); public static Result PermissionDenied => new(ModuleId, 90);
public static Result InvalidPid => new(ModuleId, 101); public static Result InvalidPid => new(ModuleId, 101);
#pragma warning restore IDE0055
} }
} }

View file

@ -17,6 +17,7 @@ namespace Ryujinx.Horizon.Prepo
{ {
return (PrepoPortIndex)portIndex switch return (PrepoPortIndex)portIndex switch
{ {
#pragma warning disable IDE0055 // Disable formatting
PrepoPortIndex.Admin => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Admin)), PrepoPortIndex.Admin => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Admin)),
PrepoPortIndex.Admin2 => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Admin)), PrepoPortIndex.Admin2 => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Admin)),
PrepoPortIndex.Manager => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Manager)), PrepoPortIndex.Manager => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Manager)),
@ -24,6 +25,7 @@ namespace Ryujinx.Horizon.Prepo
PrepoPortIndex.System => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.System)), PrepoPortIndex.System => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.System)),
PrepoPortIndex.Debug => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Debug)), PrepoPortIndex.Debug => AcceptImpl(server, new PrepoService(PrepoServicePermissionLevel.Debug)),
_ => throw new ArgumentOutOfRangeException(nameof(portIndex)), _ => throw new ArgumentOutOfRangeException(nameof(portIndex)),
#pragma warning restore IDE0055
}; };
} }
} }

View file

@ -7,6 +7,6 @@
Manager, Manager,
User, User,
System, System,
Debug Debug,
} }
} }

View file

@ -2,10 +2,10 @@
{ {
enum PrepoServicePermissionLevel enum PrepoServicePermissionLevel
{ {
Admin = -1, Admin = -1,
User = 1, User = 1,
System = 2, System = 2,
Manager = 6, Manager = 6,
Debug = unchecked((int)0x80000006) Debug = unchecked((int)0x80000006),
} }
} }

View file

@ -17,14 +17,14 @@ namespace Ryujinx.Horizon.Sdk.Account
public Uid(long low, long high) public Uid(long low, long high)
{ {
Low = low; Low = low;
High = high; High = high;
} }
public Uid(byte[] bytes) public Uid(byte[] bytes)
{ {
High = BitConverter.ToInt64(bytes, 0); High = BitConverter.ToInt64(bytes, 0);
Low = BitConverter.ToInt64(bytes, 8); Low = BitConverter.ToInt64(bytes, 8);
} }
public Uid(string hex) public Uid(string hex)
@ -34,7 +34,7 @@ namespace Ryujinx.Horizon.Sdk.Account
throw new ArgumentException("Invalid Hex value!", nameof(hex)); throw new ArgumentException("Invalid Hex value!", nameof(hex));
} }
Low = Convert.ToInt64(hex[16..], 16); Low = Convert.ToInt64(hex[16..], 16);
High = Convert.ToInt64(hex[..16], 16); High = Convert.ToInt64(hex[..16], 16);
} }

View file

@ -1,4 +1,5 @@
using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Ncm;
using Ryujinx.Horizon.Sdk.Sf; using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Bcat namespace Ryujinx.Horizon.Sdk.Bcat
@ -7,6 +8,6 @@ namespace Ryujinx.Horizon.Sdk.Bcat
{ {
Result CreateBcatService(out IBcatService service, ulong pid); Result CreateBcatService(out IBcatService service, ulong pid);
Result CreateDeliveryCacheStorageService(out IDeliveryCacheStorageService service, ulong pid); Result CreateDeliveryCacheStorageService(out IDeliveryCacheStorageService service, ulong pid);
Result CreateDeliveryCacheStorageServiceWithApplicationId(out IDeliveryCacheStorageService service, Ncm.ApplicationId applicationId); Result CreateDeliveryCacheStorageServiceWithApplicationId(out IDeliveryCacheStorageService service, ApplicationId applicationId);
} }
} }

View file

@ -6,6 +6,6 @@ namespace Ryujinx.Horizon.Sdk.Diag
Info = 1, Info = 1,
Warn = 2, Warn = 2,
Error = 3, Error = 3,
Fatal = 4 Fatal = 4,
} }
} }

View file

@ -14,6 +14,6 @@ namespace Ryujinx.Horizon.Sdk.Lm
Time = 9, Time = 9,
ProgramName = 10, ProgramName = 10,
Count Count,
} }
} }

View file

@ -9,6 +9,6 @@ namespace Ryujinx.Horizon.Sdk.Lm
Uart = 1 << 1, Uart = 1 << 1,
UartIfSleep = 1 << 2, UartIfSleep = 1 << 2,
All = 0xffff All = 0xffff,
} }
} }

View file

@ -7,6 +7,6 @@ namespace Ryujinx.Horizon.Sdk.Lm
{ {
IsHead = 1 << 0, IsHead = 1 << 0,
IsTail = 1 << 1, IsTail = 1 << 1,
IsLittleEndian = 1 << 2 IsLittleEndian = 1 << 2,
} }
} }

View file

@ -3,6 +3,6 @@
enum EventClearMode enum EventClearMode
{ {
ManualClear, ManualClear,
AutoClear AutoClear,
} }
} }

View file

@ -7,9 +7,9 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
{ {
class MultiWaitImpl class MultiWaitImpl
{ {
private const int WaitTimedOut = -1; private const int WaitTimedOut = -1;
private const int WaitCancelled = -2; private const int WaitCancelled = -2;
private const int WaitInvalid = -3; private const int WaitInvalid = -3;
private readonly List<MultiWaitHolderBase> _multiWaits; private readonly List<MultiWaitHolderBase> _multiWaits;
@ -63,10 +63,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
} }
} }
if (result == null) result ??= WaitAnyHandleImpl(infinite, timeout);
{
result = WaitAnyHandleImpl(infinite, timeout);
}
UnlinkHoldersFromObjectsList(); UnlinkHoldersFromObjectsList();
_waitingThreadHandle = 0; _waitingThreadHandle = 0;
@ -98,7 +95,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
} }
else else
{ {
index = WaitSynchronization(objectHandles.Slice(0, count), minTimeout); index = WaitSynchronization(objectHandles[..count], minTimeout);
DebugUtil.Assert(index != WaitInvalid); DebugUtil.Assert(index != WaitInvalid);
} }
@ -200,10 +197,8 @@ namespace Ryujinx.Horizon.Sdk.OsTypes.Impl
{ {
return WaitCancelled; return WaitCancelled;
} }
else
{ result.AbortOnFailure();
result.AbortOnFailure();
}
return index; return index;
} }

View file

@ -3,6 +3,6 @@ namespace Ryujinx.Horizon.Sdk.OsTypes
enum InitializationState : byte enum InitializationState : byte
{ {
NotInitialized, NotInitialized,
Initialized Initialized,
} }
} }

View file

@ -4,7 +4,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes
{ {
class MultiWaitHolderOfEvent : MultiWaitHolder class MultiWaitHolderOfEvent : MultiWaitHolder
{ {
private Event _event; private readonly Event _event;
private LinkedListNode<MultiWaitHolderBase> _node; private LinkedListNode<MultiWaitHolderBase> _node;
public override TriBool Signaled public override TriBool Signaled

View file

@ -2,7 +2,7 @@
{ {
class MultiWaitHolderOfHandle : MultiWaitHolder class MultiWaitHolderOfHandle : MultiWaitHolder
{ {
private int _handle; private readonly int _handle;
public override int Handle => _handle; public override int Handle => _handle;

View file

@ -15,7 +15,7 @@ namespace Ryujinx.Horizon.Sdk.OsTypes
InitiallySignaled = signaled, InitiallySignaled = signaled,
ClearMode = clearMode, ClearMode = clearMode,
State = InitializationState.Initialized, State = InitializationState.Initialized,
Lock = new object() Lock = new object(),
}; };
} }

View file

@ -6,6 +6,6 @@ namespace Ryujinx.Horizon.Sdk.OsTypes
{ {
private const int ModuleId = 3; private const int ModuleId = 3;
public static Result OutOfResource => new Result(ModuleId, 9); public static Result OutOfResource => new(ModuleId, 9);
} }
} }

View file

@ -6,12 +6,12 @@
{ {
NotInitialized, NotInitialized,
InitializedAsEvent, InitializedAsEvent,
InitializedAsInterProcess InitializedAsInterProcess,
} }
public InterProcessEventType InterProcessEvent; public InterProcessEventType InterProcessEvent;
public InitializationState State; public InitializationState State;
public bool NotInitialized => State == InitializationState.NotInitialized; public readonly bool NotInitialized => State == InitializationState.NotInitialized;
} }
} }

View file

@ -4,6 +4,6 @@
{ {
False, False,
True, True,
Undefined Undefined,
} }
} }

View file

@ -2,6 +2,7 @@
using Ryujinx.Horizon.Sdk.Account; using Ryujinx.Horizon.Sdk.Account;
using Ryujinx.Horizon.Sdk.Sf; using Ryujinx.Horizon.Sdk.Sf;
using System; using System;
using ApplicationId = Ryujinx.Horizon.Sdk.Ncm.ApplicationId;
namespace Ryujinx.Horizon.Sdk.Prepo namespace Ryujinx.Horizon.Sdk.Prepo
{ {
@ -12,8 +13,8 @@ namespace Ryujinx.Horizon.Sdk.Prepo
Result RequestImmediateTransmission(); Result RequestImmediateTransmission();
Result GetTransmissionStatus(out int status); Result GetTransmissionStatus(out int status);
Result GetSystemSessionId(out ulong systemSessionId); Result GetSystemSessionId(out ulong systemSessionId);
Result SaveSystemReport(ReadOnlySpan<byte> gameRoomBuffer, Ncm.ApplicationId applicationId, ReadOnlySpan<byte> reportBuffer); Result SaveSystemReport(ReadOnlySpan<byte> gameRoomBuffer, ApplicationId applicationId, ReadOnlySpan<byte> reportBuffer);
Result SaveSystemReportWithUser(Uid userId, ReadOnlySpan<byte> gameRoomBuffer, Ncm.ApplicationId applicationId, ReadOnlySpan<byte> reportBuffer); Result SaveSystemReportWithUser(Uid userId, ReadOnlySpan<byte> gameRoomBuffer, ApplicationId applicationId, ReadOnlySpan<byte> reportBuffer);
Result IsUserAgreementCheckEnabled(out bool enabled); Result IsUserAgreementCheckEnabled(out bool enabled);
Result SetUserAgreementCheckEnabled(bool enabled); Result SetUserAgreementCheckEnabled(bool enabled);
} }

View file

@ -10,15 +10,15 @@ namespace Ryujinx.Horizon.Sdk
public static Result SendRequest(out CmifResponse response, int sessionHandle, uint requestId, bool sendPid, scoped ReadOnlySpan<byte> data) public static Result SendRequest(out CmifResponse response, int sessionHandle, uint requestId, bool sendPid, scoped ReadOnlySpan<byte> data)
{ {
ulong tlsAddress = HorizonStatic.ThreadContext.TlsAddress; ulong tlsAddress = HorizonStatic.ThreadContext.TlsAddress;
int tlsSize = Api.TlsMessageBufferSize; int tlsSize = Api.TlsMessageBufferSize;
using (var tlsRegion = HorizonStatic.AddressSpace.GetWritableRegion(tlsAddress, tlsSize)) using (var tlsRegion = HorizonStatic.AddressSpace.GetWritableRegion(tlsAddress, tlsSize))
{ {
CmifRequest request = CmifMessage.CreateRequest(tlsRegion.Memory.Span, new CmifRequestFormat() CmifRequest request = CmifMessage.CreateRequest(tlsRegion.Memory.Span, new CmifRequestFormat
{ {
DataSize = data.Length, DataSize = data.Length,
RequestId = requestId, RequestId = requestId,
SendPid = sendPid SendPid = sendPid,
}); });
data.CopyTo(request.Data); data.CopyTo(request.Data);

View file

@ -3,10 +3,10 @@
struct CmifDomainInHeader struct CmifDomainInHeader
{ {
public CmifDomainRequestType Type; public CmifDomainRequestType Type;
public byte ObjectsCount; public byte ObjectsCount;
public ushort DataSize; public ushort DataSize;
public int ObjectId; public int ObjectId;
public uint Padding; public uint Padding;
public uint Token; public uint Token;
} }
} }

View file

@ -2,7 +2,7 @@
{ {
struct CmifDomainOutHeader struct CmifDomainOutHeader
{ {
#pragma warning disable CS0649 #pragma warning disable CS0649 // Field is never assigned to
public uint ObjectsCount; public uint ObjectsCount;
public uint Padding; public uint Padding;
public uint Padding2; public uint Padding2;

View file

@ -2,8 +2,8 @@
{ {
enum CmifDomainRequestType : byte enum CmifDomainRequestType : byte
{ {
Invalid = 0, Invalid = 0,
SendMessage = 1, SendMessage = 1,
Close = 2 Close = 2,
} }
} }

View file

@ -8,7 +8,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
{ {
static class CmifMessage static class CmifMessage
{ {
public const uint CmifInHeaderMagic = 0x49434653; // SFCI public const uint CmifInHeaderMagic = 0x49434653; // SFCI
public const uint CmifOutHeaderMagic = 0x4f434653; // SFCO public const uint CmifOutHeaderMagic = 0x4f434653; // SFCO
public static CmifRequest CreateRequest(Span<byte> output, CmifRequestFormat format) public static CmifRequest CreateRequest(Span<byte> output, CmifRequestFormat format)
@ -21,10 +21,10 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
} }
totalSize += Unsafe.SizeOf<CmifInHeader>() + format.DataSize; totalSize += Unsafe.SizeOf<CmifInHeader>() + format.DataSize;
totalSize = (totalSize + 1) & ~1; totalSize = (totalSize + 1) & ~1;
int outPointerSizeTableOffset = totalSize; int outPointerSizeTableOffset = totalSize;
int outPointerSizeTableSize = format.OutAutoBuffersCount + format.OutPointersCount; int outPointerSizeTableSize = format.OutAutoBuffersCount + format.OutPointersCount;
totalSize += sizeof(ushort) * outPointerSizeTableSize; totalSize += sizeof(ushort) * outPointerSizeTableSize;
@ -32,19 +32,19 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
CmifRequest request = new() CmifRequest request = new()
{ {
Hipc = HipcMessage.WriteMessage(output, new HipcMetadata() Hipc = HipcMessage.WriteMessage(output, new HipcMetadata
{ {
Type = format.Context != 0 ? (int)CommandType.RequestWithContext : (int)CommandType.Request, Type = format.Context != 0 ? (int)CommandType.RequestWithContext : (int)CommandType.Request,
SendStaticsCount = format.InAutoBuffersCount + format.InPointersCount, SendStaticsCount = format.InAutoBuffersCount + format.InPointersCount,
SendBuffersCount = format.InAutoBuffersCount + format.InBuffersCount, SendBuffersCount = format.InAutoBuffersCount + format.InBuffersCount,
ReceiveBuffersCount = format.OutAutoBuffersCount + format.OutBuffersCount, ReceiveBuffersCount = format.OutAutoBuffersCount + format.OutBuffersCount,
ExchangeBuffersCount = format.InOutBuffersCount, ExchangeBuffersCount = format.InOutBuffersCount,
DataWordsCount = rawDataSizeInWords, DataWordsCount = rawDataSizeInWords,
ReceiveStaticsCount = outPointerSizeTableSize + format.OutFixedPointersCount, ReceiveStaticsCount = outPointerSizeTableSize + format.OutFixedPointersCount,
SendPid = format.SendPid, SendPid = format.SendPid,
CopyHandlesCount = format.HandlesCount, CopyHandlesCount = format.HandlesCount,
MoveHandlesCount = 0 MoveHandlesCount = 0,
}) }),
}; };
Span<uint> data = request.Hipc.DataWords; Span<uint> data = request.Hipc.DataWords;
@ -55,14 +55,14 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
int payloadSize = Unsafe.SizeOf<CmifInHeader>() + format.DataSize; int payloadSize = Unsafe.SizeOf<CmifInHeader>() + format.DataSize;
domainHeader = new CmifDomainInHeader() domainHeader = new CmifDomainInHeader
{ {
Type = CmifDomainRequestType.SendMessage, Type = CmifDomainRequestType.SendMessage,
ObjectsCount = (byte)format.ObjectsCount, ObjectsCount = (byte)format.ObjectsCount,
DataSize = (ushort)payloadSize, DataSize = (ushort)payloadSize,
ObjectId = format.ObjectId, ObjectId = format.ObjectId,
Padding = 0, Padding = 0,
Token = format.Context Token = format.Context,
}; };
data = data[(Unsafe.SizeOf<CmifDomainInHeader>() / sizeof(uint))..]; data = data[(Unsafe.SizeOf<CmifDomainInHeader>() / sizeof(uint))..];
@ -72,12 +72,12 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
ref CmifInHeader header = ref MemoryMarshal.Cast<uint, CmifInHeader>(data)[0]; ref CmifInHeader header = ref MemoryMarshal.Cast<uint, CmifInHeader>(data)[0];
header = new CmifInHeader() header = new CmifInHeader
{ {
Magic = CmifInHeaderMagic, Magic = CmifInHeaderMagic,
Version = format.Context != 0 ? 1u : 0u, Version = format.Context != 0 ? 1u : 0u,
CommandId = format.RequestId, CommandId = format.RequestId,
Token = format.ObjectId != 0 ? 0u : format.Context Token = format.ObjectId != 0 ? 0u : format.Context,
}; };
request.Data = MemoryMarshal.Cast<uint, byte>(data)[Unsafe.SizeOf<CmifInHeader>()..]; request.Data = MemoryMarshal.Cast<uint, byte>(data)[Unsafe.SizeOf<CmifInHeader>()..];
@ -86,7 +86,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
Span<byte> outPointerTable = MemoryMarshal.Cast<uint, byte>(request.Hipc.DataWords)[(outPointerSizeTableOffset - paddingSizeBefore)..]; Span<byte> outPointerTable = MemoryMarshal.Cast<uint, byte>(request.Hipc.DataWords)[(outPointerSizeTableOffset - paddingSizeBefore)..];
request.OutPointerSizes = MemoryMarshal.Cast<byte, ushort>(outPointerTable); request.OutPointerSizes = MemoryMarshal.Cast<byte, ushort>(outPointerTable);
request.ServerPointerSize = format.ServerPointerSize; request.ServerPointerSize = format.ServerPointerSize;
return request; return request;
@ -96,12 +96,12 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
{ {
HipcMessage responseMessage = new(input); HipcMessage responseMessage = new(input);
Span<byte> data = MemoryMarshal.Cast<uint, byte>(responseMessage.Data.DataWords); Span<byte> data = MemoryMarshal.Cast<uint, byte>(responseMessage.Data.DataWords);
Span<uint> objects = Span<uint>.Empty; Span<uint> objects = Span<uint>.Empty;
if (isDomain) if (isDomain)
{ {
data = data[Unsafe.SizeOf<CmifDomainOutHeader>()..]; data = data[Unsafe.SizeOf<CmifDomainOutHeader>()..];
objects = MemoryMarshal.Cast<byte, uint>(data[(Unsafe.SizeOf<CmifOutHeader>() + size)..]); objects = MemoryMarshal.Cast<byte, uint>(data[(Unsafe.SizeOf<CmifOutHeader>() + size)..]);
} }
@ -121,12 +121,12 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
return header.Result; return header.Result;
} }
response = new CmifResponse() response = new CmifResponse
{ {
Data = data[Unsafe.SizeOf<CmifOutHeader>()..], Data = data[Unsafe.SizeOf<CmifOutHeader>()..],
Objects = objects, Objects = objects,
CopyHandles = responseMessage.Data.CopyHandles, CopyHandles = responseMessage.Data.CopyHandles,
MoveHandles = responseMessage.Data.MoveHandles MoveHandles = responseMessage.Data.MoveHandles,
}; };
return Result.Success; return Result.Success;

View file

@ -4,11 +4,11 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
{ {
struct CmifOutHeader struct CmifOutHeader
{ {
#pragma warning disable CS0649 #pragma warning disable CS0649 // Field is never assigned to
public uint Magic; public uint Magic;
public uint Version; public uint Version;
public Result Result; public Result Result;
public uint Token; public uint Token;
#pragma warning restore CS0649 #pragma warning restore CS0649
} }
} }

View file

@ -6,9 +6,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
ref struct CmifRequest ref struct CmifRequest
{ {
public HipcMessageData Hipc; public HipcMessageData Hipc;
public Span<byte> Data; public Span<byte> Data;
public Span<ushort> OutPointerSizes; public Span<ushort> OutPointerSizes;
public Span<uint> Objects; public Span<uint> Objects;
public int ServerPointerSize; public int ServerPointerSize;
} }
} }

View file

@ -2,22 +2,22 @@
{ {
struct CmifRequestFormat struct CmifRequestFormat
{ {
#pragma warning disable CS0649 #pragma warning disable CS0649 // Field is never assigned to
public int ObjectId; public int ObjectId;
public uint RequestId; public uint RequestId;
public uint Context; public uint Context;
public int DataSize; public int DataSize;
public int ServerPointerSize; public int ServerPointerSize;
public int InAutoBuffersCount; public int InAutoBuffersCount;
public int OutAutoBuffersCount; public int OutAutoBuffersCount;
public int InBuffersCount; public int InBuffersCount;
public int OutBuffersCount; public int OutBuffersCount;
public int InOutBuffersCount; public int InOutBuffersCount;
public int InPointersCount; public int InPointersCount;
public int OutPointersCount; public int OutPointersCount;
public int OutFixedPointersCount; public int OutFixedPointersCount;
public int ObjectsCount; public int ObjectsCount;
public int HandlesCount; public int HandlesCount;
public bool SendPid; public bool SendPid;
#pragma warning restore CS0649 #pragma warning restore CS0649
} }

View file

@ -6,7 +6,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
{ {
public ReadOnlySpan<byte> Data; public ReadOnlySpan<byte> Data;
public ReadOnlySpan<uint> Objects; public ReadOnlySpan<uint> Objects;
public ReadOnlySpan<int> CopyHandles; public ReadOnlySpan<int> CopyHandles;
public ReadOnlySpan<int> MoveHandles; public ReadOnlySpan<int> MoveHandles;
} }
} }

View file

@ -2,13 +2,13 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
{ {
enum CommandType enum CommandType
{ {
Invalid = 0, Invalid = 0,
LegacyRequest = 1, LegacyRequest = 1,
Close = 2, Close = 2,
LegacyControl = 3, LegacyControl = 3,
Request = 4, Request = 4,
Control = 5, Control = 5,
RequestWithContext = 6, RequestWithContext = 6,
ControlWithContext = 7 ControlWithContext = 7,
} }
} }

View file

@ -12,7 +12,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
return ProcessMessageImpl(ref context, ((DomainServiceObject)context.ServiceObject).GetServerDomain(), inRawData); return ProcessMessageImpl(ref context, ((DomainServiceObject)context.ServiceObject).GetServerDomain(), inRawData);
} }
private Result ProcessMessageImpl(ref ServiceDispatchContext context, ServerDomainBase domain, ReadOnlySpan<byte> inRawData) private static Result ProcessMessageImpl(ref ServiceDispatchContext context, ServerDomainBase domain, ReadOnlySpan<byte> inRawData)
{ {
if (inRawData.Length < Unsafe.SizeOf<CmifDomainInHeader>()) if (inRawData.Length < Unsafe.SizeOf<CmifDomainInHeader>())
{ {

View file

@ -19,7 +19,6 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
private int InObjectsCount => _inObjectIds.Length; private int InObjectsCount => _inObjectIds.Length;
private int OutObjectsCount => _implMetadata.OutObjectsCount; private int OutObjectsCount => _implMetadata.OutObjectsCount;
private int ImplOutHeadersSize => _implMetadata.OutHeadersSize;
private int ImplOutDataTotalSize => _implMetadata.OutDataSize + _implMetadata.OutHeadersSize; private int ImplOutDataTotalSize => _implMetadata.OutDataSize + _implMetadata.OutHeadersSize;
public DomainServiceObjectProcessor(ServerDomainBase domain, int[] inObjectIds) public DomainServiceObjectProcessor(ServerDomainBase domain, int[] inObjectIds)

View file

@ -17,7 +17,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
public int this[int index] public int this[int index]
{ {
get readonly get
{ {
return index switch return index switch
{ {
@ -29,22 +29,39 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
5 => _handle5, 5 => _handle5,
6 => _handle6, 6 => _handle6,
7 => _handle7, 7 => _handle7,
_ => throw new IndexOutOfRangeException() _ => throw new IndexOutOfRangeException(),
}; };
} }
set set
{ {
switch (index) switch (index)
{ {
case 0: _handle0 = value; break; case 0:
case 1: _handle1 = value; break; _handle0 = value;
case 2: _handle2 = value; break; break;
case 3: _handle3 = value; break; case 1:
case 4: _handle4 = value; break; _handle1 = value;
case 5: _handle5 = value; break; break;
case 6: _handle6 = value; break; case 2:
case 7: _handle7 = value; break; _handle2 = value;
default: throw new IndexOutOfRangeException(); break;
case 3:
_handle3 = value;
break;
case 4:
_handle4 = value;
break;
case 5:
_handle5 = value;
break;
case 6:
_handle6 = value;
break;
case 7:
_handle7 = value;
break;
default:
throw new IndexOutOfRangeException();
} }
} }
} }

View file

@ -1,6 +1,6 @@
namespace Ryujinx.Horizon.Sdk.Sf.Cmif namespace Ryujinx.Horizon.Sdk.Sf.Cmif
{ {
struct PointerAndSize readonly struct PointerAndSize
{ {
public static PointerAndSize Empty => new(0UL, 0UL); public static PointerAndSize Empty => new(0UL, 0UL);
@ -11,7 +11,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
public PointerAndSize(ulong address, ulong size) public PointerAndSize(ulong address, ulong size)
{ {
Address = address; Address = address;
Size = size; Size = size;
} }
} }
} }

View file

@ -2,7 +2,7 @@ using System;
namespace Ryujinx.Horizon.Sdk.Sf.Cmif namespace Ryujinx.Horizon.Sdk.Sf.Cmif
{ {
struct ScopedInlineContextChange : IDisposable readonly struct ScopedInlineContextChange : IDisposable
{ {
private readonly int _previousContext; private readonly int _previousContext;

View file

@ -211,7 +211,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
private readonly EntryManager _entryManager; private readonly EntryManager _entryManager;
private readonly object _entryOwnerLock; private readonly object _entryOwnerLock;
private readonly HashSet<Domain> _domains; private readonly HashSet<Domain> _domains;
private int _maxDomains; private readonly int _maxDomains;
public ServerDomainManager(int entryCount, int maxDomains) public ServerDomainManager(int entryCount, int maxDomains)
{ {

View file

@ -1,29 +1,29 @@
namespace Ryujinx.Horizon.Sdk.Sf.Cmif namespace Ryujinx.Horizon.Sdk.Sf.Cmif
{ {
struct ServerMessageRuntimeMetadata readonly struct ServerMessageRuntimeMetadata
{ {
public ushort InDataSize { get; } public ushort InDataSize { get; }
public ushort OutDataSize { get; } public ushort OutDataSize { get; }
public byte InHeadersSize { get; } public byte InHeadersSize { get; }
public byte OutHeadersSize { get; } public byte OutHeadersSize { get; }
public byte InObjectsCount { get; } public byte InObjectsCount { get; }
public byte OutObjectsCount { get; } public byte OutObjectsCount { get; }
public int UnfixedOutPointerSizeOffset => InDataSize + InHeadersSize + 0x10; public int UnfixedOutPointerSizeOffset => InDataSize + InHeadersSize + 0x10;
public ServerMessageRuntimeMetadata( public ServerMessageRuntimeMetadata(
ushort inDataSize, ushort inDataSize,
ushort outDataSize, ushort outDataSize,
byte inHeadersSize, byte inHeadersSize,
byte outHeadersSize, byte outHeadersSize,
byte inObjectsCount, byte inObjectsCount,
byte outObjectsCount) byte outObjectsCount)
{ {
InDataSize = inDataSize; InDataSize = inDataSize;
OutDataSize = outDataSize; OutDataSize = outDataSize;
InHeadersSize = inHeadersSize; InHeadersSize = inHeadersSize;
OutHeadersSize = outHeadersSize; OutHeadersSize = outHeadersSize;
InObjectsCount = inObjectsCount; InObjectsCount = inObjectsCount;
OutObjectsCount = outObjectsCount; OutObjectsCount = outObjectsCount;
} }
} }

View file

@ -5,14 +5,14 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
{ {
ref struct ServiceDispatchContext ref struct ServiceDispatchContext
{ {
public IServiceObject ServiceObject; public IServiceObject ServiceObject;
public ServerSessionManager Manager; public ServerSessionManager Manager;
public ServerSession Session; public ServerSession Session;
public ServerMessageProcessor Processor; public ServerMessageProcessor Processor;
public HandlesToClose HandlesToClose; public HandlesToClose HandlesToClose;
public PointerAndSize PointerBuffer; public PointerAndSize PointerBuffer;
public ReadOnlySpan<byte> InMessageBuffer; public ReadOnlySpan<byte> InMessageBuffer;
public Span<byte> OutMessageBuffer; public Span<byte> OutMessageBuffer;
public HipcMessage Request; public HipcMessage Request;
} }
} }

View file

@ -1,6 +1,6 @@
namespace Ryujinx.Horizon.Sdk.Sf.Cmif namespace Ryujinx.Horizon.Sdk.Sf.Cmif
{ {
struct ServiceDispatchMeta readonly struct ServiceDispatchMeta
{ {
public ServiceDispatchTableBase DispatchTable { get; } public ServiceDispatchTableBase DispatchTable { get; }

View file

@ -12,7 +12,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
public ServiceDispatchTable(string objectName, IReadOnlyDictionary<int, CommandHandler> entries) public ServiceDispatchTable(string objectName, IReadOnlyDictionary<int, CommandHandler> entries)
{ {
_objectName = objectName; _objectName = objectName;
_entries = entries; _entries = entries;
} }
public override Result ProcessMessage(ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData) public override Result ProcessMessage(ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData)

View file

@ -14,7 +14,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
public abstract Result ProcessMessage(ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData); public abstract Result ProcessMessage(ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData);
protected Result ProcessMessageImpl(ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData, IReadOnlyDictionary<int, CommandHandler> entries, string objectName) protected static Result ProcessMessageImpl(ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData, IReadOnlyDictionary<int, CommandHandler> entries, string objectName)
{ {
if (inRawData.Length < Unsafe.SizeOf<CmifInHeader>()) if (inRawData.Length < Unsafe.SizeOf<CmifInHeader>())
{ {
@ -44,7 +44,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
// If ignore missing services is enabled, just pretend that everything is fine. // If ignore missing services is enabled, just pretend that everything is fine.
PrepareForStubReply(ref context, out Span<byte> outRawData); PrepareForStubReply(ref context, out Span<byte> outRawData);
CommandHandler.GetCmifOutHeaderPointer(ref outHeader, ref outRawData); CommandHandler.GetCmifOutHeaderPointer(ref outHeader, ref outRawData);
outHeader[0] = new CmifOutHeader() { Magic = CmifMessage.CmifOutHeaderMagic, Result = Result.Success }; outHeader[0] = new CmifOutHeader { Magic = CmifMessage.CmifOutHeaderMagic, Result = Result.Success };
Logger.Warning?.Print(LogClass.Service, $"Missing service {objectName} (command ID: {commandId}) ignored"); Logger.Warning?.Print(LogClass.Service, $"Missing service {objectName} (command ID: {commandId}) ignored");
@ -80,7 +80,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif
return commandResult; return commandResult;
} }
outHeader[0] = new CmifOutHeader() { Magic = CmifMessage.CmifOutHeaderMagic, Result = commandResult }; outHeader[0] = new CmifOutHeader { Magic = CmifMessage.CmifOutHeaderMagic, Result = commandResult };
return Result.Success; return Result.Success;
} }

View file

@ -15,42 +15,42 @@ namespace Ryujinx.Horizon.Sdk.Sf
OutCopyHandle, OutCopyHandle,
OutMoveHandle, OutMoveHandle,
OutObject, OutObject,
ProcessId ProcessId,
} }
struct CommandArg readonly struct CommandArg
{ {
public CommandArgType Type { get; } public CommandArgType Type { get; }
public HipcBufferFlags BufferFlags { get; } public HipcBufferFlags BufferFlags { get; }
public ushort BufferFixedSize { get; } public ushort BufferFixedSize { get; }
public int ArgSize { get; } public int ArgSize { get; }
public int ArgAlignment { get; } public int ArgAlignment { get; }
public CommandArg(CommandArgType type) public CommandArg(CommandArgType type)
{ {
Type = type; Type = type;
BufferFlags = default; BufferFlags = default;
BufferFixedSize = 0; BufferFixedSize = 0;
ArgSize = 0; ArgSize = 0;
ArgAlignment = 0; ArgAlignment = 0;
} }
public CommandArg(CommandArgType type, int argSize, int argAlignment) public CommandArg(CommandArgType type, int argSize, int argAlignment)
{ {
Type = type; Type = type;
BufferFlags = default; BufferFlags = default;
BufferFixedSize = 0; BufferFixedSize = 0;
ArgSize = argSize; ArgSize = argSize;
ArgAlignment = argAlignment; ArgAlignment = argAlignment;
} }
public CommandArg(HipcBufferFlags flags, ushort fixedSize = 0) public CommandArg(HipcBufferFlags flags, ushort fixedSize = 0)
{ {
Type = CommandArgType.Buffer; Type = CommandArgType.Buffer;
BufferFlags = flags; BufferFlags = flags;
BufferFixedSize = fixedSize; BufferFixedSize = fixedSize;
ArgSize = 0; ArgSize = 0;
ArgAlignment = 0; ArgAlignment = 0;
} }
} }
} }

View file

@ -6,8 +6,8 @@ namespace Ryujinx.Horizon.Sdk.Sf
[AttributeUsage(AttributeTargets.Parameter)] [AttributeUsage(AttributeTargets.Parameter)]
class BufferAttribute : Attribute class BufferAttribute : Attribute
{ {
public HipcBufferFlags Flags { get; } public HipcBufferFlags Flags { get; }
public ushort FixedSize { get; } public ushort FixedSize { get; }
public BufferAttribute(HipcBufferFlags flags) public BufferAttribute(HipcBufferFlags flags)
{ {
@ -16,7 +16,7 @@ namespace Ryujinx.Horizon.Sdk.Sf
public BufferAttribute(HipcBufferFlags flags, ushort fixedSize) public BufferAttribute(HipcBufferFlags flags, ushort fixedSize)
{ {
Flags = flags | HipcBufferFlags.FixedSize; Flags = flags | HipcBufferFlags.FixedSize;
FixedSize = fixedSize; FixedSize = fixedSize;
} }
} }

View file

@ -9,20 +9,20 @@ namespace Ryujinx.Horizon.Sdk.Sf
class CommandHandler class CommandHandler
{ {
public delegate Result MethodInvoke( public delegate Result MethodInvoke(
ref ServiceDispatchContext context, ref ServiceDispatchContext context,
HipcCommandProcessor processor, HipcCommandProcessor processor,
ServerMessageRuntimeMetadata runtimeMetadata, ServerMessageRuntimeMetadata runtimeMetadata,
ReadOnlySpan<byte> inRawData, ReadOnlySpan<byte> inRawData,
ref Span<CmifOutHeader> outHeader); ref Span<CmifOutHeader> outHeader);
private readonly MethodInvoke _invoke; private readonly MethodInvoke _invoke;
private readonly HipcCommandProcessor _processor; private readonly HipcCommandProcessor _processor;
public string MethodName => _invoke.Method.Name; public string MethodName => _invoke.Method.Name;
public CommandHandler(MethodInvoke invoke, params CommandArg[] args) public CommandHandler(MethodInvoke invoke, params CommandArg[] args)
{ {
_invoke = invoke; _invoke = invoke;
_processor = new HipcCommandProcessor(args); _processor = new HipcCommandProcessor(args);
} }
@ -37,15 +37,15 @@ namespace Ryujinx.Horizon.Sdk.Sf
context.Processor.SetImplementationProcessor(_processor); context.Processor.SetImplementationProcessor(_processor);
} }
var runtimeMetadata = context.Processor.GetRuntimeMetadata(); var runtimeMetadata = context.Processor.GetRuntimeMetadata();
Result result = context.Processor.PrepareForProcess(ref context, runtimeMetadata); Result result = context.Processor.PrepareForProcess(ref context, runtimeMetadata);
return result.IsFailure ? result : _invoke(ref context, _processor, runtimeMetadata, inRawData, ref outHeader); return result.IsFailure ? result : _invoke(ref context, _processor, runtimeMetadata, inRawData, ref outHeader);
} }
public static void GetCmifOutHeaderPointer(ref Span<CmifOutHeader> outHeader, ref Span<byte> outRawData) public static void GetCmifOutHeaderPointer(ref Span<CmifOutHeader> outHeader, ref Span<byte> outRawData)
{ {
outHeader = MemoryMarshal.Cast<byte, CmifOutHeader>(outRawData)[..1]; outHeader = MemoryMarshal.Cast<byte, CmifOutHeader>(outRawData)[..1];
outRawData = outRawData[Unsafe.SizeOf<CmifOutHeader>()..]; outRawData = outRawData[Unsafe.SizeOf<CmifOutHeader>()..];
} }
} }

View file

@ -41,10 +41,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
return HorizonStatic.Syscall.ReplyAndReceive(out _, handles, 0, -1L); return HorizonStatic.Syscall.ReplyAndReceive(out _, handles, 0, -1L);
} }
else
{ throw new NotImplementedException();
throw new NotImplementedException();
}
} }
public static Result Reply(int sessionHandle, ReadOnlySpan<byte> messageBuffer) public static Result Reply(int sessionHandle, ReadOnlySpan<byte> messageBuffer)
@ -64,10 +62,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
return HorizonStatic.Syscall.ReplyAndReceive(out _, ReadOnlySpan<int>.Empty, sessionHandle, 0); return HorizonStatic.Syscall.ReplyAndReceive(out _, ReadOnlySpan<int>.Empty, sessionHandle, 0);
} }
else
{ throw new NotImplementedException();
throw new NotImplementedException();
}
} }
public static Result CreateSession(out int serverHandle, out int clientHandle) public static Result CreateSession(out int serverHandle, out int clientHandle)

View file

@ -10,55 +10,55 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
public CommandType Type public CommandType Type
{ {
get => (CommandType)_word0.Extract(0, 16); readonly get => (CommandType)_word0.Extract(0, 16);
set => _word0 = _word0.Insert(0, 16, (uint)value); set => _word0 = _word0.Insert(0, 16, (uint)value);
} }
public int SendStaticsCount public int SendStaticsCount
{ {
get => (int)_word0.Extract(16, 4); readonly get => (int)_word0.Extract(16, 4);
set => _word0 = _word0.Insert(16, 4, (uint)value); set => _word0 = _word0.Insert(16, 4, (uint)value);
} }
public int SendBuffersCount public int SendBuffersCount
{ {
get => (int)_word0.Extract(20, 4); readonly get => (int)_word0.Extract(20, 4);
set => _word0 = _word0.Insert(20, 4, (uint)value); set => _word0 = _word0.Insert(20, 4, (uint)value);
} }
public int ReceiveBuffersCount public int ReceiveBuffersCount
{ {
get => (int)_word0.Extract(24, 4); readonly get => (int)_word0.Extract(24, 4);
set => _word0 = _word0.Insert(24, 4, (uint)value); set => _word0 = _word0.Insert(24, 4, (uint)value);
} }
public int ExchangeBuffersCount public int ExchangeBuffersCount
{ {
get => (int)_word0.Extract(28, 4); readonly get => (int)_word0.Extract(28, 4);
set => _word0 = _word0.Insert(28, 4, (uint)value); set => _word0 = _word0.Insert(28, 4, (uint)value);
} }
public int DataWordsCount public int DataWordsCount
{ {
get => (int)_word1.Extract(0, 10); readonly get => (int)_word1.Extract(0, 10);
set => _word1 = _word1.Insert(0, 10, (uint)value); set => _word1 = _word1.Insert(0, 10, (uint)value);
} }
public int ReceiveStaticMode public int ReceiveStaticMode
{ {
get => (int)_word1.Extract(10, 4); readonly get => (int)_word1.Extract(10, 4);
set => _word1 = _word1.Insert(10, 4, (uint)value); set => _word1 = _word1.Insert(10, 4, (uint)value);
} }
public int ReceiveListOffset public int ReceiveListOffset
{ {
get => (int)_word1.Extract(20, 11); readonly get => (int)_word1.Extract(20, 11);
set => _word1 = _word1.Insert(20, 11, (uint)value); set => _word1 = _word1.Insert(20, 11, (uint)value);
} }
public bool HasSpecialHeader public bool HasSpecialHeader
{ {
get => _word1.Extract(31); readonly get => _word1.Extract(31);
set => _word1 = _word1.Insert(31, value); set => _word1 = _word1.Insert(31, value);
} }
} }

View file

@ -1,11 +1,11 @@
namespace Ryujinx.Horizon.Sdk.Sf.Hipc namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
struct HipcBufferDescriptor readonly struct HipcBufferDescriptor
{ {
#pragma warning disable CS0649 #pragma warning disable CS0649 // Field is never assigned to
private uint _sizeLow; private readonly uint _sizeLow;
private uint _addressLow; private readonly uint _addressLow;
private uint _word2; private readonly uint _word2;
#pragma warning restore CS0649 #pragma warning restore CS0649
public ulong Address => _addressLow | (((ulong)_word2 << 4) & 0xf00000000UL) | (((ulong)_word2 << 34) & 0x7000000000UL); public ulong Address => _addressLow | (((ulong)_word2 << 4) & 0xf00000000UL) | (((ulong)_word2 << 34) & 0x7000000000UL);

View file

@ -5,13 +5,13 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
[Flags] [Flags]
enum HipcBufferFlags : byte enum HipcBufferFlags : byte
{ {
In = 1 << 0, In = 1 << 0,
Out = 1 << 1, Out = 1 << 1,
MapAlias = 1 << 2, MapAlias = 1 << 2,
Pointer = 1 << 3, Pointer = 1 << 3,
FixedSize = 1 << 4, FixedSize = 1 << 4,
AutoSelect = 1 << 5, AutoSelect = 1 << 5,
MapTransferAllowsNonSecure = 1 << 6, MapTransferAllowsNonSecure = 1 << 6,
MapTransferAllowsNonDevice = 1 << 7 MapTransferAllowsNonDevice = 1 << 7,
} }
} }

View file

@ -2,9 +2,9 @@
{ {
enum HipcBufferMode enum HipcBufferMode
{ {
Normal = 0, Normal = 0,
NonSecure = 1, NonSecure = 1,
Invalid = 2, Invalid = 2,
NonDevice = 3 NonDevice = 3,
} }
} }

View file

@ -10,9 +10,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
public const int AutoReceiveStatic = byte.MaxValue; public const int AutoReceiveStatic = byte.MaxValue;
public HipcMetadata Meta; public HipcMetadata Meta;
public HipcMessageData Data; public HipcMessageData Data;
public ulong Pid; public ulong Pid;
public HipcMessage(Span<byte> data) public HipcMessage(Span<byte> data)
{ {
@ -22,8 +22,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
data = data[Unsafe.SizeOf<Header>()..]; data = data[Unsafe.SizeOf<Header>()..];
int receiveStaticsCount = 0; int receiveStaticsCount = 0;
ulong pid = 0; ulong pid = 0;
if (header.ReceiveStaticMode != 0) if (header.ReceiveStaticMode != 0)
{ {
@ -42,75 +42,75 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
if (header.HasSpecialHeader) if (header.HasSpecialHeader)
{ {
specialHeader = MemoryMarshal.Cast<byte, SpecialHeader>(data)[0]; specialHeader = MemoryMarshal.Cast<byte, SpecialHeader>(data)[0];
data = data[Unsafe.SizeOf<SpecialHeader>()..]; data = data[Unsafe.SizeOf<SpecialHeader>()..];
if (specialHeader.SendPid) if (specialHeader.SendPid)
{ {
pid = MemoryMarshal.Cast<byte, ulong>(data)[0]; pid = MemoryMarshal.Cast<byte, ulong>(data)[0];
data = data[sizeof(ulong)..]; data = data[sizeof(ulong)..];
} }
} }
Meta = new HipcMetadata() Meta = new HipcMetadata
{ {
Type = (int)header.Type, Type = (int)header.Type,
SendStaticsCount = header.SendStaticsCount, SendStaticsCount = header.SendStaticsCount,
SendBuffersCount = header.SendBuffersCount, SendBuffersCount = header.SendBuffersCount,
ReceiveBuffersCount = header.ReceiveBuffersCount, ReceiveBuffersCount = header.ReceiveBuffersCount,
ExchangeBuffersCount = header.ExchangeBuffersCount, ExchangeBuffersCount = header.ExchangeBuffersCount,
DataWordsCount = header.DataWordsCount, DataWordsCount = header.DataWordsCount,
ReceiveStaticsCount = receiveStaticsCount, ReceiveStaticsCount = receiveStaticsCount,
SendPid = specialHeader.SendPid, SendPid = specialHeader.SendPid,
CopyHandlesCount = specialHeader.CopyHandlesCount, CopyHandlesCount = specialHeader.CopyHandlesCount,
MoveHandlesCount = specialHeader.MoveHandlesCount MoveHandlesCount = specialHeader.MoveHandlesCount,
}; };
Data = CreateMessageData(Meta, data, initialLength); Data = CreateMessageData(Meta, data, initialLength);
Pid = pid; Pid = pid;
} }
public static HipcMessageData WriteResponse( public static HipcMessageData WriteResponse(
Span<byte> destination, Span<byte> destination,
int sendStaticCount, int sendStaticCount,
int dataWordsCount, int dataWordsCount,
int copyHandlesCount, int copyHandlesCount,
int moveHandlesCount) int moveHandlesCount)
{ {
return WriteMessage(destination, new HipcMetadata() return WriteMessage(destination, new HipcMetadata
{ {
SendStaticsCount = sendStaticCount, SendStaticsCount = sendStaticCount,
DataWordsCount = dataWordsCount, DataWordsCount = dataWordsCount,
CopyHandlesCount = copyHandlesCount, CopyHandlesCount = copyHandlesCount,
MoveHandlesCount = moveHandlesCount MoveHandlesCount = moveHandlesCount,
}); });
} }
public static HipcMessageData WriteMessage(Span<byte> destination, HipcMetadata meta) public static HipcMessageData WriteMessage(Span<byte> destination, HipcMetadata meta)
{ {
int initialLength = destination.Length; int initialLength = destination.Length;
bool hasSpecialHeader = meta.SendPid || meta.CopyHandlesCount != 0 || meta.MoveHandlesCount != 0; bool hasSpecialHeader = meta.SendPid || meta.CopyHandlesCount != 0 || meta.MoveHandlesCount != 0;
MemoryMarshal.Cast<byte, Header>(destination)[0] = new Header() MemoryMarshal.Cast<byte, Header>(destination)[0] = new Header
{ {
Type = (CommandType)meta.Type, Type = (CommandType)meta.Type,
SendStaticsCount = meta.SendStaticsCount, SendStaticsCount = meta.SendStaticsCount,
SendBuffersCount = meta.SendBuffersCount, SendBuffersCount = meta.SendBuffersCount,
ReceiveBuffersCount = meta.ReceiveBuffersCount, ReceiveBuffersCount = meta.ReceiveBuffersCount,
ExchangeBuffersCount = meta.ExchangeBuffersCount, ExchangeBuffersCount = meta.ExchangeBuffersCount,
DataWordsCount = meta.DataWordsCount, DataWordsCount = meta.DataWordsCount,
ReceiveStaticMode = meta.ReceiveStaticsCount != 0 ? (meta.ReceiveStaticsCount != AutoReceiveStatic ? meta.ReceiveStaticsCount + 2 : 2) : 0, ReceiveStaticMode = meta.ReceiveStaticsCount != 0 ? (meta.ReceiveStaticsCount != AutoReceiveStatic ? meta.ReceiveStaticsCount + 2 : 2) : 0,
HasSpecialHeader = hasSpecialHeader HasSpecialHeader = hasSpecialHeader,
}; };
destination = destination[Unsafe.SizeOf<Header>()..]; destination = destination[Unsafe.SizeOf<Header>()..];
if (hasSpecialHeader) if (hasSpecialHeader)
{ {
MemoryMarshal.Cast<byte, SpecialHeader>(destination)[0] = new SpecialHeader() MemoryMarshal.Cast<byte, SpecialHeader>(destination)[0] = new SpecialHeader
{ {
SendPid = meta.SendPid, SendPid = meta.SendPid,
CopyHandlesCount = meta.CopyHandlesCount, CopyHandlesCount = meta.CopyHandlesCount,
MoveHandlesCount = meta.MoveHandlesCount MoveHandlesCount = meta.MoveHandlesCount,
}; };
destination = destination[Unsafe.SizeOf<SpecialHeader>()..]; destination = destination[Unsafe.SizeOf<SpecialHeader>()..];
@ -184,9 +184,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
if (meta.DataWordsCount != 0) if (meta.DataWordsCount != 0)
{ {
int dataOffset = initialLength - data.Length; int dataOffset = initialLength - data.Length;
int dataOffsetAligned = BitUtils.AlignUp(dataOffset, 0x10); int dataOffsetAligned = BitUtils.AlignUp(dataOffset, 0x10);
int padding = (dataOffsetAligned - dataOffset) / sizeof(uint); int padding = (dataOffsetAligned - dataOffset) / sizeof(uint);
dataWords = MemoryMarshal.Cast<byte, uint>(data)[padding..meta.DataWordsCount]; dataWords = MemoryMarshal.Cast<byte, uint>(data)[padding..meta.DataWordsCount];
@ -202,16 +202,16 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
receiveList = MemoryMarshal.Cast<byte, HipcReceiveListEntry>(data)[..receiveListSize]; receiveList = MemoryMarshal.Cast<byte, HipcReceiveListEntry>(data)[..receiveListSize];
} }
return new HipcMessageData() return new HipcMessageData
{ {
SendStatics = sendStatics, SendStatics = sendStatics,
SendBuffers = sendBuffers, SendBuffers = sendBuffers,
ReceiveBuffers = receiveBuffers, ReceiveBuffers = receiveBuffers,
ExchangeBuffers = exchangeBuffers, ExchangeBuffers = exchangeBuffers,
DataWords = dataWords, DataWords = dataWords,
ReceiveList = receiveList, ReceiveList = receiveList,
CopyHandles = copyHandles, CopyHandles = copyHandles,
MoveHandles = moveHandles MoveHandles = moveHandles,
}; };
} }
} }

View file

@ -8,9 +8,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
public Span<HipcBufferDescriptor> SendBuffers; public Span<HipcBufferDescriptor> SendBuffers;
public Span<HipcBufferDescriptor> ReceiveBuffers; public Span<HipcBufferDescriptor> ReceiveBuffers;
public Span<HipcBufferDescriptor> ExchangeBuffers; public Span<HipcBufferDescriptor> ExchangeBuffers;
public Span<uint> DataWords; public Span<uint> DataWords;
public Span<HipcReceiveListEntry> ReceiveList; public Span<HipcReceiveListEntry> ReceiveList;
public Span<int> CopyHandles; public Span<int> CopyHandles;
public Span<int> MoveHandles; public Span<int> MoveHandles;
} }
} }

View file

@ -2,15 +2,15 @@
{ {
struct HipcMetadata struct HipcMetadata
{ {
public int Type; public int Type;
public int SendStaticsCount; public int SendStaticsCount;
public int SendBuffersCount; public int SendBuffersCount;
public int ReceiveBuffersCount; public int ReceiveBuffersCount;
public int ExchangeBuffersCount; public int ExchangeBuffersCount;
public int DataWordsCount; public int DataWordsCount;
public int ReceiveStaticsCount; public int ReceiveStaticsCount;
public bool SendPid; public bool SendPid;
public int CopyHandlesCount; public int CopyHandlesCount;
public int MoveHandlesCount; public int MoveHandlesCount;
} }
} }

View file

@ -1,14 +1,16 @@
namespace Ryujinx.Horizon.Sdk.Sf.Hipc namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
struct HipcReceiveListEntry readonly struct HipcReceiveListEntry
{ {
private uint _addressLow; #pragma warning disable IDE0052 // Remove unread private member
private uint _word1; private readonly uint _addressLow;
private readonly uint _word1;
#pragma warning restore IDE0052
public HipcReceiveListEntry(ulong address, ulong size) public HipcReceiveListEntry(ulong address, ulong size)
{ {
_addressLow = (uint)address; _addressLow = (uint)address;
_word1 = (ushort)(address >> 32) | (uint)(size << 16); _word1 = (ushort)(address >> 32) | (uint)(size << 16);
} }
} }
} }

View file

@ -6,6 +6,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
public const int ModuleId = 11; public const int ModuleId = 11;
#pragma warning disable IDE0055 // Disable formatting
public static Result OutOfSessionMemory => new(ModuleId, 102); public static Result OutOfSessionMemory => new(ModuleId, 102);
public static Result OutOfSessions => new(ModuleId, 131); public static Result OutOfSessions => new(ModuleId, 131);
public static Result PointerBufferTooSmall => new(ModuleId, 141); public static Result PointerBufferTooSmall => new(ModuleId, 141);
@ -15,5 +16,6 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
public static Result InvalidCmifRequest => new(ModuleId, 420); public static Result InvalidCmifRequest => new(ModuleId, 420);
public static Result TargetNotDomain => new(ModuleId, 491); public static Result TargetNotDomain => new(ModuleId, 491);
public static Result DomainObjectNotFound => new(ModuleId, 492); public static Result DomainObjectNotFound => new(ModuleId, 492);
#pragma warning restore IDE0055
} }
} }

View file

@ -1,12 +1,12 @@
namespace Ryujinx.Horizon.Sdk.Sf.Hipc namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
struct HipcStaticDescriptor readonly struct HipcStaticDescriptor
{ {
private readonly ulong _data; private readonly ulong _data;
public ulong Address => ((((_data >> 2) & 0x70) | ((_data >> 12) & 0xf)) << 32) | (_data >> 32); public ulong Address => ((((_data >> 2) & 0x70) | ((_data >> 12) & 0xf)) << 32) | (_data >> 32);
public ushort Size => (ushort)(_data >> 16); public ushort Size => (ushort)(_data >> 16);
public int ReceiveIndex => (int)(_data & 0xf); public int ReceiveIndex => (int)(_data & 0xf);
public HipcStaticDescriptor(ulong address, ushort size, int receiveIndex) public HipcStaticDescriptor(ulong address, ushort size, int receiveIndex)
{ {

View file

@ -1,19 +1,19 @@
namespace Ryujinx.Horizon.Sdk.Sf.Hipc namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
struct ManagerOptions readonly struct ManagerOptions
{ {
public static ManagerOptions Default => new(0, 0, 0, false); public static ManagerOptions Default => new(0, 0, 0, false);
public int PointerBufferSize { get; } public int PointerBufferSize { get; }
public int MaxDomains { get; } public int MaxDomains { get; }
public int MaxDomainObjects { get; } public int MaxDomainObjects { get; }
public bool CanDeferInvokeRequest { get; } public bool CanDeferInvokeRequest { get; }
public ManagerOptions(int pointerBufferSize, int maxDomains, int maxDomainObjects, bool canDeferInvokeRequest) public ManagerOptions(int pointerBufferSize, int maxDomains, int maxDomainObjects, bool canDeferInvokeRequest)
{ {
PointerBufferSize = pointerBufferSize; PointerBufferSize = pointerBufferSize;
MaxDomains = maxDomains; MaxDomains = maxDomains;
MaxDomainObjects = maxDomainObjects; MaxDomainObjects = maxDomainObjects;
CanDeferInvokeRequest = canDeferInvokeRequest; CanDeferInvokeRequest = canDeferInvokeRequest;
} }
} }

View file

@ -4,6 +4,6 @@
{ {
Success, Success,
Closed, Closed,
NeedsRetry NeedsRetry,
} }
} }

View file

@ -6,22 +6,22 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
class Server : MultiWaitHolderOfHandle class Server : MultiWaitHolderOfHandle
{ {
public int PortIndex { get; } public int PortIndex { get; }
public int PortHandle { get; } public int PortHandle { get; }
public ServiceName Name { get; } public ServiceName Name { get; }
public bool Managed { get; } public bool Managed { get; }
public ServiceObjectHolder StaticObject { get; } public ServiceObjectHolder StaticObject { get; }
public Server( public Server(
int portIndex, int portIndex,
int portHandle, int portHandle,
ServiceName name, ServiceName name,
bool managed, bool managed,
ServiceObjectHolder staticHoder) : base(portHandle) ServiceObjectHolder staticHoder) : base(portHandle)
{ {
PortHandle = portHandle; PortHandle = portHandle;
Name = name; Name = name;
Managed = managed; Managed = managed;
if (staticHoder != null) if (staticHoder != null)
{ {

View file

@ -14,8 +14,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
private readonly bool _canDeferInvokeRequest; private readonly bool _canDeferInvokeRequest;
private readonly int _maxSessions; private readonly int _maxSessions;
private ulong _pointerBuffersBaseAddress; private readonly ulong _pointerBuffersBaseAddress;
private ulong _savedMessagesBaseAddress; private readonly ulong _savedMessagesBaseAddress;
private readonly object _resourceLock; private readonly object _resourceLock;
private readonly ulong[] _sessionAllocationBitmap; private readonly ulong[] _sessionAllocationBitmap;
@ -35,7 +35,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
if (options.CanDeferInvokeRequest) if (options.CanDeferInvokeRequest)
{ {
_savedMessagesBaseAddress = allocator.Allocate((ulong)maxSessions * (ulong)Api.TlsMessageBufferSize); _savedMessagesBaseAddress = allocator.Allocate((ulong)maxSessions * Api.TlsMessageBufferSize);
} }
} }
@ -45,7 +45,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
_servers = new HashSet<Server>(); _servers = new HashSet<Server>();
} }
private PointerAndSize GetObjectBySessionIndex(ServerSession session, ulong baseAddress, ulong size) private static PointerAndSize GetObjectBySessionIndex(ServerSession session, ulong baseAddress, ulong size)
{ {
return new PointerAndSize(baseAddress + (ulong)session.SessionIndex * size, size); return new PointerAndSize(baseAddress + (ulong)session.SessionIndex * size, size);
} }
@ -61,7 +61,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
return null; return null;
} }
for (int i = 0; i <_sessionAllocationBitmap.Length; i++) for (int i = 0; i < _sessionAllocationBitmap.Length; i++)
{ {
ref ulong mask = ref _sessionAllocationBitmap[i]; ref ulong mask = ref _sessionAllocationBitmap[i];
@ -145,10 +145,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
return GetObjectBySessionIndex(session, _pointerBuffersBaseAddress, (ulong)_pointerBufferSize); return GetObjectBySessionIndex(session, _pointerBuffersBaseAddress, (ulong)_pointerBufferSize);
} }
else
{ return PointerAndSize.Empty;
return PointerAndSize.Empty;
}
} }
protected override PointerAndSize GetSessionSavedMessageBuffer(ServerSession session) protected override PointerAndSize GetSessionSavedMessageBuffer(ServerSession session)
@ -157,10 +155,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
return GetObjectBySessionIndex(session, _savedMessagesBaseAddress, Api.TlsMessageBufferSize); return GetObjectBySessionIndex(session, _savedMessagesBaseAddress, Api.TlsMessageBufferSize);
} }
else
{ return PointerAndSize.Empty;
return PointerAndSize.Empty;
}
} }
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)

View file

@ -10,7 +10,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
private readonly SmApi _sm; private readonly SmApi _sm;
private bool _canDeferInvokeRequest; private readonly bool _canDeferInvokeRequest;
private readonly MultiWait _multiWait; private readonly MultiWait _multiWait;
private readonly MultiWait _waitList; private readonly MultiWait _waitList;
@ -26,8 +26,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
private enum UserDataTag private enum UserDataTag
{ {
Server = 1, Server = 1,
Session = 2 Session = 2,
} }
public ServerManagerBase(SmApi sm, ManagerOptions options) : base(options.MaxDomainObjects, options.MaxDomains) public ServerManagerBase(SmApi sm, ManagerOptions options) : base(options.MaxDomainObjects, options.MaxDomains)
@ -36,13 +36,13 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
_canDeferInvokeRequest = options.CanDeferInvokeRequest; _canDeferInvokeRequest = options.CanDeferInvokeRequest;
_multiWait = new MultiWait(); _multiWait = new MultiWait();
_waitList = new MultiWait(); _waitList = new MultiWait();
_multiWaitSelectionLock = new object(); _multiWaitSelectionLock = new object();
_waitListLock = new object(); _waitListLock = new object();
_requestStopEvent = new Event(EventClearMode.ManualClear); _requestStopEvent = new Event(EventClearMode.ManualClear);
_notifyEvent = new Event(EventClearMode.ManualClear); _notifyEvent = new Event(EventClearMode.ManualClear);
_requestStopEventHolder = new MultiWaitHolderOfEvent(_requestStopEvent); _requestStopEventHolder = new MultiWaitHolderOfEvent(_requestStopEvent);
_multiWait.LinkMultiWaitHolder(_requestStopEventHolder); _multiWait.LinkMultiWaitHolder(_requestStopEventHolder);
@ -113,7 +113,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
public void ServiceRequests() public void ServiceRequests()
{ {
while (WaitAndProcessRequestsImpl()); while (WaitAndProcessRequestsImpl())
{
}
} }
public void WaitAndProcessRequests() public void WaitAndProcessRequests()
@ -183,7 +185,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
protected override void RegisterSessionToWaitList(ServerSession session) protected override void RegisterSessionToWaitList(ServerSession session)
{ {
session.HasReceived = false; session.HasReceived = false;
session.UserData = UserDataTag.Session; session.UserData = UserDataTag.Session;
RegisterToWaitList(session); RegisterToWaitList(session);
} }
@ -209,9 +211,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
return (UserDataTag)holder.UserData switch return (UserDataTag)holder.UserData switch
{ {
UserDataTag.Server => ProcessForServer(holder), UserDataTag.Server => ProcessForServer(holder),
UserDataTag.Session => ProcessForSession(holder), UserDataTag.Session => ProcessForSession(holder),
_ => throw new NotImplementedException(((UserDataTag)holder.UserData).ToString()) _ => throw new NotImplementedException(((UserDataTag)holder.UserData).ToString()),
}; };
} }

View file

@ -6,18 +6,18 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
class ServerSession : MultiWaitHolderOfHandle class ServerSession : MultiWaitHolderOfHandle
{ {
public ServiceObjectHolder ServiceObjectHolder { get; set; } public ServiceObjectHolder ServiceObjectHolder { get; set; }
public PointerAndSize PointerBuffer { get; set; } public PointerAndSize PointerBuffer { get; set; }
public PointerAndSize SavedMessage { get; set; } public PointerAndSize SavedMessage { get; set; }
public int SessionIndex { get; } public int SessionIndex { get; }
public int SessionHandle { get; } public int SessionHandle { get; }
public bool IsClosed { get; set; } public bool IsClosed { get; set; }
public bool HasReceived { get; set; } public bool HasReceived { get; set; }
public ServerSession(int index, int handle, ServiceObjectHolder obj) : base(handle) public ServerSession(int index, int handle, ServiceObjectHolder obj) : base(handle)
{ {
ServiceObjectHolder = obj; ServiceObjectHolder = obj;
SessionIndex = index; SessionIndex = index;
SessionHandle = handle; SessionHandle = handle;
} }
} }
} }

View file

@ -75,7 +75,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
} }
session.PointerBuffer = GetSessionPointerBuffer(session); session.PointerBuffer = GetSessionPointerBuffer(session);
session.SavedMessage = GetSessionSavedMessageBuffer(session); session.SavedMessage = GetSessionSavedMessageBuffer(session);
RegisterSessionToWaitList(session); RegisterSessionToWaitList(session);
@ -110,10 +110,10 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
} }
protected virtual Server AllocateServer( protected virtual Server AllocateServer(
int portIndex, int portIndex,
int portHandle, int portHandle,
ServiceName name, ServiceName name,
bool managed, bool managed,
ServiceObjectHolder staticHoder) ServiceObjectHolder staticHoder)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
@ -161,29 +161,25 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
return Result.Success; return Result.Success;
} }
else
Result result = ProcessRequestImpl(session, message, message);
if (result.IsSuccess)
{ {
Result result = ProcessRequestImpl(session, message, message); RegisterSessionToWaitList(session);
if (result.IsSuccess) return Result.Success;
{
RegisterSessionToWaitList(session);
return Result.Success;
}
else if (SfResult.RequestContextChanged(result))
{
return result;
}
else
{
Logger.Warning?.Print(LogClass.KernelIpc, $"Request processing returned error {result}");
CloseSessionImpl(session);
return Result.Success;
}
} }
else if (SfResult.RequestContextChanged(result))
{
return result;
}
Logger.Warning?.Print(LogClass.KernelIpc, $"Request processing returned error {result}");
CloseSessionImpl(session);
return Result.Success;
} }
private Result ProcessRequestImpl(ServerSession session, Span<byte> inMessage, Span<byte> outMessage) private Result ProcessRequestImpl(ServerSession session, Span<byte> inMessage, Span<byte> outMessage)
@ -192,18 +188,13 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
using var _ = new ScopedInlineContextChange(GetInlineContext(commandType, inMessage)); using var _ = new ScopedInlineContextChange(GetInlineContext(commandType, inMessage));
switch (commandType) return commandType switch
{ {
case CommandType.Request: CommandType.Request or CommandType.RequestWithContext => DispatchRequest(session.ServiceObjectHolder, session, inMessage, outMessage),
case CommandType.RequestWithContext: CommandType.Control or CommandType.ControlWithContext => DispatchManagerRequest(session, inMessage, outMessage),
return DispatchRequest(session.ServiceObjectHolder, session, inMessage, outMessage); _ => HipcResult.UnknownCommandType,
case CommandType.Control: };
case CommandType.ControlWithContext:
return DispatchManagerRequest(session, inMessage, outMessage);
default:
return HipcResult.UnknownCommandType;
} }
}
private static int GetInlineContext(CommandType commandType, ReadOnlySpan<byte> inMessage) private static int GetInlineContext(CommandType commandType, ReadOnlySpan<byte> inMessage)
{ {
@ -221,12 +212,12 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
return 0; return 0;
} }
protected Result ReceiveRequest(ServerSession session, Span<byte> message) protected static Result ReceiveRequest(ServerSession session, Span<byte> message)
{ {
return ReceiveRequestImpl(session, message); return ReceiveRequestImpl(session, message);
} }
private Result ReceiveRequestImpl(ServerSession session, Span<byte> message) private static Result ReceiveRequestImpl(ServerSession session, Span<byte> message)
{ {
PointerAndSize pointerBuffer = session.PointerBuffer; PointerAndSize pointerBuffer = session.PointerBuffer;
@ -234,19 +225,19 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
{ {
if (pointerBuffer.Address != 0) if (pointerBuffer.Address != 0)
{ {
HipcMessageData messageData = HipcMessage.WriteMessage(message, new HipcMetadata() HipcMessageData messageData = HipcMessage.WriteMessage(message, new HipcMetadata
{ {
Type = (int)CommandType.Invalid, Type = (int)CommandType.Invalid,
ReceiveStaticsCount = HipcMessage.AutoReceiveStatic ReceiveStaticsCount = HipcMessage.AutoReceiveStatic,
}); });
messageData.ReceiveList[0] = new HipcReceiveListEntry(pointerBuffer.Address, pointerBuffer.Size); messageData.ReceiveList[0] = new HipcReceiveListEntry(pointerBuffer.Address, pointerBuffer.Size);
} }
else else
{ {
MemoryMarshal.Cast<byte, Header>(message)[0] = new Header() MemoryMarshal.Cast<byte, Header>(message)[0] = new Header
{ {
Type = CommandType.Invalid Type = CommandType.Invalid,
}; };
} }
@ -276,9 +267,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
protected virtual Result DispatchRequest( protected virtual Result DispatchRequest(
ServiceObjectHolder objectHolder, ServiceObjectHolder objectHolder,
ServerSession session, ServerSession session,
Span<byte> inMessage, Span<byte> inMessage,
Span<byte> outMessage) Span<byte> outMessage)
{ {
HipcMessage request; HipcMessage request;
@ -291,16 +282,16 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
return HipcResult.InvalidRequestSize; return HipcResult.InvalidRequestSize;
} }
var dispatchCtx = new ServiceDispatchContext() var dispatchCtx = new ServiceDispatchContext
{ {
ServiceObject = objectHolder.ServiceObject, ServiceObject = objectHolder.ServiceObject,
Manager = this, Manager = this,
Session = session, Session = session,
HandlesToClose = new HandlesToClose(), HandlesToClose = new HandlesToClose(),
PointerBuffer = session.PointerBuffer, PointerBuffer = session.PointerBuffer,
InMessageBuffer = inMessage, InMessageBuffer = inMessage,
OutMessageBuffer = outMessage, OutMessageBuffer = outMessage,
Request = request Request = request,
}; };
ReadOnlySpan<byte> inRawData = MemoryMarshal.Cast<uint, byte>(dispatchCtx.Request.Data.DataWords); ReadOnlySpan<byte> inRawData = MemoryMarshal.Cast<uint, byte>(dispatchCtx.Request.Data.DataWords);

View file

@ -8,19 +8,19 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc
public bool SendPid public bool SendPid
{ {
get => _word.Extract(0); readonly get => _word.Extract(0);
set => _word = _word.Insert(0, value); set => _word = _word.Insert(0, value);
} }
public int CopyHandlesCount public int CopyHandlesCount
{ {
get => (int)_word.Extract(1, 4); readonly get => (int)_word.Extract(1, 4);
set => _word = _word.Insert(1, 4, (uint)value); set => _word = _word.Insert(1, 4, (uint)value);
} }
public int MoveHandlesCount public int MoveHandlesCount
{ {
get => (int)_word.Extract(5, 4); readonly get => (int)_word.Extract(5, 4);
set => _word = _word.Insert(5, 4, (uint)value); set => _word = _word.Insert(5, 4, (uint)value);
} }
} }

View file

@ -134,9 +134,9 @@ namespace Ryujinx.Horizon.Sdk.Sf
ulong pointerBufferTail = context.PointerBuffer.Address; ulong pointerBufferTail = context.PointerBuffer.Address;
ulong pointerBufferHead = pointerBufferTail + context.PointerBuffer.Size; ulong pointerBufferHead = pointerBufferTail + context.PointerBuffer.Size;
int sendMapAliasIndex = 0; int sendMapAliasIndex = 0;
int recvMapAliasIndex = 0; int recvMapAliasIndex = 0;
int sendPointerIndex = 0; int sendPointerIndex = 0;
int unfixedRecvPointerIndex = 0; int unfixedRecvPointerIndex = 0;
for (int i = 0; i < _args.Length; i++) for (int i = 0; i < _args.Length; i++)
@ -186,8 +186,8 @@ namespace Ryujinx.Horizon.Sdk.Sf
if (flags.HasFlag(HipcBufferFlags.In)) if (flags.HasFlag(HipcBufferFlags.In))
{ {
var descriptor = context.Request.Data.SendStatics[sendPointerIndex++]; var descriptor = context.Request.Data.SendStatics[sendPointerIndex++];
ulong address = descriptor.Address; ulong address = descriptor.Address;
ulong size = descriptor.Size; ulong size = descriptor.Size;
_bufferRanges[i] = new PointerAndSize(address, size); _bufferRanges[i] = new PointerAndSize(address, size);
@ -206,14 +206,14 @@ namespace Ryujinx.Horizon.Sdk.Sf
} }
else else
{ {
var data = MemoryMarshal.Cast<uint, byte>(context.Request.Data.DataWords); var data = MemoryMarshal.Cast<uint, byte>(context.Request.Data.DataWords);
var recvPointerSizes = MemoryMarshal.Cast<byte, ushort>(data[runtimeMetadata.UnfixedOutPointerSizeOffset..]); var recvPointerSizes = MemoryMarshal.Cast<byte, ushort>(data[runtimeMetadata.UnfixedOutPointerSizeOffset..]);
size = recvPointerSizes[unfixedRecvPointerIndex++]; size = recvPointerSizes[unfixedRecvPointerIndex++];
} }
pointerBufferHead = BitUtils.AlignDown(pointerBufferHead - size, 0x10UL); pointerBufferHead = BitUtils.AlignDown(pointerBufferHead - size, 0x10UL);
_bufferRanges[i] = new PointerAndSize(pointerBufferHead, size); _bufferRanges[i] = new PointerAndSize(pointerBufferHead, size);
} }
} }
} }
@ -305,13 +305,13 @@ namespace Ryujinx.Horizon.Sdk.Sf
{ {
ref var meta = ref context.Request.Meta; ref var meta = ref context.Request.Meta;
bool requestValid = true; bool requestValid = true;
requestValid &= meta.SendPid == _hasInProcessIdHolder; requestValid &= meta.SendPid == _hasInProcessIdHolder;
requestValid &= meta.SendStaticsCount == _inPointerBuffersCount; requestValid &= meta.SendStaticsCount == _inPointerBuffersCount;
requestValid &= meta.SendBuffersCount == _inMapAliasBuffersCount; requestValid &= meta.SendBuffersCount == _inMapAliasBuffersCount;
requestValid &= meta.ReceiveBuffersCount == _outMapAliasBuffersCount; requestValid &= meta.ReceiveBuffersCount == _outMapAliasBuffersCount;
requestValid &= meta.ExchangeBuffersCount == 0; requestValid &= meta.ExchangeBuffersCount == 0;
requestValid &= meta.CopyHandlesCount == _inCopyHandlesCount; requestValid &= meta.CopyHandlesCount == _inCopyHandlesCount;
requestValid &= meta.MoveHandlesCount == _inMoveHandlesCount; requestValid &= meta.MoveHandlesCount == _inMoveHandlesCount;
int rawSizeInBytes = meta.DataWordsCount * sizeof(uint); int rawSizeInBytes = meta.DataWordsCount * sizeof(uint);
int commandRawSize = BitUtils.AlignUp(runtimeMetadata.UnfixedOutPointerSizeOffset + (OutUnfixedSizePointerBuffersCount * sizeof(ushort)), sizeof(uint)); int commandRawSize = BitUtils.AlignUp(runtimeMetadata.UnfixedOutPointerSizeOffset + (OutUnfixedSizePointerBuffersCount * sizeof(ushort)), sizeof(uint));
@ -345,7 +345,7 @@ namespace Ryujinx.Horizon.Sdk.Sf
continue; continue;
} }
int index = inObjectIndex++; int index = inObjectIndex++;
var inObject = inObjects[index]; var inObject = inObjects[index];
objects[index] = inObject?.ServiceObject; objects[index] = inObject?.ServiceObject;
@ -386,7 +386,9 @@ namespace Ryujinx.Horizon.Sdk.Sf
outRawData = MemoryMarshal.Cast<uint, byte>(response.DataWords); outRawData = MemoryMarshal.Cast<uint, byte>(response.DataWords);
} }
#pragma warning disable CA1822 // Mark member as static
public void SetOutObjects(ref ServiceDispatchContext context, HipcMessageData response, Span<IServiceObject> objects) public void SetOutObjects(ref ServiceDispatchContext context, HipcMessageData response, Span<IServiceObject> objects)
#pragma warning restore CA1822
{ {
if (objects.Length == 0) if (objects.Length == 0)
{ {
@ -411,7 +413,7 @@ namespace Ryujinx.Horizon.Sdk.Sf
} }
} }
private void SetOutObjectImpl(int index, HipcMessageData response, ServerSessionManager manager, ServiceObjectHolder obj) private static void SetOutObjectImpl(int index, HipcMessageData response, ServerSessionManager manager, ServiceObjectHolder obj)
{ {
if (obj == null) if (obj == null)
{ {

View file

@ -12,15 +12,15 @@ namespace Ryujinx.Horizon.Sdk.Sf
{ {
int argsCount = args.Length; int argsCount = args.Length;
int[] sizes = new int[argsCount]; int[] sizes = new int[argsCount];
int[] aligns = new int[argsCount]; int[] aligns = new int[argsCount];
int[] map = new int[argsCount]; int[] map = new int[argsCount];
for (int i = 0; i < argsCount; i++) for (int i = 0; i < argsCount; i++)
{ {
sizes[i] = args[i].ArgSize; sizes[i] = args[i].ArgSize;
aligns[i] = args[i].ArgAlignment; aligns[i] = args[i].ArgAlignment;
map[i] = i; map[i] = i;
} }
for (int i = 1; i < argsCount; i++) for (int i = 1; i < argsCount; i++)
@ -35,9 +35,9 @@ namespace Ryujinx.Horizon.Sdk.Sf
foreach (int i in map) foreach (int i in map)
{ {
offset = BitUtils.AlignUp(offset, aligns[i]); offset = BitUtils.AlignUp(offset, aligns[i]);
offsets[i] = offset; offsets[i] = offset;
offset += sizes[i]; offset += sizes[i];
} }
offsets[argsCount] = offset; offsets[argsCount] = offset;

View file

@ -6,6 +6,7 @@ namespace Ryujinx.Horizon.Sdk.Sf
{ {
public const int ModuleId = 10; public const int ModuleId = 10;
#pragma warning disable IDE0055 // Disable formatting
public static Result NotSupported => new(ModuleId, 1); public static Result NotSupported => new(ModuleId, 1);
public static Result InvalidHeaderSize => new(ModuleId, 202); public static Result InvalidHeaderSize => new(ModuleId, 202);
public static Result InvalidInHeader => new(ModuleId, 211); public static Result InvalidInHeader => new(ModuleId, 211);
@ -23,5 +24,6 @@ namespace Ryujinx.Horizon.Sdk.Sf
public static bool RequestContextChanged(Result result) => result.InRange(800, 899); public static bool RequestContextChanged(Result result) => result.InRange(800, 899);
public static bool Invalidated(Result result) => result.InRange(801, 809); public static bool Invalidated(Result result) => result.InRange(801, 809);
public static bool RequestDeferred(Result result) => result.InRange(811, 819); public static bool RequestDeferred(Result result) => result.InRange(811, 819);
#pragma warning restore IDE0055
} }
} }

View file

@ -4,13 +4,13 @@ using System.Runtime.InteropServices;
namespace Ryujinx.Horizon.Sdk.Sm namespace Ryujinx.Horizon.Sdk.Sm
{ {
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ServiceName readonly struct ServiceName
{ {
public static ServiceName Invalid { get; } = new ServiceName(0); public static ServiceName Invalid { get; } = new(0);
public bool IsValid => Packed != 0; public bool IsValid => Packed != 0;
public int Length => sizeof(ulong); public const int Length = sizeof(ulong);
public ulong Packed { get; } public ulong Packed { get; }

View file

@ -4,17 +4,17 @@ using System;
namespace Ryujinx.Horizon namespace Ryujinx.Horizon
{ {
public struct ServiceEntry public readonly struct ServiceEntry
{ {
private readonly Action<ServiceTable> _entrypoint; private readonly Action<ServiceTable> _entrypoint;
private readonly ServiceTable _serviceTable; private readonly ServiceTable _serviceTable;
private readonly HorizonOptions _options; private readonly HorizonOptions _options;
internal ServiceEntry(Action<ServiceTable> entrypoint, ServiceTable serviceTable, HorizonOptions options) internal ServiceEntry(Action<ServiceTable> entrypoint, ServiceTable serviceTable, HorizonOptions options)
{ {
_entrypoint = entrypoint; _entrypoint = entrypoint;
_serviceTable = serviceTable; _serviceTable = serviceTable;
_options = options; _options = options;
} }
public void Start(ISyscallApi syscallApi, IVirtualMemoryManager addressSpace, IThreadContext threadContext) public void Start(ISyscallApi syscallApi, IVirtualMemoryManager addressSpace, IThreadContext threadContext)

View file

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

View file

@ -40,7 +40,7 @@ namespace Ryujinx.Horizon.Sm.Impl
return result == KernelResult.SessionCountExceeded ? SmResult.OutOfSessions : result; return result == KernelResult.SessionCountExceeded ? SmResult.OutOfSessions : result;
} }
private Result GetServiceImpl(out int handle, ref ServiceInfo serviceInfo) private static Result GetServiceImpl(out int handle, ref ServiceInfo serviceInfo)
{ {
return HorizonStatic.Syscall.ConnectToPort(out handle, serviceInfo.PortHandle); return HorizonStatic.Syscall.ConnectToPort(out handle, serviceInfo.PortHandle);
} }
@ -96,8 +96,8 @@ namespace Ryujinx.Horizon.Sm.Impl
return result; return result;
} }
freeService.PortHandle = clientPort; freeService.PortHandle = clientPort;
freeService.Name = name; freeService.Name = name;
freeService.OwnerProcessId = processId; freeService.OwnerProcessId = processId;
return Result.Success; return Result.Success;
@ -140,7 +140,7 @@ namespace Ryujinx.Horizon.Sm.Impl
int nameLength = 1; int nameLength = 1;
for (; nameLength < name.Length; nameLength++) for (; nameLength < ServiceName.Length; nameLength++)
{ {
if (name[nameLength] == 0) if (name[nameLength] == 0)
{ {
@ -148,7 +148,7 @@ namespace Ryujinx.Horizon.Sm.Impl
} }
} }
while (nameLength < name.Length) while (nameLength < ServiceName.Length)
{ {
if (name[nameLength++] != 0) if (name[nameLength++] != 0)
{ {

View file

@ -10,7 +10,7 @@ namespace Ryujinx.Horizon.Sm.Ipc
private readonly ServiceManager _serviceManager; private readonly ServiceManager _serviceManager;
private ulong _clientProcessId; private ulong _clientProcessId;
private bool _initialized; private bool _initialized;
public UserService(ServiceManager serviceManager) public UserService(ServiceManager serviceManager)
{ {
@ -21,7 +21,7 @@ namespace Ryujinx.Horizon.Sm.Ipc
public Result Initialize([ClientProcessId] ulong clientProcessId) public Result Initialize([ClientProcessId] ulong clientProcessId)
{ {
_clientProcessId = clientProcessId; _clientProcessId = clientProcessId;
_initialized = true; _initialized = true;
return Result.Success; return Result.Success;
} }

View file

@ -1,6 +1,4 @@
using Ryujinx.Horizon.Prepo; using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Prepo.Types;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm; using Ryujinx.Horizon.Sdk.Sm;
using Ryujinx.Horizon.Sm.Impl; using Ryujinx.Horizon.Sm.Impl;
using Ryujinx.Horizon.Sm.Types; using Ryujinx.Horizon.Sm.Types;
@ -9,8 +7,8 @@ namespace Ryujinx.Horizon.Sm
{ {
public class SmMain public class SmMain
{ {
private const int SmMaxSessionsCount = 64; private const int SmMaxSessionsCount = 64;
private const int SmmMaxSessionsCount = 1; private const int SmmMaxSessionsCount = 1;
private const int SmTotalMaxSessionsCount = SmMaxSessionsCount + SmmMaxSessionsCount; private const int SmTotalMaxSessionsCount = SmMaxSessionsCount + SmmMaxSessionsCount;
private const int MaxPortsCount = 2; private const int MaxPortsCount = 2;

View file

@ -6,6 +6,7 @@ namespace Ryujinx.Horizon.Sm
{ {
private const int ModuleId = 21; private const int ModuleId = 21;
#pragma warning disable IDE0055 // Disable formatting
public static Result OutOfProcess => new(ModuleId, 1); public static Result OutOfProcess => new(ModuleId, 1);
public static Result InvalidClient => new(ModuleId, 2); public static Result InvalidClient => new(ModuleId, 2);
public static Result OutOfSessions => new(ModuleId, 3); public static Result OutOfSessions => new(ModuleId, 3);
@ -15,5 +16,6 @@ namespace Ryujinx.Horizon.Sm
public static Result NotRegistered => new(ModuleId, 7); public static Result NotRegistered => new(ModuleId, 7);
public static Result NotAllowed => new(ModuleId, 8); public static Result NotAllowed => new(ModuleId, 8);
public static Result TooLargeAccessControl => new(ModuleId, 9); public static Result TooLargeAccessControl => new(ModuleId, 9);
#pragma warning restore IDE0055
} }
} }

View file

@ -21,9 +21,9 @@ namespace Ryujinx.Horizon.Sm
{ {
return (SmPortIndex)portIndex switch return (SmPortIndex)portIndex switch
{ {
SmPortIndex.User => AcceptImpl(server, new UserService(_serviceManager)), SmPortIndex.User => AcceptImpl(server, new UserService(_serviceManager)),
SmPortIndex.Manager => AcceptImpl(server, new ManagerService()), SmPortIndex.Manager => AcceptImpl(server, new ManagerService()),
_ => throw new ArgumentOutOfRangeException(nameof(portIndex)), _ => throw new ArgumentOutOfRangeException(nameof(portIndex)),
}; };
} }
} }

View file

@ -3,6 +3,6 @@
enum SmPortIndex enum SmPortIndex
{ {
User, User,
Manager Manager,
} }
} }