From 07f49e588e323f4247fe5abca529f738f12d8a8f Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Sun, 12 Apr 2020 19:30:56 -0500
Subject: [PATCH] Services/APT: Implemented the IsTitleAllowed function.

The Home Menu uses this to determine whether it is allowed to launch an app (call StartApplication)

This is a no-op for us, we allow any and all titles to be launched. The official APT module holds a list of some forbidden titles like some versions of IronFall and Flipnote Studio 3D.
---
 src/core/hle/service/apt/apt.cpp   | 15 +++++++++++++++
 src/core/hle/service/apt/apt.h     | 13 +++++++++++++
 src/core/hle/service/apt/apt_a.cpp |  2 +-
 src/core/hle/service/apt/apt_s.cpp |  2 +-
 4 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index d93b4bcb2..19f590540 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -878,6 +878,21 @@ void Module::APTInterface::CheckNew3DS(Kernel::HLERequestContext& ctx) {
     LOG_WARNING(Service_APT, "(STUBBED) called");
 }
 
+void Module::APTInterface::IsTitleAllowed(Kernel::HLERequestContext& ctx) {
+    IPC::RequestParser rp(ctx, 0x105, 4, 0); // 0x01050100
+    const u64 program_id = rp.Pop<u64>();
+    const auto media_type = rp.PopEnum<FS::MediaType>();
+    rp.Skip(1, false); // Padding
+
+    // We allow all titles to be launched, so this function is a no-op
+    IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
+    rb.Push(RESULT_SUCCESS);
+    rb.Push(true);
+
+    LOG_DEBUG(Service_APT, "called, title_id={:016X} media_type={}", program_id,
+              static_cast<u32>(media_type));
+}
+
 Module::APTInterface::APTInterface(std::shared_ptr<Module> apt, const char* name, u32 max_session)
     : ServiceFramework(name, max_session), apt(std::move(apt)) {}
 
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h
index 8b01d3b8e..261e15b1a 100644
--- a/src/core/hle/service/apt/apt.h
+++ b/src/core/hle/service/apt/apt.h
@@ -603,6 +603,19 @@ public:
          */
         void CheckNew3DS(Kernel::HLERequestContext& ctx);
 
+        /**
+         * APT::IsTitleAllowed service function
+         *  Inputs:
+         *      0 : Header Code[0x01050100]
+         *    1-2 : Program id
+         *      3 : Media type
+         *      4 : Padding
+         *  Outputs:
+         *      1: Result code, 0 on success, otherwise error code
+         *      2: u8 output, 0 if the title is not allowed, 1 if it is
+         */
+        void IsTitleAllowed(Kernel::HLERequestContext& ctx);
+
     protected:
         bool application_reset_prepared{};
         std::shared_ptr<Module> apt;
diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp
index 0d6e64d30..abe1a948b 100644
--- a/src/core/hle/service/apt/apt_a.cpp
+++ b/src/core/hle/service/apt/apt_a.cpp
@@ -100,7 +100,7 @@ APT_A::APT_A(std::shared_ptr<Module> apt)
         {0x01010000, &APT_A::CheckNew3DSApp, "CheckNew3DSApp"},
         {0x01020000, &APT_A::CheckNew3DS, "CheckNew3DS"},
         {0x01040000, nullptr, "IsStandardMemoryLayout"},
-        {0x01050100, nullptr, "IsTitleAllowed"},
+        {0x01050100, &APT_A::IsTitleAllowed, "IsTitleAllowed"},
     };
     RegisterHandlers(functions);
 }
diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp
index d0e5f5526..5e91fb930 100644
--- a/src/core/hle/service/apt/apt_s.cpp
+++ b/src/core/hle/service/apt/apt_s.cpp
@@ -100,7 +100,7 @@ APT_S::APT_S(std::shared_ptr<Module> apt)
         {0x01010000, &APT_S::CheckNew3DSApp, "CheckNew3DSApp"},
         {0x01020000, &APT_S::CheckNew3DS, "CheckNew3DS"},
         {0x01040000, nullptr, "IsStandardMemoryLayout"},
-        {0x01050100, nullptr, "IsTitleAllowed"},
+        {0x01050100, &APT_S::IsTitleAllowed, "IsTitleAllowed"},
     };
     RegisterHandlers(functions);
 }