From 9a22e8d9ed52119e11a652e6c6eca1970d1d928f Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Sun, 10 Dec 2017 20:09:03 -0500
Subject: [PATCH] HLE/APT: Implement GetAppletInfo for LLE applets.

Calling this function for AppletId::Application is not yet implemented because we don't support launching applications from APT.
---
 src/core/hle/service/apt/apt.cpp | 34 +++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 4a4276e70..3e6d6b200 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -971,7 +971,20 @@ void GetAppletInfo(Service::Interface* self) {
     IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x6, 1, 0); // 0x60040
     auto app_id = static_cast<AppletId>(rp.Pop<u32>());
 
-    if (auto applet = HLE::Applets::Applet::Get(app_id)) {
+    LOG_DEBUG(Service_APT, "called appid=%u", static_cast<u32>(app_id));
+
+    const auto* slot = GetAppletSlotData(app_id);
+
+    if (slot == nullptr || !slot->registered) {
+        // See if there's an HLE applet and try to use it before erroring out.
+        auto hle_applet = HLE::Applets::Applet::Get(app_id);
+        if (hle_applet == nullptr) {
+            IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
+            rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::Applet,
+                               ErrorSummary::NotFound, ErrorLevel::Status));
+            return;
+        }
+
         // TODO(Subv): Get the title id for the current applet and write it in the response[2-3]
         IPC::RequestBuilder rb = rp.MakeBuilder(7, 0);
         rb.Push(RESULT_SUCCESS);
@@ -981,12 +994,27 @@ void GetAppletInfo(Service::Interface* self) {
         rb.Push(true);   // Registered
         rb.Push(true);   // Loaded
         rb.Push<u32>(0); // Applet Attributes
-    } else {
+        LOG_WARNING(Service_APT, "Using HLE applet info for applet %03X", static_cast<u32>(app_id));
+        return;
+    }
+
+    if (app_id == AppletId::Application) {
+        // TODO(Subv): Implement this once Application launching is implemented
+        LOG_ERROR(Service_APT, "Unimplemented GetAppletInfo(Application)");
         IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
         rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotFound,
                            ErrorLevel::Status));
+        return;
     }
-    LOG_WARNING(Service_APT, "(stubbed) called appid=%u", static_cast<u32>(app_id));
+
+    IPC::RequestBuilder rb = rp.MakeBuilder(7, 0);
+    rb.Push(RESULT_SUCCESS);
+    rb.Push(GetTitleIdForApplet(app_id));
+    // Note: The NS service hardcodes this to NAND for all applets except the Application applet.
+    rb.Push(static_cast<u8>(Service::FS::MediaType::NAND));
+    rb.Push(slot->registered);
+    rb.Push(slot->loaded);
+    rb.Push(slot->attributes.raw);
 }
 
 void GetStartupArgument(Service::Interface* self) {