From b06f468049829ba2d9e8f7e9e42710d9490e6b19 Mon Sep 17 00:00:00 2001
From: wwylele <wwylele@gmail.com>
Date: Fri, 22 Jun 2018 18:52:24 +0300
Subject: [PATCH] service/SSL: convert to ServiceFramework

---
 src/core/hle/service/service.cpp |  2 +-
 src/core/hle/service/ssl_c.cpp   | 91 +++++++++++++++++---------------
 src/core/hle/service/ssl_c.h     | 14 +++--
 3 files changed, 58 insertions(+), 49 deletions(-)

diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 7defd40b4..62a4b4e90 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -262,7 +262,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
     AddService(new HTTP::HTTP_C);
     AddService(new PM::PM_APP);
     AddService(new SOC::SOC_U);
-    AddService(new SSL::SSL_C);
+    SSL::InstallInterfaces(*sm);
     Y2R::InstallInterfaces(*sm);
 
     NGLOG_DEBUG(Service, "initialized OK");
diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp
index d71e2cf9c..63ef2c2bb 100644
--- a/src/core/hle/service/ssl_c.cpp
+++ b/src/core/hle/service/ssl_c.cpp
@@ -2,34 +2,31 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
-#include <random>
 #include "common/common_types.h"
 #include "core/hle/ipc.h"
+#include "core/hle/ipc_helpers.h"
 #include "core/hle/service/ssl_c.h"
