From 69e32e5bbc661627b9548bf414fff67f1756034d Mon Sep 17 00:00:00 2001 From: gdkchan Date: Fri, 6 Apr 2018 01:01:52 -0300 Subject: Rename services with the official interface names --- Ryujinx.Core/OsHle/Process.cs | 8 +- .../Services/Acc/IAccountServiceForApplication.cs | 47 ++ Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs | 47 -- .../OsHle/Services/Am/IApplicationProxyService.cs | 27 + Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs | 27 - Ryujinx.Core/OsHle/Services/Apm/IManager.cs | 27 + Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs | 27 - Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs | 63 -- .../OsHle/Services/Aud/IAudioDeviceService.cs | 63 ++ .../OsHle/Services/Aud/IAudioRendererManager.cs | 2 +- Ryujinx.Core/OsHle/Services/Bsd/BsdError.cs | 8 + Ryujinx.Core/OsHle/Services/Bsd/BsdSocket.cs | 18 + Ryujinx.Core/OsHle/Services/Bsd/IClient.cs | 452 ++++++++++++ Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs | 492 ------------- .../OsHle/Services/Friend/IServiceCreator.cs | 27 + .../OsHle/Services/Friend/ServiceFriend.cs | 27 - .../OsHle/Services/FspSrv/IFileSystemProxy.cs | 65 ++ .../OsHle/Services/FspSrv/ServiceFspSrv.cs | 65 -- Ryujinx.Core/OsHle/Services/Hid/IHidServer.cs | 180 +++++ Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs | 180 ----- Ryujinx.Core/OsHle/Services/Lm/ILogService.cs | 27 + Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs | 27 - Ryujinx.Core/OsHle/Services/Nifm/IStaticService.cs | 27 + Ryujinx.Core/OsHle/Services/Nifm/ServiceNifm.cs | 27 - .../OsHle/Services/Ns/IAddOnContentManager.cs | 37 + Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs | 37 - Ryujinx.Core/OsHle/Services/Nv/INvDrvServices.cs | 781 +++++++++++++++++++++ Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs | 781 --------------------- .../Pctl/IParentalControlServiceFactory.cs | 27 + Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs | 27 - .../OsHle/Services/Pl/ISharedFontManager.cs | 61 ++ Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs | 61 -- Ryujinx.Core/OsHle/Services/ServiceFactory.cs | 54 +- Ryujinx.Core/OsHle/Services/Set/ISettingsServer.cs | 81 +++ .../OsHle/Services/Set/ISystemSettingsServer.cs | 33 + Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs | 81 --- Ryujinx.Core/OsHle/Services/Set/ServiceSetSys.cs | 33 - Ryujinx.Core/OsHle/Services/Sfdnsres/IResolver.cs | 20 + .../OsHle/Services/Sfdnsres/ServiceSfdnsres.cs | 20 - Ryujinx.Core/OsHle/Services/Sm/IUserInterface.cs | 69 ++ Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs | 69 -- Ryujinx.Core/OsHle/Services/Ssl/ISslService.cs | 20 + Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs | 20 - Ryujinx.Core/OsHle/Services/Time/IStaticService.cs | 60 ++ Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs | 60 -- .../OsHle/Services/Vi/IApplicationRootService.cs | 29 + .../OsHle/Services/Vi/IManagerRootService.cs | 29 + .../OsHle/Services/Vi/ISystemRootService.cs | 29 + Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs | 14 +- Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs | 31 - 50 files changed, 2282 insertions(+), 2242 deletions(-) create mode 100644 Ryujinx.Core/OsHle/Services/Acc/IAccountServiceForApplication.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs create mode 100644 Ryujinx.Core/OsHle/Services/Am/IApplicationProxyService.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs create mode 100644 Ryujinx.Core/OsHle/Services/Apm/IManager.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs create mode 100644 Ryujinx.Core/OsHle/Services/Aud/IAudioDeviceService.cs create mode 100644 Ryujinx.Core/OsHle/Services/Bsd/BsdError.cs create mode 100644 Ryujinx.Core/OsHle/Services/Bsd/BsdSocket.cs create mode 100644 Ryujinx.Core/OsHle/Services/Bsd/IClient.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs create mode 100644 Ryujinx.Core/OsHle/Services/Friend/IServiceCreator.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs create mode 100644 Ryujinx.Core/OsHle/Services/FspSrv/IFileSystemProxy.cs delete mode 100644 Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs create mode 100644 Ryujinx.Core/OsHle/Services/Hid/IHidServer.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs create mode 100644 Ryujinx.Core/OsHle/Services/Lm/ILogService.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs create mode 100644 Ryujinx.Core/OsHle/Services/Nifm/IStaticService.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Nifm/ServiceNifm.cs create mode 100644 Ryujinx.Core/OsHle/Services/Ns/IAddOnContentManager.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs create mode 100644 Ryujinx.Core/OsHle/Services/Nv/INvDrvServices.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs create mode 100644 Ryujinx.Core/OsHle/Services/Pctl/IParentalControlServiceFactory.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs create mode 100644 Ryujinx.Core/OsHle/Services/Pl/ISharedFontManager.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs create mode 100644 Ryujinx.Core/OsHle/Services/Set/ISettingsServer.cs create mode 100644 Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Set/ServiceSetSys.cs create mode 100644 Ryujinx.Core/OsHle/Services/Sfdnsres/IResolver.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Sfdnsres/ServiceSfdnsres.cs create mode 100644 Ryujinx.Core/OsHle/Services/Sm/IUserInterface.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs create mode 100644 Ryujinx.Core/OsHle/Services/Ssl/ISslService.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs create mode 100644 Ryujinx.Core/OsHle/Services/Time/IStaticService.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs create mode 100644 Ryujinx.Core/OsHle/Services/Vi/IApplicationRootService.cs create mode 100644 Ryujinx.Core/OsHle/Services/Vi/IManagerRootService.cs create mode 100644 Ryujinx.Core/OsHle/Services/Vi/ISystemRootService.cs delete mode 100644 Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs diff --git a/Ryujinx.Core/OsHle/Process.cs b/Ryujinx.Core/OsHle/Process.cs index cda921be..0d1342e7 100644 --- a/Ryujinx.Core/OsHle/Process.cs +++ b/Ryujinx.Core/OsHle/Process.cs @@ -354,11 +354,11 @@ namespace Ryujinx.Core.OsHle } } - ServiceNvDrv.Fds.DeleteProcess(this); + INvDrvServices.Fds.DeleteProcess(this); - ServiceNvDrv.NvMaps .DeleteProcess(this); - ServiceNvDrv.NvMapsById.DeleteProcess(this); - ServiceNvDrv.NvMapsFb .DeleteProcess(this); + INvDrvServices.NvMaps .DeleteProcess(this); + INvDrvServices.NvMapsById.DeleteProcess(this); + INvDrvServices.NvMapsFb .DeleteProcess(this); Scheduler.Dispose(); diff --git a/Ryujinx.Core/OsHle/Services/Acc/IAccountServiceForApplication.cs b/Ryujinx.Core/OsHle/Services/Acc/IAccountServiceForApplication.cs new file mode 100644 index 00000000..b6b219ee --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Acc/IAccountServiceForApplication.cs @@ -0,0 +1,47 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Acc +{ + class IAccountServiceForApplication : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IAccountServiceForApplication() + { + m_Commands = new Dictionary() + { + { 3, ListOpenUsers }, + { 5, GetProfile }, + { 100, InitializeApplicationInfo }, + { 101, GetBaasAccountManagerForApplication } + }; + } + + public long ListOpenUsers(ServiceCtx Context) + { + return 0; + } + + public long GetProfile(ServiceCtx Context) + { + MakeObject(Context, new IProfile()); + + return 0; + } + + public long InitializeApplicationInfo(ServiceCtx Context) + { + return 0; + } + + public long GetBaasAccountManagerForApplication(ServiceCtx Context) + { + MakeObject(Context, new IManagerForApplication()); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs b/Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs deleted file mode 100644 index 59f4e47f..00000000 --- a/Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Acc -{ - class ServiceAcc : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceAcc() - { - m_Commands = new Dictionary() - { - { 3, ListOpenUsers }, - { 5, GetProfile }, - { 100, InitializeApplicationInfo }, - { 101, GetBaasAccountManagerForApplication } - }; - } - - public long ListOpenUsers(ServiceCtx Context) - { - return 0; - } - - public long GetProfile(ServiceCtx Context) - { - MakeObject(Context, new IProfile()); - - return 0; - } - - public long InitializeApplicationInfo(ServiceCtx Context) - { - return 0; - } - - public long GetBaasAccountManagerForApplication(ServiceCtx Context) - { - MakeObject(Context, new IManagerForApplication()); - - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Am/IApplicationProxyService.cs b/Ryujinx.Core/OsHle/Services/Am/IApplicationProxyService.cs new file mode 100644 index 00000000..6e33a1de --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Am/IApplicationProxyService.cs @@ -0,0 +1,27 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Am +{ + class IApplicationProxyService : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IApplicationProxyService() + { + m_Commands = new Dictionary() + { + { 0, OpenApplicationProxy } + }; + } + + public long OpenApplicationProxy(ServiceCtx Context) + { + MakeObject(Context, new IApplicationProxy()); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs b/Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs deleted file mode 100644 index 65cdad42..00000000 --- a/Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Am -{ - class ServiceAppletOE : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceAppletOE() - { - m_Commands = new Dictionary() - { - { 0, OpenApplicationProxy } - }; - } - - public long OpenApplicationProxy(ServiceCtx Context) - { - MakeObject(Context, new IApplicationProxy()); - - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Apm/IManager.cs b/Ryujinx.Core/OsHle/Services/Apm/IManager.cs new file mode 100644 index 00000000..7320328e --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Apm/IManager.cs @@ -0,0 +1,27 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Apm +{ + class IManager : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IManager() + { + m_Commands = new Dictionary() + { + { 0, OpenSession } + }; + } + + public long OpenSession(ServiceCtx Context) + { + MakeObject(Context, new ISession()); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs b/Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs deleted file mode 100644 index fcd64a2f..00000000 --- a/Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Apm -{ - class ServiceApm : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceApm() - { - m_Commands = new Dictionary() - { - { 0, OpenSession } - }; - } - - public long OpenSession(ServiceCtx Context) - { - MakeObject(Context, new ISession()); - - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs deleted file mode 100644 index 546c9eba..00000000 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs +++ /dev/null @@ -1,63 +0,0 @@ -using ChocolArm64.Memory; -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; -using System.Text; - -namespace Ryujinx.Core.OsHle.Services.Aud -{ - class IAudioDevice : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public IAudioDevice() - { - m_Commands = new Dictionary() - { - { 0, ListAudioDeviceName }, - { 1, SetAudioDeviceOutputVolume }, - }; - } - - public long ListAudioDeviceName(ServiceCtx Context) - { - string[] Names = new string[] { "FIXME" }; - - Context.ResponseData.Write(Names.Length); - - long Position = Context.Request.ReceiveBuff[0].Position; - long Size = Context.Request.ReceiveBuff[0].Size; - - long BasePosition = Position; - - foreach (string Name in Names) - { - byte[] Buffer = Encoding.ASCII.GetBytes(Name + '\0'); - - if ((Position - BasePosition) + Buffer.Length > Size) - { - break; - } - - AMemoryHelper.WriteBytes(Context.Memory, Position, Buffer); - - Position += Buffer.Length; - } - - return 0; - } - - public long SetAudioDeviceOutputVolume(ServiceCtx Context) - { - float Volume = Context.RequestData.ReadSingle(); - - long Position = Context.Request.SendBuff[0].Position; - long Size = Context.Request.SendBuff[0].Size; - - string Name = AMemoryHelper.ReadAsciiString(Context.Memory, Position, Size); - - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioDeviceService.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioDeviceService.cs new file mode 100644 index 00000000..65588192 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioDeviceService.cs @@ -0,0 +1,63 @@ +using ChocolArm64.Memory; +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; +using System.Text; + +namespace Ryujinx.Core.OsHle.Services.Aud +{ + class IAudioDeviceService : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IAudioDeviceService() + { + m_Commands = new Dictionary() + { + { 0, ListAudioDeviceName }, + { 1, SetAudioDeviceOutputVolume }, + }; + } + + public long ListAudioDeviceName(ServiceCtx Context) + { + string[] Names = new string[] { "FIXME" }; + + Context.ResponseData.Write(Names.Length); + + long Position = Context.Request.ReceiveBuff[0].Position; + long Size = Context.Request.ReceiveBuff[0].Size; + + long BasePosition = Position; + + foreach (string Name in Names) + { + byte[] Buffer = Encoding.ASCII.GetBytes(Name + '\0'); + + if ((Position - BasePosition) + Buffer.Length > Size) + { + break; + } + + AMemoryHelper.WriteBytes(Context.Memory, Position, Buffer); + + Position += Buffer.Length; + } + + return 0; + } + + public long SetAudioDeviceOutputVolume(ServiceCtx Context) + { + float Volume = Context.RequestData.ReadSingle(); + + long Position = Context.Request.SendBuff[0].Position; + long Size = Context.Request.SendBuff[0].Size; + + string Name = AMemoryHelper.ReadAsciiString(Context.Memory, Position, Size); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioRendererManager.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioRendererManager.cs index fcf084a9..07082da7 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioRendererManager.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioRendererManager.cs @@ -51,7 +51,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud { long UserId = Context.RequestData.ReadInt64(); - MakeObject(Context, new IAudioDevice()); + MakeObject(Context, new IAudioDeviceService()); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Bsd/BsdError.cs b/Ryujinx.Core/OsHle/Services/Bsd/BsdError.cs new file mode 100644 index 00000000..a1ac0433 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Bsd/BsdError.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Core.OsHle.Services.Bsd +{ + //bsd_errno == (SocketException.ErrorCode - 10000) + public enum BsdError + { + Timeout = 60 + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Bsd/BsdSocket.cs b/Ryujinx.Core/OsHle/Services/Bsd/BsdSocket.cs new file mode 100644 index 00000000..592b07d9 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Bsd/BsdSocket.cs @@ -0,0 +1,18 @@ +using System.Net; +using System.Net.Sockets; + +namespace Ryujinx.Core.OsHle.Services.Bsd +{ + class BsdSocket + { + public int Family; + public int Type; + public int Protocol; + + public IPAddress IpAddress; + + public IPEndPoint RemoteEP; + + public Socket Handle; + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Bsd/IClient.cs b/Ryujinx.Core/OsHle/Services/Bsd/IClient.cs new file mode 100644 index 00000000..cc497026 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Bsd/IClient.cs @@ -0,0 +1,452 @@ +using ChocolArm64.Memory; +using Ryujinx.Core.OsHle.Ipc; +using Ryujinx.Core.OsHle.Utilities; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Threading.Tasks; + +namespace Ryujinx.Core.OsHle.Services.Bsd +{ + class IClient : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + private List Sockets = new List(); + + public IClient() + { + m_Commands = new Dictionary() + { + { 0, Initialize }, + { 1, StartMonitoring }, + { 2, Socket }, + { 6, Poll }, + { 8, Recv }, + { 10, Send }, + { 11, SendTo }, + { 12, Accept }, + { 13, Bind }, + { 14, Connect }, + { 18, Listen }, + { 21, SetSockOpt }, + { 26, Close } + }; + } + + //(u32, u32, u32, u32, u32, u32, u32, u32, u64 pid, u64 transferMemorySize, pid, KObject) -> u32 bsd_errno + public long Initialize(ServiceCtx Context) + { + /* + typedef struct { + u32 version; // Observed 1 on 2.0 LibAppletWeb, 2 on 3.0. + u32 tcp_tx_buf_size; // Size of the TCP transfer (send) buffer (initial or fixed). + u32 tcp_rx_buf_size; // Size of the TCP recieve buffer (initial or fixed). + u32 tcp_tx_buf_max_size; // Maximum size of the TCP transfer (send) buffer. If it is 0, the size of the buffer is fixed to its initial value. + u32 tcp_rx_buf_max_size; // Maximum size of the TCP receive buffer. If it is 0, the size of the buffer is fixed to its initial value. + u32 udp_tx_buf_size; // Size of the UDP transfer (send) buffer (typically 0x2400 bytes). + u32 udp_rx_buf_size; // Size of the UDP receive buffer (typically 0xA500 bytes). + u32 sb_efficiency; // Number of buffers for each socket (standard values range from 1 to 8). + } BsdBufferConfig; + */ + + Context.ResponseData.Write(0); + + //Todo: Stub + + return 0; + } + + //(u64, pid) + public long StartMonitoring(ServiceCtx Context) + { + //Todo: Stub + + return 0; + } + + //(u32 domain, u32 type, u32 protocol) -> (i32 ret, u32 bsd_errno) + public long Socket(ServiceCtx Context) + { + BsdSocket NewBsdSocket = new BsdSocket + { + Family = Context.RequestData.ReadInt32(), + Type = Context.RequestData.ReadInt32(), + Protocol = Context.RequestData.ReadInt32() + }; + + Sockets.Add(NewBsdSocket); + + NewBsdSocket.Handle = new Socket((AddressFamily)NewBsdSocket.Family, + (SocketType)NewBsdSocket.Type, + (ProtocolType)NewBsdSocket.Protocol); + + Context.ResponseData.Write(Sockets.Count - 1); + Context.ResponseData.Write(0); + + return 0; + } + + //(u32, u32, buffer) -> (i32 ret, u32 bsd_errno, buffer) + public long Poll(ServiceCtx Context) + { + int PollCount = Context.RequestData.ReadInt32(); + int TimeOut = Context.RequestData.ReadInt32(); + + //https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/poll.h + //https://msdn.microsoft.com/fr-fr/library/system.net.sockets.socket.poll(v=vs.110).aspx + //https://github.com/switchbrew/libnx/blob/e0457c4534b3c37426d83e1a620f82cb28c3b528/nx/source/services/bsd.c#L343 + //https://github.com/TuxSH/ftpd/blob/switch_pr/source/ftp.c#L1634 + //https://linux.die.net/man/2/poll + + byte[] SentBuffer = AMemoryHelper.ReadBytes(Context.Memory, + Context.Request.SendBuff[0].Position, + Context.Request.SendBuff[0].Size); + + int SocketId = Get32(SentBuffer, 0); + int RequestedEvents = Get16(SentBuffer, 4); + int ReturnedEvents = Get16(SentBuffer, 6); + + //Todo: Stub - Need to implemented the Type-22 buffer. + + Context.ResponseData.Write(1); + Context.ResponseData.Write(0); + + return 0; + } + + //(u32 socket, u32 flags) -> (i32 ret, u32 bsd_errno, buffer message) + public long Recv(ServiceCtx Context) + { + int SocketId = Context.RequestData.ReadInt32(); + int SocketFlags = Context.RequestData.ReadInt32(); + + byte[] ReceivedBuffer = new byte[Context.Request.ReceiveBuff[0].Size]; + + try + { + int BytesRead = Sockets[SocketId].Handle.Receive(ReceivedBuffer); + + //Logging.Debug("Received Buffer:" + Environment.NewLine + Logging.HexDump(ReceivedBuffer)); + + AMemoryHelper.WriteBytes(Context.Memory, Context.Request.ReceiveBuff[0].Position, ReceivedBuffer); + + Context.ResponseData.Write(BytesRead); + Context.ResponseData.Write(0); + } + catch (SocketException Ex) + { + Context.ResponseData.Write(-1); + Context.ResponseData.Write(Ex.ErrorCode - 10000); + } + + return 0; + } + + //(u32 socket, u32 flags, buffer) -> (i32 ret, u32 bsd_errno) + public long Send(ServiceCtx Context) + { + int SocketId = Context.RequestData.ReadInt32(); + int SocketFlags = Context.RequestData.ReadInt32(); + + byte[] SentBuffer = AMemoryHelper.ReadBytes(Context.Memory, + Context.Request.SendBuff[0].Position, + Context.Request.SendBuff[0].Size); + + try + { + //Logging.Debug("Sent Buffer:" + Environment.NewLine + Logging.HexDump(SentBuffer)); + + int BytesSent = Sockets[SocketId].Handle.Send(SentBuffer); + + Context.ResponseData.Write(BytesSent); + Context.ResponseData.Write(0); + } + catch (SocketException Ex) + { + Context.ResponseData.Write(-1); + Context.ResponseData.Write(Ex.ErrorCode - 10000); + } + + return 0; + } + + //(u32 socket, u32 flags, buffer, buffer) -> (i32 ret, u32 bsd_errno) + public long SendTo(ServiceCtx Context) + { + int SocketId = Context.RequestData.ReadInt32(); + int SocketFlags = Context.RequestData.ReadInt32(); + + byte[] SentBuffer = AMemoryHelper.ReadBytes(Context.Memory, + Context.Request.SendBuff[0].Position, + Context.Request.SendBuff[0].Size); + + byte[] AddressBuffer = AMemoryHelper.ReadBytes(Context.Memory, + Context.Request.SendBuff[1].Position, + Context.Request.SendBuff[1].Size); + + if (!Sockets[SocketId].Handle.Connected) + { + try + { + ParseAddrBuffer(SocketId, AddressBuffer); + + Sockets[SocketId].Handle.Connect(Sockets[SocketId].RemoteEP); + } + catch (SocketException Ex) + { + Context.ResponseData.Write(-1); + Context.ResponseData.Write(Ex.ErrorCode - 10000); + } + } + + try + { + //Logging.Debug("Sent Buffer:" + Environment.NewLine + Logging.HexDump(SentBuffer)); + + int BytesSent = Sockets[SocketId].Handle.Send(SentBuffer); + + Context.ResponseData.Write(BytesSent); + Context.ResponseData.Write(0); + } + catch (SocketException Ex) + { + Context.ResponseData.Write(-1); + Context.ResponseData.Write(Ex.ErrorCode - 10000); + } + + return 0; + } + + //(u32 socket) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer addr) + public long Accept(ServiceCtx Context) + { + int SocketId = Context.RequestData.ReadInt32(); + + long AddrBufferPtr = Context.Request.ReceiveBuff[0].Position; + + Socket HandleAccept = null; + + Task TimeOut = Task.Factory.StartNew(() => + { + try + { + HandleAccept = Sockets[SocketId].Handle.Accept(); + } + catch (SocketException Ex) + { + Context.ResponseData.Write(-1); + Context.ResponseData.Write(Ex.ErrorCode - 10000); + } + }); + + TimeOut.Wait(10000); + + if (HandleAccept != null) + { + BsdSocket NewBsdSocket = new BsdSocket + { + IpAddress = ((IPEndPoint)Sockets[SocketId].Handle.LocalEndPoint).Address, + RemoteEP = ((IPEndPoint)Sockets[SocketId].Handle.LocalEndPoint), + Handle = HandleAccept + }; + + Sockets.Add(NewBsdSocket); + + using (MemoryStream MS = new MemoryStream()) + { + BinaryWriter Writer = new BinaryWriter(MS); + + Writer.Write((byte)0); + + Writer.Write((byte)NewBsdSocket.Handle.AddressFamily); + + Writer.Write((short)((IPEndPoint)NewBsdSocket.Handle.LocalEndPoint).Port); + + byte[] IpAdress = NewBsdSocket.IpAddress.GetAddressBytes(); + + AMemoryHelper.WriteBytes(Context.Memory, AddrBufferPtr, IpAdress); + + Context.ResponseData.Write(Sockets.Count - 1); + Context.ResponseData.Write(0); + Context.ResponseData.Write(IpAdress.Length); + } + } + else + { + Context.ResponseData.Write(-1); + Context.ResponseData.Write((int)BsdError.Timeout); + } + + return 0; + } + + //(u32 socket, buffer) -> (i32 ret, u32 bsd_errno) + public long Bind(ServiceCtx Context) + { + int SocketId = Context.RequestData.ReadInt32(); + + byte[] AddressBuffer = AMemoryHelper.ReadBytes(Context.Memory, + Context.Request.SendBuff[0].Position, + Context.Request.SendBuff[0].Size); + + try + { + ParseAddrBuffer(SocketId, AddressBuffer); + + Context.ResponseData.Write(0); + Context.ResponseData.Write(0); + } + catch (SocketException Ex) + { + Context.ResponseData.Write(-1); + Context.ResponseData.Write(Ex.ErrorCode - 10000); + } + + return 0; + } + + //(u32 socket, buffer) -> (i32 ret, u32 bsd_errno) + public long Connect(ServiceCtx Context) + { + int SocketId = Context.RequestData.ReadInt32(); + + byte[] AddressBuffer = AMemoryHelper.ReadBytes(Context.Memory, + Context.Request.SendBuff[0].Position, + Context.Request.SendBuff[0].Size); + + try + { + ParseAddrBuffer(SocketId, AddressBuffer); + + Sockets[SocketId].Handle.Connect(Sockets[SocketId].RemoteEP); + + Context.ResponseData.Write(0); + Context.ResponseData.Write(0); + } + catch (SocketException Ex) + { + Context.ResponseData.Write(-1); + Context.ResponseData.Write(Ex.ErrorCode - 10000); + } + + return 0; + } + + //(u32 socket, u32 backlog) -> (i32 ret, u32 bsd_errno) + public long Listen(ServiceCtx Context) + { + int SocketId = Context.RequestData.ReadInt32(); + int BackLog = Context.RequestData.ReadInt32(); + + try + { + Sockets[SocketId].Handle.Bind(Sockets[SocketId].RemoteEP); + Sockets[SocketId].Handle.Listen(BackLog); + + Context.ResponseData.Write(0); + Context.ResponseData.Write(0); + } + catch (SocketException Ex) + { + Context.ResponseData.Write(-1); + Context.ResponseData.Write(Ex.ErrorCode - 10000); + } + + return 0; + } + + //(u32 socket, u32 level, u32 option_name, buffer) -> (i32 ret, u32 bsd_errno) + public long SetSockOpt(ServiceCtx Context) + { + int SocketId = Context.RequestData.ReadInt32(); + + SocketOptionLevel SocketLevel = (SocketOptionLevel)Context.RequestData.ReadInt32(); + SocketOptionName SocketOptionName = (SocketOptionName)Context.RequestData.ReadInt32(); + + byte[] SocketOptionValue = AMemoryHelper.ReadBytes(Context.Memory, + Context.Request.PtrBuff[0].Position, + Context.Request.PtrBuff[0].Size); + + int OptionValue = Get32(SocketOptionValue, 0); + + try + { + Sockets[SocketId].Handle.SetSocketOption(SocketLevel, SocketOptionName, OptionValue); + + Context.ResponseData.Write(0); + Context.ResponseData.Write(0); + } + catch (SocketException Ex) + { + Context.ResponseData.Write(-1); + Context.ResponseData.Write(Ex.ErrorCode - 10000); + } + + return 0; + } + + //(u32 socket) -> (i32 ret, u32 bsd_errno) + public long Close(ServiceCtx Context) + { + int SocketId = Context.RequestData.ReadInt32(); + + try + { + Sockets[SocketId].Handle.Close(); + Sockets[SocketId] = null; + + Context.ResponseData.Write(0); + Context.ResponseData.Write(0); + } + catch (SocketException Ex) + { + Context.ResponseData.Write(-1); + Context.ResponseData.Write(Ex.ErrorCode - 10000); + } + + return 0; + } + + public void ParseAddrBuffer(int SocketId, byte[] AddrBuffer) + { + using (MemoryStream MS = new MemoryStream(AddrBuffer)) + { + BinaryReader Reader = new BinaryReader(MS); + + int Size = Reader.ReadByte(); + int Family = Reader.ReadByte(); + int Port = EndianSwap.Swap16(Reader.ReadInt16()); + + string IpAddress = Reader.ReadByte().ToString() + "." + + Reader.ReadByte().ToString() + "." + + Reader.ReadByte().ToString() + "." + + Reader.ReadByte().ToString(); + + Logging.Debug($"Try to connect to {IpAddress}:{Port}"); + + Sockets[SocketId].IpAddress = IPAddress.Parse(IpAddress); + Sockets[SocketId].RemoteEP = new IPEndPoint(Sockets[SocketId].IpAddress, Port); + } + } + + private int Get16(byte[] Data, int Address) + { + return + Data[Address + 0] << 0 | + Data[Address + 1] << 8; + } + + private int Get32(byte[] Data, int Address) + { + return + Data[Address + 0] << 0 | + Data[Address + 1] << 8 | + Data[Address + 2] << 16 | + Data[Address + 3] << 24; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs b/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs deleted file mode 100644 index 94d3370d..00000000 --- a/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs +++ /dev/null @@ -1,492 +0,0 @@ -using ChocolArm64.Memory; -using Ryujinx.Core.OsHle.Ipc; -using Ryujinx.Core.OsHle.Utilities; -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Net.Sockets; -using System.Threading.Tasks; - -namespace Ryujinx.Core.OsHle.Services.Bsd -{ - - //bsd_errno == (SocketException.ErrorCode - 10000) - //https://github.com/freebsd/freebsd/blob/master/sys/sys/errno.h - public enum BsdError - { - ENOTSOCK = 38, /* Socket operation on non-socket */ - EDESTADDRREQ = 39, /* Destination address required */ - EMSGSIZE = 40, /* Message too long */ - EPROTOTYPE = 41, /* Protocol wrong type for socket */ - ENOPROTOOPT = 42, /* Protocol not available */ - EPROTONOSUPPORT = 43, /* Protocol not supported */ - ESOCKTNOSUPPORT = 44, /* Socket type not supported */ - EOPNOTSUPP = 45, /* Operation not supported */ - EPFNOSUPPORT = 46, /* Protocol family not supported */ - EAFNOSUPPORT = 47, /* Address family not supported by protocol family */ - EADDRINUSE = 48, /* Address already in use */ - EADDRNOTAVAIL = 49, /* Can't assign requested address */ - ENETDOWN = 50, /* Network is down */ - ENETUNREACH = 51, /* Network is unreachable */ - ENETRESET = 52, /* Network dropped connection on reset */ - ECONNABORTED = 53, /* Software caused connection abort */ - ECONNRESET = 54, /* Connection reset by peer */ - ENOBUFS = 55, /* No buffer space available */ - EISCONN = 56, /* Socket is already connected */ - ENOTCONN = 57, /* Socket is not connected */ - ESHUTDOWN = 58, /* Can't send after socket shutdown */ - ETOOMANYREFS = 59, /* Too many references: can't splice */ - ETIMEDOUT = 60, /* Operation timed out */ - ECONNREFUSED = 61 /* Connection refused */ - } - - class SocketBsd - { - public int Family; - public int Type; - public int Protocol; - public IPAddress IpAddress; - public IPEndPoint RemoteEP; - public Socket Handle; - } - - class ServiceBsd : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - private List Sockets = new List(); - - public ServiceBsd() - { - m_Commands = new Dictionary() - { - { 0, Initialize }, - { 1, StartMonitoring }, - { 2, Socket }, - { 6, Poll }, - { 8, Recv }, - { 10, Send }, - { 11, SendTo }, - { 12, Accept }, - { 13, Bind }, - { 14, Connect }, - { 18, Listen }, - { 21, SetSockOpt }, - { 26, Close } - }; - } - - //(u32, u32, u32, u32, u32, u32, u32, u32, u64 pid, u64 transferMemorySize, pid, KObject) -> u32 bsd_errno - public long Initialize(ServiceCtx Context) - { - /* - typedef struct { - u32 version; // Observed 1 on 2.0 LibAppletWeb, 2 on 3.0. - u32 tcp_tx_buf_size; // Size of the TCP transfer (send) buffer (initial or fixed). - u32 tcp_rx_buf_size; // Size of the TCP recieve buffer (initial or fixed). - u32 tcp_tx_buf_max_size; // Maximum size of the TCP transfer (send) buffer. If it is 0, the size of the buffer is fixed to its initial value. - u32 tcp_rx_buf_max_size; // Maximum size of the TCP receive buffer. If it is 0, the size of the buffer is fixed to its initial value. - u32 udp_tx_buf_size; // Size of the UDP transfer (send) buffer (typically 0x2400 bytes). - u32 udp_rx_buf_size; // Size of the UDP receive buffer (typically 0xA500 bytes). - u32 sb_efficiency; // Number of buffers for each socket (standard values range from 1 to 8). - } BsdBufferConfig; - */ - - long Pid = Context.RequestData.ReadInt64(); - long TransferMemorySize = Context.RequestData.ReadInt64(); - - // Two other args are unknown! - - Context.ResponseData.Write(0); - - //Todo: Stub - - return 0; - } - - //(u64, pid) - public long StartMonitoring(ServiceCtx Context) - { - //Todo: Stub - - return 0; - } - - //(u32 domain, u32 type, u32 protocol) -> (i32 ret, u32 bsd_errno) - public long Socket(ServiceCtx Context) - { - SocketBsd NewBSDSocket = new SocketBsd - { - Family = Context.RequestData.ReadInt32(), - Type = Context.RequestData.ReadInt32(), - Protocol = Context.RequestData.ReadInt32() - }; - - Sockets.Add(NewBSDSocket); - - Sockets[Sockets.Count - 1].Handle = new Socket((AddressFamily)Sockets[Sockets.Count - 1].Family, - (SocketType)Sockets[Sockets.Count - 1].Type, - (ProtocolType)Sockets[Sockets.Count - 1].Protocol); - - Context.ResponseData.Write(Sockets.Count - 1); - Context.ResponseData.Write(0); - - return 0; - } - - //(u32, u32, buffer) -> (i32 ret, u32 bsd_errno, buffer) - public long Poll(ServiceCtx Context) - { - int PollCount = Context.RequestData.ReadInt32(); - int TimeOut = Context.RequestData.ReadInt32(); - - //https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/poll.h - //https://msdn.microsoft.com/fr-fr/library/system.net.sockets.socket.poll(v=vs.110).aspx - //https://github.com/switchbrew/libnx/blob/e0457c4534b3c37426d83e1a620f82cb28c3b528/nx/source/services/bsd.c#L343 - //https://github.com/TuxSH/ftpd/blob/switch_pr/source/ftp.c#L1634 - //https://linux.die.net/man/2/poll - - byte[] SentBuffer = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.SendBuff[0].Position, - Context.Request.SendBuff[0].Size); - int SocketId = Get32(SentBuffer, 0); - short RequestedEvents = (short)Get16(SentBuffer, 4); - short ReturnedEvents = (short)Get16(SentBuffer, 6); - - //Todo: Stub - Need to implemented the Type-22 buffer. - - Context.ResponseData.Write(1); - Context.ResponseData.Write(0); - - return 0; - } - - //(u32 socket, u32 flags) -> (i32 ret, u32 bsd_errno, buffer message) - public long Recv(ServiceCtx Context) - { - try - { - int SocketId = Context.RequestData.ReadInt32(); - int SocketFlags = Context.RequestData.ReadInt32(); - byte[] ReceivedBuffer = new byte[Context.Request.ReceiveBuff[0].Size]; - int ReadedBytes = Sockets[SocketId].Handle.Receive(ReceivedBuffer); - - //Logging.Debug("Received Buffer:" + Environment.NewLine + Logging.HexDump(ReceivedBuffer)); - - AMemoryHelper.WriteBytes(Context.Memory, Context.Request.ReceiveBuff[0].Position, ReceivedBuffer); - - Context.ResponseData.Write(ReadedBytes); - Context.ResponseData.Write(0); - } - catch (SocketException Ex) - { - Context.ResponseData.Write(-1); - Context.ResponseData.Write(Ex.ErrorCode - 10000); - } - - return 0; - } - - //(u32 socket, u32 flags, buffer) -> (i32 ret, u32 bsd_errno) - public long Send(ServiceCtx Context) - { - int SocketId = Context.RequestData.ReadInt32(); - int SocketFlags = Context.RequestData.ReadInt32(); - byte[] SentBuffer = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.SendBuff[0].Position, - Context.Request.SendBuff[0].Size); - - try - { - //Logging.Debug("Sended Buffer:" + Environment.NewLine + Logging.HexDump(SendedBuffer)); - - int BytesSent = Sockets[SocketId].Handle.Send(SentBuffer); - - Context.ResponseData.Write(BytesSent); - Context.ResponseData.Write(0); - } - catch (SocketException Ex) - { - Context.ResponseData.Write(-1); - Context.ResponseData.Write(Ex.ErrorCode - 10000); - } - - return 0; - } - - //(u32 socket, u32 flags, buffer, buffer) -> (i32 ret, u32 bsd_errno) - public long SendTo(ServiceCtx Context) - { - int SocketId = Context.RequestData.ReadInt32(); - int SocketFlags = Context.RequestData.ReadInt32(); - byte[] SentBuffer = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.SendBuff[0].Position, - Context.Request.SendBuff[0].Size); - byte[] AddressBuffer = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.SendBuff[1].Position, - Context.Request.SendBuff[1].Size); - - if (!Sockets[SocketId].Handle.Connected) - { - try - { - ParseAddrBuffer(SocketId, AddressBuffer); - - Sockets[SocketId].Handle.Connect(Sockets[SocketId].RemoteEP); - } - catch (SocketException Ex) - { - Context.ResponseData.Write(-1); - Context.ResponseData.Write(Ex.ErrorCode - 10000); - } - } - - try - { - //Logging.Debug("Sended Buffer:" + Environment.NewLine + Logging.HexDump(SendedBuffer)); - - int BytesSent = Sockets[SocketId].Handle.Send(SentBuffer); - - Context.ResponseData.Write(BytesSent); - Context.ResponseData.Write(0); - } - catch (SocketException Ex) - { - Context.ResponseData.Write(-1); - Context.ResponseData.Write(Ex.ErrorCode - 10000); - } - - return 0; - } - - //(u32 socket) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer addr) - public long Accept(ServiceCtx Context) - { - int SocketId = Context.RequestData.ReadInt32(); - long AddrBufferPtr = Context.Request.ReceiveBuff[0].Position; - - Socket HandleAccept = null; - - var TimeOut = Task.Factory.StartNew(() => - { - try - { - HandleAccept = Sockets[SocketId].Handle.Accept(); - } - catch (SocketException Ex) - { - Context.ResponseData.Write(-1); - Context.ResponseData.Write(Ex.ErrorCode - 10000); - } - }); - - TimeOut.Wait(10000); - - if (HandleAccept != null) - { - SocketBsd NewBSDSocket = new SocketBsd - { - IpAddress = ((IPEndPoint)Sockets[SocketId].Handle.LocalEndPoint).Address, - RemoteEP = ((IPEndPoint)Sockets[SocketId].Handle.LocalEndPoint), - Handle = HandleAccept - }; - - Sockets.Add(NewBSDSocket); - - using (MemoryStream MS = new MemoryStream()) - { - BinaryWriter Writer = new BinaryWriter(MS); - - Writer.Write((byte)0); - Writer.Write((byte)Sockets[Sockets.Count - 1].Handle.AddressFamily); - Writer.Write((Int16)((IPEndPoint)Sockets[Sockets.Count - 1].Handle.LocalEndPoint).Port); - - string[] IpAdress = Sockets[Sockets.Count - 1].IpAddress.ToString().Split('.'); - Writer.Write(byte.Parse(IpAdress[0])); - Writer.Write(byte.Parse(IpAdress[1])); - Writer.Write(byte.Parse(IpAdress[2])); - Writer.Write(byte.Parse(IpAdress[3])); - - AMemoryHelper.WriteBytes(Context.Memory, AddrBufferPtr, MS.ToArray()); - - Context.ResponseData.Write(Sockets.Count - 1); - Context.ResponseData.Write(0); - Context.ResponseData.Write(MS.Length); - } - } - else - { - Context.ResponseData.Write(-1); - Context.ResponseData.Write((int)BsdError.ETIMEDOUT); - } - - return 0; - } - - //(u32 socket, buffer) -> (i32 ret, u32 bsd_errno) - public long Bind(ServiceCtx Context) - { - int SocketId = Context.RequestData.ReadInt32(); - - byte[] AddressBuffer = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.SendBuff[0].Position, - Context.Request.SendBuff[0].Size); - - try - { - ParseAddrBuffer(SocketId, AddressBuffer); - - Context.ResponseData.Write(0); - Context.ResponseData.Write(0); - } - catch (SocketException Ex) - { - Context.ResponseData.Write(-1); - Context.ResponseData.Write(Ex.ErrorCode - 10000); - } - - return 0; - } - - //(u32 socket, buffer) -> (i32 ret, u32 bsd_errno) - public long Connect(ServiceCtx Context) - { - int SocketId = Context.RequestData.ReadInt32(); - - byte[] AddressBuffer = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.SendBuff[0].Position, - Context.Request.SendBuff[0].Size); - - try - { - ParseAddrBuffer(SocketId, AddressBuffer); - - Sockets[SocketId].Handle.Connect(Sockets[SocketId].RemoteEP); - - Context.ResponseData.Write(0); - Context.ResponseData.Write(0); - } - catch (SocketException Ex) - { - Context.ResponseData.Write(-1); - Context.ResponseData.Write(Ex.ErrorCode - 10000); - } - - return 0; - } - - //(u32 socket, u32 backlog) -> (i32 ret, u32 bsd_errno) - public long Listen(ServiceCtx Context) - { - int SocketId = Context.RequestData.ReadInt32(); - int BackLog = Context.RequestData.ReadInt32(); - - try - { - Sockets[SocketId].Handle.Bind(Sockets[SocketId].RemoteEP); - Sockets[SocketId].Handle.Listen(BackLog); - - Context.ResponseData.Write(0); - Context.ResponseData.Write(0); - } - catch (SocketException Ex) - { - Context.ResponseData.Write(-1); - Context.ResponseData.Write(Ex.ErrorCode - 10000); - } - - return 0; - } - - //(u32 socket, u32 level, u32 option_name, buffer) -> (i32 ret, u32 bsd_errno) - public long SetSockOpt(ServiceCtx Context) - { - int SocketId = Context.RequestData.ReadInt32(); - int SocketLevel = Context.RequestData.ReadInt32(); - int SocketOptionName = Context.RequestData.ReadInt32(); - - byte[] SocketOptionValue = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.PtrBuff[0].Position, - Context.Request.PtrBuff[0].Size); - - try - { - Sockets[SocketId].Handle.SetSocketOption((SocketOptionLevel)SocketLevel, - (SocketOptionName)SocketOptionName, - Get32(SocketOptionValue, 0)); - - Context.ResponseData.Write(0); - Context.ResponseData.Write(0); - } - catch (SocketException Ex) - { - Context.ResponseData.Write(-1); - Context.ResponseData.Write(Ex.ErrorCode - 10000); - } - - return 0; - } - - //(u32 socket) -> (i32 ret, u32 bsd_errno) - public long Close(ServiceCtx Context) - { - int SocketId = Context.RequestData.ReadInt32(); - - try - { - Sockets[SocketId].Handle.Close(); - Sockets[SocketId] = null; - - Context.ResponseData.Write(0); - Context.ResponseData.Write(0); - } - catch (SocketException Ex) - { - Context.ResponseData.Write(-1); - Context.ResponseData.Write(Ex.ErrorCode - 10000); - } - - return 0; - } - - public void ParseAddrBuffer(int SocketId, byte[] AddrBuffer) - { - using (MemoryStream MS = new MemoryStream(AddrBuffer)) - { - BinaryReader Reader = new BinaryReader(MS); - - int Size = Reader.ReadByte(); - int Family = Reader.ReadByte(); - int Port = EndianSwap.Swap16(Reader.ReadInt16()); - string IpAddress = Reader.ReadByte().ToString() + - "." + Reader.ReadByte().ToString() + - "." + Reader.ReadByte().ToString() + - "." + Reader.ReadByte().ToString(); - - Logging.Debug($"Try to connect to {IpAddress}:{Port}"); - - Sockets[SocketId].IpAddress = IPAddress.Parse(IpAddress); - Sockets[SocketId].RemoteEP = new IPEndPoint(Sockets[SocketId].IpAddress, Port); - } - } - - private int Get16(byte[] Data, int Address) - { - return - Data[Address + 0] << 0 | - Data[Address + 1] << 8; - } - - private int Get32(byte[] Data, int Address) - { - return - Data[Address + 0] << 0 | - Data[Address + 1] << 8 | - Data[Address + 2] << 16 | - Data[Address + 3] << 24; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Friend/IServiceCreator.cs b/Ryujinx.Core/OsHle/Services/Friend/IServiceCreator.cs new file mode 100644 index 00000000..2c66d965 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Friend/IServiceCreator.cs @@ -0,0 +1,27 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Friend +{ + class IServiceCreator : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IServiceCreator() + { + m_Commands = new Dictionary() + { + { 0, CreateFriendService } + }; + } + + public static long CreateFriendService(ServiceCtx Context) + { + MakeObject(Context, new IFriendService()); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs b/Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs deleted file mode 100644 index 1b87d22b..00000000 --- a/Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Friend -{ - class ServiceFriend : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceFriend() - { - m_Commands = new Dictionary() - { - { 0, CreateFriendService } - }; - } - - public static long CreateFriendService(ServiceCtx Context) - { - MakeObject(Context, new IFriendService()); - - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystemProxy.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystemProxy.cs new file mode 100644 index 00000000..3afee1a1 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystemProxy.cs @@ -0,0 +1,65 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.FspSrv +{ + class IFileSystemProxy : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IFileSystemProxy() + { + m_Commands = new Dictionary() + { + { 1, SetCurrentProcess }, + { 18, OpenSdCardFileSystem }, + { 51, OpenSaveDataFileSystem }, + { 200, OpenDataStorageByCurrentProcess }, + { 203, OpenPatchDataStorageByCurrentProcess }, + { 1005, GetGlobalAccessLogMode } + }; + } + + public long SetCurrentProcess(ServiceCtx Context) + { + return 0; + } + + public long OpenSdCardFileSystem(ServiceCtx Context) + { + MakeObject(Context, new IFileSystem(Context.Ns.VFs.GetSdCardPath())); + + return 0; + } + + public long OpenSaveDataFileSystem(ServiceCtx Context) + { + MakeObject(Context, new IFileSystem(Context.Ns.VFs.GetGameSavesPath())); + + return 0; + } + + public long OpenDataStorageByCurrentProcess(ServiceCtx Context) + { + MakeObject(Context, new IStorage(Context.Ns.VFs.RomFs)); + + return 0; + } + + public long OpenPatchDataStorageByCurrentProcess(ServiceCtx Context) + { + MakeObject(Context, new IStorage(Context.Ns.VFs.RomFs)); + + return 0; + } + + public long GetGlobalAccessLogMode(ServiceCtx Context) + { + Context.ResponseData.Write(0); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs b/Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs deleted file mode 100644 index 5f068668..00000000 --- a/Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.FspSrv -{ - class ServiceFspSrv : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceFspSrv() - { - m_Commands = new Dictionary() - { - { 1, SetCurrentProcess }, - { 18, OpenSdCardFileSystem }, - { 51, OpenSaveDataFileSystem }, - { 200, OpenDataStorageByCurrentProcess }, - { 203, OpenPatchDataStorageByCurrentProcess }, - { 1005, GetGlobalAccessLogMode } - }; - } - - public long SetCurrentProcess(ServiceCtx Context) - { - return 0; - } - - public long OpenSdCardFileSystem(ServiceCtx Context) - { - MakeObject(Context, new IFileSystem(Context.Ns.VFs.GetSdCardPath())); - - return 0; - } - - public long OpenSaveDataFileSystem(ServiceCtx Context) - { - MakeObject(Context, new IFileSystem(Context.Ns.VFs.GetGameSavesPath())); - - return 0; - } - - public long OpenDataStorageByCurrentProcess(ServiceCtx Context) - { - MakeObject(Context, new IStorage(Context.Ns.VFs.RomFs)); - - return 0; - } - - public long OpenPatchDataStorageByCurrentProcess(ServiceCtx Context) - { - MakeObject(Context, new IStorage(Context.Ns.VFs.RomFs)); - - return 0; - } - - public long GetGlobalAccessLogMode(ServiceCtx Context) - { - Context.ResponseData.Write(0); - - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Hid/IHidServer.cs b/Ryujinx.Core/OsHle/Services/Hid/IHidServer.cs new file mode 100644 index 00000000..f03b25dd --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Hid/IHidServer.cs @@ -0,0 +1,180 @@ +using Ryujinx.Core.Input; +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Hid +{ + class IHidServer : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IHidServer() + { + m_Commands = new Dictionary() + { + { 0, CreateAppletResource }, + { 1, ActivateDebugPad }, + { 11, ActivateTouchScreen }, + { 21, ActivateMouse }, + { 31, ActivateKeyboard }, + { 66, StartSixAxisSensor }, + { 100, SetSupportedNpadStyleSet }, + { 101, GetSupportedNpadStyleSet }, + { 102, SetSupportedNpadIdType }, + { 103, ActivateNpad }, + { 120, SetNpadJoyHoldType }, + { 121, GetNpadJoyHoldType }, + { 122, SetNpadJoyAssignmentModeSingleByDefault }, + { 123, SetNpadJoyAssignmentModeSingle }, + { 124, SetNpadJoyAssignmentModeDual }, + { 125, MergeSingleJoyAsDualJoy }, + { 200, GetVibrationDeviceInfo }, + { 203, CreateActiveVibrationDeviceList }, + { 206, SendVibrationValues } + }; + } + + public long CreateAppletResource(ServiceCtx Context) + { + MakeObject(Context, new IAppletResource(Context.Ns.Os.HidSharedMem)); + + return 0; + } + + public long ActivateDebugPad(ServiceCtx Context) + { + return 0; + } + + public long ActivateTouchScreen(ServiceCtx Context) + { + long AppletResourceUserId = Context.RequestData.ReadInt64(); + + return 0; + } + + public long ActivateMouse(ServiceCtx Context) + { + long AppletResourceUserId = Context.RequestData.ReadInt64(); + + return 0; + } + + public long ActivateKeyboard(ServiceCtx Context) + { + long AppletResourceUserId = Context.RequestData.ReadInt64(); + + return 0; + } + + public long StartSixAxisSensor(ServiceCtx Context) + { + int Handle = Context.RequestData.ReadInt32(); + + long AppletResourceUserId = Context.RequestData.ReadInt64(); + + return 0; + } + + public long GetSupportedNpadStyleSet(ServiceCtx Context) + { + Context.ResponseData.Write(0); + + return 0; + } + + public long SetSupportedNpadStyleSet(ServiceCtx Context) + { + long Unknown0 = Context.RequestData.ReadInt64(); + long Unknown8 = Context.RequestData.ReadInt64(); + + return 0; + } + + public long SetSupportedNpadIdType(ServiceCtx Context) + { + long Unknown = Context.RequestData.ReadInt64(); + + return 0; + } + + public long ActivateNpad(ServiceCtx Context) + { + long Unknown = Context.RequestData.ReadInt64(); + + return 0; + } + + public long SetNpadJoyHoldType(ServiceCtx Context) + { + long Unknown0 = Context.RequestData.ReadInt64(); + long Unknown8 = Context.RequestData.ReadInt64(); + + return 0; + } + + public long GetNpadJoyHoldType(ServiceCtx Context) + { + Context.ResponseData.Write(0L); + + return 0; + } + + public long SetNpadJoyAssignmentModeSingleByDefault(ServiceCtx Context) + { + HidControllerId HidControllerId = (HidControllerId)Context.RequestData.ReadInt32(); + long AppletUserResourseId = Context.RequestData.ReadInt64(); + + return 0; + } + + public long SetNpadJoyAssignmentModeSingle(ServiceCtx Context) + { + HidControllerId HidControllerId = (HidControllerId)Context.RequestData.ReadInt32(); + long AppletUserResourseId = Context.RequestData.ReadInt64(); + long NpadJoyDeviceType = Context.RequestData.ReadInt64(); + + return 0; + } + + public long SetNpadJoyAssignmentModeDual(ServiceCtx Context) + { + HidControllerId HidControllerId = (HidControllerId)Context.RequestData.ReadInt32(); + long AppletUserResourseId = Context.RequestData.ReadInt64(); + + return 0; + } + + public long MergeSingleJoyAsDualJoy(ServiceCtx Context) + { + long Unknown0 = Context.RequestData.ReadInt32(); + long Unknown8 = Context.RequestData.ReadInt32(); + long AppletUserResourseId = Context.RequestData.ReadInt64(); + + return 0; + } + + public long GetVibrationDeviceInfo(ServiceCtx Context) + { + int VibrationDeviceHandle = Context.RequestData.ReadInt32(); + + Context.ResponseData.Write(0L); //VibrationDeviceInfoForIpc + + return 0; + } + + public long CreateActiveVibrationDeviceList(ServiceCtx Context) + { + MakeObject(Context, new IActiveApplicationDeviceList()); + + return 0; + } + + public long SendVibrationValues(ServiceCtx Context) + { + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs b/Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs deleted file mode 100644 index 9226cfdd..00000000 --- a/Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs +++ /dev/null @@ -1,180 +0,0 @@ -using Ryujinx.Core.Input; -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Hid -{ - class ServiceHid : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceHid() - { - m_Commands = new Dictionary() - { - { 0, CreateAppletResource }, - { 1, ActivateDebugPad }, - { 11, ActivateTouchScreen }, - { 21, ActivateMouse }, - { 31, ActivateKeyboard }, - { 66, StartSixAxisSensor }, - { 100, SetSupportedNpadStyleSet }, - { 101, GetSupportedNpadStyleSet }, - { 102, SetSupportedNpadIdType }, - { 103, ActivateNpad }, - { 120, SetNpadJoyHoldType }, - { 121, GetNpadJoyHoldType }, - { 122, SetNpadJoyAssignmentModeSingleByDefault }, - { 123, SetNpadJoyAssignmentModeSingle }, - { 124, SetNpadJoyAssignmentModeDual }, - { 125, MergeSingleJoyAsDualJoy }, - { 200, GetVibrationDeviceInfo }, - { 203, CreateActiveVibrationDeviceList }, - { 206, SendVibrationValues } - }; - } - - public long CreateAppletResource(ServiceCtx Context) - { - MakeObject(Context, new IAppletResource(Context.Ns.Os.HidSharedMem)); - - return 0; - } - - public long ActivateDebugPad(ServiceCtx Context) - { - return 0; - } - - public long ActivateTouchScreen(ServiceCtx Context) - { - long AppletResourceUserId = Context.RequestData.ReadInt64(); - - return 0; - } - - public long ActivateMouse(ServiceCtx Context) - { - long AppletResourceUserId = Context.RequestData.ReadInt64(); - - return 0; - } - - public long ActivateKeyboard(ServiceCtx Context) - { - long AppletResourceUserId = Context.RequestData.ReadInt64(); - - return 0; - } - - public long StartSixAxisSensor(ServiceCtx Context) - { - int Handle = Context.RequestData.ReadInt32(); - - long AppletResourceUserId = Context.RequestData.ReadInt64(); - - return 0; - } - - public long GetSupportedNpadStyleSet(ServiceCtx Context) - { - Context.ResponseData.Write(0); - - return 0; - } - - public long SetSupportedNpadStyleSet(ServiceCtx Context) - { - long Unknown0 = Context.RequestData.ReadInt64(); - long Unknown8 = Context.RequestData.ReadInt64(); - - return 0; - } - - public long SetSupportedNpadIdType(ServiceCtx Context) - { - long Unknown = Context.RequestData.ReadInt64(); - - return 0; - } - - public long ActivateNpad(ServiceCtx Context) - { - long Unknown = Context.RequestData.ReadInt64(); - - return 0; - } - - public long SetNpadJoyHoldType(ServiceCtx Context) - { - long Unknown0 = Context.RequestData.ReadInt64(); - long Unknown8 = Context.RequestData.ReadInt64(); - - return 0; - } - - public long GetNpadJoyHoldType(ServiceCtx Context) - { - Context.ResponseData.Write(0L); - - return 0; - } - - public long SetNpadJoyAssignmentModeSingleByDefault(ServiceCtx Context) - { - HidControllerId HidControllerId = (HidControllerId)Context.RequestData.ReadInt32(); - long AppletUserResourseId = Context.RequestData.ReadInt64(); - - return 0; - } - - public long SetNpadJoyAssignmentModeSingle(ServiceCtx Context) - { - HidControllerId HidControllerId = (HidControllerId)Context.RequestData.ReadInt32(); - long AppletUserResourseId = Context.RequestData.ReadInt64(); - long NpadJoyDeviceType = Context.RequestData.ReadInt64(); - - return 0; - } - - public long SetNpadJoyAssignmentModeDual(ServiceCtx Context) - { - HidControllerId HidControllerId = (HidControllerId)Context.RequestData.ReadInt32(); - long AppletUserResourseId = Context.RequestData.ReadInt64(); - - return 0; - } - - public long MergeSingleJoyAsDualJoy(ServiceCtx Context) - { - long Unknown0 = Context.RequestData.ReadInt32(); - long Unknown8 = Context.RequestData.ReadInt32(); - long AppletUserResourseId = Context.RequestData.ReadInt64(); - - return 0; - } - - public long GetVibrationDeviceInfo(ServiceCtx Context) - { - int VibrationDeviceHandle = Context.RequestData.ReadInt32(); - - Context.ResponseData.Write(0L); //VibrationDeviceInfoForIpc - - return 0; - } - - public long CreateActiveVibrationDeviceList(ServiceCtx Context) - { - MakeObject(Context, new IActiveApplicationDeviceList()); - - return 0; - } - - public long SendVibrationValues(ServiceCtx Context) - { - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Lm/ILogService.cs b/Ryujinx.Core/OsHle/Services/Lm/ILogService.cs new file mode 100644 index 00000000..3315cf4c --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Lm/ILogService.cs @@ -0,0 +1,27 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Lm +{ + class ILogService : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public ILogService() + { + m_Commands = new Dictionary() + { + { 0, Initialize } + }; + } + + public long Initialize(ServiceCtx Context) + { + MakeObject(Context, new ILogger()); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs b/Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs deleted file mode 100644 index f1c2204e..00000000 --- a/Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Lm -{ - class ServiceLm : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceLm() - { - m_Commands = new Dictionary() - { - { 0, Initialize } - }; - } - - public long Initialize(ServiceCtx Context) - { - MakeObject(Context, new ILogger()); - - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Nifm/IStaticService.cs b/Ryujinx.Core/OsHle/Services/Nifm/IStaticService.cs new file mode 100644 index 00000000..2129ce43 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Nifm/IStaticService.cs @@ -0,0 +1,27 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Nifm +{ + class IStaticService : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IStaticService() + { + m_Commands = new Dictionary() + { + { 4, CreateGeneralServiceOld } + }; + } + + public long CreateGeneralServiceOld(ServiceCtx Context) + { + MakeObject(Context, new IGeneralService()); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Nifm/ServiceNifm.cs b/Ryujinx.Core/OsHle/Services/Nifm/ServiceNifm.cs deleted file mode 100644 index 7e5ecacd..00000000 --- a/Ryujinx.Core/OsHle/Services/Nifm/ServiceNifm.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Nifm -{ - class ServiceNifm : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceNifm() - { - m_Commands = new Dictionary() - { - { 4, CreateGeneralServiceOld } - }; - } - - public long CreateGeneralServiceOld(ServiceCtx Context) - { - MakeObject(Context, new IGeneralService()); - - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Ns/IAddOnContentManager.cs b/Ryujinx.Core/OsHle/Services/Ns/IAddOnContentManager.cs new file mode 100644 index 00000000..57fea077 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Ns/IAddOnContentManager.cs @@ -0,0 +1,37 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Ns +{ + class IAddOnContentManager : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IAddOnContentManager() + { + m_Commands = new Dictionary() + { + { 2, CountAddOnContent }, + { 3, ListAddOnContent } + }; + } + + public static long CountAddOnContent(ServiceCtx Context) + { + Context.ResponseData.Write(0); + + return 0; + } + + public static long ListAddOnContent(ServiceCtx Context) + { + //TODO: This is supposed to write a u32 array aswell. + //It's unknown what it contains. + Context.ResponseData.Write(0); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs b/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs deleted file mode 100644 index 5e00a0f6..00000000 --- a/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Ns -{ - class ServiceNs : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceNs() - { - m_Commands = new Dictionary() - { - { 2, CountAddOnContent }, - { 3, ListAddOnContent } - }; - } - - public static long CountAddOnContent(ServiceCtx Context) - { - Context.ResponseData.Write(0); - - return 0; - } - - public static long ListAddOnContent(ServiceCtx Context) - { - //TODO: This is supposed to write a u32 array aswell. - //It's unknown what it contains. - Context.ResponseData.Write(0); - - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Nv/INvDrvServices.cs b/Ryujinx.Core/OsHle/Services/Nv/INvDrvServices.cs new file mode 100644 index 00000000..8568e8f2 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Nv/INvDrvServices.cs @@ -0,0 +1,781 @@ +using ChocolArm64.Memory; +using Ryujinx.Core.OsHle.Handles; +using Ryujinx.Core.OsHle.Ipc; +using Ryujinx.Core.OsHle.Utilities; +using Ryujinx.Graphics.Gpu; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Ryujinx.Core.OsHle.Services.Nv +{ + class INvDrvServices : IpcService, IDisposable + { + private delegate long ServiceProcessIoctl(ServiceCtx Context); + + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + private Dictionary<(string, int), ServiceProcessIoctl> IoctlCmds; + + public static GlobalStateTable Fds { get; private set; } + + public static GlobalStateTable NvMaps { get; private set; } + public static GlobalStateTable NvMapsById { get; private set; } + public static GlobalStateTable NvMapsFb { get; private set; } + + private KEvent Event; + + public INvDrvServices() + { + m_Commands = new Dictionary() + { + { 0, Open }, + { 1, Ioctl }, + { 2, Close }, + { 3, Initialize }, + { 4, QueryEvent }, + { 8, SetClientPid }, + }; + + IoctlCmds = new Dictionary<(string, int), ServiceProcessIoctl>() + { + { ("/dev/nvhost-as-gpu", 0x4101), NvGpuAsIoctlBindChannel }, + { ("/dev/nvhost-as-gpu", 0x4102), NvGpuAsIoctlAllocSpace }, + { ("/dev/nvhost-as-gpu", 0x4106), NvGpuAsIoctlMapBufferEx }, + { ("/dev/nvhost-as-gpu", 0x4108), NvGpuAsIoctlGetVaRegions }, + { ("/dev/nvhost-as-gpu", 0x4109), NvGpuAsIoctlInitializeEx }, + { ("/dev/nvhost-as-gpu", 0x4114), NvGpuAsIoctlRemap }, + { ("/dev/nvhost-ctrl", 0x001b), NvHostIoctlCtrlGetConfig }, + { ("/dev/nvhost-ctrl", 0x001d), NvHostIoctlCtrlEventWait }, + { ("/dev/nvhost-ctrl-gpu", 0x4701), NvGpuIoctlZcullGetCtxSize }, + { ("/dev/nvhost-ctrl-gpu", 0x4702), NvGpuIoctlZcullGetInfo }, + { ("/dev/nvhost-ctrl-gpu", 0x4703), NvGpuIoctlZbcSetTable }, + { ("/dev/nvhost-ctrl-gpu", 0x4705), NvGpuIoctlGetCharacteristics }, + { ("/dev/nvhost-ctrl-gpu", 0x4706), NvGpuIoctlGetTpcMasks }, + { ("/dev/nvhost-ctrl-gpu", 0x4714), NvGpuIoctlZbcGetActiveSlotMask }, + { ("/dev/nvhost-gpu", 0x4714), NvMapIoctlChannelSetUserData }, + { ("/dev/nvhost-gpu", 0x4801), NvMapIoctlChannelSetNvMap }, + { ("/dev/nvhost-gpu", 0x4808), NvMapIoctlChannelSubmitGpFifo }, + { ("/dev/nvhost-gpu", 0x4809), NvMapIoctlChannelAllocObjCtx }, + { ("/dev/nvhost-gpu", 0x480b), NvMapIoctlChannelZcullBind }, + { ("/dev/nvhost-gpu", 0x480c), NvMapIoctlChannelSetErrorNotifier }, + { ("/dev/nvhost-gpu", 0x480d), NvMapIoctlChannelSetPriority }, + { ("/dev/nvhost-gpu", 0x481a), NvMapIoctlChannelAllocGpFifoEx2 }, + { ("/dev/nvmap", 0x0101), NvMapIocCreate }, + { ("/dev/nvmap", 0x0103), NvMapIocFromId }, + { ("/dev/nvmap", 0x0104), NvMapIocAlloc }, + { ("/dev/nvmap", 0x0105), NvMapIocFree }, + { ("/dev/nvmap", 0x0109), NvMapIocParam }, + { ("/dev/nvmap", 0x010e), NvMapIocGetId }, + }; + + Event = new KEvent(); + } + + static INvDrvServices() + { + Fds = new GlobalStateTable(); + + NvMaps = new GlobalStateTable(); + NvMapsById = new GlobalStateTable(); + NvMapsFb = new GlobalStateTable(); + } + + public long Open(ServiceCtx Context) + { + long NamePtr = Context.Request.SendBuff[0].Position; + + string Name = AMemoryHelper.ReadAsciiString(Context.Memory, NamePtr); + + int Fd = Fds.Add(Context.Process, new NvFd(Name)); + + Context.ResponseData.Write(Fd); + Context.ResponseData.Write(0); + + return 0; + } + + public long Ioctl(ServiceCtx Context) + { + int Fd = Context.RequestData.ReadInt32(); + int Cmd = Context.RequestData.ReadInt32() & 0xffff; + + NvFd FdData = Fds.GetData(Context.Process, Fd); + + long Position = Context.Request.GetSendBuffPtr(); + + Context.ResponseData.Write(0); + + if (IoctlCmds.TryGetValue((FdData.Name, Cmd), out ServiceProcessIoctl ProcReq)) + { + return ProcReq(Context); + } + else + { + throw new NotImplementedException($"{FdData.Name} {Cmd:x4}"); + } + } + + public long Close(ServiceCtx Context) + { + int Fd = Context.RequestData.ReadInt32(); + + Fds.Delete(Context.Process, Fd); + + Context.ResponseData.Write(0); + + return 0; + } + + public long Initialize(ServiceCtx Context) + { + long TransferMemSize = Context.RequestData.ReadInt64(); + int TransferMemHandle = Context.Request.HandleDesc.ToCopy[0]; + + Context.ResponseData.Write(0); + + NvMapsFb.Add(Context.Process, 0, new NvMapFb()); + + return 0; + } + + public long QueryEvent(ServiceCtx Context) + { + int Fd = Context.RequestData.ReadInt32(); + int EventId = Context.RequestData.ReadInt32(); + + //TODO: Use Fd/EventId, different channels have different events. + int Handle = Context.Process.HandleTable.OpenHandle(Event); + + Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); + + Context.ResponseData.Write(0); + + return 0; + } + + public long SetClientPid(ServiceCtx Context) + { + long Pid = Context.RequestData.ReadInt64(); + + Context.ResponseData.Write(0); + + return 0; + } + + private long NvGpuAsIoctlBindChannel(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + int Fd = Context.Memory.ReadInt32(Position); + + return 0; + } + + private long NvGpuAsIoctlAllocSpace(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + int Pages = Reader.ReadInt32(); + int PageSize = Reader.ReadInt32(); + int Flags = Reader.ReadInt32(); + int Padding = Reader.ReadInt32(); + long Align = Reader.ReadInt64(); + + if ((Flags & 1) != 0) + { + Align = Context.Ns.Gpu.ReserveMemory(Align, (long)Pages * PageSize, 1); + } + else + { + Align = Context.Ns.Gpu.ReserveMemory((long)Pages * PageSize, Align); + } + + Context.Memory.WriteInt64(Position + 0x10, Align); + + return 0; + } + + private long NvGpuAsIoctlMapBufferEx(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + int Flags = Reader.ReadInt32(); + int Kind = Reader.ReadInt32(); + int Handle = Reader.ReadInt32(); + int PageSize = Reader.ReadInt32(); + long BuffAddr = Reader.ReadInt64(); + long MapSize = Reader.ReadInt64(); + long Offset = Reader.ReadInt64(); + + if (Handle == 0) + { + //This is used to store offsets for the Framebuffer(s); + NvMapFb MapFb = (NvMapFb)NvMapsFb.GetData(Context.Process, 0); + + MapFb.AddBufferOffset(BuffAddr); + + return 0; + } + + NvMap Map = NvMaps.GetData(Context.Process, Handle); + + if (Map == null) + { + Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); + + return -1; //TODO: Corrent error code. + } + + if ((Flags & 1) != 0) + { + Offset = Context.Ns.Gpu.MapMemory(Map.CpuAddress, Offset, Map.Size); + } + else + { + Offset = Context.Ns.Gpu.MapMemory(Map.CpuAddress, Map.Size); + } + + Context.Memory.WriteInt64(Position + 0x20, Offset); + + return 0; + } + + private long NvGpuAsIoctlGetVaRegions(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + MemWriter Writer = new MemWriter(Context.Memory, Position); + + long Unused = Reader.ReadInt64(); + int BuffSize = Reader.ReadInt32(); + int Padding = Reader.ReadInt32(); + + BuffSize = 0x30; + + Writer.WriteInt64(Unused); + Writer.WriteInt32(BuffSize); + Writer.WriteInt32(Padding); + + Writer.WriteInt64(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt64(0); + + Writer.WriteInt64(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt64(0); + + return 0; + } + + private long NvGpuAsIoctlInitializeEx(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + int BigPageSize = Reader.ReadInt32(); + int AsFd = Reader.ReadInt32(); + int Flags = Reader.ReadInt32(); + int Reserved = Reader.ReadInt32(); + long Unknown10 = Reader.ReadInt64(); + long Unknown18 = Reader.ReadInt64(); + long Unknown20 = Reader.ReadInt64(); + + return 0; + } + + private long NvGpuAsIoctlRemap(ServiceCtx Context) + { + Context.RequestData.BaseStream.Seek(-4, SeekOrigin.Current); + + int Cmd = Context.RequestData.ReadInt32(); + + int Size = (Cmd >> 16) & 0xff; + + int Count = Size / 0x18; + + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + for (int Index = 0; Index < Count; Index++) + { + int Flags = Reader.ReadInt32(); + int Kind = Reader.ReadInt32(); + int Handle = Reader.ReadInt32(); + int Padding = Reader.ReadInt32(); + int Offset = Reader.ReadInt32(); + int Pages = Reader.ReadInt32(); + } + + //TODO + + return 0; + } + + private long NvHostIoctlCtrlGetConfig(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + MemWriter Writer = new MemWriter(Context.Memory, Position + 0x82); + + for (int Index = 0; Index < 0x101; Index++) + { + Writer.WriteByte(0); + } + + return 0; + } + + private long NvHostIoctlCtrlEventWait(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + int SyncPtId = Reader.ReadInt32(); + int Threshold = Reader.ReadInt32(); + int Timeout = Reader.ReadInt32(); + int Value = Reader.ReadInt32(); + + Context.Memory.WriteInt32(Position + 0xc, 0xcafe); + + return 0; + } + + private long NvGpuIoctlZcullGetCtxSize(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + Context.Memory.WriteInt32(Position, 1); + + return 0; + } + + private long NvGpuIoctlZcullGetInfo(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemWriter Writer = new MemWriter(Context.Memory, Position); + + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + Writer.WriteInt32(0); + + return 0; + } + + private long NvGpuIoctlZbcSetTable(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + int[] ColorDs = new int[4]; + int[] ColorL2 = new int[4]; + + ColorDs[0] = Reader.ReadInt32(); + ColorDs[1] = Reader.ReadInt32(); + ColorDs[2] = Reader.ReadInt32(); + ColorDs[3] = Reader.ReadInt32(); + + ColorL2[0] = Reader.ReadInt32(); + ColorL2[1] = Reader.ReadInt32(); + ColorL2[2] = Reader.ReadInt32(); + ColorL2[3] = Reader.ReadInt32(); + + int Depth = Reader.ReadInt32(); + int Format = Reader.ReadInt32(); + int Type = Reader.ReadInt32(); + + return 0; + } + + private long NvGpuIoctlGetCharacteristics(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + MemWriter Writer = new MemWriter(Context.Memory, Position); + + //Note: We should just ignore the BuffAddr, because official code + //does __memcpy_device from Position + 0x10 to BuffAddr. + long BuffSize = Reader.ReadInt64(); + long BuffAddr = Reader.ReadInt64(); + + BuffSize = 0xa0; + + Writer.WriteInt64(BuffSize); + Writer.WriteInt64(BuffAddr); + Writer.WriteInt32(0x120); //NVGPU_GPU_ARCH_GM200 + Writer.WriteInt32(0xb); //NVGPU_GPU_IMPL_GM20B + Writer.WriteInt32(0xa1); + Writer.WriteInt32(1); + Writer.WriteInt64(0x40000); + Writer.WriteInt64(0); + Writer.WriteInt32(2); + Writer.WriteInt32(0x20); //NVGPU_GPU_BUS_TYPE_AXI + Writer.WriteInt32(0x20000); + Writer.WriteInt32(0x20000); + Writer.WriteInt32(0x1b); + Writer.WriteInt32(0x30000); + Writer.WriteInt32(1); + Writer.WriteInt32(0x503); + Writer.WriteInt32(0x503); + Writer.WriteInt32(0x80); + Writer.WriteInt32(0x28); + Writer.WriteInt32(0); + Writer.WriteInt64(0x55); + Writer.WriteInt32(0x902d); //FERMI_TWOD_A + Writer.WriteInt32(0xb197); //MAXWELL_B + Writer.WriteInt32(0xb1c0); //MAXWELL_COMPUTE_B + Writer.WriteInt32(0xb06f); //MAXWELL_CHANNEL_GPFIFO_A + Writer.WriteInt32(0xa140); //KEPLER_INLINE_TO_MEMORY_B + Writer.WriteInt32(0xb0b5); //MAXWELL_DMA_COPY_A + Writer.WriteInt32(1); + Writer.WriteInt32(0); + Writer.WriteInt32(2); + Writer.WriteInt32(1); + Writer.WriteInt32(0); + Writer.WriteInt32(1); + Writer.WriteInt32(0x21d70); + Writer.WriteInt32(0); + Writer.WriteByte((byte)'g'); + Writer.WriteByte((byte)'m'); + Writer.WriteByte((byte)'2'); + Writer.WriteByte((byte)'0'); + Writer.WriteByte((byte)'b'); + Writer.WriteByte((byte)'\0'); + Writer.WriteByte((byte)'\0'); + Writer.WriteByte((byte)'\0'); + Writer.WriteInt64(0); + + return 0; + } + + private long NvGpuIoctlGetTpcMasks(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + int MaskBuffSize = Reader.ReadInt32(); + int Reserved = Reader.ReadInt32(); + long MaskBuffAddr = Reader.ReadInt64(); + long Unknown = Reader.ReadInt64(); + + return 0; + } + + private long NvGpuIoctlZbcGetActiveSlotMask(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + Context.Memory.WriteInt32(Position + 0, 7); + Context.Memory.WriteInt32(Position + 4, 1); + + return 0; + } + + private long NvMapIoctlChannelSetUserData(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + return 0; + } + + private long NvMapIoctlChannelSetNvMap(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + int Fd = Context.Memory.ReadInt32(Position); + + return 0; + } + + private long NvMapIoctlChannelSubmitGpFifo(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + MemWriter Writer = new MemWriter(Context.Memory, Position + 0x10); + + long GpFifo = Reader.ReadInt64(); + int Count = Reader.ReadInt32(); + int Flags = Reader.ReadInt32(); + int FenceId = Reader.ReadInt32(); + int FenceVal = Reader.ReadInt32(); + + for (int Index = 0; Index < Count; Index++) + { + long GpFifoHdr = Reader.ReadInt64(); + + long GpuAddr = GpFifoHdr & 0xffffffffff; + + int Size = (int)(GpFifoHdr >> 40) & 0x7ffffc; + + long CpuAddr = Context.Ns.Gpu.GetCpuAddr(GpuAddr); + + if (CpuAddr != -1) + { + byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, CpuAddr, Size); + + NsGpuPBEntry[] PushBuffer = NsGpuPBEntry.DecodePushBuffer(Data); + + Context.Ns.Gpu.ProcessPushBuffer(PushBuffer, Context.Memory); + } + } + + Writer.WriteInt32(0); + Writer.WriteInt32(0); + + return 0; + } + + private long NvMapIoctlChannelAllocObjCtx(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + int ClassNum = Context.Memory.ReadInt32(Position + 0); + int Flags = Context.Memory.ReadInt32(Position + 4); + + Context.Memory.WriteInt32(Position + 8, 0); + + return 0; + } + + private long NvMapIoctlChannelZcullBind(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + long GpuVa = Reader.ReadInt64(); + int Mode = Reader.ReadInt32(); + int Padding = Reader.ReadInt32(); + + return 0; + } + + private long NvMapIoctlChannelSetErrorNotifier(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + long Offset = Reader.ReadInt64(); + long Size = Reader.ReadInt64(); + int Mem = Reader.ReadInt32(); + int Padding = Reader.ReadInt32(); + + return 0; + } + + private long NvMapIoctlChannelSetPriority(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + int Priority = Context.Memory.ReadInt32(Position); + + return 0; + } + + private long NvMapIoctlChannelAllocGpFifoEx2(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + MemWriter Writer = new MemWriter(Context.Memory, Position + 0xc); + + int Count = Reader.ReadInt32(); + int Flags = Reader.ReadInt32(); + int Unknown8 = Reader.ReadInt32(); + long Fence = Reader.ReadInt64(); + int Unknown14 = Reader.ReadInt32(); + int Unknown18 = Reader.ReadInt32(); + + Writer.WriteInt32(0); + Writer.WriteInt32(0); + + return 0; + } + + private long NvMapIocCreate(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + int Size = Context.Memory.ReadInt32(Position); + + NvMap Map = new NvMap() { Size = Size }; + + Map.Handle = NvMaps.Add(Context.Process, Map); + + Map.Id = NvMapsById.Add(Context.Process, Map); + + Context.Memory.WriteInt32(Position + 4, Map.Handle); + + Logging.Info($"NvMap {Map.Id} created with size {Size:x8}!"); + + return 0; + } + + private long NvMapIocFromId(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + int Id = Context.Memory.ReadInt32(Position); + + NvMap Map = NvMapsById.GetData(Context.Process, Id); + + if (Map == null) + { + Logging.Warn($"Trying to use invalid NvMap Id {Id}!"); + + return -1; //TODO: Corrent error code. + } + + Context.Memory.WriteInt32(Position + 4, Map.Handle); + + return 0; + } + + private long NvMapIocAlloc(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + int Handle = Reader.ReadInt32(); + int HeapMask = Reader.ReadInt32(); + int Flags = Reader.ReadInt32(); + int Align = Reader.ReadInt32(); + byte Kind = (byte)Reader.ReadInt64(); + long Addr = Reader.ReadInt64(); + + NvMap Map = NvMaps.GetData(Context.Process, Handle); + + if (Map == null) + { + Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); + + return -1; //TODO: Corrent error code. + } + + Map.CpuAddress = Addr; + Map.Align = Align; + Map.Kind = Kind; + + return 0; + } + + private long NvMapIocFree(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + MemWriter Writer = new MemWriter(Context.Memory, Position + 8); + + int Handle = Reader.ReadInt32(); + int Padding = Reader.ReadInt32(); + + NvMap Map = NvMaps.GetData(Context.Process, Handle); + + if (Map == null) + { + Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); + + return -1; //TODO: Corrent error code. + } + + Writer.WriteInt64(0); + Writer.WriteInt32(Map.Size); + Writer.WriteInt32(0); + + return 0; + } + + private long NvMapIocParam(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + MemReader Reader = new MemReader(Context.Memory, Position); + + int Handle = Reader.ReadInt32(); + int Param = Reader.ReadInt32(); + + NvMap Map = NvMaps.GetData(Context.Process, Handle); + + if (Map == null) + { + Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); + + return -1; //TODO: Corrent error code. + } + + int Response = 0; + + switch (Param) + { + case 1: Response = Map.Size; break; + case 2: Response = Map.Align; break; + case 4: Response = 0x40000000; break; + case 5: Response = Map.Kind; break; + } + + Context.Memory.WriteInt32(Position + 8, Response); + + return 0; + } + + private long NvMapIocGetId(ServiceCtx Context) + { + long Position = Context.Request.GetSendBuffPtr(); + + int Handle = Context.Memory.ReadInt32(Position + 4); + + NvMap Map = NvMaps.GetData(Context.Process, Handle); + + if (Map == null) + { + Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); + + return -1; //TODO: Corrent error code. + } + + Context.Memory.WriteInt32(Position, Map.Id); + + return 0; + } + + public void Dispose() + { + Dispose(true); + } + + protected virtual void Dispose(bool Disposing) + { + if (Disposing) + { + Event.Dispose(); + } + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs deleted file mode 100644 index e314169b..00000000 --- a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs +++ /dev/null @@ -1,781 +0,0 @@ -using ChocolArm64.Memory; -using Ryujinx.Core.OsHle.Handles; -using Ryujinx.Core.OsHle.Ipc; -using Ryujinx.Core.OsHle.Utilities; -using Ryujinx.Graphics.Gpu; -using System; -using System.Collections.Generic; -using System.IO; - -namespace Ryujinx.Core.OsHle.Services.Nv -{ - class ServiceNvDrv : IpcService, IDisposable - { - private delegate long ServiceProcessIoctl(ServiceCtx Context); - - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - private Dictionary<(string, int), ServiceProcessIoctl> IoctlCmds; - - public static GlobalStateTable Fds { get; private set; } - - public static GlobalStateTable NvMaps { get; private set; } - public static GlobalStateTable NvMapsById { get; private set; } - public static GlobalStateTable NvMapsFb { get; private set; } - - private KEvent Event; - - public ServiceNvDrv() - { - m_Commands = new Dictionary() - { - { 0, Open }, - { 1, Ioctl }, - { 2, Close }, - { 3, Initialize }, - { 4, QueryEvent }, - { 8, SetClientPid }, - }; - - IoctlCmds = new Dictionary<(string, int), ServiceProcessIoctl>() - { - { ("/dev/nvhost-as-gpu", 0x4101), NvGpuAsIoctlBindChannel }, - { ("/dev/nvhost-as-gpu", 0x4102), NvGpuAsIoctlAllocSpace }, - { ("/dev/nvhost-as-gpu", 0x4106), NvGpuAsIoctlMapBufferEx }, - { ("/dev/nvhost-as-gpu", 0x4108), NvGpuAsIoctlGetVaRegions }, - { ("/dev/nvhost-as-gpu", 0x4109), NvGpuAsIoctlInitializeEx }, - { ("/dev/nvhost-as-gpu", 0x4114), NvGpuAsIoctlRemap }, - { ("/dev/nvhost-ctrl", 0x001b), NvHostIoctlCtrlGetConfig }, - { ("/dev/nvhost-ctrl", 0x001d), NvHostIoctlCtrlEventWait }, - { ("/dev/nvhost-ctrl-gpu", 0x4701), NvGpuIoctlZcullGetCtxSize }, - { ("/dev/nvhost-ctrl-gpu", 0x4702), NvGpuIoctlZcullGetInfo }, - { ("/dev/nvhost-ctrl-gpu", 0x4703), NvGpuIoctlZbcSetTable }, - { ("/dev/nvhost-ctrl-gpu", 0x4705), NvGpuIoctlGetCharacteristics }, - { ("/dev/nvhost-ctrl-gpu", 0x4706), NvGpuIoctlGetTpcMasks }, - { ("/dev/nvhost-ctrl-gpu", 0x4714), NvGpuIoctlZbcGetActiveSlotMask }, - { ("/dev/nvhost-gpu", 0x4714), NvMapIoctlChannelSetUserData }, - { ("/dev/nvhost-gpu", 0x4801), NvMapIoctlChannelSetNvMap }, - { ("/dev/nvhost-gpu", 0x4808), NvMapIoctlChannelSubmitGpFifo }, - { ("/dev/nvhost-gpu", 0x4809), NvMapIoctlChannelAllocObjCtx }, - { ("/dev/nvhost-gpu", 0x480b), NvMapIoctlChannelZcullBind }, - { ("/dev/nvhost-gpu", 0x480c), NvMapIoctlChannelSetErrorNotifier }, - { ("/dev/nvhost-gpu", 0x480d), NvMapIoctlChannelSetPriority }, - { ("/dev/nvhost-gpu", 0x481a), NvMapIoctlChannelAllocGpFifoEx2 }, - { ("/dev/nvmap", 0x0101), NvMapIocCreate }, - { ("/dev/nvmap", 0x0103), NvMapIocFromId }, - { ("/dev/nvmap", 0x0104), NvMapIocAlloc }, - { ("/dev/nvmap", 0x0105), NvMapIocFree }, - { ("/dev/nvmap", 0x0109), NvMapIocParam }, - { ("/dev/nvmap", 0x010e), NvMapIocGetId }, - }; - - Event = new KEvent(); - } - - static ServiceNvDrv() - { - Fds = new GlobalStateTable(); - - NvMaps = new GlobalStateTable(); - NvMapsById = new GlobalStateTable(); - NvMapsFb = new GlobalStateTable(); - } - - public long Open(ServiceCtx Context) - { - long NamePtr = Context.Request.SendBuff[0].Position; - - string Name = AMemoryHelper.ReadAsciiString(Context.Memory, NamePtr); - - int Fd = Fds.Add(Context.Process, new NvFd(Name)); - - Context.ResponseData.Write(Fd); - Context.ResponseData.Write(0); - - return 0; - } - - public long Ioctl(ServiceCtx Context) - { - int Fd = Context.RequestData.ReadInt32(); - int Cmd = Context.RequestData.ReadInt32() & 0xffff; - - NvFd FdData = Fds.GetData(Context.Process, Fd); - - long Position = Context.Request.GetSendBuffPtr(); - - Context.ResponseData.Write(0); - - if (IoctlCmds.TryGetValue((FdData.Name, Cmd), out ServiceProcessIoctl ProcReq)) - { - return ProcReq(Context); - } - else - { - throw new NotImplementedException($"{FdData.Name} {Cmd:x4}"); - } - } - - public long Close(ServiceCtx Context) - { - int Fd = Context.RequestData.ReadInt32(); - - Fds.Delete(Context.Process, Fd); - - Context.ResponseData.Write(0); - - return 0; - } - - public long Initialize(ServiceCtx Context) - { - long TransferMemSize = Context.RequestData.ReadInt64(); - int TransferMemHandle = Context.Request.HandleDesc.ToCopy[0]; - - Context.ResponseData.Write(0); - - NvMapsFb.Add(Context.Process, 0, new NvMapFb()); - - return 0; - } - - public long QueryEvent(ServiceCtx Context) - { - int Fd = Context.RequestData.ReadInt32(); - int EventId = Context.RequestData.ReadInt32(); - - //TODO: Use Fd/EventId, different channels have different events. - int Handle = Context.Process.HandleTable.OpenHandle(Event); - - Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); - - Context.ResponseData.Write(0); - - return 0; - } - - public long SetClientPid(ServiceCtx Context) - { - long Pid = Context.RequestData.ReadInt64(); - - Context.ResponseData.Write(0); - - return 0; - } - - private long NvGpuAsIoctlBindChannel(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - int Fd = Context.Memory.ReadInt32(Position); - - return 0; - } - - private long NvGpuAsIoctlAllocSpace(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - - int Pages = Reader.ReadInt32(); - int PageSize = Reader.ReadInt32(); - int Flags = Reader.ReadInt32(); - int Padding = Reader.ReadInt32(); - long Align = Reader.ReadInt64(); - - if ((Flags & 1) != 0) - { - Align = Context.Ns.Gpu.ReserveMemory(Align, (long)Pages * PageSize, 1); - } - else - { - Align = Context.Ns.Gpu.ReserveMemory((long)Pages * PageSize, Align); - } - - Context.Memory.WriteInt64(Position + 0x10, Align); - - return 0; - } - - private long NvGpuAsIoctlMapBufferEx(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - - int Flags = Reader.ReadInt32(); - int Kind = Reader.ReadInt32(); - int Handle = Reader.ReadInt32(); - int PageSize = Reader.ReadInt32(); - long BuffAddr = Reader.ReadInt64(); - long MapSize = Reader.ReadInt64(); - long Offset = Reader.ReadInt64(); - - if (Handle == 0) - { - //This is used to store offsets for the Framebuffer(s); - NvMapFb MapFb = (NvMapFb)NvMapsFb.GetData(Context.Process, 0); - - MapFb.AddBufferOffset(BuffAddr); - - return 0; - } - - NvMap Map = NvMaps.GetData(Context.Process, Handle); - - if (Map == null) - { - Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); - - return -1; //TODO: Corrent error code. - } - - if ((Flags & 1) != 0) - { - Offset = Context.Ns.Gpu.MapMemory(Map.CpuAddress, Offset, Map.Size); - } - else - { - Offset = Context.Ns.Gpu.MapMemory(Map.CpuAddress, Map.Size); - } - - Context.Memory.WriteInt64(Position + 0x20, Offset); - - return 0; - } - - private long NvGpuAsIoctlGetVaRegions(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - MemWriter Writer = new MemWriter(Context.Memory, Position); - - long Unused = Reader.ReadInt64(); - int BuffSize = Reader.ReadInt32(); - int Padding = Reader.ReadInt32(); - - BuffSize = 0x30; - - Writer.WriteInt64(Unused); - Writer.WriteInt32(BuffSize); - Writer.WriteInt32(Padding); - - Writer.WriteInt64(0); - Writer.WriteInt32(0); - Writer.WriteInt32(0); - Writer.WriteInt64(0); - - Writer.WriteInt64(0); - Writer.WriteInt32(0); - Writer.WriteInt32(0); - Writer.WriteInt64(0); - - return 0; - } - - private long NvGpuAsIoctlInitializeEx(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - - int BigPageSize = Reader.ReadInt32(); - int AsFd = Reader.ReadInt32(); - int Flags = Reader.ReadInt32(); - int Reserved = Reader.ReadInt32(); - long Unknown10 = Reader.ReadInt64(); - long Unknown18 = Reader.ReadInt64(); - long Unknown20 = Reader.ReadInt64(); - - return 0; - } - - private long NvGpuAsIoctlRemap(ServiceCtx Context) - { - Context.RequestData.BaseStream.Seek(-4, SeekOrigin.Current); - - int Cmd = Context.RequestData.ReadInt32(); - - int Size = (Cmd >> 16) & 0xff; - - int Count = Size / 0x18; - - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - - for (int Index = 0; Index < Count; Index++) - { - int Flags = Reader.ReadInt32(); - int Kind = Reader.ReadInt32(); - int Handle = Reader.ReadInt32(); - int Padding = Reader.ReadInt32(); - int Offset = Reader.ReadInt32(); - int Pages = Reader.ReadInt32(); - } - - //TODO - - return 0; - } - - private long NvHostIoctlCtrlGetConfig(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - MemWriter Writer = new MemWriter(Context.Memory, Position + 0x82); - - for (int Index = 0; Index < 0x101; Index++) - { - Writer.WriteByte(0); - } - - return 0; - } - - private long NvHostIoctlCtrlEventWait(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - - int SyncPtId = Reader.ReadInt32(); - int Threshold = Reader.ReadInt32(); - int Timeout = Reader.ReadInt32(); - int Value = Reader.ReadInt32(); - - Context.Memory.WriteInt32(Position + 0xc, 0xcafe); - - return 0; - } - - private long NvGpuIoctlZcullGetCtxSize(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - Context.Memory.WriteInt32(Position, 1); - - return 0; - } - - private long NvGpuIoctlZcullGetInfo(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemWriter Writer = new MemWriter(Context.Memory, Position); - - Writer.WriteInt32(0); - Writer.WriteInt32(0); - Writer.WriteInt32(0); - Writer.WriteInt32(0); - Writer.WriteInt32(0); - Writer.WriteInt32(0); - Writer.WriteInt32(0); - Writer.WriteInt32(0); - Writer.WriteInt32(0); - Writer.WriteInt32(0); - - return 0; - } - - private long NvGpuIoctlZbcSetTable(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - - int[] ColorDs = new int[4]; - int[] ColorL2 = new int[4]; - - ColorDs[0] = Reader.ReadInt32(); - ColorDs[1] = Reader.ReadInt32(); - ColorDs[2] = Reader.ReadInt32(); - ColorDs[3] = Reader.ReadInt32(); - - ColorL2[0] = Reader.ReadInt32(); - ColorL2[1] = Reader.ReadInt32(); - ColorL2[2] = Reader.ReadInt32(); - ColorL2[3] = Reader.ReadInt32(); - - int Depth = Reader.ReadInt32(); - int Format = Reader.ReadInt32(); - int Type = Reader.ReadInt32(); - - return 0; - } - - private long NvGpuIoctlGetCharacteristics(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - MemWriter Writer = new MemWriter(Context.Memory, Position); - - //Note: We should just ignore the BuffAddr, because official code - //does __memcpy_device from Position + 0x10 to BuffAddr. - long BuffSize = Reader.ReadInt64(); - long BuffAddr = Reader.ReadInt64(); - - BuffSize = 0xa0; - - Writer.WriteInt64(BuffSize); - Writer.WriteInt64(BuffAddr); - Writer.WriteInt32(0x120); //NVGPU_GPU_ARCH_GM200 - Writer.WriteInt32(0xb); //NVGPU_GPU_IMPL_GM20B - Writer.WriteInt32(0xa1); - Writer.WriteInt32(1); - Writer.WriteInt64(0x40000); - Writer.WriteInt64(0); - Writer.WriteInt32(2); - Writer.WriteInt32(0x20); //NVGPU_GPU_BUS_TYPE_AXI - Writer.WriteInt32(0x20000); - Writer.WriteInt32(0x20000); - Writer.WriteInt32(0x1b); - Writer.WriteInt32(0x30000); - Writer.WriteInt32(1); - Writer.WriteInt32(0x503); - Writer.WriteInt32(0x503); - Writer.WriteInt32(0x80); - Writer.WriteInt32(0x28); - Writer.WriteInt32(0); - Writer.WriteInt64(0x55); - Writer.WriteInt32(0x902d); //FERMI_TWOD_A - Writer.WriteInt32(0xb197); //MAXWELL_B - Writer.WriteInt32(0xb1c0); //MAXWELL_COMPUTE_B - Writer.WriteInt32(0xb06f); //MAXWELL_CHANNEL_GPFIFO_A - Writer.WriteInt32(0xa140); //KEPLER_INLINE_TO_MEMORY_B - Writer.WriteInt32(0xb0b5); //MAXWELL_DMA_COPY_A - Writer.WriteInt32(1); - Writer.WriteInt32(0); - Writer.WriteInt32(2); - Writer.WriteInt32(1); - Writer.WriteInt32(0); - Writer.WriteInt32(1); - Writer.WriteInt32(0x21d70); - Writer.WriteInt32(0); - Writer.WriteByte((byte)'g'); - Writer.WriteByte((byte)'m'); - Writer.WriteByte((byte)'2'); - Writer.WriteByte((byte)'0'); - Writer.WriteByte((byte)'b'); - Writer.WriteByte((byte)'\0'); - Writer.WriteByte((byte)'\0'); - Writer.WriteByte((byte)'\0'); - Writer.WriteInt64(0); - - return 0; - } - - private long NvGpuIoctlGetTpcMasks(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - - int MaskBuffSize = Reader.ReadInt32(); - int Reserved = Reader.ReadInt32(); - long MaskBuffAddr = Reader.ReadInt64(); - long Unknown = Reader.ReadInt64(); - - return 0; - } - - private long NvGpuIoctlZbcGetActiveSlotMask(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - Context.Memory.WriteInt32(Position + 0, 7); - Context.Memory.WriteInt32(Position + 4, 1); - - return 0; - } - - private long NvMapIoctlChannelSetUserData(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - return 0; - } - - private long NvMapIoctlChannelSetNvMap(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - int Fd = Context.Memory.ReadInt32(Position); - - return 0; - } - - private long NvMapIoctlChannelSubmitGpFifo(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - MemWriter Writer = new MemWriter(Context.Memory, Position + 0x10); - - long GpFifo = Reader.ReadInt64(); - int Count = Reader.ReadInt32(); - int Flags = Reader.ReadInt32(); - int FenceId = Reader.ReadInt32(); - int FenceVal = Reader.ReadInt32(); - - for (int Index = 0; Index < Count; Index++) - { - long GpFifoHdr = Reader.ReadInt64(); - - long GpuAddr = GpFifoHdr & 0xffffffffff; - - int Size = (int)(GpFifoHdr >> 40) & 0x7ffffc; - - long CpuAddr = Context.Ns.Gpu.GetCpuAddr(GpuAddr); - - if (CpuAddr != -1) - { - byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, CpuAddr, Size); - - NsGpuPBEntry[] PushBuffer = NsGpuPBEntry.DecodePushBuffer(Data); - - Context.Ns.Gpu.ProcessPushBuffer(PushBuffer, Context.Memory); - } - } - - Writer.WriteInt32(0); - Writer.WriteInt32(0); - - return 0; - } - - private long NvMapIoctlChannelAllocObjCtx(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - int ClassNum = Context.Memory.ReadInt32(Position + 0); - int Flags = Context.Memory.ReadInt32(Position + 4); - - Context.Memory.WriteInt32(Position + 8, 0); - - return 0; - } - - private long NvMapIoctlChannelZcullBind(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - - long GpuVa = Reader.ReadInt64(); - int Mode = Reader.ReadInt32(); - int Padding = Reader.ReadInt32(); - - return 0; - } - - private long NvMapIoctlChannelSetErrorNotifier(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - - long Offset = Reader.ReadInt64(); - long Size = Reader.ReadInt64(); - int Mem = Reader.ReadInt32(); - int Padding = Reader.ReadInt32(); - - return 0; - } - - private long NvMapIoctlChannelSetPriority(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - int Priority = Context.Memory.ReadInt32(Position); - - return 0; - } - - private long NvMapIoctlChannelAllocGpFifoEx2(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - MemWriter Writer = new MemWriter(Context.Memory, Position + 0xc); - - int Count = Reader.ReadInt32(); - int Flags = Reader.ReadInt32(); - int Unknown8 = Reader.ReadInt32(); - long Fence = Reader.ReadInt64(); - int Unknown14 = Reader.ReadInt32(); - int Unknown18 = Reader.ReadInt32(); - - Writer.WriteInt32(0); - Writer.WriteInt32(0); - - return 0; - } - - private long NvMapIocCreate(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - int Size = Context.Memory.ReadInt32(Position); - - NvMap Map = new NvMap() { Size = Size }; - - Map.Handle = NvMaps.Add(Context.Process, Map); - - Map.Id = NvMapsById.Add(Context.Process, Map); - - Context.Memory.WriteInt32(Position + 4, Map.Handle); - - Logging.Info($"NvMap {Map.Id} created with size {Size:x8}!"); - - return 0; - } - - private long NvMapIocFromId(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - int Id = Context.Memory.ReadInt32(Position); - - NvMap Map = NvMapsById.GetData(Context.Process, Id); - - if (Map == null) - { - Logging.Warn($"Trying to use invalid NvMap Id {Id}!"); - - return -1; //TODO: Corrent error code. - } - - Context.Memory.WriteInt32(Position + 4, Map.Handle); - - return 0; - } - - private long NvMapIocAlloc(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - - int Handle = Reader.ReadInt32(); - int HeapMask = Reader.ReadInt32(); - int Flags = Reader.ReadInt32(); - int Align = Reader.ReadInt32(); - byte Kind = (byte)Reader.ReadInt64(); - long Addr = Reader.ReadInt64(); - - NvMap Map = NvMaps.GetData(Context.Process, Handle); - - if (Map == null) - { - Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); - - return -1; //TODO: Corrent error code. - } - - Map.CpuAddress = Addr; - Map.Align = Align; - Map.Kind = Kind; - - return 0; - } - - private long NvMapIocFree(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - MemWriter Writer = new MemWriter(Context.Memory, Position + 8); - - int Handle = Reader.ReadInt32(); - int Padding = Reader.ReadInt32(); - - NvMap Map = NvMaps.GetData(Context.Process, Handle); - - if (Map == null) - { - Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); - - return -1; //TODO: Corrent error code. - } - - Writer.WriteInt64(0); - Writer.WriteInt32(Map.Size); - Writer.WriteInt32(0); - - return 0; - } - - private long NvMapIocParam(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - MemReader Reader = new MemReader(Context.Memory, Position); - - int Handle = Reader.ReadInt32(); - int Param = Reader.ReadInt32(); - - NvMap Map = NvMaps.GetData(Context.Process, Handle); - - if (Map == null) - { - Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); - - return -1; //TODO: Corrent error code. - } - - int Response = 0; - - switch (Param) - { - case 1: Response = Map.Size; break; - case 2: Response = Map.Align; break; - case 4: Response = 0x40000000; break; - case 5: Response = Map.Kind; break; - } - - Context.Memory.WriteInt32(Position + 8, Response); - - return 0; - } - - private long NvMapIocGetId(ServiceCtx Context) - { - long Position = Context.Request.GetSendBuffPtr(); - - int Handle = Context.Memory.ReadInt32(Position + 4); - - NvMap Map = NvMaps.GetData(Context.Process, Handle); - - if (Map == null) - { - Logging.Warn($"Trying to use invalid NvMap Handle {Handle}!"); - - return -1; //TODO: Corrent error code. - } - - Context.Memory.WriteInt32(Position, Map.Id); - - return 0; - } - - public void Dispose() - { - Dispose(true); - } - - protected virtual void Dispose(bool Disposing) - { - if (Disposing) - { - Event.Dispose(); - } - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Pctl/IParentalControlServiceFactory.cs b/Ryujinx.Core/OsHle/Services/Pctl/IParentalControlServiceFactory.cs new file mode 100644 index 00000000..5421f165 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Pctl/IParentalControlServiceFactory.cs @@ -0,0 +1,27 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Pctl +{ + class IParentalControlServiceFactory : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IParentalControlServiceFactory() + { + m_Commands = new Dictionary() + { + { 0, CreateService } + }; + } + + public static long CreateService(ServiceCtx Context) + { + MakeObject(Context, new IParentalControlService()); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs b/Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs deleted file mode 100644 index 0eb4cb87..00000000 --- a/Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Pctl -{ - class ServicePctl : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServicePctl() - { - m_Commands = new Dictionary() - { - { 0, CreateService } - }; - } - - public static long CreateService(ServiceCtx Context) - { - MakeObject(Context, new IParentalControlService()); - - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Pl/ISharedFontManager.cs b/Ryujinx.Core/OsHle/Services/Pl/ISharedFontManager.cs new file mode 100644 index 00000000..2872577f --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Pl/ISharedFontManager.cs @@ -0,0 +1,61 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Pl +{ + class ISharedFontManager : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public ISharedFontManager() + { + m_Commands = new Dictionary() + { + { 0, RequestLoad }, + { 1, GetLoadState }, + { 2, GetFontSize }, + { 3, GetSharedMemoryAddressOffset }, + { 4, GetSharedMemoryNativeHandle } + }; + } + + public long RequestLoad(ServiceCtx Context) + { + SharedFontType FontType = (SharedFontType)Context.RequestData.ReadInt32(); + + return 0; + } + + public long GetLoadState(ServiceCtx Context) + { + Context.ResponseData.Write(1); //Loaded + + return 0; + } + + public long GetFontSize(ServiceCtx Context) + { + Context.ResponseData.Write(Horizon.FontSize); + + return 0; + } + + public long GetSharedMemoryAddressOffset(ServiceCtx Context) + { + Context.ResponseData.Write(0); + + return 0; + } + + public long GetSharedMemoryNativeHandle(ServiceCtx Context) + { + int Handle = Context.Process.HandleTable.OpenHandle(Context.Ns.Os.FontSharedMem); + + Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs b/Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs deleted file mode 100644 index 8deaa5f4..00000000 --- a/Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Pl -{ - class ServicePl : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServicePl() - { - m_Commands = new Dictionary() - { - { 0, RequestLoad }, - { 1, GetLoadState }, - { 2, GetFontSize }, - { 3, GetSharedMemoryAddressOffset }, - { 4, GetSharedMemoryNativeHandle } - }; - } - - public long RequestLoad(ServiceCtx Context) - { - SharedFontType FontType = (SharedFontType)Context.RequestData.ReadInt32(); - - return 0; - } - - public long GetLoadState(ServiceCtx Context) - { - Context.ResponseData.Write(1); //Loaded - - return 0; - } - - public long GetFontSize(ServiceCtx Context) - { - Context.ResponseData.Write(Horizon.FontSize); - - return 0; - } - - public long GetSharedMemoryAddressOffset(ServiceCtx Context) - { - Context.ResponseData.Write(0); - - return 0; - } - - public long GetSharedMemoryNativeHandle(ServiceCtx Context) - { - int Handle = Context.Process.HandleTable.OpenHandle(Context.Ns.Os.FontSharedMem); - - Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); - - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ServiceFactory.cs b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs index 427b239b..76adcfa5 100644 --- a/Ryujinx.Core/OsHle/Services/ServiceFactory.cs +++ b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs @@ -7,7 +7,6 @@ using Ryujinx.Core.OsHle.Services.Friend; using Ryujinx.Core.OsHle.Services.FspSrv; using Ryujinx.Core.OsHle.Services.Hid; using Ryujinx.Core.OsHle.Services.Lm; -using Ryujinx.Core.OsHle.Services.Nifm; using Ryujinx.Core.OsHle.Services.Ns; using Ryujinx.Core.OsHle.Services.Nv; using Ryujinx.Core.OsHle.Services.Pctl; @@ -16,7 +15,6 @@ using Ryujinx.Core.OsHle.Services.Set; using Ryujinx.Core.OsHle.Services.Sfdnsres; using Ryujinx.Core.OsHle.Services.Sm; using Ryujinx.Core.OsHle.Services.Ssl; -using Ryujinx.Core.OsHle.Services.Time; using Ryujinx.Core.OsHle.Services.Vi; using System; @@ -29,19 +27,19 @@ namespace Ryujinx.Core.OsHle.Services switch (Name) { case "acc:u0": - return new ServiceAcc(); + return new IAccountServiceForApplication(); case "aoc:u": - return new ServiceNs(); + return new IAddOnContentManager(); case "apm": - return new ServiceApm(); + return new IManager(); case "apm:p": - return new ServiceApm(); + return new IManager(); case "appletOE": - return new ServiceAppletOE(); + return new IApplicationProxyService(); case "audout:u": return new IAudioOutManager(); @@ -50,67 +48,67 @@ namespace Ryujinx.Core.OsHle.Services return new IAudioRendererManager(); case "bsd:s": - return new ServiceBsd(); + return new IClient(); case "bsd:u": - return new ServiceBsd(); + return new IClient(); case "friend:a": - return new ServiceFriend(); + return new IServiceCreator(); case "fsp-srv": - return new ServiceFspSrv(); + return new IFileSystemProxy(); case "hid": - return new ServiceHid(); + return new IHidServer(); case "lm": - return new ServiceLm(); + return new ILogService(); case "nifm:u": - return new ServiceNifm(); + return new Nifm.IStaticService(); case "nvdrv": - return new ServiceNvDrv(); + return new INvDrvServices(); case "nvdrv:a": - return new ServiceNvDrv(); + return new INvDrvServices(); case "pctl:a": - return new ServicePctl(); + return new IParentalControlServiceFactory(); case "pl:u": - return new ServicePl(); + return new ISharedFontManager(); case "set": - return new ServiceSet(); + return new ISettingsServer(); case "set:sys": - return new ServiceSetSys(); + return new ISystemSettingsServer(); case "sfdnsres": - return new ServiceSfdnsres(); + return new IResolver(); case "sm:": - return new ServiceSm(); + return new IUserInterface(); case "ssl": - return new ServiceSsl(); + return new ISslService(); case "time:s": - return new ServiceTime(); + return new Time.IStaticService(); case "time:u": - return new ServiceTime(); + return new Time.IStaticService(); case "vi:m": - return new ServiceVi(); + return new IManagerRootService(); case "vi:s": - return new ServiceVi(); + return new ISystemRootService(); case "vi:u": - return new ServiceVi(); + return new IApplicationRootService(); } throw new NotImplementedException(Name); diff --git a/Ryujinx.Core/OsHle/Services/Set/ISettingsServer.cs b/Ryujinx.Core/OsHle/Services/Set/ISettingsServer.cs new file mode 100644 index 00000000..9d5b4888 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Set/ISettingsServer.cs @@ -0,0 +1,81 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Set +{ + class ISettingsServer : IpcService + { + private static string[] LanguageCodes = new string[] + { + "ja", + "en-US", + "fr", + "de", + "it", + "es", + "zh-CN", + "ko", + "nl", + "pt", + "ru", + "zh-TW", + "en-GB", + "fr-CA", + "es-419", + "zh-Hans", + "zh-Hant" + }; + + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public ISettingsServer() + { + m_Commands = new Dictionary() + { + { 1, GetAvailableLanguageCodes }, + { 3, GetAvailableLanguageCodeCount } + }; + } + + public static long GetAvailableLanguageCodes(ServiceCtx Context) + { + long Position = Context.Request.RecvListBuff[0].Position; + short Size = Context.Request.RecvListBuff[0].Size; + + int Count = (int)((uint)Size / 8); + + if (Count > LanguageCodes.Length) + { + Count = LanguageCodes.Length; + } + + for (int Index = 0; Index < Count; Index++) + { + string LanguageCode = LanguageCodes[Index]; + + foreach (char Chr in LanguageCode) + { + Context.Memory.WriteByte(Position++, (byte)Chr); + } + + for (int Offs = 0; Offs < (8 - LanguageCode.Length); Offs++) + { + Context.Memory.WriteByte(Position++, 0); + } + } + + Context.ResponseData.Write(Count); + + return 0; + } + + public static long GetAvailableLanguageCodeCount(ServiceCtx Context) + { + Context.ResponseData.Write(LanguageCodes.Length); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs b/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs new file mode 100644 index 00000000..0be46505 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs @@ -0,0 +1,33 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Set +{ + class ISystemSettingsServer : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public ISystemSettingsServer() + { + m_Commands = new Dictionary() + { + { 23, GetColorSetId }, + { 24, SetColorSetId } + }; + } + + public static long GetColorSetId(ServiceCtx Context) + { + Context.ResponseData.Write((int)Context.Ns.Settings.ThemeColor); + + return 0; + } + + public static long SetColorSetId(ServiceCtx Context) + { + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs b/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs deleted file mode 100644 index a2aaeeaf..00000000 --- a/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs +++ /dev/null @@ -1,81 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Set -{ - class ServiceSet : IpcService - { - private static string[] LanguageCodes = new string[] - { - "ja", - "en-US", - "fr", - "de", - "it", - "es", - "zh-CN", - "ko", - "nl", - "pt", - "ru", - "zh-TW", - "en-GB", - "fr-CA", - "es-419", - "zh-Hans", - "zh-Hant" - }; - - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceSet() - { - m_Commands = new Dictionary() - { - { 1, GetAvailableLanguageCodes }, - { 3, GetAvailableLanguageCodeCount } - }; - } - - public static long GetAvailableLanguageCodes(ServiceCtx Context) - { - long Position = Context.Request.RecvListBuff[0].Position; - short Size = Context.Request.RecvListBuff[0].Size; - - int Count = (int)((uint)Size / 8); - - if (Count > LanguageCodes.Length) - { - Count = LanguageCodes.Length; - } - - for (int Index = 0; Index < Count; Index++) - { - string LanguageCode = LanguageCodes[Index]; - - foreach (char Chr in LanguageCode) - { - Context.Memory.WriteByte(Position++, (byte)Chr); - } - - for (int Offs = 0; Offs < (8 - LanguageCode.Length); Offs++) - { - Context.Memory.WriteByte(Position++, 0); - } - } - - Context.ResponseData.Write(Count); - - return 0; - } - - public static long GetAvailableLanguageCodeCount(ServiceCtx Context) - { - Context.ResponseData.Write(LanguageCodes.Length); - - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Set/ServiceSetSys.cs b/Ryujinx.Core/OsHle/Services/Set/ServiceSetSys.cs deleted file mode 100644 index e4fcafcc..00000000 --- a/Ryujinx.Core/OsHle/Services/Set/ServiceSetSys.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Set -{ - class ServiceSetSys : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceSetSys() - { - m_Commands = new Dictionary() - { - { 23, GetColorSetId }, - { 24, SetColorSetId } - }; - } - - public static long GetColorSetId(ServiceCtx Context) - { - Context.ResponseData.Write((int)Context.Ns.Settings.ThemeColor); - - return 0; - } - - public static long SetColorSetId(ServiceCtx Context) - { - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Sfdnsres/IResolver.cs b/Ryujinx.Core/OsHle/Services/Sfdnsres/IResolver.cs new file mode 100644 index 00000000..e8d48cee --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Sfdnsres/IResolver.cs @@ -0,0 +1,20 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Sfdnsres +{ + class IResolver : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IResolver() + { + m_Commands = new Dictionary() + { + //... + }; + } + } +} diff --git a/Ryujinx.Core/OsHle/Services/Sfdnsres/ServiceSfdnsres.cs b/Ryujinx.Core/OsHle/Services/Sfdnsres/ServiceSfdnsres.cs deleted file mode 100644 index 1ef80829..00000000 --- a/Ryujinx.Core/OsHle/Services/Sfdnsres/ServiceSfdnsres.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Sfdnsres -{ - class ServiceSfdnsres : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceSfdnsres() - { - m_Commands = new Dictionary() - { - //{ 0, Function } - }; - } - } -} diff --git a/Ryujinx.Core/OsHle/Services/Sm/IUserInterface.cs b/Ryujinx.Core/OsHle/Services/Sm/IUserInterface.cs new file mode 100644 index 00000000..6b695dda --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Sm/IUserInterface.cs @@ -0,0 +1,69 @@ +using Ryujinx.Core.OsHle.Handles; +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Sm +{ + class IUserInterface : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + private bool IsInitialized; + + public IUserInterface() + { + m_Commands = new Dictionary() + { + { 0, Initialize }, + { 1, GetService } + }; + } + + private const int SmNotInitialized = 0x415; + + public long Initialize(ServiceCtx Context) + { + IsInitialized = true; + + return 0; + } + + public long GetService(ServiceCtx Context) + { + //Only for kernel version > 3.0.0. + if (!IsInitialized) + { + //return SmNotInitialized; + } + + string Name = string.Empty; + + for (int Index = 0; Index < 8 && + Context.RequestData.BaseStream.Position < + Context.RequestData.BaseStream.Length; Index++) + { + byte Chr = Context.RequestData.ReadByte(); + + if (Chr >= 0x20 && Chr < 0x7f) + { + Name += (char)Chr; + } + } + + if (Name == string.Empty) + { + return 0; + } + + KSession Session = new KSession(ServiceFactory.MakeService(Name)); + + int Handle = Context.Process.HandleTable.OpenHandle(Session); + + Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs b/Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs deleted file mode 100644 index e7fd4a10..00000000 --- a/Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Ryujinx.Core.OsHle.Handles; -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Sm -{ - class ServiceSm : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - private bool IsInitialized; - - public ServiceSm() - { - m_Commands = new Dictionary() - { - { 0, Initialize }, - { 1, GetService } - }; - } - - private const int SmNotInitialized = 0x415; - - public long Initialize(ServiceCtx Context) - { - IsInitialized = true; - - return 0; - } - - public long GetService(ServiceCtx Context) - { - //Only for kernel version > 3.0.0. - if (!IsInitialized) - { - //return SmNotInitialized; - } - - string Name = string.Empty; - - for (int Index = 0; Index < 8 && - Context.RequestData.BaseStream.Position < - Context.RequestData.BaseStream.Length; Index++) - { - byte Chr = Context.RequestData.ReadByte(); - - if (Chr >= 0x20 && Chr < 0x7f) - { - Name += (char)Chr; - } - } - - if (Name == string.Empty) - { - return 0; - } - - KSession Session = new KSession(ServiceFactory.MakeService(Name)); - - int Handle = Context.Process.HandleTable.OpenHandle(Session); - - Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle); - - return 0; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Ssl/ISslService.cs b/Ryujinx.Core/OsHle/Services/Ssl/ISslService.cs new file mode 100644 index 00000000..825e3363 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Ssl/ISslService.cs @@ -0,0 +1,20 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Ssl +{ + class ISslService : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public ISslService() + { + m_Commands = new Dictionary() + { + //... + }; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs b/Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs deleted file mode 100644 index e23811e0..00000000 --- a/Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Ssl -{ - class ServiceSsl : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceSsl() - { - m_Commands = new Dictionary() - { - //{ 0, Function } - }; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Time/IStaticService.cs b/Ryujinx.Core/OsHle/Services/Time/IStaticService.cs new file mode 100644 index 00000000..94d9ae74 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Time/IStaticService.cs @@ -0,0 +1,60 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Time +{ + class IStaticService : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IStaticService() + { + m_Commands = new Dictionary() + { + { 0, GetStandardUserSystemClock }, + { 1, GetStandardNetworkSystemClock }, + { 2, GetStandardSteadyClock }, + { 3, GetTimeZoneService }, + { 4, GetStandardLocalSystemClock } + }; + } + + public long GetStandardUserSystemClock(ServiceCtx Context) + { + MakeObject(Context, new ISystemClock(SystemClockType.User)); + + return 0; + } + + public long GetStandardNetworkSystemClock(ServiceCtx Context) + { + MakeObject(Context, new ISystemClock(SystemClockType.Network)); + + return 0; + } + + public long GetStandardSteadyClock(ServiceCtx Context) + { + MakeObject(Context, new ISteadyClock()); + + return 0; + } + + public long GetTimeZoneService(ServiceCtx Context) + { + MakeObject(Context, new ITimeZoneService()); + + return 0; + } + + public long GetStandardLocalSystemClock(ServiceCtx Context) + { + MakeObject(Context, new ISystemClock(SystemClockType.Local)); + + return 0; + } + + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs b/Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs deleted file mode 100644 index 00defb98..00000000 --- a/Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Time -{ - class ServiceTime : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceTime() - { - m_Commands = new Dictionary() - { - { 0, GetStandardUserSystemClock }, - { 1, GetStandardNetworkSystemClock }, - { 2, GetStandardSteadyClock }, - { 3, GetTimeZoneService }, - { 4, GetStandardLocalSystemClock } - }; - } - - public long GetStandardUserSystemClock(ServiceCtx Context) - { - MakeObject(Context, new ISystemClock(SystemClockType.User)); - - return 0; - } - - public long GetStandardNetworkSystemClock(ServiceCtx Context) - { - MakeObject(Context, new ISystemClock(SystemClockType.Network)); - - return 0; - } - - public long GetStandardSteadyClock(ServiceCtx Context) - { - MakeObject(Context, new ISteadyClock()); - - return 0; - } - - public long GetTimeZoneService(ServiceCtx Context) - { - MakeObject(Context, new ITimeZoneService()); - - return 0; - } - - public long GetStandardLocalSystemClock(ServiceCtx Context) - { - MakeObject(Context, new ISystemClock(SystemClockType.Local)); - - return 0; - } - - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Vi/IApplicationRootService.cs b/Ryujinx.Core/OsHle/Services/Vi/IApplicationRootService.cs new file mode 100644 index 00000000..d92b2d9d --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Vi/IApplicationRootService.cs @@ -0,0 +1,29 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Vi +{ + class IApplicationRootService : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IApplicationRootService() + { + m_Commands = new Dictionary() + { + { 0, GetDisplayService } + }; + } + + public long GetDisplayService(ServiceCtx Context) + { + int ServiceType = Context.RequestData.ReadInt32(); + + MakeObject(Context, new IApplicationDisplayService()); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Vi/IManagerRootService.cs b/Ryujinx.Core/OsHle/Services/Vi/IManagerRootService.cs new file mode 100644 index 00000000..177e5e66 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Vi/IManagerRootService.cs @@ -0,0 +1,29 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Vi +{ + class IManagerRootService : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public IManagerRootService() + { + m_Commands = new Dictionary() + { + { 2, GetDisplayService } + }; + } + + public long GetDisplayService(ServiceCtx Context) + { + int ServiceType = Context.RequestData.ReadInt32(); + + MakeObject(Context, new IApplicationDisplayService()); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Vi/ISystemRootService.cs b/Ryujinx.Core/OsHle/Services/Vi/ISystemRootService.cs new file mode 100644 index 00000000..47123a55 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Vi/ISystemRootService.cs @@ -0,0 +1,29 @@ +using Ryujinx.Core.OsHle.Ipc; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.Services.Vi +{ + class ISystemRootService : IpcService + { + private Dictionary m_Commands; + + public override IReadOnlyDictionary Commands => m_Commands; + + public ISystemRootService() + { + m_Commands = new Dictionary() + { + { 1, GetDisplayService } + }; + } + + public long GetDisplayService(ServiceCtx Context) + { + int ServiceType = Context.RequestData.ReadInt32(); + + MakeObject(Context, new IApplicationDisplayService()); + + return 0; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs index 36030d20..4301c0e6 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs @@ -62,7 +62,7 @@ namespace Ryujinx.Core.OsHle.Services.Android private BufferEntry[] BufferQueue; private ManualResetEvent WaitBufferFree; - + private object RenderQueueLock; private int RenderQueueCount; @@ -85,7 +85,7 @@ namespace Ryujinx.Core.OsHle.Services.Android { ("android.gui.IGraphicBufferProducer", 0xb), GbpDisconnect }, { ("android.gui.IGraphicBufferProducer", 0xe), GbpPreallocBuffer } }; - + this.Renderer = Renderer; this.ReleaseEvent = ReleaseEvent; @@ -139,7 +139,7 @@ namespace Ryujinx.Core.OsHle.Services.Android using (MemoryStream MS = new MemoryStream()) { BinaryWriter Writer = new BinaryWriter(MS); - + BufferEntry Entry = BufferQueue[Slot]; int BufferCount = 1; //? @@ -243,7 +243,7 @@ namespace Ryujinx.Core.OsHle.Services.Android private long GbpPreallocBuffer(ServiceCtx Context, BinaryReader ParcelReader) { int Slot = ParcelReader.ReadInt32(); - + int BufferCount = ParcelReader.ReadInt32(); long BufferSize = ParcelReader.ReadInt64(); @@ -290,10 +290,10 @@ namespace Ryujinx.Core.OsHle.Services.Android NvMap Map = GetNvMap(Context, Slot); - NvMapFb MapFb = (NvMapFb)ServiceNvDrv.NvMapsFb.GetData(Context.Process, 0); + NvMapFb MapFb = (NvMapFb)INvDrvServices.NvMapsFb.GetData(Context.Process, 0); long Address = Map.CpuAddress; - + if (MapFb.HasBufferOffset(Slot)) { Address += MapFb.GetBufferOffset(Slot); @@ -413,7 +413,7 @@ namespace Ryujinx.Core.OsHle.Services.Android NvMapHandle = BitConverter.ToInt32(RawValue, 0); } - return ServiceNvDrv.NvMaps.GetData(Context.Process, NvMapHandle); + return INvDrvServices.NvMaps.GetData(Context.Process, NvMapHandle); } private int GetFreeSlotBlocking(int Width, int Height) diff --git a/Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs b/Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs deleted file mode 100644 index cf814116..00000000 --- a/Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Ryujinx.Core.OsHle.Ipc; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle.Services.Vi -{ - class ServiceVi : IpcService - { - private Dictionary m_Commands; - - public override IReadOnlyDictionary Commands => m_Commands; - - public ServiceVi() - { - m_Commands = new Dictionary() - { - { 0, GetDisplayService }, - { 1, GetDisplayService }, - { 2, GetDisplayService } - }; - } - - public long GetDisplayService(ServiceCtx Context) - { - int ServiceType = Context.RequestData.ReadInt32(); - - MakeObject(Context, new IApplicationDisplayService()); - - return 0; - } - } -} \ No newline at end of file -- cgit v1.2.3