From 4906acdde96c09b4e12a3801a4bacd5233a2f8e6 Mon Sep 17 00:00:00 2001
From: Ac_K <Acoustik666@gmail.com>
Date: Sat, 21 Apr 2018 23:04:43 +0000
Subject: [PATCH] Some implementations (#99)

* Some implementations

- ICommonStateGetter
* GetBootMode
- ISelfController
* SetHandlesRequestToDisplay
- IServiceGetterInterface
- ISystemUpdateInterface
- IVulnerabilityManagerInterface
- IPrepoService
- ISettingsServer
* GetLanguageCode
- ISystemSettingsServer
* GetFirmwareVersion2
- IHOSBinderDriver
* TransactParcelAuto

* Fix Implementations

* Fix Implementations 2
---
 Ryujinx.Core/LogClass.cs                      |  1 +
 .../OsHle/Services/Am/ICommonStateGetter.cs   | 10 ++++
 .../OsHle/Services/Am/ISelfController.cs      | 12 +++-
 .../Services/Ns/IServiceGetterInterface.cs    | 20 +++++++
 .../Services/Ns/ISystemUpdateInterface.cs     | 20 +++++++
 .../Ns/IVulnerabilityManagerInterface.cs      | 20 +++++++
 .../OsHle/Services/Prepo/IPrepoService.cs     | 20 +++++++
 Ryujinx.Core/OsHle/Services/ServiceFactory.cs | 20 ++++++-
 .../OsHle/Services/Set/ISettingsServer.cs     | 28 ++++++++++
 .../Services/Set/ISystemSettingsServer.cs     | 56 ++++++++++++++++++-
 .../OsHle/Services/Vi/IHOSBinderDriver.cs     | 25 ++++++++-
 11 files changed, 223 insertions(+), 9 deletions(-)
 create mode 100644 Ryujinx.Core/OsHle/Services/Ns/IServiceGetterInterface.cs
 create mode 100644 Ryujinx.Core/OsHle/Services/Ns/ISystemUpdateInterface.cs
 create mode 100644 Ryujinx.Core/OsHle/Services/Ns/IVulnerabilityManagerInterface.cs
 create mode 100644 Ryujinx.Core/OsHle/Services/Prepo/IPrepoService.cs

diff --git a/Ryujinx.Core/LogClass.cs b/Ryujinx.Core/LogClass.cs
index 1a3fbb590..60a8de787 100644
--- a/Ryujinx.Core/LogClass.cs
+++ b/Ryujinx.Core/LogClass.cs
@@ -25,6 +25,7 @@
         ServiceNv,
         ServicePctl,
         ServicePl,
+        ServicePrepo,
         ServiceSet,
         ServiceSfdnsres,
         ServiceSm,
diff --git a/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs b/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs
index 7fb144ee1..c1b78e834 100644
--- a/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs
+++ b/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs
@@ -20,6 +20,7 @@ namespace Ryujinx.Core.OsHle.Services.Am
                 { 1, ReceiveMessage       },
                 { 5, GetOperationMode     },
                 { 6, GetPerformanceMode   },
+                { 8, GetBootMode          },
                 { 9, GetCurrentFocusState }
             };
         }
@@ -61,6 +62,15 @@ namespace Ryujinx.Core.OsHle.Services.Am
             return 0;
         }
 
+        public long GetBootMode(ServiceCtx Context)
+        {
+            Context.ResponseData.Write((byte)0); //Unknown value.
+
+            Logging.Stub(LogClass.ServiceAm, "Stubbed");
+
+            return 0;
+        }
+
         public long GetCurrentFocusState(ServiceCtx Context)
         {
             Context.ResponseData.Write((byte)Context.Process.AppletState.FocusState);
diff --git a/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs b/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs
index 2fb6d8567..e508b5f6a 100644
--- a/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs
+++ b/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs
@@ -19,7 +19,8 @@ namespace Ryujinx.Core.OsHle.Services.Am
                 { 12, SetPerformanceModeChangedNotification },
                 { 13, SetFocusHandlingMode                  },
                 { 14, SetRestartMessageEnabled              },
-                { 16, SetOutOfFocusSuspendingEnabled        }
+                { 16, SetOutOfFocusSuspendingEnabled        },
+                { 50, SetHandlesRequestToDisplay            }
             };
         }
 
@@ -83,5 +84,14 @@ namespace Ryujinx.Core.OsHle.Services.Am
 
             return 0;
         }