-#include "core/memory.h"
 
 namespace Service {
 namespace SSL {
 
-// TODO: Implement a proper CSPRNG in the future when actual security is needed
-static std::mt19937 rand_gen;
-
-static void Initialize(Interface* self) {
-    u32* cmd_buff = Kernel::GetCommandBuffer();
+void SSL_C::Initialize(Kernel::HLERequestContext& ctx) {
+    IPC::RequestParser rp(ctx, 0x01, 0, 2);
+    rp.PopPID();
 
     // Seed random number generator when the SSL service is initialized
     std::random_device rand_device;
     rand_gen.seed(rand_device());
 
     // Stub, return success
-    cmd_buff[1] = RESULT_SUCCESS.raw;
+    IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
+    rb.Push(RESULT_SUCCESS);
 }
 
-static void GenerateRandomData(Interface* self) {
-    u32* cmd_buff = Kernel::GetCommandBuffer();
-
-    u32 size = cmd_buff[1];
-    VAddr address = cmd_buff[3];
+void SSL_C::GenerateRandomData(Kernel::HLERequestContext& ctx) {
+    IPC::RequestParser rp(ctx, 0x11, 1, 2);
+    u32 size = rp.Pop<u32>();
+    auto buffer = rp.PopMappedBuffer();
 
     // Fill the output buffer with random data.
     u32 data = 0;
@@ -43,49 +40,55 @@ static void GenerateRandomData(Interface* self) {
 
         if (size > 4) {
             // Use up the entire 4 bytes of the random data for as long as possible
-            Memory::Write32(address + i, data);
+            buffer.Write(&data, i, 4);
             i += 4;
         } else if (size == 2) {
-            Memory::Write16(address + i, static_cast<u16>(data & 0xffff));
+            buffer.Write(&data, i, 2);
             i += 2;
         } else {
-            Memory::Write8(address + i, static_cast<u8>(data & 0xff));
+            buffer.Write(&data, i, 1);
             i++;
         }
     }
 
     // Stub, return success
-    cmd_buff[1] = RESULT_SUCCESS.raw;
+    IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
+    rb.Push(RESULT_SUCCESS);
+    rb.PushMappedBuffer(buffer);
 }
 
-const Interface::FunctionInfo FunctionTable[] = {
-    {0x00010002, Initialize, "Initialize"},
-    {0x000200C2, nullptr, "CreateContext"},
-    {0x00030000, nullptr, "CreateRootCertChain"},
-    {0x00040040, nullptr, "DestroyRootCertChain"},
-    {0x00050082, nullptr, "AddTrustedRootCA"},
-    {0x00060080, nullptr, "RootCertChainAddDefaultCert"},
-    {0x00070080, nullptr, "RootCertChainRemoveCert"},
-    {0x000D0084, nullptr, "OpenClientCertContext"},
-    {0x000E0040, nullptr, "OpenDefaultClientCertContext"},
-    {0x000F0040, nullptr, "CloseClientCertContext"},
-    {0x00110042, GenerateRandomData, "GenerateRandomData"},
-    {0x00120042, nullptr, "InitializeConnectionSession"},
-    {0x00130040, nullptr, "StartConnection"},
-    {0x00140040, nullptr, "StartConnectionGetOut"},
-    {0x00150082, nullptr, "Read"},
-    {0x00160082, nullptr, "ReadPeek"},
-    {0x00170082, nullptr, "Write"},
-    {0x00180080, nullptr, "ContextSetRootCertChain"},
-    {0x00190080, nullptr, "ContextSetClientCert"},
-    {0x001B0080, nullptr, "ContextClearOpt"},
-    {0x001C00C4, nullptr, "ContextGetProtocolCipher"},
-    {0x001E0040, nullptr, "DestroyContext"},
-    {0x001F0082, nullptr, "ContextInitSharedmem"},
-};
+SSL_C::SSL_C() : ServiceFramework("ssl:C") {
+    static const FunctionInfo functions[] = {
+        {0x00010002, &SSL_C::Initialize, "Initialize"},
+        {0x000200C2, nullptr, "CreateContext"},
+        {0x00030000, nullptr, "CreateRootCertChain"},
+        {0x00040040, nullptr, "DestroyRootCertChain"},
+        {0x00050082, nullptr, "AddTrustedRootCA"},
+        {0x00060080, nullptr, "RootCertChainAddDefaultCert"},
+        {0x00070080, nullptr, "RootCertChainRemoveCert"},
+        {0x000D0084, nullptr, "OpenClientCertContext"},
+        {0x000E0040, nullptr, "OpenDefaultClientCertContext"},
+        {0x000F0040, nullptr, "CloseClientCertContext"},
+        {0x00110042, &SSL_C::GenerateRandomData, "GenerateRandomData"},
+        {0x00120042, nullptr, "InitializeConnectionSession"},
+        {0x00130040, nullptr, "StartConnection"},
+        {0x00140040, nullptr, "StartConnectionGetOut"},
+        {0x00150082, nullptr, "Read"},
+        {0x00160082, nullptr, "ReadPeek"},
+        {0x00170082, nullptr, "Write"},
+        {0x00180080, nullptr, "ContextSetRootCertChain"},
+        {0x00190080, nullptr, "ContextSetClientCert"},
+        {0x001B0080, nullptr, "ContextClearOpt"},
+        {0x001C00C4, nullptr, "ContextGetProtocolCipher"},
+        {0x001E0040, nullptr, "DestroyContext"},
+        {0x001F0082, nullptr, "ContextInitSharedmem"},
+    };
 
-SSL_C::SSL_C() {
-    Register(FunctionTable);
+    RegisterHandlers(functions);
+}
+
+void InstallInterfaces(SM::ServiceManager& service_manager) {
+    std::make_shared<SSL_C>()->InstallAsService(service_manager);
 }
 
 } // namespace SSL
diff --git a/src/core/hle/service/ssl_c.h b/src/core/hle/service/ssl_c.h
index fc50a2eb2..06d8f4371 100644
--- a/src/core/hle/service/ssl_c.h
+++ b/src/core/hle/service/ssl_c.h
@@ -4,19 +4,25 @@
 
 #pragma once
 
+#include <random>
 #include "core/hle/service/service.h"
 
 namespace Service {
 namespace SSL {
 
-class SSL_C final : public Interface {
+class SSL_C final : public ServiceFramework<SSL_C> {
 public:
     SSL_C();
 
-    std::string GetPortName() const override {
-        return "ssl:C";
-    }
+private:
+    void Initialize(Kernel::HLERequestContext& ctx);
+    void GenerateRandomData(Kernel::HLERequestContext& ctx);
+
+    // TODO: Implement a proper CSPRNG in the future when actual security is needed
+    std::mt19937 rand_gen;
 };
 
+void InstallInterfaces(SM::ServiceManager& service_manager);
+
 } // namespace SSL
 } // namespace Service