diff options
Diffstat (limited to 'Ryujinx.Horizon/Sdk/Sf')
38 files changed, 375 insertions, 357 deletions
diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainInHeader.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainInHeader.cs index 88211501..beaff613 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainInHeader.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainInHeader.cs @@ -3,10 +3,10 @@ struct CmifDomainInHeader { public CmifDomainRequestType Type; - public byte ObjectsCount; - public ushort DataSize; - public int ObjectId; - public uint Padding; - public uint Token; + public byte ObjectsCount; + public ushort DataSize; + public int ObjectId; + public uint Padding; + public uint Token; } } diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainRequestType.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainRequestType.cs index b913db94..1a02e082 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainRequestType.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifDomainRequestType.cs @@ -2,8 +2,8 @@ { enum CmifDomainRequestType : byte { - Invalid = 0, + Invalid = 0, SendMessage = 1, - Close = 2 + Close = 2 } } diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifMessage.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifMessage.cs index 781452e3..0d23d33b 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifMessage.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifMessage.cs @@ -8,7 +8,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif { static class CmifMessage { - public const uint CmifInHeaderMagic = 0x49434653; // SFCI + public const uint CmifInHeaderMagic = 0x49434653; // SFCI public const uint CmifOutHeaderMagic = 0x4f434653; // SFCO public static CmifRequest CreateRequest(Span<byte> output, CmifRequestFormat format) @@ -21,27 +21,31 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif } totalSize += Unsafe.SizeOf<CmifInHeader>() + format.DataSize; - totalSize = (totalSize + 1) & ~1; + totalSize = (totalSize + 1) & ~1; + int outPointerSizeTableOffset = totalSize; - int outPointerSizeTableSize = format.OutAutoBuffersCount + format.OutPointersCount; + int outPointerSizeTableSize = format.OutAutoBuffersCount + format.OutPointersCount; + totalSize += sizeof(ushort) * outPointerSizeTableSize; - int rawDataSizeInWords = (totalSize + sizeof(uint) - 1) / sizeof(uint); - CmifRequest request = new CmifRequest(); + int rawDataSizeInWords = (totalSize + sizeof(uint) - 1) / sizeof(uint); - request.Hipc = HipcMessage.WriteMessage(output, new HipcMetadata() + CmifRequest request = new() { - Type = format.Context != 0 ? (int)CommandType.RequestWithContext : (int)CommandType.Request, - SendStaticsCount = format.InAutoBuffersCount + format.InPointersCount, - SendBuffersCount = format.InAutoBuffersCount + format.InBuffersCount, - ReceiveBuffersCount = format.OutAutoBuffersCount + format.OutBuffersCount, - ExchangeBuffersCount = format.InOutBuffersCount, - DataWordsCount = rawDataSizeInWords, - ReceiveStaticsCount = outPointerSizeTableSize + format.OutFixedPointersCount, - SendPid = format.SendPid, - CopyHandlesCount = format.HandlesCount, - MoveHandlesCount = 0 - }); + Hipc = HipcMessage.WriteMessage(output, new HipcMetadata() + { + Type = format.Context != 0 ? (int)CommandType.RequestWithContext : (int)CommandType.Request, + SendStaticsCount = format.InAutoBuffersCount + format.InPointersCount, + SendBuffersCount = format.InAutoBuffersCount + format.InBuffersCount, + ReceiveBuffersCount = format.OutAutoBuffersCount + format.OutBuffersCount, + ExchangeBuffersCount = format.InOutBuffersCount, + DataWordsCount = rawDataSizeInWords, + ReceiveStaticsCount = outPointerSizeTableSize + format.OutFixedPointersCount, + SendPid = format.SendPid, + CopyHandlesCount = format.HandlesCount, + MoveHandlesCount = 0 + }) + }; Span<uint> data = request.Hipc.DataWords; @@ -53,35 +57,36 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif domainHeader = new CmifDomainInHeader() { - Type = CmifDomainRequestType.SendMessage, + Type = CmifDomainRequestType.SendMessage, ObjectsCount = (byte)format.ObjectsCount, - DataSize = (ushort)payloadSize, - ObjectId = format.ObjectId, - Padding = 0, - Token = format.Context + DataSize = (ushort)payloadSize, + ObjectId = format.ObjectId, + Padding = 0, + Token = format.Context }; - data = data.Slice(Unsafe.SizeOf<CmifDomainInHeader>() / sizeof(uint)); + data = data[(Unsafe.SizeOf<CmifDomainInHeader>() / sizeof(uint))..]; - request.Objects = data.Slice((payloadSize + sizeof(uint) - 1) / sizeof(uint)); + request.Objects = data[((payloadSize + sizeof(uint) - 1) / sizeof(uint))..]; } ref CmifInHeader header = ref MemoryMarshal.Cast<uint, CmifInHeader>(data)[0]; header = new CmifInHeader() { - Magic = CmifInHeaderMagic, - Version = format.Context != 0 ? 1u : 0u, + Magic = CmifInHeaderMagic, + Version = format.Context != 0 ? 1u : 0u, CommandId = format.RequestId, - Token = format.ObjectId != 0 ? 0u : format.Context + Token = format.ObjectId != 0 ? 0u : format.Context }; - request.Data = MemoryMarshal.Cast<uint, byte>(data).Slice(Unsafe.SizeOf<CmifInHeader>()); + request.Data = MemoryMarshal.Cast<uint, byte>(data)[Unsafe.SizeOf<CmifInHeader>()..]; int paddingSizeBefore = (rawDataSizeInWords - request.Hipc.DataWords.Length) * sizeof(uint); - Span<byte> outPointerTable = MemoryMarshal.Cast<uint, byte>(request.Hipc.DataWords).Slice(outPointerSizeTableOffset - paddingSizeBefore); - request.OutPointerSizes = MemoryMarshal.Cast<byte, ushort>(outPointerTable); + Span<byte> outPointerTable = MemoryMarshal.Cast<uint, byte>(request.Hipc.DataWords)[(outPointerSizeTableOffset - paddingSizeBefore)..]; + + request.OutPointerSizes = MemoryMarshal.Cast<byte, ushort>(outPointerTable); request.ServerPointerSize = format.ServerPointerSize; return request; @@ -89,15 +94,15 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif public static Result ParseResponse(out CmifResponse response, Span<byte> input, bool isDomain, int size) { - HipcMessage responseMessage = new HipcMessage(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; if (isDomain) { - data = data.Slice(Unsafe.SizeOf<CmifDomainOutHeader>()); - objects = MemoryMarshal.Cast<byte, uint>(data.Slice(Unsafe.SizeOf<CmifOutHeader>() + size)); + data = data[Unsafe.SizeOf<CmifDomainOutHeader>()..]; + objects = MemoryMarshal.Cast<byte, uint>(data[(Unsafe.SizeOf<CmifOutHeader>() + size)..]); } CmifOutHeader header = MemoryMarshal.Cast<byte, CmifOutHeader>(data)[0]; @@ -105,19 +110,21 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif if (header.Magic != CmifOutHeaderMagic) { response = default; + return SfResult.InvalidOutHeader; } if (header.Result.IsFailure) { response = default; + return header.Result; } response = new CmifResponse() { - Data = data.Slice(Unsafe.SizeOf<CmifOutHeader>()), - Objects = objects, + Data = data[Unsafe.SizeOf<CmifOutHeader>()..], + Objects = objects, CopyHandles = responseMessage.Data.CopyHandles, MoveHandles = responseMessage.Data.MoveHandles }; @@ -125,4 +132,4 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif return Result.Success; } } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifOutHeader.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifOutHeader.cs index 2828cde5..00b9d2bd 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifOutHeader.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifOutHeader.cs @@ -5,10 +5,10 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif struct CmifOutHeader { #pragma warning disable CS0649 - public uint Magic; - public uint Version; + public uint Magic; + public uint Version; public Result Result; - public uint Token; + public uint Token; #pragma warning restore CS0649 } } diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequest.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequest.cs index 80772ad3..e44a84ec 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequest.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequest.cs @@ -6,9 +6,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif ref struct CmifRequest { public HipcMessageData Hipc; - public Span<byte> Data; - public Span<ushort> OutPointerSizes; - public Span<uint> Objects; - public int ServerPointerSize; + public Span<byte> Data; + public Span<ushort> OutPointerSizes; + public Span<uint> Objects; + public int ServerPointerSize; } } diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequestFormat.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequestFormat.cs index d1154578..592f11f4 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequestFormat.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifRequestFormat.cs @@ -3,21 +3,21 @@ struct CmifRequestFormat { #pragma warning disable CS0649 - public int ObjectId; + public int ObjectId; public uint RequestId; public uint Context; - public int DataSize; - public int ServerPointerSize; - public int InAutoBuffersCount; - public int OutAutoBuffersCount; - public int InBuffersCount; - public int OutBuffersCount; - public int InOutBuffersCount; - public int InPointersCount; - public int OutPointersCount; - public int OutFixedPointersCount; - public int ObjectsCount; - public int HandlesCount; + public int DataSize; + public int ServerPointerSize; + public int InAutoBuffersCount; + public int OutAutoBuffersCount; + public int InBuffersCount; + public int OutBuffersCount; + public int InOutBuffersCount; + public int InPointersCount; + public int OutPointersCount; + public int OutFixedPointersCount; + public int ObjectsCount; + public int HandlesCount; public bool SendPid; #pragma warning restore CS0649 } diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifResponse.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifResponse.cs index d1d8dc9c..2ff31eb6 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifResponse.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/CmifResponse.cs @@ -6,7 +6,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif { public ReadOnlySpan<byte> Data; public ReadOnlySpan<uint> Objects; - public ReadOnlySpan<int> CopyHandles; - public ReadOnlySpan<int> MoveHandles; + public ReadOnlySpan<int> CopyHandles; + public ReadOnlySpan<int> MoveHandles; } } diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/CommandType.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/CommandType.cs index b3b05864..82c0648b 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/CommandType.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/CommandType.cs @@ -2,12 +2,12 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif { enum CommandType { - Invalid = 0, - LegacyRequest = 1, - Close = 2, - LegacyControl = 3, - Request = 4, - Control = 5, + Invalid = 0, + LegacyRequest = 1, + Close = 2, + LegacyControl = 3, + Request = 4, + Control = 5, RequestWithContext = 6, ControlWithContext = 7 } diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectDispatchTable.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectDispatchTable.cs index bcf311b2..b0b4498d 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectDispatchTable.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectDispatchTable.cs @@ -21,7 +21,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif var inHeader = MemoryMarshal.Cast<byte, CmifDomainInHeader>(inRawData)[0]; - ReadOnlySpan<byte> inDomainRawData = inRawData.Slice(Unsafe.SizeOf<CmifDomainInHeader>()); + ReadOnlySpan<byte> inDomainRawData = inRawData[Unsafe.SizeOf<CmifDomainInHeader>()..]; int targetObjectId = inHeader.ObjectId; @@ -39,7 +39,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif return SfResult.InvalidHeaderSize; } - ReadOnlySpan<byte> inMessageRawData = inDomainRawData.Slice(0, inHeader.DataSize); + ReadOnlySpan<byte> inMessageRawData = inDomainRawData[..inHeader.DataSize]; if (inHeader.ObjectsCount > DomainServiceObjectProcessor.MaximumObjects) { diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectProcessor.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectProcessor.cs index 92d86196..796b8a78 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectProcessor.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/DomainServiceObjectProcessor.cs @@ -63,7 +63,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif return SfResult.InvalidInObjectsCount; } - Result result = _domain.ReserveIds(new Span<int>(_reservedObjectIds).Slice(0, OutObjectsCount)); + Result result = _domain.ReserveIds(new Span<int>(_reservedObjectIds)[..OutObjectsCount]); if (result.IsFailure) { @@ -92,7 +92,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif DebugUtil.Assert(outHeaderSize + implOutDataTotalSize + OutObjectsCount * sizeof(int) <= outRawData.Length); - outRawData = outRawData.Slice(outHeaderSize); + outRawData = outRawData[outHeaderSize..]; _outObjectIdsOffset = (response.DataWords.Length * sizeof(uint) - outRawData.Length) + implOutDataTotalSize; return response; @@ -107,9 +107,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif DebugUtil.Assert(outHeaderSize + implOutDataTotalSize <= outRawData.Length); - outRawData = outRawData.Slice(outHeaderSize); + outRawData = outRawData[outHeaderSize..]; - _domain.UnreserveIds(new Span<int>(_reservedObjectIds).Slice(0, OutObjectsCount)); + _domain.UnreserveIds(new Span<int>(_reservedObjectIds)[..OutObjectsCount]); } public override void SetOutObjects(scoped ref ServiceDispatchContext context, HipcMessageData response, Span<ServiceObjectHolder> outObjects) @@ -129,7 +129,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif _domain.RegisterObject(objectIds[i], outObjects[i]); } - Span<int> outObjectIds = MemoryMarshal.Cast<byte, int>(MemoryMarshal.Cast<uint, byte>(response.DataWords).Slice(_outObjectIdsOffset)); + Span<int> outObjectIds = MemoryMarshal.Cast<byte, int>(MemoryMarshal.Cast<uint, byte>(response.DataWords)[_outObjectIdsOffset..]); for (int i = 0; i < outObjectsCount; i++) { diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/PointerAndSize.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/PointerAndSize.cs index 5af00077..ad0e1824 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/PointerAndSize.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/PointerAndSize.cs @@ -2,7 +2,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif { struct PointerAndSize { - public static PointerAndSize Empty => new PointerAndSize(0UL, 0UL); + public static PointerAndSize Empty => new(0UL, 0UL); public ulong Address { get; } public ulong Size { get; } @@ -11,7 +11,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif public PointerAndSize(ulong address, ulong size) { Address = address; - Size = size; + Size = size; } } } diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerMessageRuntimeMetadata.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerMessageRuntimeMetadata.cs index 18a40430..6a92e8d5 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerMessageRuntimeMetadata.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/ServerMessageRuntimeMetadata.cs @@ -2,28 +2,29 @@ { struct ServerMessageRuntimeMetadata { - public ushort InDataSize { get; } - public ushort OutDataSize { get; } - public byte InHeadersSize { get; } - public byte OutHeadersSize { get; } - public byte InObjectsCount { get; } - public byte OutObjectsCount { get; } + public ushort InDataSize { get; } + public ushort OutDataSize { get; } + public byte InHeadersSize { get; } + public byte OutHeadersSize { get; } + public byte InObjectsCount { get; } + public byte OutObjectsCount { get; } + public int UnfixedOutPointerSizeOffset => InDataSize + InHeadersSize + 0x10; public ServerMessageRuntimeMetadata( ushort inDataSize, ushort outDataSize, - byte inHeadersSize, - byte outHeadersSize, - byte inObjectsCount, - byte outObjectsCount) + byte inHeadersSize, + byte outHeadersSize, + byte inObjectsCount, + byte outObjectsCount) { - InDataSize = inDataSize; - OutDataSize = outDataSize; - InHeadersSize = inHeadersSize; - OutHeadersSize = outHeadersSize; - InObjectsCount = inObjectsCount; + InDataSize = inDataSize; + OutDataSize = outDataSize; + InHeadersSize = inHeadersSize; + OutHeadersSize = outHeadersSize; + InObjectsCount = inObjectsCount; OutObjectsCount = outObjectsCount; } } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchContext.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchContext.cs index 3339a1a6..31be810d 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchContext.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchContext.cs @@ -5,14 +5,14 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif { ref struct ServiceDispatchContext { - public IServiceObject ServiceObject; - public ServerSessionManager Manager; - public ServerSession Session; + public IServiceObject ServiceObject; + public ServerSessionManager Manager; + public ServerSession Session; public ServerMessageProcessor Processor; - public HandlesToClose HandlesToClose; - public PointerAndSize PointerBuffer; - public ReadOnlySpan<byte> InMessageBuffer; - public Span<byte> OutMessageBuffer; - public HipcMessage Request; + public HandlesToClose HandlesToClose; + public PointerAndSize PointerBuffer; + public ReadOnlySpan<byte> InMessageBuffer; + public Span<byte> OutMessageBuffer; + public HipcMessage Request; } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTable.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTable.cs index 145c1783..21b342df 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTable.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTable.cs @@ -12,7 +12,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif public ServiceDispatchTable(string objectName, IReadOnlyDictionary<int, CommandHandler> entries) { _objectName = objectName; - _entries = entries; + _entries = entries; } public override Result ProcessMessage(ref ServiceDispatchContext context, ReadOnlySpan<byte> inRawData) @@ -30,4 +30,4 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif return new ServiceDispatchTable(instance.GetType().Name, instance.GetCommandHandlers()); } } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTableBase.cs b/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTableBase.cs index a0e28ca8..81600067 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTableBase.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Cmif/ServiceDispatchTableBase.cs @@ -39,17 +39,21 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif if (!entries.TryGetValue((int)commandId, out var commandHandler)) { - Logger.Warning?.Print(LogClass.KernelIpc, $"{objectName} command ID 0x{commandId:X} is not implemented"); - if (HorizonStatic.Options.IgnoreMissingServices) { // If ignore missing services is enabled, just pretend that everything is fine. - var response = PrepareForStubReply(ref context, out Span<byte> outRawData); + PrepareForStubReply(ref context, out Span<byte> outRawData); CommandHandler.GetCmifOutHeaderPointer(ref outHeader, ref outRawData); outHeader[0] = new CmifOutHeader() { Magic = CmifMessage.CmifOutHeaderMagic, Result = Result.Success }; + Logger.Warning?.Print(LogClass.Service, $"Missing service {objectName} (command ID: {commandId}) ignored"); + return Result.Success; } + else if (HorizonStatic.Options.ThrowOnInvalidCommandIds) + { + throw new NotImplementedException($"{objectName} command ID: {commandId} is not implemented"); + } return SfResult.UnknownCommandId; } @@ -72,6 +76,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif if (outHeader.IsEmpty) { commandResult.AbortOnSuccess(); + return commandResult; } @@ -80,11 +85,10 @@ namespace Ryujinx.Horizon.Sdk.Sf.Cmif return Result.Success; } - private static HipcMessageData PrepareForStubReply(scoped ref ServiceDispatchContext context, out Span<byte> outRawData) + private static void PrepareForStubReply(scoped ref ServiceDispatchContext context, out Span<byte> outRawData) { var response = HipcMessage.WriteResponse(context.OutMessageBuffer, 0, 0x20 / sizeof(uint), 0, 0); outRawData = MemoryMarshal.Cast<uint, byte>(response.DataWords); - return response; } } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/CommandArg.cs b/Ryujinx.Horizon/Sdk/Sf/CommandArg.cs index 8f367b4e..47aedde9 100644 --- a/Ryujinx.Horizon/Sdk/Sf/CommandArg.cs +++ b/Ryujinx.Horizon/Sdk/Sf/CommandArg.cs @@ -20,37 +20,37 @@ namespace Ryujinx.Horizon.Sdk.Sf struct CommandArg { - public CommandArgType Type { get; } - public HipcBufferFlags BufferFlags { get; } - public ushort BufferFixedSize { get; } - public int ArgSize { get; } - public int ArgAlignment { get; } + public CommandArgType Type { get; } + public HipcBufferFlags BufferFlags { get; } + public ushort BufferFixedSize { get; } + public int ArgSize { get; } + public int ArgAlignment { get; } public CommandArg(CommandArgType type) { - Type = type; - BufferFlags = default; + Type = type; + BufferFlags = default; BufferFixedSize = 0; - ArgSize = 0; - ArgAlignment = 0; + ArgSize = 0; + ArgAlignment = 0; } public CommandArg(CommandArgType type, int argSize, int argAlignment) { - Type = type; - BufferFlags = default; + Type = type; + BufferFlags = default; BufferFixedSize = 0; - ArgSize = argSize; - ArgAlignment = argAlignment; + ArgSize = argSize; + ArgAlignment = argAlignment; } public CommandArg(HipcBufferFlags flags, ushort fixedSize = 0) { - Type = CommandArgType.Buffer; - BufferFlags = flags; + Type = CommandArgType.Buffer; + BufferFlags = flags; BufferFixedSize = fixedSize; - ArgSize = 0; - ArgAlignment = 0; + ArgSize = 0; + ArgAlignment = 0; } } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/CommandArgAttributes.cs b/Ryujinx.Horizon/Sdk/Sf/CommandArgAttributes.cs index 5b7c302f..294c7d58 100644 --- a/Ryujinx.Horizon/Sdk/Sf/CommandArgAttributes.cs +++ b/Ryujinx.Horizon/Sdk/Sf/CommandArgAttributes.cs @@ -6,8 +6,8 @@ namespace Ryujinx.Horizon.Sdk.Sf [AttributeUsage(AttributeTargets.Parameter)] class BufferAttribute : Attribute { - public HipcBufferFlags Flags { get; } - public ushort FixedSize { get; } + public HipcBufferFlags Flags { get; } + public ushort FixedSize { get; } public BufferAttribute(HipcBufferFlags flags) { @@ -16,7 +16,7 @@ namespace Ryujinx.Horizon.Sdk.Sf public BufferAttribute(HipcBufferFlags flags, ushort fixedSize) { - Flags = flags | HipcBufferFlags.FixedSize; + Flags = flags | HipcBufferFlags.FixedSize; FixedSize = fixedSize; } } @@ -35,4 +35,4 @@ namespace Ryujinx.Horizon.Sdk.Sf class MoveHandleAttribute : Attribute { } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/CommandHandler.cs b/Ryujinx.Horizon/Sdk/Sf/CommandHandler.cs index ae42a8ef..fe079d47 100644 --- a/Ryujinx.Horizon/Sdk/Sf/CommandHandler.cs +++ b/Ryujinx.Horizon/Sdk/Sf/CommandHandler.cs @@ -9,20 +9,20 @@ namespace Ryujinx.Horizon.Sdk.Sf class CommandHandler { public delegate Result MethodInvoke( - ref ServiceDispatchContext context, - HipcCommandProcessor processor, + ref ServiceDispatchContext context, + HipcCommandProcessor processor, ServerMessageRuntimeMetadata runtimeMetadata, - ReadOnlySpan<byte> inRawData, - ref Span<CmifOutHeader> outHeader); + ReadOnlySpan<byte> inRawData, + ref Span<CmifOutHeader> outHeader); - private readonly MethodInvoke _invoke; + private readonly MethodInvoke _invoke; private readonly HipcCommandProcessor _processor; public string MethodName => _invoke.Method.Name; public CommandHandler(MethodInvoke invoke, params CommandArg[] args) { - _invoke = invoke; + _invoke = invoke; _processor = new HipcCommandProcessor(args); } @@ -37,8 +37,8 @@ namespace Ryujinx.Horizon.Sdk.Sf context.Processor.SetImplementationProcessor(_processor); } - var runtimeMetadata = context.Processor.GetRuntimeMetadata(); - Result result = context.Processor.PrepareForProcess(ref context, runtimeMetadata); + var runtimeMetadata = context.Processor.GetRuntimeMetadata(); + Result result = context.Processor.PrepareForProcess(ref context, runtimeMetadata); if (result.IsFailure) { @@ -50,8 +50,8 @@ namespace Ryujinx.Horizon.Sdk.Sf public static void GetCmifOutHeaderPointer(ref Span<CmifOutHeader> outHeader, ref Span<byte> outRawData) { - outHeader = MemoryMarshal.Cast<byte, CmifOutHeader>(outRawData).Slice(0, 1); - outRawData = outRawData.Slice(Unsafe.SizeOf<CmifOutHeader>()); + outHeader = MemoryMarshal.Cast<byte, CmifOutHeader>(outRawData)[..1]; + outRawData = outRawData[Unsafe.SizeOf<CmifOutHeader>()..]; } } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/CommandSerialization.cs b/Ryujinx.Horizon/Sdk/Sf/CommandSerialization.cs index 9a3a511a..feb2d666 100644 --- a/Ryujinx.Horizon/Sdk/Sf/CommandSerialization.cs +++ b/Ryujinx.Horizon/Sdk/Sf/CommandSerialization.cs @@ -22,6 +22,7 @@ namespace Ryujinx.Horizon.Sdk.Sf public static ref T GetRef<T>(PointerAndSize bufferRange) where T : unmanaged { var writableRegion = GetWritableRegion(bufferRange); + return ref MemoryMarshal.Cast<byte, T>(writableRegion.Memory.Span)[0]; } @@ -65,4 +66,4 @@ namespace Ryujinx.Horizon.Sdk.Sf response.MoveHandles[index] = value; } } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferFlags.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferFlags.cs index 594af2c8..269ab4fe 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferFlags.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferFlags.cs @@ -5,12 +5,12 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc [Flags] enum HipcBufferFlags : byte { - In = 1 << 0, - Out = 1 << 1, - MapAlias = 1 << 2, - Pointer = 1 << 3, - FixedSize = 1 << 4, - AutoSelect = 1 << 5, + In = 1 << 0, + Out = 1 << 1, + MapAlias = 1 << 2, + Pointer = 1 << 3, + FixedSize = 1 << 4, + AutoSelect = 1 << 5, MapTransferAllowsNonSecure = 1 << 6, MapTransferAllowsNonDevice = 1 << 7 } diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferMode.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferMode.cs index 4ef6374b..b1e67253 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferMode.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcBufferMode.cs @@ -2,9 +2,9 @@ { enum HipcBufferMode { - Normal = 0, + Normal = 0, NonSecure = 1, - Invalid = 2, + Invalid = 2, NonDevice = 3 } } diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs index ea2ec650..7541e294 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcManager.cs @@ -61,7 +61,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc { clientHandle = 0; - if (!(_session.ServiceObjectHolder.ServiceObject is DomainServiceObject domain)) + if (_session.ServiceObjectHolder.ServiceObject is not DomainServiceObject domain) { return HipcResult.TargetNotDomain; } @@ -112,4 +112,4 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc return Result.Success; } } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessage.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessage.cs index 3017f404..6500d6cf 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessage.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessage.cs @@ -10,9 +10,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc { public const int AutoReceiveStatic = byte.MaxValue; - public HipcMetadata Meta; + public HipcMetadata Meta; public HipcMessageData Data; - public ulong Pid; + public ulong Pid; public HipcMessage(Span<byte> data) { @@ -20,10 +20,10 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc Header header = MemoryMarshal.Cast<byte, Header>(data)[0]; - data = data.Slice(Unsafe.SizeOf<Header>()); + data = data[Unsafe.SizeOf<Header>()..]; - int receiveStaticsCount = 0; - ulong pid = 0; + int receiveStaticsCount = 0; + ulong pid = 0; if (header.ReceiveStaticMode != 0) { @@ -42,46 +42,44 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc if (header.HasSpecialHeader) { specialHeader = MemoryMarshal.Cast<byte, SpecialHeader>(data)[0]; - - data = data.Slice(Unsafe.SizeOf<SpecialHeader>()); + data = data[Unsafe.SizeOf<SpecialHeader>()..]; if (specialHeader.SendPid) { - pid = MemoryMarshal.Cast<byte, ulong>(data)[0]; - - data = data.Slice(sizeof(ulong)); + pid = MemoryMarshal.Cast<byte, ulong>(data)[0]; + data = data[sizeof(ulong)..]; } } Meta = new HipcMetadata() { - Type = (int)header.Type, - SendStaticsCount = header.SendStaticsCount, - SendBuffersCount = header.SendBuffersCount, - ReceiveBuffersCount = header.ReceiveBuffersCount, + Type = (int)header.Type, + SendStaticsCount = header.SendStaticsCount, + SendBuffersCount = header.SendBuffersCount, + ReceiveBuffersCount = header.ReceiveBuffersCount, ExchangeBuffersCount = header.ExchangeBuffersCount, - DataWordsCount = header.DataWordsCount, - ReceiveStaticsCount = receiveStaticsCount, - SendPid = specialHeader.SendPid, - CopyHandlesCount = specialHeader.CopyHandlesCount, - MoveHandlesCount = specialHeader.MoveHandlesCount + DataWordsCount = header.DataWordsCount, + ReceiveStaticsCount = receiveStaticsCount, + SendPid = specialHeader.SendPid, + CopyHandlesCount = specialHeader.CopyHandlesCount, + MoveHandlesCount = specialHeader.MoveHandlesCount }; Data = CreateMessageData(Meta, data, initialLength); - Pid = pid; + Pid = pid; } public static HipcMessageData WriteResponse( Span<byte> destination, - int sendStaticCount, - int dataWordsCount, - int copyHandlesCount, - int moveHandlesCount) + int sendStaticCount, + int dataWordsCount, + int copyHandlesCount, + int moveHandlesCount) { return WriteMessage(destination, new HipcMetadata() { SendStaticsCount = sendStaticCount, - DataWordsCount = dataWordsCount, + DataWordsCount = dataWordsCount, CopyHandlesCount = copyHandlesCount, MoveHandlesCount = moveHandlesCount }); @@ -89,38 +87,37 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc 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; MemoryMarshal.Cast<byte, Header>(destination)[0] = new Header() { - Type = (CommandType)meta.Type, - SendStaticsCount = meta.SendStaticsCount, - SendBuffersCount = meta.SendBuffersCount, - ReceiveBuffersCount = meta.ReceiveBuffersCount, + Type = (CommandType)meta.Type, + SendStaticsCount = meta.SendStaticsCount, + SendBuffersCount = meta.SendBuffersCount, + ReceiveBuffersCount = meta.ReceiveBuffersCount, ExchangeBuffersCount = meta.ExchangeBuffersCount, - DataWordsCount = meta.DataWordsCount, - ReceiveStaticMode = meta.ReceiveStaticsCount != 0 ? (meta.ReceiveStaticsCount != AutoReceiveStatic ? meta.ReceiveStaticsCount + 2 : 2) : 0, - HasSpecialHeader = hasSpecialHeader + DataWordsCount = meta.DataWordsCount, + ReceiveStaticMode = meta.ReceiveStaticsCount != 0 ? (meta.ReceiveStaticsCount != AutoReceiveStatic ? meta.ReceiveStaticsCount + 2 : 2) : 0, + HasSpecialHeader = hasSpecialHeader }; - destination = destination.Slice(Unsafe.SizeOf<Header>()); + destination = destination[Unsafe.SizeOf<Header>()..]; if (hasSpecialHeader) { MemoryMarshal.Cast<byte, SpecialHeader>(destination)[0] = new SpecialHeader() { - SendPid = meta.SendPid, + SendPid = meta.SendPid, CopyHandlesCount = meta.CopyHandlesCount, MoveHandlesCount = meta.MoveHandlesCount }; - destination = destination.Slice(Unsafe.SizeOf<SpecialHeader>()); + destination = destination[Unsafe.SizeOf<SpecialHeader>()..]; if (meta.SendPid) { - destination = destination.Slice(sizeof(ulong)); + destination = destination[sizeof(ulong)..]; } } @@ -133,68 +130,67 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc if (meta.CopyHandlesCount != 0) { - copyHandles = MemoryMarshal.Cast<byte, int>(data).Slice(0, meta.CopyHandlesCount); + copyHandles = MemoryMarshal.Cast<byte, int>(data)[..meta.CopyHandlesCount]; - data = data.Slice(meta.CopyHandlesCount * sizeof(int)); + data = data[(meta.CopyHandlesCount * sizeof(int))..]; } Span<int> moveHandles = Span<int>.Empty; if (meta.MoveHandlesCount != 0) { - moveHandles = MemoryMarshal.Cast<byte, int>(data).Slice(0, meta.MoveHandlesCount); + moveHandles = MemoryMarshal.Cast<byte, int>(data)[..meta.MoveHandlesCount]; - data = data.Slice(meta.MoveHandlesCount * sizeof(int)); + data = data[(meta.MoveHandlesCount * sizeof(int))..]; } Span<HipcStaticDescriptor> sendStatics = Span<HipcStaticDescriptor>.Empty; if (meta.SendStaticsCount != 0) { - sendStatics = MemoryMarshal.Cast<byte, HipcStaticDescriptor>(data).Slice(0, meta.SendStaticsCount); + sendStatics = MemoryMarshal.Cast<byte, HipcStaticDescriptor>(data)[..meta.SendStaticsCount]; - data = data.Slice(meta.SendStaticsCount * Unsafe.SizeOf<HipcStaticDescriptor>()); + data = data[(meta.SendStaticsCount * Unsafe.SizeOf<HipcStaticDescriptor>())..]; } Span<HipcBufferDescriptor> sendBuffers = Span<HipcBufferDescriptor>.Empty; if (meta.SendBuffersCount != 0) { - sendBuffers = MemoryMarshal.Cast<byte, HipcBufferDescriptor>(data).Slice(0, meta.SendBuffersCount); + sendBuffers = MemoryMarshal.Cast<byte, HipcBufferDescriptor>(data)[..meta.SendBuffersCount]; - data = data.Slice(meta.SendBuffersCount * Unsafe.SizeOf<HipcBufferDescriptor>()); + data = data[(meta.SendBuffersCount * Unsafe.SizeOf<HipcBufferDescriptor>())..]; } Span<HipcBufferDescriptor> receiveBuffers = Span<HipcBufferDescriptor>.Empty; if (meta.ReceiveBuffersCount != 0) { - receiveBuffers = MemoryMarshal.Cast<byte, HipcBufferDescriptor>(data).Slice(0, meta.ReceiveBuffersCount); + receiveBuffers = MemoryMarshal.Cast<byte, HipcBufferDescriptor>(data)[..meta.ReceiveBuffersCount]; - data = data.Slice(meta.ReceiveBuffersCount * Unsafe.SizeOf<HipcBufferDescriptor>()); + data = data[(meta.ReceiveBuffersCount * Unsafe.SizeOf<HipcBufferDescriptor>())..]; } Span<HipcBufferDescriptor> exchangeBuffers = Span<HipcBufferDescriptor>.Empty; if (meta.ExchangeBuffersCount != 0) { - exchangeBuffers = MemoryMarshal.Cast<byte, HipcBufferDescriptor>(data).Slice(0, meta.ExchangeBuffersCount); + exchangeBuffers = MemoryMarshal.Cast<byte, HipcBufferDescriptor>(data)[..meta.ExchangeBuffersCount]; - data = data.Slice(meta.ExchangeBuffersCount * Unsafe.SizeOf<HipcBufferDescriptor>()); + data = data[(meta.ExchangeBuffersCount * Unsafe.SizeOf<HipcBufferDescriptor>())..]; } Span<uint> dataWords = Span<uint>.Empty; if (meta.DataWordsCount != 0) { - int dataOffset = initialLength - data.Length; + int dataOffset = initialLength - data.Length; int dataOffsetAligned = BitUtils.AlignUp(dataOffset, 0x10); + int padding = (dataOffsetAligned - dataOffset) / sizeof(uint); - int padding = (dataOffsetAligned - dataOffset) / sizeof(uint); - - dataWords = MemoryMarshal.Cast<byte, uint>(data).Slice(padding, meta.DataWordsCount - padding); + dataWords = MemoryMarshal.Cast<byte, uint>(data)[padding..meta.DataWordsCount]; - data = data.Slice(meta.DataWordsCount * sizeof(uint)); + data = data[(meta.DataWordsCount * sizeof(uint))..]; } Span<HipcReceiveListEntry> receiveList = Span<HipcReceiveListEntry>.Empty; @@ -203,19 +199,19 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc { int receiveListSize = meta.ReceiveStaticsCount == AutoReceiveStatic ? 1 : meta.ReceiveStaticsCount; - receiveList = MemoryMarshal.Cast<byte, HipcReceiveListEntry>(data).Slice(0, receiveListSize); + receiveList = MemoryMarshal.Cast<byte, HipcReceiveListEntry>(data)[..receiveListSize]; } return new HipcMessageData() { - SendStatics = sendStatics, - SendBuffers = sendBuffers, - ReceiveBuffers = receiveBuffers, + SendStatics = sendStatics, + SendBuffers = sendBuffers, + ReceiveBuffers = receiveBuffers, ExchangeBuffers = exchangeBuffers, - DataWords = dataWords, - ReceiveList = receiveList, - CopyHandles = copyHandles, - MoveHandles = moveHandles + DataWords = dataWords, + ReceiveList = receiveList, + CopyHandles = copyHandles, + MoveHandles = moveHandles }; } } diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessageData.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessageData.cs index c83c422c..154b8f07 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessageData.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMessageData.cs @@ -8,9 +8,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc public Span<HipcBufferDescriptor> SendBuffers; public Span<HipcBufferDescriptor> ReceiveBuffers; public Span<HipcBufferDescriptor> ExchangeBuffers; - public Span<uint> DataWords; + public Span<uint> DataWords; public Span<HipcReceiveListEntry> ReceiveList; - public Span<int> CopyHandles; - public Span<int> MoveHandles; + public Span<int> CopyHandles; + public Span<int> MoveHandles; } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMetadata.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMetadata.cs index fe13137a..10abc400 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMetadata.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcMetadata.cs @@ -2,15 +2,15 @@ { struct HipcMetadata { - public int Type; - public int SendStaticsCount; - public int SendBuffersCount; - public int ReceiveBuffersCount; - public int ExchangeBuffersCount; - public int DataWordsCount; - public int ReceiveStaticsCount; + public int Type; + public int SendStaticsCount; + public int SendBuffersCount; + public int ReceiveBuffersCount; + public int ExchangeBuffersCount; + public int DataWordsCount; + public int ReceiveStaticsCount; public bool SendPid; - public int CopyHandlesCount; - public int MoveHandlesCount; + public int CopyHandlesCount; + public int MoveHandlesCount; } } diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcReceiveListEntry.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcReceiveListEntry.cs index 94bf0968..56cf16fb 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcReceiveListEntry.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcReceiveListEntry.cs @@ -8,7 +8,7 @@ public HipcReceiveListEntry(ulong address, ulong size) { _addressLow = (uint)address; - _word1 = (ushort)(address >> 32) | (uint)(size << 16); + _word1 = (ushort)(address >> 32) | (uint)(size << 16); } } } diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcResult.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcResult.cs index ef989a98..3b483be8 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcResult.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcResult.cs @@ -6,17 +6,14 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc { public const int ModuleId = 11; - public static Result OutOfSessionMemory => new Result(ModuleId, 102); - public static Result OutOfSessions => new Result(ModuleId, 131); - public static Result PointerBufferTooSmall => new Result(ModuleId, 141); - public static Result OutOfDomains => new Result(ModuleId, 200); - - public static Result InvalidRequestSize => new Result(ModuleId, 402); - public static Result UnknownCommandType => new Result(ModuleId, 403); - - public static Result InvalidCmifRequest => new Result(ModuleId, 420); - - public static Result TargetNotDomain => new Result(ModuleId, 491); - public static Result DomainObjectNotFound => new Result(ModuleId, 492); + public static Result OutOfSessionMemory => new(ModuleId, 102); + public static Result OutOfSessions => new(ModuleId, 131); + public static Result PointerBufferTooSmall => new(ModuleId, 141); + public static Result OutOfDomains => new(ModuleId, 200); + public static Result InvalidRequestSize => new(ModuleId, 402); + public static Result UnknownCommandType => new(ModuleId, 403); + public static Result InvalidCmifRequest => new(ModuleId, 420); + public static Result TargetNotDomain => new(ModuleId, 491); + public static Result DomainObjectNotFound => new(ModuleId, 492); } } diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcStaticDescriptor.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcStaticDescriptor.cs index 5cebf47c..103820a6 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcStaticDescriptor.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/HipcStaticDescriptor.cs @@ -4,9 +4,9 @@ { private readonly ulong _data; - public ulong Address => ((((_data >> 2) & 0x70) | ((_data >> 12) & 0xf)) << 32) | (_data >> 32); - public ushort Size => (ushort)(_data >> 16); - public int ReceiveIndex => (int)(_data & 0xf); + public ulong Address => ((((_data >> 2) & 0x70) | ((_data >> 12) & 0xf)) << 32) | (_data >> 32); + public ushort Size => (ushort)(_data >> 16); + public int ReceiveIndex => (int)(_data & 0xf); public HipcStaticDescriptor(ulong address, ushort size, int receiveIndex) { @@ -19,4 +19,4 @@ _data = data; } } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/ManagerOptions.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/ManagerOptions.cs index e087cb22..b99d63c5 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/ManagerOptions.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/ManagerOptions.cs @@ -2,19 +2,19 @@ { struct ManagerOptions { - public static ManagerOptions Default => new ManagerOptions(0, 0, 0, false); + public static ManagerOptions Default => new(0, 0, 0, false); - public int PointerBufferSize { get; } - public int MaxDomains { get; } - public int MaxDomainObjects { get; } + public int PointerBufferSize { get; } + public int MaxDomains { get; } + public int MaxDomainObjects { get; } public bool CanDeferInvokeRequest { get; } public ManagerOptions(int pointerBufferSize, int maxDomains, int maxDomainObjects, bool canDeferInvokeRequest) { - PointerBufferSize = pointerBufferSize; - MaxDomains = maxDomains; - MaxDomainObjects = maxDomainObjects; + PointerBufferSize = pointerBufferSize; + MaxDomains = maxDomains; + MaxDomainObjects = maxDomainObjects; CanDeferInvokeRequest = canDeferInvokeRequest; } } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/Server.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/Server.cs index 923f2d52..bbbab898 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/Server.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/Server.cs @@ -6,22 +6,22 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc { class Server : MultiWaitHolderOfHandle { - public int PortIndex { get; } - public int PortHandle { get; } - public ServiceName Name { get; } - public bool Managed { get; } + public int PortIndex { get; } + public int PortHandle { get; } + public ServiceName Name { get; } + public bool Managed { get; } public ServiceObjectHolder StaticObject { get; } public Server( - int portIndex, - int portHandle, - ServiceName name, - bool managed, + int portIndex, + int portHandle, + ServiceName name, + bool managed, ServiceObjectHolder staticHoder) : base(portHandle) { PortHandle = portHandle; - Name = name; - Managed = managed; + Name = name; + Managed = managed; if (staticHoder != null) { diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerDomainSessionManager.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerDomainSessionManager.cs index d920a659..dda77539 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerDomainSessionManager.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerDomainSessionManager.cs @@ -15,7 +15,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc protected override Result DispatchManagerRequest(ServerSession session, Span<byte> inMessage, Span<byte> outMessage) { - HipcManager hipcManager = new HipcManager(this, session); + HipcManager hipcManager = new(this, session); return DispatchRequest(new ServiceObjectHolder(hipcManager), session, inMessage, outMessage); } diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManager.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManager.cs index 5bb2de25..2ca9ceea 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManager.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManager.cs @@ -80,7 +80,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc return null; } - ServerSession session = new ServerSession(sessionIndex, sessionHandle, obj); + ServerSession session = new(sessionIndex, sessionHandle, obj); _sessions.Add(session); @@ -111,7 +111,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc { lock (_resourceLock) { - Server server = new Server(portIndex, portHandle, name, managed, staticHoder); + Server server = new(portIndex, portHandle, name, managed, staticHoder); _servers.Add(server); diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManagerBase.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManagerBase.cs index 68cae6bc..9d21290d 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManagerBase.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerManagerBase.cs @@ -26,7 +26,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc private enum UserDataTag { - Server = 1, + Server = 1, Session = 2 } @@ -36,16 +36,17 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc _canDeferInvokeRequest = options.CanDeferInvokeRequest; _multiWait = new MultiWait(); - _waitList = new MultiWait(); + _waitList = new MultiWait(); _multiWaitSelectionLock = new object(); - _waitListLock = new object(); + _waitListLock = new object(); _requestStopEvent = new Event(EventClearMode.ManualClear); - _notifyEvent = new Event(EventClearMode.ManualClear); + _notifyEvent = new Event(EventClearMode.ManualClear); _requestStopEventHolder = new MultiWaitHolderOfEvent(_requestStopEvent); _multiWait.LinkMultiWaitHolder(_requestStopEventHolder); + _notifyEventHolder = new MultiWaitHolderOfEvent(_notifyEvent); _multiWait.LinkMultiWaitHolder(_notifyEventHolder); } @@ -73,6 +74,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc private void RegisterServerImpl(int portIndex, ServiceObjectHolder staticHolder, int portHandle) { Server server = AllocateServer(portIndex, portHandle, ServiceName.Invalid, managed: false, staticHolder); + RegisterServerImpl(server); } @@ -86,6 +88,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc } Server server = AllocateServer(portIndex, portHandle, name, managed: true, staticHolder); + RegisterServerImpl(server); return Result.Success; @@ -103,6 +106,11 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc throw new NotSupportedException(); } + protected Result AcceptImpl(Server server, IServiceObject obj) + { + return AcceptSession(server.PortHandle, new ServiceObjectHolder(obj)); + } + public void ServiceRequests() { while (WaitAndProcessRequestsImpl()); @@ -175,7 +183,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc protected override void RegisterSessionToWaitList(ServerSession session) { session.HasReceived = false; - session.UserData = UserDataTag.Session; + session.UserData = UserDataTag.Session; + RegisterToWaitList(session); } @@ -198,15 +207,12 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc private Result Process(MultiWaitHolder holder) { - switch ((UserDataTag)holder.UserData) + return (UserDataTag)holder.UserData switch { - case UserDataTag.Server: - return ProcessForServer(holder); - case UserDataTag.Session: - return ProcessForSession(holder); - default: - throw new NotImplementedException(((UserDataTag)holder.UserData).ToString()); - } + UserDataTag.Server => ProcessForServer(holder), + UserDataTag.Session => ProcessForSession(holder), + _ => throw new NotImplementedException(((UserDataTag)holder.UserData).ToString()) + }; } private Result ProcessForServer(MultiWaitHolder holder) @@ -259,6 +265,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc } session.HasReceived = true; + tlsMessage.Memory.Span.CopyTo(savedMessage.Memory.Span); } else diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerSession.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerSession.cs index eb98fefd..a1730082 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerSession.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerSession.cs @@ -6,18 +6,18 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc class ServerSession : MultiWaitHolderOfHandle { public ServiceObjectHolder ServiceObjectHolder { get; set; } - public PointerAndSize PointerBuffer { get; set; } - public PointerAndSize SavedMessage { get; set; } - public int SessionIndex { get; } - public int SessionHandle { get; } - public bool IsClosed { get; set; } - public bool HasReceived { get; set; } + public PointerAndSize PointerBuffer { get; set; } + public PointerAndSize SavedMessage { get; set; } + public int SessionIndex { get; } + public int SessionHandle { get; } + public bool IsClosed { get; set; } + public bool HasReceived { get; set; } public ServerSession(int index, int handle, ServiceObjectHolder obj) : base(handle) { ServiceObjectHolder = obj; - SessionIndex = index; - SessionHandle = handle; + SessionIndex = index; + SessionHandle = handle; } } } diff --git a/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerSessionManager.cs b/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerSessionManager.cs index e85892f2..6d395081 100644 --- a/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerSessionManager.cs +++ b/Ryujinx.Horizon/Sdk/Sf/Hipc/ServerSessionManager.cs @@ -75,9 +75,10 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc } session.PointerBuffer = GetSessionPointerBuffer(session); - session.SavedMessage = GetSessionSavedMessageBuffer(session); + session.SavedMessage = GetSessionSavedMessageBuffer(session); RegisterSessionToWaitList(session); + return Result.Success; } @@ -109,10 +110,10 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc } protected virtual Server AllocateServer( - int portIndex, - int portHandle, - ServiceName name, - bool managed, + int portIndex, + int portHandle, + ServiceName name, + bool managed, ServiceObjectHolder staticHoder) { throw new NotSupportedException(); @@ -141,6 +142,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc protected void CloseSessionImpl(ServerSession session) { int sessionHandle = session.Handle; + Os.FinalizeMultiWaitHolder(session); DestroySession(session); HorizonStatic.Syscall.CloseHandle(sessionHandle).AbortOnFailure(); @@ -156,6 +158,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc if (session.IsClosed || GetCmifCommandType(message) == CommandType.Close) { CloseSessionImpl(session); + return Result.Success; } else @@ -165,6 +168,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc if (result.IsSuccess) { RegisterSessionToWaitList(session); + return Result.Success; } else if (SfResult.RequestContextChanged(result)) @@ -176,6 +180,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc Logger.Warning?.Print(LogClass.KernelIpc, $"Request processing returned error {result}"); CloseSessionImpl(session); + return Result.Success; } } @@ -197,8 +202,8 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc return DispatchManagerRequest(session, inMessage, outMessage); default: return HipcResult.UnknownCommandType; - } } + } private static int GetInlineContext(CommandType commandType, ReadOnlySpan<byte> inMessage) { @@ -231,7 +236,7 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc { HipcMessageData messageData = HipcMessage.WriteMessage(message, new HipcMetadata() { - Type = (int)CommandType.Invalid, + Type = (int)CommandType.Invalid, ReceiveStaticsCount = HipcMessage.AutoReceiveStatic }); @@ -271,9 +276,9 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc protected virtual Result DispatchRequest( ServiceObjectHolder objectHolder, - ServerSession session, - Span<byte> inMessage, - Span<byte> outMessage) + ServerSession session, + Span<byte> inMessage, + Span<byte> outMessage) { HipcMessage request; @@ -288,14 +293,14 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc var dispatchCtx = new ServiceDispatchContext() { - ServiceObject = objectHolder.ServiceObject, - Manager = this, - Session = session, - HandlesToClose = new HandlesToClose(), - PointerBuffer = session.PointerBuffer, - InMessageBuffer = inMessage, + ServiceObject = objectHolder.ServiceObject, + Manager = this, + Session = session, + HandlesToClose = new HandlesToClose(), + PointerBuffer = session.PointerBuffer, + InMessageBuffer = inMessage, OutMessageBuffer = outMessage, - Request = request + Request = request }; ReadOnlySpan<byte> inRawData = MemoryMarshal.Cast<uint, byte>(dispatchCtx.Request.Data.DataWords); @@ -332,4 +337,4 @@ namespace Ryujinx.Horizon.Sdk.Sf.Hipc return this; } } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/HipcCommandProcessor.cs b/Ryujinx.Horizon/Sdk/Sf/HipcCommandProcessor.cs index 53202ede..6bba49ae 100644 --- a/Ryujinx.Horizon/Sdk/Sf/HipcCommandProcessor.cs +++ b/Ryujinx.Horizon/Sdk/Sf/HipcCommandProcessor.cs @@ -136,9 +136,9 @@ namespace Ryujinx.Horizon.Sdk.Sf ulong pointerBufferTail = context.PointerBuffer.Address; ulong pointerBufferHead = pointerBufferTail + context.PointerBuffer.Size; - int sendMapAliasIndex = 0; - int recvMapAliasIndex = 0; - int sendPointerIndex = 0; + int sendMapAliasIndex = 0; + int recvMapAliasIndex = 0; + int sendPointerIndex = 0; int unfixedRecvPointerIndex = 0; for (int i = 0; i < _args.Length; i++) @@ -188,8 +188,9 @@ namespace Ryujinx.Horizon.Sdk.Sf if (flags.HasFlag(HipcBufferFlags.In)) { var descriptor = context.Request.Data.SendStatics[sendPointerIndex++]; - ulong address = descriptor.Address; - ulong size = descriptor.Size; + ulong address = descriptor.Address; + ulong size = descriptor.Size; + _bufferRanges[i] = new PointerAndSize(address, size); if (size != 0) @@ -207,13 +208,14 @@ namespace Ryujinx.Horizon.Sdk.Sf } else { - var data = MemoryMarshal.Cast<uint, byte>(context.Request.Data.DataWords); - var recvPointerSizes = MemoryMarshal.Cast<byte, ushort>(data.Slice(runtimeMetadata.UnfixedOutPointerSizeOffset)); + var data = MemoryMarshal.Cast<uint, byte>(context.Request.Data.DataWords); + var recvPointerSizes = MemoryMarshal.Cast<byte, ushort>(data[runtimeMetadata.UnfixedOutPointerSizeOffset..]); + size = recvPointerSizes[unfixedRecvPointerIndex++]; } pointerBufferHead = BitUtils.AlignDown(pointerBufferHead - size, 0x10UL); - _bufferRanges[i] = new PointerAndSize(pointerBufferHead, size); + _bufferRanges[i] = new PointerAndSize(pointerBufferHead, size); } } } @@ -304,16 +306,17 @@ namespace Ryujinx.Horizon.Sdk.Sf { ref var meta = ref context.Request.Meta; bool requestValid = true; - requestValid &= meta.SendPid == _hasInProcessIdHolder; - requestValid &= meta.SendStaticsCount == _inPointerBuffersCount; - requestValid &= meta.SendBuffersCount == _inMapAliasBuffersCount; - requestValid &= meta.ReceiveBuffersCount == _outMapAliasBuffersCount; + requestValid &= meta.SendPid == _hasInProcessIdHolder; + requestValid &= meta.SendStaticsCount == _inPointerBuffersCount; + requestValid &= meta.SendBuffersCount == _inMapAliasBuffersCount; + requestValid &= meta.ReceiveBuffersCount == _outMapAliasBuffersCount; requestValid &= meta.ExchangeBuffersCount == 0; - requestValid &= meta.CopyHandlesCount == _inCopyHandlesCount; - requestValid &= meta.MoveHandlesCount == _inMoveHandlesCount; + requestValid &= meta.CopyHandlesCount == _inCopyHandlesCount; + requestValid &= meta.MoveHandlesCount == _inMoveHandlesCount; int rawSizeInBytes = meta.DataWordsCount * sizeof(uint); int commandRawSize = BitUtils.AlignUp(runtimeMetadata.UnfixedOutPointerSizeOffset + (OutUnfixedSizePointerBuffersCount * sizeof(ushort)), sizeof(uint)); + requestValid &= rawSizeInBytes >= commandRawSize; return requestValid ? Result.Success : HipcResult.InvalidCmifRequest; @@ -340,7 +343,7 @@ namespace Ryujinx.Horizon.Sdk.Sf { if (_args[i].Type == CommandArgType.InObject) { - int index = inObjectIndex++; + int index = inObjectIndex++; var inObject = inObjects[index]; objects[index] = inObject?.ServiceObject; @@ -365,6 +368,7 @@ namespace Ryujinx.Horizon.Sdk.Sf _outCopyHandlesCount, _outMoveHandlesCount + runtimeMetadata.OutObjectsCount); outRawData = MemoryMarshal.Cast<uint, byte>(response.DataWords); + return response; } @@ -377,6 +381,7 @@ namespace Ryujinx.Horizon.Sdk.Sf (BitUtils.AlignUp(rawDataSize, 4) + 0x10) / sizeof(uint), 0, 0); + outRawData = MemoryMarshal.Cast<uint, byte>(response.DataWords); } @@ -410,6 +415,7 @@ namespace Ryujinx.Horizon.Sdk.Sf if (obj == null) { response.MoveHandles[index] = 0; + return; } @@ -418,4 +424,4 @@ namespace Ryujinx.Horizon.Sdk.Sf response.MoveHandles[index] = clientHandle; } } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/RawDataOffsetCalculator.cs b/Ryujinx.Horizon/Sdk/Sf/RawDataOffsetCalculator.cs index 982f454f..10e4f909 100644 --- a/Ryujinx.Horizon/Sdk/Sf/RawDataOffsetCalculator.cs +++ b/Ryujinx.Horizon/Sdk/Sf/RawDataOffsetCalculator.cs @@ -12,24 +12,22 @@ namespace Ryujinx.Horizon.Sdk.Sf { int argsCount = args.Length; - int[] sizes = new int[argsCount]; + int[] sizes = 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++) { - sizes[i] = args[i].ArgSize; + sizes[i] = args[i].ArgSize; aligns[i] = args[i].ArgAlignment; - map[i] = i; + map[i] = i; } for (int i = 1; i < argsCount; i++) { for (int j = i; j > 0 && aligns[map[j - 1]] > aligns[map[j]]; j--) { - var temp = map[j - 1]; - map[j - 1] = map[j]; - map[j] = temp; + (map[j], map[j - 1]) = (map[j - 1], map[j]); } } @@ -37,9 +35,9 @@ namespace Ryujinx.Horizon.Sdk.Sf foreach (int i in map) { - offset = BitUtils.AlignUp(offset, aligns[i]); + offset = BitUtils.AlignUp(offset, aligns[i]); offsets[i] = offset; - offset += sizes[i]; + offset += sizes[i]; } offsets[argsCount] = offset; @@ -48,4 +46,4 @@ namespace Ryujinx.Horizon.Sdk.Sf return offsets; } } -} +}
\ No newline at end of file diff --git a/Ryujinx.Horizon/Sdk/Sf/SfResult.cs b/Ryujinx.Horizon/Sdk/Sf/SfResult.cs index 6aa11ba5..72502d17 100644 --- a/Ryujinx.Horizon/Sdk/Sf/SfResult.cs +++ b/Ryujinx.Horizon/Sdk/Sf/SfResult.cs @@ -6,26 +6,22 @@ namespace Ryujinx.Horizon.Sdk.Sf { public const int ModuleId = 10; - public static Result NotSupported => new Result(ModuleId, 1); - public static Result InvalidHeaderSize => new Result(ModuleId, 202); - public static Result InvalidInHeader => new Result(ModuleId, 211); - public static Result InvalidOutHeader => new Result(ModuleId, 212); - public static Result UnknownCommandId => new Result(ModuleId, 221); - public static Result InvalidOutRawSize => new Result(ModuleId, 232); - public static Result InvalidInObjectsCount => new Result(ModuleId, 235); - public static Result InvalidOutObjectsCount => new Result(ModuleId, 236); - public static Result InvalidInObject => new Result(ModuleId, 239); - - public static Result TargetNotFound => new Result(ModuleId, 261); - - public static Result OutOfDomainEntries => new Result(ModuleId, 301); - - public static Result InvalidatedByUser => new Result(ModuleId, 802); - public static Result RequestDeferredByUser => new Result(ModuleId, 812); + public static Result NotSupported => new(ModuleId, 1); + public static Result InvalidHeaderSize => new(ModuleId, 202); + public static Result InvalidInHeader => new(ModuleId, 211); + public static Result InvalidOutHeader => new(ModuleId, 212); + public static Result UnknownCommandId => new(ModuleId, 221); + public static Result InvalidOutRawSize => new(ModuleId, 232); + public static Result InvalidInObjectsCount => new(ModuleId, 235); + public static Result InvalidOutObjectsCount => new(ModuleId, 236); + public static Result InvalidInObject => new(ModuleId, 239); + public static Result TargetNotFound => new(ModuleId, 261); + public static Result OutOfDomainEntries => new(ModuleId, 301); + public static Result InvalidatedByUser => new(ModuleId, 802); + public static Result RequestDeferredByUser => new(ModuleId, 812); public static bool RequestContextChanged(Result result) => result.InRange(800, 899); - public static bool Invalidated(Result result) => result.InRange(801, 809); - - public static bool RequestDeferred(Result result) => result.InRange(811, 819); + public static bool Invalidated(Result result) => result.InRange(801, 809); + public static bool RequestDeferred(Result result) => result.InRange(811, 819); } -} +}
\ No newline at end of file |
