Compare commits

...

3 Commits

Author SHA1 Message Date
fb55f57da7 Horizon: Migrate wlan and stubs latest services (#5708)
* Horizon: Migrate wlan and stubs latest services

This PR migrate empty wlan services, values are found by RE.
Latest firmwares added some other services which are now stubbed and up-to-date.

* Fix imports ordering
2023-09-20 22:55:27 +02:00
44862dce3e Stub unsupported BSD socket options (#5670)
* Stub unsupported BSD socket options

* Span.Clear
2023-09-19 19:35:56 +02:00
e601419bd4 make cheat list binding public (#5697) 2023-09-19 16:51:56 +00:00
33 changed files with 382 additions and 59 deletions

View File

@ -17,7 +17,7 @@ namespace Ryujinx.Ava.UI.Windows
private readonly string _enabledCheatsPath;
public bool NoCheatsFound { get; }
private AvaloniaList<CheatsList> LoadedCheats { get; }
public AvaloniaList<CheatsList> LoadedCheats { get; }
public string Heading { get; }
public string BuildId { get; }

View File

@ -299,11 +299,21 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl
{
try
{
LinuxError result = WinSockHelper.ValidateSocketOption(option, level, write: false);
if (result != LinuxError.SUCCESS)
{
Logger.Warning?.Print(LogClass.ServiceBsd, $"Invalid GetSockOpt Option: {option} Level: {level}");
return result;
}
if (!WinSockHelper.TryConvertSocketOption(option, level, out SocketOptionName optionName))
{
Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported GetSockOpt Option: {option} Level: {level}");
optionValue.Clear();
return LinuxError.EOPNOTSUPP;
return LinuxError.SUCCESS;
}
byte[] tempOptionValue = new byte[optionValue.Length];
@ -324,11 +334,20 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl
{
try
{
LinuxError result = WinSockHelper.ValidateSocketOption(option, level, write: true);
if (result != LinuxError.SUCCESS)
{
Logger.Warning?.Print(LogClass.ServiceBsd, $"Invalid SetSockOpt Option: {option} Level: {level}");
return result;
}
if (!WinSockHelper.TryConvertSocketOption(option, level, out SocketOptionName optionName))
{
Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported SetSockOpt Option: {option} Level: {level}");
return LinuxError.EOPNOTSUPP;
return LinuxError.SUCCESS;
}
int value = optionValue.Length >= 4 ? MemoryMarshal.Read<int>(optionValue) : MemoryMarshal.Read<byte>(optionValue);

View File

@ -183,6 +183,104 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl
{ BsdSocketOption.TcpKeepCnt, SocketOptionName.TcpKeepAliveRetryCount },
};
[Flags]
private enum OptionDir
{
Get = 1 << 0,
Set = 1 << 1,
GetSet = Get | Set,
}
private static readonly Dictionary<BsdSocketOption, OptionDir> _validSoSocketOptionMap = new()
{
{ BsdSocketOption.SoDebug, OptionDir.GetSet },
{ BsdSocketOption.SoAcceptConn, OptionDir.Get },
{ BsdSocketOption.SoReuseAddr, OptionDir.GetSet },
{ BsdSocketOption.SoKeepAlive, OptionDir.GetSet },
{ BsdSocketOption.SoDontRoute, OptionDir.GetSet },
{ BsdSocketOption.SoBroadcast, OptionDir.GetSet },
{ BsdSocketOption.SoUseLoopBack, OptionDir.GetSet },
{ BsdSocketOption.SoLinger, OptionDir.GetSet },
{ BsdSocketOption.SoOobInline, OptionDir.GetSet },
{ BsdSocketOption.SoReusePort, OptionDir.GetSet },
{ BsdSocketOption.SoTimestamp, OptionDir.GetSet },
{ BsdSocketOption.SoNoSigpipe, OptionDir.GetSet },
{ BsdSocketOption.SoAcceptFilter, OptionDir.GetSet },
{ BsdSocketOption.SoSndBuf, OptionDir.GetSet },
{ BsdSocketOption.SoRcvBuf, OptionDir.GetSet },
{ BsdSocketOption.SoSndLoWat, OptionDir.GetSet },
{ BsdSocketOption.SoRcvLoWat, OptionDir.GetSet },
{ BsdSocketOption.SoSndTimeo, OptionDir.GetSet },
{ BsdSocketOption.SoRcvTimeo, OptionDir.GetSet },
{ BsdSocketOption.SoError, OptionDir.Get },
{ BsdSocketOption.SoType, OptionDir.Get },
{ BsdSocketOption.SoLabel, OptionDir.Get },
{ BsdSocketOption.SoPeerLabel, OptionDir.Get },
{ BsdSocketOption.SoListenQLimit, OptionDir.Get },
{ BsdSocketOption.SoListenQLen, OptionDir.Get },
{ BsdSocketOption.SoListenIncQLen, OptionDir.Get },
{ BsdSocketOption.SoSetFib, OptionDir.Set },
{ BsdSocketOption.SoUserCookie, OptionDir.Set },
{ BsdSocketOption.SoProtocol, OptionDir.Get },
{ BsdSocketOption.SoBinTime, OptionDir.GetSet },
{ BsdSocketOption.SoNoOffload, OptionDir.Set },
{ BsdSocketOption.SoNoDdp, OptionDir.Set },
{ BsdSocketOption.SoReusePortLb, OptionDir.GetSet },
};
private static readonly Dictionary<BsdSocketOption, OptionDir> _validIpSocketOptionMap = new()
{
{ BsdSocketOption.IpOptions, OptionDir.GetSet },
{ BsdSocketOption.IpHdrIncl, OptionDir.GetSet },
{ BsdSocketOption.IpTos, OptionDir.GetSet },
{ BsdSocketOption.IpTtl, OptionDir.GetSet },
{ BsdSocketOption.IpRecvOpts, OptionDir.GetSet },
{ BsdSocketOption.IpRecvRetOpts, OptionDir.GetSet },
{ BsdSocketOption.IpRecvDstAddr, OptionDir.GetSet },
{ BsdSocketOption.IpRetOpts, OptionDir.GetSet },
{ BsdSocketOption.IpMulticastIf, OptionDir.GetSet },
{ BsdSocketOption.IpMulticastTtl, OptionDir.GetSet },
{ BsdSocketOption.IpMulticastLoop, OptionDir.GetSet },
{ BsdSocketOption.IpAddMembership, OptionDir.GetSet },
{ BsdSocketOption.IpDropMembership, OptionDir.GetSet },
{ BsdSocketOption.IpMulticastVif, OptionDir.GetSet },
{ BsdSocketOption.IpRsvpOn, OptionDir.GetSet },
{ BsdSocketOption.IpRsvpOff, OptionDir.GetSet },
{ BsdSocketOption.IpRsvpVifOn, OptionDir.GetSet },
{ BsdSocketOption.IpRsvpVifOff, OptionDir.GetSet },
{ BsdSocketOption.IpPortRange, OptionDir.GetSet },
{ BsdSocketOption.IpRecvIf, OptionDir.GetSet },
{ BsdSocketOption.IpIpsecPolicy, OptionDir.GetSet },
{ BsdSocketOption.IpOnesBcast, OptionDir.GetSet },
{ BsdSocketOption.IpBindany, OptionDir.GetSet },
{ BsdSocketOption.IpBindMulti, OptionDir.GetSet },
{ BsdSocketOption.IpRssListenBucket, OptionDir.GetSet },
{ BsdSocketOption.IpOrigDstAddr, OptionDir.GetSet },
{ BsdSocketOption.IpRecvTtl, OptionDir.GetSet },
{ BsdSocketOption.IpMinTtl, OptionDir.GetSet },
{ BsdSocketOption.IpDontFrag, OptionDir.GetSet },
{ BsdSocketOption.IpRecvTos, OptionDir.GetSet },
{ BsdSocketOption.IpAddSourceMembership, OptionDir.GetSet },
{ BsdSocketOption.IpDropSourceMembership, OptionDir.GetSet },
{ BsdSocketOption.IpBlockSource, OptionDir.GetSet },
{ BsdSocketOption.IpUnblockSource, OptionDir.GetSet },
};
private static readonly Dictionary<BsdSocketOption, OptionDir> _validTcpSocketOptionMap = new()
{
{ BsdSocketOption.TcpNoDelay, OptionDir.GetSet },
{ BsdSocketOption.TcpMaxSeg, OptionDir.GetSet },
{ BsdSocketOption.TcpNoPush, OptionDir.GetSet },
{ BsdSocketOption.TcpNoOpt, OptionDir.GetSet },
{ BsdSocketOption.TcpMd5Sig, OptionDir.GetSet },
{ BsdSocketOption.TcpInfo, OptionDir.GetSet },
{ BsdSocketOption.TcpCongestion, OptionDir.GetSet },
{ BsdSocketOption.TcpKeepInit, OptionDir.GetSet },
{ BsdSocketOption.TcpKeepIdle, OptionDir.GetSet },
{ BsdSocketOption.TcpKeepIntvl, OptionDir.GetSet },
{ BsdSocketOption.TcpKeepCnt, OptionDir.GetSet },
};
public static LinuxError ConvertError(WsaError errorCode)
{
if (OperatingSystem.IsMacOS())
@ -221,5 +319,29 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl
return table.TryGetValue(option, out name);
}
public static LinuxError ValidateSocketOption(BsdSocketOption option, SocketOptionLevel level, bool write)
{
var table = level switch
{
SocketOptionLevel.Socket => _validSoSocketOptionMap,
SocketOptionLevel.IP => _validIpSocketOptionMap,
SocketOptionLevel.Tcp => _validTcpSocketOptionMap,
_ => null,
};
OptionDir dir = write ? OptionDir.Set : OptionDir.Get;
if (table == null || !table.TryGetValue(option, out OptionDir validDir))
{
return LinuxError.ENOPROTOOPT;
}
else if ((validDir & dir) != dir)
{
return LinuxError.EOPNOTSUPP;
}
return LinuxError.SUCCESS;
}
}
}

View File

@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Wlan
{
[Service("wlan:inf")]
class IInfraManager : IpcService
{
public IInfraManager(ServiceCtx context) { }
}
}

View File

@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Wlan
{
[Service("wlan:lga")]
class ILocalGetActionFrame : IpcService
{
public ILocalGetActionFrame(ServiceCtx context) { }
}
}

View File

@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Wlan
{
[Service("wlan:lg")]
class ILocalGetFrame : IpcService
{
public ILocalGetFrame(ServiceCtx context) { }
}
}

View File

@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Wlan
{
[Service("wlan:lcl")]
class ILocalManager : IpcService
{
public ILocalManager(ServiceCtx context) { }
}
}

View File

@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Wlan
{
[Service("wlan:sg")]
class ISocketGetFrame : IpcService
{
public ISocketGetFrame(ServiceCtx context) { }
}
}

View File

@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Wlan
{
[Service("wlan:soc")]
class ISocketManager : IpcService
{
public ISocketManager(ServiceCtx context) { }
}
}

View File

@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Wlan
{
[Service("wlan:dtc")] // 6.0.0+
class IUnknown1 : IpcService
{
public IUnknown1(ServiceCtx context) { }
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Wlan
{
interface IDetectManager : IServiceObject
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Wlan
{
interface IGeneralServiceCreator : IServiceObject
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Wlan
{
interface IInfraManager : IServiceObject
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Wlan
{
interface ILocalGetActionFrame : IServiceObject
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Wlan
{
interface ILocalGetFrame : IServiceObject
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Wlan
{
interface ILocalManager : IServiceObject
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Wlan
{
interface IPrivateServiceCreator : IServiceObject
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Wlan
{
interface ISfDriverServiceCreator : IServiceObject
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Wlan
{
interface ISocketGetFrame : IServiceObject
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Wlan
{
interface ISocketManager : IServiceObject
{
}
}

View File

@ -3,6 +3,7 @@ using Ryujinx.Horizon.Lbl;
using Ryujinx.Horizon.LogManager;
using Ryujinx.Horizon.MmNv;
using Ryujinx.Horizon.Prepo;
using Ryujinx.Horizon.Wlan;
using System.Collections.Generic;
using System.Threading;
@ -29,6 +30,7 @@ namespace Ryujinx.Horizon
RegisterService<LmMain>();
RegisterService<MmNvMain>();
RegisterService<PrepoMain>();
RegisterService<WlanMain>();
_totalServices = entries.Count;

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Wlan;
namespace Ryujinx.Horizon.Wlan.Ipc
{
partial class DetectManager : IDetectManager
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Wlan;
namespace Ryujinx.Horizon.Wlan.Ipc
{
partial class GeneralServiceCreator : IGeneralServiceCreator
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Wlan;
namespace Ryujinx.Horizon.Wlan.Ipc
{
partial class InfraManager : IInfraManager
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Wlan;
namespace Ryujinx.Horizon.Wlan.Ipc
{
partial class LocalGetActionFrame : ILocalGetActionFrame
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Wlan;
namespace Ryujinx.Horizon.Wlan.Ipc
{
partial class LocalGetFrame : ILocalGetFrame
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Wlan;
namespace Ryujinx.Horizon.Wlan.Ipc
{
partial class LocalManager : ILocalManager
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Wlan;
namespace Ryujinx.Horizon.Wlan.Ipc
{
partial class PrivateServiceCreator : IPrivateServiceCreator
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Wlan;
namespace Ryujinx.Horizon.Wlan.Ipc
{
partial class SfDriverServiceCreator : ISfDriverServiceCreator
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Wlan;
namespace Ryujinx.Horizon.Wlan.Ipc
{
partial class SocketGetFrame : ISocketGetFrame
{
}
}

View File

@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Wlan;
namespace Ryujinx.Horizon.Wlan.Ipc
{
partial class SocketManager : ISocketManager
{
}
}

View File

@ -0,0 +1,59 @@
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
using Ryujinx.Horizon.Wlan.Ipc;
namespace Ryujinx.Horizon.Wlan
{
class WlanIpcServer
{
private const int WlanOtherMaxSessionsCount = 10;
private const int WlanDtcMaxSessionsCount = 4;
private const int WlanMaxSessionsCount = 30;
private const int WlanNdMaxSessionsCount = 5;
private const int WlanPMaxSessionsCount = 30;
private const int TotalMaxSessionsCount = WlanDtcMaxSessionsCount + WlanMaxSessionsCount + WlanNdMaxSessionsCount + WlanPMaxSessionsCount + WlanOtherMaxSessionsCount * 6;
private const int PointerBufferSize = 0x1000;
private const int MaxDomains = 16;
private const int MaxDomainObjects = 10;
private const int MaxPortsCount = 10;
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterObjectForServer(new GeneralServiceCreator(), ServiceName.Encode("wlan"), WlanMaxSessionsCount); // 15.0.0+
_serverManager.RegisterObjectForServer(new DetectManager(), ServiceName.Encode("wlan:dtc"), WlanDtcMaxSessionsCount); // 6.0.0-14.1.2
_serverManager.RegisterObjectForServer(new InfraManager(), ServiceName.Encode("wlan:inf"), WlanOtherMaxSessionsCount); // 1.0.0-14.1.2
_serverManager.RegisterObjectForServer(new LocalManager(), ServiceName.Encode("wlan:lcl"), WlanOtherMaxSessionsCount); // 1.0.0-14.1.2
_serverManager.RegisterObjectForServer(new LocalGetFrame(), ServiceName.Encode("wlan:lg"), WlanOtherMaxSessionsCount); // 1.0.0-14.1.2
_serverManager.RegisterObjectForServer(new LocalGetActionFrame(), ServiceName.Encode("wlan:lga"), WlanOtherMaxSessionsCount); // 1.0.0-14.1.2
_serverManager.RegisterObjectForServer(new SfDriverServiceCreator(), ServiceName.Encode("wlan:nd"), WlanNdMaxSessionsCount); // 15.0.0+
_serverManager.RegisterObjectForServer(new PrivateServiceCreator(), ServiceName.Encode("wlan:p"), WlanPMaxSessionsCount); // 15.0.0+
_serverManager.RegisterObjectForServer(new SocketGetFrame(), ServiceName.Encode("wlan:sg"), WlanOtherMaxSessionsCount); // 1.0.0-14.1.2
_serverManager.RegisterObjectForServer(new SocketManager(), ServiceName.Encode("wlan:soc"), WlanOtherMaxSessionsCount); // 1.0.0-14.1.2
#pragma warning restore IDE0055
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Wlan
{
class WlanMain : IService
{
public static void Main(ServiceTable serviceTable)
{
WlanIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}