+
+        public long SetHandlesRequestToDisplay(ServiceCtx Context)
+        {
+            bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
+
+            Logging.Stub(LogClass.ServiceAm, $"HandlesRequestToDisplay Allowed = {Enable}");
+
+            return 0;
+        }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/Services/Ns/IServiceGetterInterface.cs b/Ryujinx.Core/OsHle/Services/Ns/IServiceGetterInterface.cs
new file mode 100644
index 000000000..603445f99
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Services/Ns/IServiceGetterInterface.cs
@@ -0,0 +1,20 @@
+using Ryujinx.Core.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.Core.OsHle.Services.Ns
+{
+    class IServiceGetterInterface : IpcService
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IServiceGetterInterface()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/Services/Ns/ISystemUpdateInterface.cs b/Ryujinx.Core/OsHle/Services/Ns/ISystemUpdateInterface.cs
new file mode 100644
index 000000000..4d9895ed9
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Services/Ns/ISystemUpdateInterface.cs
@@ -0,0 +1,20 @@
+using Ryujinx.Core.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.Core.OsHle.Services.Ns
+{
+    class ISystemUpdateInterface : IpcService
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public ISystemUpdateInterface()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/Services/Ns/IVulnerabilityManagerInterface.cs b/Ryujinx.Core/OsHle/Services/Ns/IVulnerabilityManagerInterface.cs
new file mode 100644
index 000000000..1091da0d3
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Services/Ns/IVulnerabilityManagerInterface.cs
@@ -0,0 +1,20 @@
+using Ryujinx.Core.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.Core.OsHle.Services.Ns
+{
+    class IVulnerabilityManagerInterface : IpcService
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IVulnerabilityManagerInterface()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/Services/Prepo/IPrepoService.cs b/Ryujinx.Core/OsHle/Services/Prepo/IPrepoService.cs
new file mode 100644
index 000000000..42e438414
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Services/Prepo/IPrepoService.cs
@@ -0,0 +1,20 @@
+using Ryujinx.Core.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.Core.OsHle.Services.Prepo
+{
+    class IPrepoService : IpcService
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IPrepoService()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/Services/ServiceFactory.cs b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs
index 0a9760ba3..11a5e46ab 100644
--- a/Ryujinx.Core/OsHle/Services/ServiceFactory.cs
+++ b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs
@@ -11,6 +11,7 @@ using Ryujinx.Core.OsHle.Services.Ns;
 using Ryujinx.Core.OsHle.Services.Nv;
 using Ryujinx.Core.OsHle.Services.Pctl;
 using Ryujinx.Core.OsHle.Services.Pl;
+using Ryujinx.Core.OsHle.Services.Prepo;
 using Ryujinx.Core.OsHle.Services.Set;
 using Ryujinx.Core.OsHle.Services.Sfdnsres;
 using Ryujinx.Core.OsHle.Services.Sm;
@@ -40,7 +41,7 @@ namespace Ryujinx.Core.OsHle.Services
 
                 case "appletAE":
                     return new IAllSystemAppletProxiesService();
-                    
+
                 case "appletOE":
                     return new IApplicationProxyService();
 
@@ -71,6 +72,15 @@ namespace Ryujinx.Core.OsHle.Services
                 case "nifm:u":
                     return new Nifm.IStaticService();
 
+                case "ns:ec":
+                    return new IServiceGetterInterface();
+
+                case "ns:su":
+                    return new ISystemUpdateInterface();
+
+                case "ns:vm":
+                    return new IVulnerabilityManagerInterface();
+
                 case "nvdrv":
                     return new INvDrvServices();
 
@@ -83,6 +93,9 @@ namespace Ryujinx.Core.OsHle.Services
                 case "pl:u":
                     return new ISharedFontManager();
 
+                case "prepo:u":
+                    return new IPrepoService();
+
                 case "set":
                     return new ISettingsServer();
 
@@ -98,6 +111,9 @@ namespace Ryujinx.Core.OsHle.Services
                 case "ssl":
                     return new ISslService();
 
+                case "time:a":
+                    return new Time.IStaticService();
+
                 case "time:s":
                     return new Time.IStaticService();
 
@@ -117,4 +133,4 @@ namespace Ryujinx.Core.OsHle.Services
             throw new NotImplementedException(Name);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/Services/Set/ISettingsServer.cs b/Ryujinx.Core/OsHle/Services/Set/ISettingsServer.cs
index 9d5b48880..ea0303f0a 100644
--- a/Ryujinx.Core/OsHle/Services/Set/ISettingsServer.cs
+++ b/Ryujinx.Core/OsHle/Services/Set/ISettingsServer.cs
@@ -1,5 +1,7 @@
 using Ryujinx.Core.OsHle.Ipc;
+using System;
 using System.Collections.Generic;
+using System.IO;
 
 namespace Ryujinx.Core.OsHle.Services.Set
 {
@@ -34,11 +36,37 @@ namespace Ryujinx.Core.OsHle.Services.Set
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
+                { 0, GetLanguageCode               },
                 { 1, GetAvailableLanguageCodes     },
                 { 3, GetAvailableLanguageCodeCount }
             };
         }
 
+        public static long GetLanguageCode(ServiceCtx Context)
+        {
+            Context.ResponseData.Write(LanguageCodetoLongBE(LanguageCodes[1]));
+
+            return 0;
+        }
+
+        private static long LanguageCodetoLongBE(string LanguageCode)
+        {
+            using (MemoryStream MS = new MemoryStream())
+            {
+                foreach (char Chr in LanguageCode)
+                {
+                    MS.WriteByte((byte)Chr);
+                }
+
+                for (int Offs = 0; Offs < (8 - LanguageCode.Length); Offs++)
+                {
+                    MS.WriteByte(0);
+                }
+
+                return BitConverter.ToInt64(MS.ToArray(), 0);
+            }
+        }
+
         public static long GetAvailableLanguageCodes(ServiceCtx Context)
         {
             long  Position = Context.Request.RecvListBuff[0].Position;
diff --git a/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs b/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs
index 21b737a06..bdf5c7b40 100644
--- a/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs
+++ b/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs
@@ -1,6 +1,9 @@
-using Ryujinx.Core.OsHle.Ipc;
+using ChocolArm64.Memory;
+using Ryujinx.Core.OsHle.Ipc;
 using Ryujinx.Core.Settings;
 using System.Collections.Generic;
+using System.IO;
+using System.Text;
 
 namespace Ryujinx.Core.OsHle.Services.Set
 {
@@ -14,11 +17,58 @@ namespace Ryujinx.Core.OsHle.Services.Set
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                { 23, GetColorSetId },
-                { 24, SetColorSetId }
+                {  4, GetFirmwareVersion2 },
+                { 23, GetColorSetId       },
+                { 24, SetColorSetId       }
             };
         }
 
+        public static long GetFirmwareVersion2(ServiceCtx Context)
+        {
+            long ReplyPos  = Context.Request.RecvListBuff[0].Position;
+            long ReplySize = Context.Request.RecvListBuff[0].Size;
+
+            byte MajorFWVersion = 0x03;
+            byte MinorFWVersion = 0x00;
+            byte MicroFWVersion = 0x00;
+            byte Unknown        = 0x00; //Build?
+
+            int RevisionNumber  = 0x0A;
+
+            string Platform     = "NX";
+            string UnknownHex   = "7fbde2b0bba4d14107bf836e4643043d9f6c8e47";
+            string Version      = "3.0.0";
+            string Build        = "NintendoSDK Firmware for NX 3.0.0-10.0";
+
+            //http://switchbrew.org/index.php?title=System_Version_Title
+            using (MemoryStream MS = new MemoryStream(0x100))
+            {
+                BinaryWriter Writer = new BinaryWriter(MS);
+
+                Writer.Write(MajorFWVersion);
+                Writer.Write(MinorFWVersion);
+                Writer.Write(MicroFWVersion);
+                Writer.Write(Unknown);
+
+                Writer.Write(RevisionNumber);
+
+                Writer.Write(Encoding.ASCII.GetBytes(Platform));
+
+                MS.Seek(0x28, SeekOrigin.Begin);
+                Writer.Write(Encoding.ASCII.GetBytes(UnknownHex));
+
+                MS.Seek(0x68, SeekOrigin.Begin);
+                Writer.Write(Encoding.ASCII.GetBytes(Version));
+
+                MS.Seek(0x80, SeekOrigin.Begin);
+                Writer.Write(Encoding.ASCII.GetBytes(Build));
+
+                AMemoryHelper.WriteBytes(Context.Memory, ReplyPos, MS.ToArray());
+            }
+
+            return 0;
+        }
+
         public static long GetColorSetId(ServiceCtx Context)
         {
             Context.ResponseData.Write((int)Context.Ns.Settings.ThemeColor);
diff --git a/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs b/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs
index b1b7a2682..72e8ef198 100644
--- a/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs
+++ b/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs
@@ -22,9 +22,10 @@ namespace Ryujinx.Core.OsHle.Services.Vi
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                { 0, TransactParcel  },
-                { 1, AdjustRefcount  },
-                { 2, GetNativeHandle }
+                { 0, TransactParcel     },
+                { 1, AdjustRefcount     },
+                { 2, GetNativeHandle    },
+                { 3, TransactParcelAuto }
             };
 
             ReleaseEvent = new KEvent();
@@ -47,6 +48,24 @@ namespace Ryujinx.Core.OsHle.Services.Vi
             return Flinger.ProcessParcelRequest(Context, Data, Code);
         }
 
+        //TransactParcelAuto(i32, u32, u32, buffer<unknown, 0x21, 0>) -> buffer<unknown, 0x22, 0>
+        //Buffer C (PtrBuff) and X (ReceiveListBuff) can be used here...
+        //But they are all null during all my tests.
+        public long TransactParcelAuto(ServiceCtx Context)
+        {
+            int Id   = Context.RequestData.ReadInt32();
+            int Code = Context.RequestData.ReadInt32();
+
+            long DataPos  = Context.Request.SendBuff[0].Position;
+            long DataSize = Context.Request.SendBuff[0].Size;
+
+            byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, DataPos, DataSize);
+
+            Data = Parcel.GetParcelData(Data);
+
+            return Flinger.ProcessParcelRequest(Context, Data, Code);
+        }
+
         public long AdjustRefcount(ServiceCtx Context)
         {
             int Id     = Context.RequestData.ReadInt32();