diff options
| author | TSR Berry <20988865+TSRBerry@users.noreply.github.com> | 2023-04-08 01:22:00 +0200 |
|---|---|---|
| committer | Mary <thog@protonmail.com> | 2023-04-27 23:51:14 +0200 |
| commit | cee712105850ac3385cd0091a923438167433f9f (patch) | |
| tree | 4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /src/Ryujinx.HLE/HOS/Services/Nifm | |
| parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) | |
Move solution and projects to src
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Services/Nifm')
16 files changed, 611 insertions, 0 deletions
diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/IStaticService.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/IStaticService.cs new file mode 100644 index 00000000..d6a4a29f --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/IStaticService.cs @@ -0,0 +1,30 @@ +using Ryujinx.HLE.HOS.Services.Nifm.StaticService; + +namespace Ryujinx.HLE.HOS.Services.Nifm +{ + [Service("nifm:a")] // Max sessions: 2 + [Service("nifm:s")] // Max sessions: 16 + [Service("nifm:u")] // Max sessions: 5 + class IStaticService : IpcService + { + public IStaticService(ServiceCtx context) { } + + [CommandCmif(4)] + // CreateGeneralServiceOld() -> object<nn::nifm::detail::IGeneralService> + public ResultCode CreateGeneralServiceOld(ServiceCtx context) + { + MakeObject(context, new IGeneralService()); + + return ResultCode.Success; + } + + [CommandCmif(5)] // 3.0.0+ + // CreateGeneralService(u64, pid) -> object<nn::nifm::detail::IGeneralService> + public ResultCode CreateGeneralService(ServiceCtx context) + { + MakeObject(context, new IGeneralService()); + + return ResultCode.Success; + } + } +}
\ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/ResultCode.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/ResultCode.cs new file mode 100644 index 00000000..73cadb11 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/ResultCode.cs @@ -0,0 +1,15 @@ +namespace Ryujinx.HLE.HOS.Services.Nifm +{ + enum ResultCode + { + ModuleId = 110, + ErrorCodeShift = 9, + + Success = 0, + + Unknown112 = (112 << ErrorCodeShift) | ModuleId, // IRequest::GetResult + Unknown180 = (180 << ErrorCodeShift) | ModuleId, // IRequest::GetAppletInfo + NoInternetConnection = (300 << ErrorCodeShift) | ModuleId, + ObjectIsNull = (350 << ErrorCodeShift) | ModuleId + } +}
\ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/GeneralServiceManager.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/GeneralServiceManager.cs new file mode 100644 index 00000000..bbb218bb --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/GeneralServiceManager.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService +{ + static class GeneralServiceManager + { + private static List<GeneralServiceDetail> _generalServices = new List<GeneralServiceDetail>(); + + public static int Count + { + get => _generalServices.Count; + } + + public static void Add(GeneralServiceDetail generalServiceDetail) + { + _generalServices.Add(generalServiceDetail); + } + + public static void Remove(int index) + { + _generalServices.RemoveAt(index); + } + + public static GeneralServiceDetail Get(int clientId) + { + return _generalServices.First(item => item.ClientId == clientId); + } + } +}
\ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/Types/GeneralServiceDetail.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/Types/GeneralServiceDetail.cs new file mode 100644 index 00000000..3cf55345 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/GeneralService/Types/GeneralServiceDetail.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService +{ + class GeneralServiceDetail + { + public int ClientId; + public bool IsAnyInternetRequestAccepted; + } +}
\ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs new file mode 100644 index 00000000..e9712e92 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs @@ -0,0 +1,203 @@ +using Ryujinx.Common; +using Ryujinx.Common.Logging; +using Ryujinx.Common.Utilities; +using Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService; +using Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types; +using System; +using System.Net.NetworkInformation; +using System.Runtime.CompilerServices; + +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService +{ + class IGeneralService : DisposableIpcService + { + private GeneralServiceDetail _generalServiceDetail; + + private IPInterfaceProperties _targetPropertiesCache = null; + private UnicastIPAddressInformation _targetAddressInfoCache = null; + private string _cacheChosenInterface = null; + + public IGeneralService() + { + _generalServiceDetail = new GeneralServiceDetail + { + ClientId = GeneralServiceManager.Count, + IsAnyInternetRequestAccepted = true // NOTE: Why not accept any internet request? + }; + + NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(LocalInterfaceCacheHandler); + + GeneralServiceManager.Add(_generalServiceDetail); + } + + [CommandCmif(1)] + // GetClientId() -> buffer<nn::nifm::ClientId, 0x1a, 4> + public ResultCode GetClientId(ServiceCtx context) + { + ulong position = context.Request.RecvListBuff[0].Position; + + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(sizeof(int)); + + context.Memory.Write(position, _generalServiceDetail.ClientId); + + return ResultCode.Success; + } + + [CommandCmif(4)] + // CreateRequest(u32 version) -> object<nn::nifm::detail::IRequest> + public ResultCode CreateRequest(ServiceCtx context) + { + uint version = context.RequestData.ReadUInt32(); + + MakeObject(context, new IRequest(context.Device.System, version)); + + // Doesn't occur in our case. + // return ResultCode.ObjectIsNull; + + Logger.Stub?.PrintStub(LogClass.ServiceNifm, new { version }); + + return ResultCode.Success; + } + + [CommandCmif(5)] + // GetCurrentNetworkProfile() -> buffer<nn::nifm::detail::sf::NetworkProfileData, 0x1a, 0x17c> + public ResultCode GetCurrentNetworkProfile(ServiceCtx context) + { + ulong networkProfileDataPosition = context.Request.RecvListBuff[0].Position; + + (IPInterfaceProperties interfaceProperties, UnicastIPAddressInformation unicastAddress) = GetLocalInterface(context); + + if (interfaceProperties == null || unicastAddress == null) + { + return ResultCode.NoInternetConnection; + } + + Logger.Info?.Print(LogClass.ServiceNifm, $"Console's local IP is \"{unicastAddress.Address}\"."); + + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Unsafe.SizeOf<NetworkProfileData>()); + + NetworkProfileData networkProfile = new NetworkProfileData + { + Uuid = UInt128Utils.CreateRandom() + }; + + networkProfile.IpSettingData.IpAddressSetting = new IpAddressSetting(interfaceProperties, unicastAddress); + networkProfile.IpSettingData.DnsSetting = new DnsSetting(interfaceProperties); + + "RyujinxNetwork"u8.CopyTo(networkProfile.Name.AsSpan()); + + context.Memory.Write(networkProfileDataPosition, networkProfile); + + return ResultCode.Success; + } + + [CommandCmif(12)] + // GetCurrentIpAddress() -> nn::nifm::IpV4Address + public ResultCode GetCurrentIpAddress(ServiceCtx context) + { + (_, UnicastIPAddressInformation unicastAddress) = GetLocalInterface(context); + + if (unicastAddress == null) + { + return ResultCode.NoInternetConnection; + } + + context.ResponseData.WriteStruct(new IpV4Address(unicastAddress.Address)); + + Logger.Info?.Print(LogClass.ServiceNifm, $"Console's local IP is \"{unicastAddress.Address}\"."); + + return ResultCode.Success; + } + + [CommandCmif(15)] + // GetCurrentIpConfigInfo() -> (nn::nifm::IpAddressSetting, nn::nifm::DnsSetting) + public ResultCode GetCurrentIpConfigInfo(ServiceCtx context) + { + (IPInterfaceProperties interfaceProperties, UnicastIPAddressInformation unicastAddress) = GetLocalInterface(context); + + if (interfaceProperties == null || unicastAddress == null) + { + return ResultCode.NoInternetConnection; + } + + Logger.Info?.Print(LogClass.ServiceNifm, $"Console's local IP is \"{unicastAddress.Address}\"."); + + context.ResponseData.WriteStruct(new IpAddressSetting(interfaceProperties, unicastAddress)); + context.ResponseData.WriteStruct(new DnsSetting(interfaceProperties)); + + return ResultCode.Success; + } + + [CommandCmif(18)] + // GetInternetConnectionStatus() -> nn::nifm::detail::sf::InternetConnectionStatus + public ResultCode GetInternetConnectionStatus(ServiceCtx context) + { + if (!NetworkInterface.GetIsNetworkAvailable()) + { + return ResultCode.NoInternetConnection; + } + + InternetConnectionStatus internetConnectionStatus = new InternetConnectionStatus + { + Type = InternetConnectionType.WiFi, + WifiStrength = 3, + State = InternetConnectionState.Connected, + }; + + context.ResponseData.WriteStruct(internetConnectionStatus); + + return ResultCode.Success; + } + + [CommandCmif(21)] + // IsAnyInternetRequestAccepted(buffer<nn::nifm::ClientId, 0x19, 4>) -> bool + public ResultCode IsAnyInternetRequestAccepted(ServiceCtx context) + { + ulong position = context.Request.PtrBuff[0].Position; + ulong size = context.Request.PtrBuff[0].Size; + + int clientId = context.Memory.Read<int>(position); + + context.ResponseData.Write(GeneralServiceManager.Get(clientId).IsAnyInternetRequestAccepted); + + return ResultCode.Success; + } + + private (IPInterfaceProperties, UnicastIPAddressInformation) GetLocalInterface(ServiceCtx context) + { + if (!NetworkInterface.GetIsNetworkAvailable()) + { + return (null, null); + } + + string chosenInterface = context.Device.Configuration.MultiplayerLanInterfaceId; + + if (_targetPropertiesCache == null || _targetAddressInfoCache == null || _cacheChosenInterface != chosenInterface) + { + _cacheChosenInterface = chosenInterface; + + (_targetPropertiesCache, _targetAddressInfoCache) = NetworkHelpers.GetLocalInterface(chosenInterface); + } + + return (_targetPropertiesCache, _targetAddressInfoCache); + } + + private void LocalInterfaceCacheHandler(object sender, EventArgs e) + { + Logger.Info?.Print(LogClass.ServiceNifm, $"NetworkAddress changed, invalidating cached data."); + + _targetPropertiesCache = null; + _targetAddressInfoCache = null; + } + + protected override void Dispose(bool isDisposing) + { + if (isDisposing) + { + NetworkChange.NetworkAddressChanged -= LocalInterfaceCacheHandler; + + GeneralServiceManager.Remove(_generalServiceDetail.ClientId); + } + } + } +}
\ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs new file mode 100644 index 00000000..87aad30b --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs @@ -0,0 +1,142 @@ +using Ryujinx.Common.Logging; +using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.Horizon.Common; +using System; + +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService +{ + class IRequest : IpcService + { + private enum RequestState + { + Error = 1, + OnHold = 2, + Available = 3 + } + + private KEvent _event0; + private KEvent _event1; + + private int _event0Handle; + private int _event1Handle; + + private uint _version; + + public IRequest(Horizon system, uint version) + { + _event0 = new KEvent(system.KernelContext); + _event1 = new KEvent(system.KernelContext); + + _version = version; + } + + [CommandCmif(0)] + // GetRequestState() -> u32 + public ResultCode GetRequestState(ServiceCtx context) + { + RequestState requestState = context.Device.Configuration.EnableInternetAccess + ? RequestState.Available + : RequestState.Error; + + context.ResponseData.Write((int)requestState); + + Logger.Stub?.PrintStub(LogClass.ServiceNifm); + + return ResultCode.Success; + } + + [CommandCmif(1)] + // GetResult() + public ResultCode GetResult(ServiceCtx context) + { + Logger.Stub?.PrintStub(LogClass.ServiceNifm); + + return GetResultImpl(); + } + + private ResultCode GetResultImpl() + { + return ResultCode.Success; + } + + [CommandCmif(2)] + // GetSystemEventReadableHandles() -> (handle<copy>, handle<copy>) + public ResultCode GetSystemEventReadableHandles(ServiceCtx context) + { + if (_event0Handle == 0) + { + if (context.Process.HandleTable.GenerateHandle(_event0.ReadableEvent, out _event0Handle) != Result.Success) + { + throw new InvalidOperationException("Out of handles!"); + } + } + + if (_event1Handle == 0) + { + if (context.Process.HandleTable.GenerateHandle(_event1.ReadableEvent, out _event1Handle) != Result.Success) + { + throw new InvalidOperationException("Out of handles!"); + } + } + + context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_event0Handle, _event1Handle); + + return ResultCode.Success; + } + + [CommandCmif(3)] + // Cancel() + public ResultCode Cancel(ServiceCtx context) + { + Logger.Stub?.PrintStub(LogClass.ServiceNifm); + + return ResultCode.Success; + } + + [CommandCmif(4)] + // Submit() + public ResultCode Submit(ServiceCtx context) + { + Logger.Stub?.PrintStub(LogClass.ServiceNifm); + + return ResultCode.Success; + } + + [CommandCmif(11)] + // SetConnectionConfirmationOption(i8) + public ResultCode SetConnectionConfirmationOption(ServiceCtx context) + { + Logger.Stub?.PrintStub(LogClass.ServiceNifm); + + return ResultCode.Success; + } + + [CommandCmif(21)] + // GetAppletInfo(u32) -> (u32, u32, u32, buffer<bytes, 6>) + public ResultCode GetAppletInfo(ServiceCtx context) + { + uint themeColor = context.RequestData.ReadUInt32(); + + Logger.Stub?.PrintStub(LogClass.ServiceNifm); + + ResultCode result = GetResultImpl(); + + if (result == ResultCode.Success || (ResultCode)((int)result & 0x3fffff) == ResultCode.Unknown112) + { + return ResultCode.Unknown180; + } + + // Returns appletId, libraryAppletMode, outSize and a buffer. + // Returned applet ids- (0x19, 0xf, 0xe) + // libraryAppletMode seems to be 0 for all applets supported. + + // TODO: check order + context.ResponseData.Write(0xe); // Use error applet as default for now + context.ResponseData.Write(0); // libraryAppletMode + context.ResponseData.Write(0); // outSize + + return ResultCode.Success; + } + } +}
\ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs new file mode 100644 index 00000000..374558ea --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs @@ -0,0 +1,31 @@ +using System; +using System.Net.NetworkInformation; +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +{ + [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 9)] + struct DnsSetting + { + [MarshalAs(UnmanagedType.U1)] + public bool IsDynamicDnsEnabled; + public IpV4Address PrimaryDns; + public IpV4Address SecondaryDns; + + public DnsSetting(IPInterfaceProperties interfaceProperties) + { + IsDynamicDnsEnabled = OperatingSystem.IsWindows() && interfaceProperties.IsDynamicDnsEnabled; + + if (interfaceProperties.DnsAddresses.Count == 0) + { + PrimaryDns = new IpV4Address(); + SecondaryDns = new IpV4Address(); + } + else + { + PrimaryDns = new IpV4Address(interfaceProperties.DnsAddresses[0]); + SecondaryDns = new IpV4Address(interfaceProperties.DnsAddresses[interfaceProperties.DnsAddresses.Count > 1 ? 1 : 0]); + } + } + } +}
\ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionState.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionState.cs new file mode 100644 index 00000000..dfb8f76c --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionState.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +{ + enum InternetConnectionState : byte + { + ConnectingType0 = 0, + ConnectingType1 = 1, + ConnectingType2 = 2, + ConnectingType3 = 3, + Connected = 4, + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionStatus.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionStatus.cs new file mode 100644 index 00000000..ff944eca --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionStatus.cs @@ -0,0 +1,12 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +{ + [StructLayout(LayoutKind.Sequential)] + struct InternetConnectionStatus + { + public InternetConnectionType Type; + public byte WifiStrength; + public InternetConnectionState State; + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionType.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionType.cs new file mode 100644 index 00000000..af2bcfa1 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionType.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +{ + enum InternetConnectionType : byte + { + Invalid = 0, + WiFi = 1, + Ethernet = 2, + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs new file mode 100644 index 00000000..59c1f6a7 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs @@ -0,0 +1,24 @@ +using System; +using System.Net.NetworkInformation; +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +{ + [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0xd)] + struct IpAddressSetting + { + [MarshalAs(UnmanagedType.U1)] + public bool IsDhcpEnabled; + public IpV4Address Address; + public IpV4Address IPv4Mask; + public IpV4Address GatewayAddress; + + public IpAddressSetting(IPInterfaceProperties interfaceProperties, UnicastIPAddressInformation unicastIPAddressInformation) + { + IsDhcpEnabled = OperatingSystem.IsMacOS() || interfaceProperties.DhcpServerAddresses.Count != 0; + Address = new IpV4Address(unicastIPAddressInformation.Address); + IPv4Mask = new IpV4Address(unicastIPAddressInformation.IPv4Mask); + GatewayAddress = (interfaceProperties.GatewayAddresses.Count == 0) ? new IpV4Address() : new IpV4Address(interfaceProperties.GatewayAddresses[0].Address); + } + } +}
\ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpSettingData.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpSettingData.cs new file mode 100644 index 00000000..8ffe824c --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpSettingData.cs @@ -0,0 +1,13 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +{ + [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0xc2)] + struct IpSettingData + { + public IpAddressSetting IpAddressSetting; + public DnsSetting DnsSetting; + public ProxySetting ProxySetting; + public short Mtu; + } +}
\ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpV4Address.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpV4Address.cs new file mode 100644 index 00000000..e5c2f39a --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpV4Address.cs @@ -0,0 +1,24 @@ +using System; +using System.Net; +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +{ + [StructLayout(LayoutKind.Sequential)] + struct IpV4Address + { + public uint Address; + + public IpV4Address(IPAddress address) + { + if (address == null) + { + Address = 0; + } + else + { + Address = BitConverter.ToUInt32(address.GetAddressBytes()); + } + } + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/NetworkProfileData.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/NetworkProfileData.cs new file mode 100644 index 00000000..e270c10a --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/NetworkProfileData.cs @@ -0,0 +1,17 @@ +using Ryujinx.Common.Memory; +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +{ + [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0x17C)] + struct NetworkProfileData + { + public IpSettingData IpSettingData; + public UInt128 Uuid; + public Array64<byte> Name; + public Array4<byte> Unknown; + public WirelessSettingData WirelessSettingData; + public byte Padding; + } +}
\ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/ProxySetting.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/ProxySetting.cs new file mode 100644 index 00000000..6e534fe1 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/ProxySetting.cs @@ -0,0 +1,27 @@ +using Ryujinx.Common.Memory; +using Ryujinx.Common.Utilities; +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +{ + [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0xaa)] + public struct ProxySetting + { + [MarshalAs(UnmanagedType.I1)] + public bool Enabled; + private byte _padding; + public short Port; + private NameStruct _name; + [MarshalAs(UnmanagedType.I1)] + public bool AutoAuthEnabled; + public Array32<byte> User; + public Array32<byte> Pass; + private byte _padding2; + + [StructLayout(LayoutKind.Sequential, Size = 0x64)] + private struct NameStruct { } + + public Span<byte> Name => SpanHelpers.AsSpan<NameStruct, byte>(ref _name); + } +}
\ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/WirelessSettingData.cs b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/WirelessSettingData.cs new file mode 100644 index 00000000..8aa122c7 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/WirelessSettingData.cs @@ -0,0 +1,15 @@ +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +{ + [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0x65)] + struct WirelessSettingData + { + public byte SsidLength; + public Array32<byte> Ssid; + public Array3<byte> Unknown; + public Array64<byte> Passphrase1; + public byte Passphrase2; + } +}
\ No newline at end of file |
