service/apt: Implement Deliver Args (#5611)
* service/apt: Add GetModule and GetAppletManager These will be used to retrieve and set deliver args across system resets (which are currently implemented as complete restarts) * applet_manager: Implement DeliverArg `flags` was added to `ApplicationJumpParameters` as flags 0x2 is handled differently from 0x0. * service/apt: Add ReceiveDeliverArg, implement GetStartupArgument Some based on guesses. * Address review comments
This commit is contained in:
		| @@ -31,6 +31,8 @@ | |||||||
| #include "core/hle/kernel/kernel.h" | #include "core/hle/kernel/kernel.h" | ||||||
| #include "core/hle/kernel/process.h" | #include "core/hle/kernel/process.h" | ||||||
| #include "core/hle/kernel/thread.h" | #include "core/hle/kernel/thread.h" | ||||||
|  | #include "core/hle/service/apt/applet_manager.h" | ||||||
|  | #include "core/hle/service/apt/apt.h" | ||||||
| #include "core/hle/service/fs/archive.h" | #include "core/hle/service/fs/archive.h" | ||||||
| #include "core/hle/service/gsp/gsp.h" | #include "core/hle/service/gsp/gsp.h" | ||||||
| #include "core/hle/service/pm/pm_app.h" | #include "core/hle/service/pm/pm_app.h" | ||||||
| @@ -561,9 +563,20 @@ void System::Reset() { | |||||||
|     // reloading. |     // reloading. | ||||||
|     // TODO: Properly implement the reset |     // TODO: Properly implement the reset | ||||||
|  |  | ||||||
|  |     // Since the system is completely reinitialized, we'll have to store the deliver arg manually. | ||||||
|  |     boost::optional<Service::APT::AppletManager::DeliverArg> deliver_arg; | ||||||
|  |     if (auto apt = Service::APT::GetModule(*this)) { | ||||||
|  |         deliver_arg = apt->GetAppletManager()->ReceiveDeliverArg(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     Shutdown(); |     Shutdown(); | ||||||
|     // Reload the system with the same setting |     // Reload the system with the same setting | ||||||
|     Load(*m_emu_window, m_filepath); |     Load(*m_emu_window, m_filepath); | ||||||
|  |  | ||||||
|  |     // Restore the deliver arg. | ||||||
|  |     if (auto apt = Service::APT::GetModule(*this)) { | ||||||
|  |         apt->GetAppletManager()->SetDeliverArg(std::move(deliver_arg)); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| template <class Archive> | template <class Archive> | ||||||
|   | |||||||
| @@ -498,6 +498,7 @@ ResultCode AppletManager::PrepareToDoApplicationJump(u64 title_id, FS::MediaType | |||||||
|     app_jump_parameters.current_media_type = FS::MediaType::NAND; |     app_jump_parameters.current_media_type = FS::MediaType::NAND; | ||||||
|     app_jump_parameters.next_title_id = title_id; |     app_jump_parameters.next_title_id = title_id; | ||||||
|     app_jump_parameters.next_media_type = media_type; |     app_jump_parameters.next_media_type = media_type; | ||||||
|  |     app_jump_parameters.flags = flags; | ||||||
|  |  | ||||||
|     // Note: The real console uses the Home Menu to perform the application jump, therefore the menu |     // Note: The real console uses the Home Menu to perform the application jump, therefore the menu | ||||||
|     // needs to be running. The real APT module starts the Home Menu here if it's not already |     // needs to be running. The real APT module starts the Home Menu here if it's not already | ||||||
| @@ -505,16 +506,23 @@ ResultCode AppletManager::PrepareToDoApplicationJump(u64 title_id, FS::MediaType | |||||||
|     return RESULT_SUCCESS; |     return RESULT_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
| ResultCode AppletManager::DoApplicationJump() { | ResultCode AppletManager::DoApplicationJump(DeliverArg arg) { | ||||||
|     // Note: The real console uses the Home Menu to perform the application jump, it goes |     // Note: The real console uses the Home Menu to perform the application jump, it goes | ||||||
|     // OldApplication->Home Menu->NewApplication. We do not need to use the Home Menu to do this so |     // OldApplication->Home Menu->NewApplication. We do not need to use the Home Menu to do this so | ||||||
|     // we launch the new application directly. In the real APT service, the Home Menu must be |     // we launch the new application directly. In the real APT service, the Home Menu must be | ||||||
|     // running to do this, otherwise error 0xC8A0CFF0 is returned. |     // running to do this, otherwise error 0xC8A0CFF0 is returned. | ||||||
|  |  | ||||||
|     auto& application_slot = applet_slots[static_cast<size_t>(AppletSlot::Application)]; |     auto& application_slot = applet_slots[static_cast<size_t>(AppletSlot::Application)]; | ||||||
|  |  | ||||||
|  |     if (app_jump_parameters.flags != ApplicationJumpFlags::UseCurrentParameters) { | ||||||
|  |         // The source program ID is not updated when using flags 0x2. | ||||||
|  |         arg.source_program_id = application_slot.title_id; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     application_slot.Reset(); |     application_slot.Reset(); | ||||||
|  |  | ||||||
|     // TODO(Subv): Set the delivery parameters. |     // Set the delivery parameters. | ||||||
|  |     deliver_arg = std::move(arg); | ||||||
|  |  | ||||||
|     // TODO(Subv): Terminate the current Application. |     // TODO(Subv): Terminate the current Application. | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,7 +5,9 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <array> | #include <array> | ||||||
|  | #include <limits> | ||||||
| #include <memory> | #include <memory> | ||||||
|  | #include <optional> | ||||||
| #include <vector> | #include <vector> | ||||||
| #include <boost/serialization/array.hpp> | #include <boost/serialization/array.hpp> | ||||||
| #include <boost/serialization/optional.hpp> | #include <boost/serialization/optional.hpp> | ||||||
| @@ -158,7 +160,30 @@ public: | |||||||
|  |  | ||||||
|     ResultCode PrepareToDoApplicationJump(u64 title_id, FS::MediaType media_type, |     ResultCode PrepareToDoApplicationJump(u64 title_id, FS::MediaType media_type, | ||||||
|                                           ApplicationJumpFlags flags); |                                           ApplicationJumpFlags flags); | ||||||
|     ResultCode DoApplicationJump(); |  | ||||||
|  |     struct DeliverArg { | ||||||
|  |         std::vector<u8> param; | ||||||
|  |         std::vector<u8> hmac; | ||||||
|  |         u64 source_program_id = std::numeric_limits<u64>::max(); | ||||||
|  |  | ||||||
|  |     private: | ||||||
|  |         template <class Archive> | ||||||
|  |         void serialize(Archive& ar, const unsigned int) { | ||||||
|  |             ar& param; | ||||||
|  |             ar& hmac; | ||||||
|  |             ar& source_program_id; | ||||||
|  |         } | ||||||
|  |         friend class boost::serialization::access; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     ResultCode DoApplicationJump(DeliverArg arg); | ||||||
|  |  | ||||||
|  |     boost::optional<DeliverArg> ReceiveDeliverArg() const { | ||||||
|  |         return deliver_arg; | ||||||
|  |     } | ||||||
|  |     void SetDeliverArg(boost::optional<DeliverArg> arg) { | ||||||
|  |         deliver_arg = std::move(arg); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     struct AppletInfo { |     struct AppletInfo { | ||||||
|         u64 title_id; |         u64 title_id; | ||||||
| @@ -173,15 +198,19 @@ public: | |||||||
|     struct ApplicationJumpParameters { |     struct ApplicationJumpParameters { | ||||||
|         u64 next_title_id; |         u64 next_title_id; | ||||||
|         FS::MediaType next_media_type; |         FS::MediaType next_media_type; | ||||||
|  |         ApplicationJumpFlags flags; | ||||||
|  |  | ||||||
|         u64 current_title_id; |         u64 current_title_id; | ||||||
|         FS::MediaType current_media_type; |         FS::MediaType current_media_type; | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|         template <class Archive> |         template <class Archive> | ||||||
|         void serialize(Archive& ar, const unsigned int) { |         void serialize(Archive& ar, const unsigned int file_version) { | ||||||
|             ar& next_title_id; |             ar& next_title_id; | ||||||
|             ar& next_media_type; |             ar& next_media_type; | ||||||
|  |             if (file_version > 0) { | ||||||
|  |                 ar& flags; | ||||||
|  |             } | ||||||
|             ar& current_title_id; |             ar& current_title_id; | ||||||
|             ar& current_media_type; |             ar& current_media_type; | ||||||
|         } |         } | ||||||
| @@ -242,6 +271,7 @@ private: | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     ApplicationJumpParameters app_jump_parameters{}; |     ApplicationJumpParameters app_jump_parameters{}; | ||||||
|  |     boost::optional<DeliverArg> deliver_arg{}; | ||||||
|  |  | ||||||
|     // Holds data about the concurrently running applets in the system. |     // Holds data about the concurrently running applets in the system. | ||||||
|     std::array<AppletSlotData, NumAppletSlot> applet_slots = {}; |     std::array<AppletSlotData, NumAppletSlot> applet_slots = {}; | ||||||
| @@ -259,9 +289,12 @@ private: | |||||||
|  |  | ||||||
| private: | private: | ||||||
|     template <class Archive> |     template <class Archive> | ||||||
|     void serialize(Archive& ar, const unsigned int) { |     void serialize(Archive& ar, const unsigned int file_version) { | ||||||
|         ar& next_parameter; |         ar& next_parameter; | ||||||
|         ar& app_jump_parameters; |         ar& app_jump_parameters; | ||||||
|  |         if (file_version > 0) { | ||||||
|  |             ar& deliver_arg; | ||||||
|  |         } | ||||||
|         ar& applet_slots; |         ar& applet_slots; | ||||||
|         ar& library_applet_closing_command; |         ar& library_applet_closing_command; | ||||||
|     } |     } | ||||||
| @@ -270,4 +303,7 @@ private: | |||||||
|  |  | ||||||
| } // namespace Service::APT | } // namespace Service::APT | ||||||
|  |  | ||||||
|  | BOOST_CLASS_VERSION(Service::APT::AppletManager::ApplicationJumpParameters, 1) | ||||||
|  | BOOST_CLASS_VERSION(Service::APT::AppletManager, 1) | ||||||
|  |  | ||||||
| SERVICE_CONSTRUCT(Service::APT::AppletManager) | SERVICE_CONSTRUCT(Service::APT::AppletManager) | ||||||
|   | |||||||
| @@ -56,6 +56,10 @@ Module::NSInterface::NSInterface(std::shared_ptr<Module> apt, const char* name, | |||||||
|  |  | ||||||
| Module::NSInterface::~NSInterface() = default; | Module::NSInterface::~NSInterface() = default; | ||||||
|  |  | ||||||
|  | std::shared_ptr<Module> Module::NSInterface::GetModule() const { | ||||||
|  |     return apt; | ||||||
|  | } | ||||||
|  |  | ||||||
| void Module::NSInterface::SetWirelessRebootInfo(Kernel::HLERequestContext& ctx) { | void Module::NSInterface::SetWirelessRebootInfo(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp(ctx, 0x06, 1, 2); // 0x00060042 |     IPC::RequestParser rp(ctx, 0x06, 1, 2); // 0x00060042 | ||||||
|     u32 size = rp.Pop<u32>(); |     u32 size = rp.Pop<u32>(); | ||||||
| @@ -476,19 +480,32 @@ void Module::APTInterface::PrepareToDoApplicationJump(Kernel::HLERequestContext& | |||||||
|  |  | ||||||
| void Module::APTInterface::DoApplicationJump(Kernel::HLERequestContext& ctx) { | void Module::APTInterface::DoApplicationJump(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp(ctx, 0x32, 2, 4); // 0x00320084 |     IPC::RequestParser rp(ctx, 0x32, 2, 4); // 0x00320084 | ||||||
|     const auto param_size = rp.Pop<u32>(); |     auto param_size = rp.Pop<u32>(); | ||||||
|     const auto hmac_size = rp.Pop<u32>(); |     auto hmac_size = rp.Pop<u32>(); | ||||||
|  |  | ||||||
|     [[maybe_unused]] const auto param = rp.PopStaticBuffer(); |     constexpr u32 max_param_size{0x300}; | ||||||
|     [[maybe_unused]] const auto hmac = rp.PopStaticBuffer(); |     constexpr u32 max_hmac_size{0x20}; | ||||||
|  |     if (param_size > max_param_size) { | ||||||
|  |         LOG_ERROR(Service_APT, | ||||||
|  |                   "Param size is outside the valid range (capped to {:#010X}): param_size={:#010X}", | ||||||
|  |                   max_param_size, param_size); | ||||||
|  |         param_size = max_param_size; | ||||||
|  |     } | ||||||
|  |     if (hmac_size > max_hmac_size) { | ||||||
|  |         LOG_ERROR(Service_APT, | ||||||
|  |                   "HMAC size is outside the valid range (capped to {:#010X}): hmac_size={:#010X}", | ||||||
|  |                   max_hmac_size, hmac_size); | ||||||
|  |         hmac_size = max_hmac_size; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     LOG_WARNING(Service_APT, "(STUBBED) called param_size={:08X}, hmac_size={:08X}", param_size, |     auto param = rp.PopStaticBuffer(); | ||||||
|                 hmac_size); |     auto hmac = rp.PopStaticBuffer(); | ||||||
|  |  | ||||||
|     // TODO(Subv): Set the delivery parameters before starting the new application. |     LOG_INFO(Service_APT, "called param_size={:08X}, hmac_size={:08X}", param_size, hmac_size); | ||||||
|  |  | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); |     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||||
|     rb.Push(apt->applet_manager->DoApplicationJump()); |     rb.Push(apt->applet_manager->DoApplicationJump( | ||||||
|  |         AppletManager::DeliverArg{std::move(param), std::move(hmac)})); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Module::APTInterface::GetProgramIdOnApplicationJump(Kernel::HLERequestContext& ctx) { | void Module::APTInterface::GetProgramIdOnApplicationJump(Kernel::HLERequestContext& ctx) { | ||||||
| @@ -506,6 +523,25 @@ void Module::APTInterface::GetProgramIdOnApplicationJump(Kernel::HLERequestConte | |||||||
|     rb.Push(static_cast<u8>(parameters.next_media_type)); |     rb.Push(static_cast<u8>(parameters.next_media_type)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void Module::APTInterface::ReceiveDeliverArg(Kernel::HLERequestContext& ctx) { | ||||||
|  |     IPC::RequestParser rp(ctx, 0x35, 2, 4); // 0x00350080 | ||||||
|  |     const auto param_size = rp.Pop<u32>(); | ||||||
|  |     const auto hmac_size = rp.Pop<u32>(); | ||||||
|  |  | ||||||
|  |     LOG_DEBUG(Service_APT, "called param_size={:08X}, hmac_size={:08X}", param_size, hmac_size); | ||||||
|  |  | ||||||
|  |     auto arg = apt->applet_manager->ReceiveDeliverArg().value_or(AppletManager::DeliverArg{}); | ||||||
|  |     arg.param.resize(param_size); | ||||||
|  |     arg.hmac.resize(std::max<std::size_t>(hmac_size, 0x20)); | ||||||
|  |  | ||||||
|  |     IPC::RequestBuilder rb = rp.MakeBuilder(4, 4); | ||||||
|  |     rb.Push(RESULT_SUCCESS); | ||||||
|  |     rb.Push(arg.source_program_id); | ||||||
|  |     rb.Push<u8>(1); | ||||||
|  |     rb.PushStaticBuffer(std::move(arg.param), 0); | ||||||
|  |     rb.PushStaticBuffer(std::move(arg.hmac), 1); | ||||||
|  | } | ||||||
|  |  | ||||||
| void Module::APTInterface::PrepareToStartApplication(Kernel::HLERequestContext& ctx) { | void Module::APTInterface::PrepareToStartApplication(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp(ctx, 0x15, 5, 0); // 0x00150140 |     IPC::RequestParser rp(ctx, 0x15, 5, 0); // 0x00150140 | ||||||
|     u32 title_info1 = rp.Pop<u32>(); |     u32 title_info1 = rp.Pop<u32>(); | ||||||
| @@ -809,6 +845,9 @@ void Module::APTInterface::GetStartupArgument(Kernel::HLERequestContext& ctx) { | |||||||
|     constexpr u32 max_parameter_size{0x1000}; |     constexpr u32 max_parameter_size{0x1000}; | ||||||
|     const auto startup_argument_type = static_cast<StartupArgumentType>(rp.Pop<u8>()); |     const auto startup_argument_type = static_cast<StartupArgumentType>(rp.Pop<u8>()); | ||||||
|  |  | ||||||
|  |     LOG_WARNING(Service_APT, "called, startup_argument_type={}, parameter_size={:#010X}", | ||||||
|  |                 static_cast<u32>(startup_argument_type), parameter_size); | ||||||
|  |  | ||||||
|     if (parameter_size > max_parameter_size) { |     if (parameter_size > max_parameter_size) { | ||||||
|         LOG_ERROR(Service_APT, |         LOG_ERROR(Service_APT, | ||||||
|                   "Parameter size is outside the valid range (capped to {:#010X}): " |                   "Parameter size is outside the valid range (capped to {:#010X}): " | ||||||
| @@ -817,15 +856,36 @@ void Module::APTInterface::GetStartupArgument(Kernel::HLERequestContext& ctx) { | |||||||
|         parameter_size = max_parameter_size; |         parameter_size = max_parameter_size; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     std::vector<u8> parameter(parameter_size); |     std::vector<u8> param; | ||||||
|  |     bool exists = false; | ||||||
|  |  | ||||||
|     LOG_WARNING(Service_APT, "(STUBBED) called, startup_argument_type={}, parameter_size={:#010X}", |     if (auto arg = apt->applet_manager->ReceiveDeliverArg()) { | ||||||
|                 static_cast<u32>(startup_argument_type), parameter_size); |         param = std::move(arg->param); | ||||||
|  |  | ||||||
|  |         // TODO: This is a complete guess based on observations. It is unknown how the OtherMedia | ||||||
|  |         // type is handled and how it interacts with the OtherApp type, and it is unknown if | ||||||
|  |         // this (checking the jump parameters) is indeed the way the 3DS checks the types. | ||||||
|  |         const auto& jump_parameters = apt->applet_manager->GetApplicationJumpParameters(); | ||||||
|  |         switch (startup_argument_type) { | ||||||
|  |         case StartupArgumentType::OtherApp: | ||||||
|  |             exists = jump_parameters.current_title_id != jump_parameters.next_title_id && | ||||||
|  |                      jump_parameters.current_media_type == jump_parameters.next_media_type; | ||||||
|  |             break; | ||||||
|  |         case StartupArgumentType::Restart: | ||||||
|  |             exists = jump_parameters.current_title_id == jump_parameters.next_title_id; | ||||||
|  |             break; | ||||||
|  |         case StartupArgumentType::OtherMedia: | ||||||
|  |             exists = jump_parameters.current_media_type != jump_parameters.next_media_type; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     param.resize(parameter_size); | ||||||
|  |  | ||||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); |     IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|     rb.Push<u32>(0); |     rb.Push(exists); | ||||||
|     rb.PushStaticBuffer(std::move(parameter), 0); |     rb.PushStaticBuffer(std::move(param), 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Module::APTInterface::Wrap(Kernel::HLERequestContext& ctx) { | void Module::APTInterface::Wrap(Kernel::HLERequestContext& ctx) { | ||||||
| @@ -967,6 +1027,10 @@ Module::APTInterface::APTInterface(std::shared_ptr<Module> apt, const char* name | |||||||
|  |  | ||||||
| Module::APTInterface::~APTInterface() = default; | Module::APTInterface::~APTInterface() = default; | ||||||
|  |  | ||||||
|  | std::shared_ptr<Module> Module::APTInterface::GetModule() const { | ||||||
|  |     return apt; | ||||||
|  | } | ||||||
|  |  | ||||||
| Module::Module(Core::System& system) : system(system) { | Module::Module(Core::System& system) : system(system) { | ||||||
|     applet_manager = std::make_shared<AppletManager>(system); |     applet_manager = std::make_shared<AppletManager>(system); | ||||||
|  |  | ||||||
| @@ -982,6 +1046,17 @@ Module::Module(Core::System& system) : system(system) { | |||||||
|  |  | ||||||
| Module::~Module() {} | Module::~Module() {} | ||||||
|  |  | ||||||
|  | std::shared_ptr<AppletManager> Module::GetAppletManager() const { | ||||||
|  |     return applet_manager; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::shared_ptr<Module> GetModule(Core::System& system) { | ||||||
|  |     auto apt = system.ServiceManager().GetService<Service::APT::Module::APTInterface>("APT:A"); | ||||||
|  |     if (!apt) | ||||||
|  |         return nullptr; | ||||||
|  |     return apt->GetModule(); | ||||||
|  | } | ||||||
|  |  | ||||||
| void InstallInterfaces(Core::System& system) { | void InstallInterfaces(Core::System& system) { | ||||||
|     auto& service_manager = system.ServiceManager(); |     auto& service_manager = system.ServiceManager(); | ||||||
|     auto apt = std::make_shared<Module>(system); |     auto apt = std::make_shared<Module>(system); | ||||||
|   | |||||||
| @@ -65,11 +65,15 @@ public: | |||||||
|     explicit Module(Core::System& system); |     explicit Module(Core::System& system); | ||||||
|     ~Module(); |     ~Module(); | ||||||
|  |  | ||||||
|  |     std::shared_ptr<AppletManager> GetAppletManager() const; | ||||||
|  |  | ||||||
|     class NSInterface : public ServiceFramework<NSInterface> { |     class NSInterface : public ServiceFramework<NSInterface> { | ||||||
|     public: |     public: | ||||||
|         NSInterface(std::shared_ptr<Module> apt, const char* name, u32 max_session); |         NSInterface(std::shared_ptr<Module> apt, const char* name, u32 max_session); | ||||||
|         ~NSInterface(); |         ~NSInterface(); | ||||||
|  |  | ||||||
|  |         std::shared_ptr<Module> GetModule() const; | ||||||
|  |  | ||||||
|     protected: |     protected: | ||||||
|         std::shared_ptr<Module> apt; |         std::shared_ptr<Module> apt; | ||||||
|  |  | ||||||
| @@ -90,6 +94,8 @@ public: | |||||||
|         APTInterface(std::shared_ptr<Module> apt, const char* name, u32 max_session); |         APTInterface(std::shared_ptr<Module> apt, const char* name, u32 max_session); | ||||||
|         ~APTInterface(); |         ~APTInterface(); | ||||||
|  |  | ||||||
|  |         std::shared_ptr<Module> GetModule() const; | ||||||
|  |  | ||||||
|     protected: |     protected: | ||||||
|         /** |         /** | ||||||
|          * APT::Initialize service function |          * APT::Initialize service function | ||||||
| @@ -505,6 +511,23 @@ public: | |||||||
|          */ |          */ | ||||||
|         void GetProgramIdOnApplicationJump(Kernel::HLERequestContext& ctx); |         void GetProgramIdOnApplicationJump(Kernel::HLERequestContext& ctx); | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * APT::ReceiveDeliverArg service function | ||||||
|  |          *  Inputs: | ||||||
|  |          *      0 : Command header [0x00350080] | ||||||
|  |          *      1 : Parameter Size (capped to 0x300) | ||||||
|  |          *      2 : HMAC Size (capped to 0x20) | ||||||
|  |          *     64 : (Parameter Size << 14) | 2 | ||||||
|  |          *     65 : Output buffer for Parameter | ||||||
|  |          *     66 : (HMAC Size << 14) | 0x802 | ||||||
|  |          *     67 : Output buffer for HMAC | ||||||
|  |          *  Outputs: | ||||||
|  |          *      1 : Result of function, 0 on success, otherwise error code | ||||||
|  |          *    2-3 : Source program id | ||||||
|  |          *      4 : u8, whether the arg is received (0 = not received, 1 = received) | ||||||
|  |          */ | ||||||
|  |         void ReceiveDeliverArg(Kernel::HLERequestContext& ctx); | ||||||
|  |  | ||||||
|         /** |         /** | ||||||
|          * APT::CancelLibraryApplet service function |          * APT::CancelLibraryApplet service function | ||||||
|          *  Inputs: |          *  Inputs: | ||||||
| @@ -725,6 +748,8 @@ private: | |||||||
|     friend class boost::serialization::access; |     friend class boost::serialization::access; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | std::shared_ptr<Module> GetModule(Core::System& system); | ||||||
|  |  | ||||||
| void InstallInterfaces(Core::System& system); | void InstallInterfaces(Core::System& system); | ||||||
|  |  | ||||||
| } // namespace Service::APT | } // namespace Service::APT | ||||||
|   | |||||||
| @@ -62,7 +62,7 @@ APT_A::APT_A(std::shared_ptr<Module> apt) | |||||||
|         {0x00320084, &APT_A::DoApplicationJump, "DoApplicationJump"}, |         {0x00320084, &APT_A::DoApplicationJump, "DoApplicationJump"}, | ||||||
|         {0x00330000, &APT_A::GetProgramIdOnApplicationJump, "GetProgramIdOnApplicationJump"}, |         {0x00330000, &APT_A::GetProgramIdOnApplicationJump, "GetProgramIdOnApplicationJump"}, | ||||||
|         {0x00340084, nullptr, "SendDeliverArg"}, |         {0x00340084, nullptr, "SendDeliverArg"}, | ||||||
|         {0x00350080, nullptr, "ReceiveDeliverArg"}, |         {0x00350080, &APT_A::ReceiveDeliverArg, "ReceiveDeliverArg"}, | ||||||
|         {0x00360040, nullptr, "LoadSysMenuArg"}, |         {0x00360040, nullptr, "LoadSysMenuArg"}, | ||||||
|         {0x00370042, nullptr, "StoreSysMenuArg"}, |         {0x00370042, nullptr, "StoreSysMenuArg"}, | ||||||
|         {0x00380040, nullptr, "PreloadResidentApplet"}, |         {0x00380040, nullptr, "PreloadResidentApplet"}, | ||||||
|   | |||||||
| @@ -62,7 +62,7 @@ APT_U::APT_U(std::shared_ptr<Module> apt) | |||||||
|         {0x00320084, &APT_U::DoApplicationJump, "DoApplicationJump"}, |         {0x00320084, &APT_U::DoApplicationJump, "DoApplicationJump"}, | ||||||
|         {0x00330000, &APT_U::GetProgramIdOnApplicationJump, "GetProgramIdOnApplicationJump"}, |         {0x00330000, &APT_U::GetProgramIdOnApplicationJump, "GetProgramIdOnApplicationJump"}, | ||||||
|         {0x00340084, nullptr, "SendDeliverArg"}, |         {0x00340084, nullptr, "SendDeliverArg"}, | ||||||
|         {0x00350080, nullptr, "ReceiveDeliverArg"}, |         {0x00350080, &APT_U::ReceiveDeliverArg, "ReceiveDeliverArg"}, | ||||||
|         {0x00360040, &APT_U::LoadSysMenuArg, "LoadSysMenuArg"}, |         {0x00360040, &APT_U::LoadSysMenuArg, "LoadSysMenuArg"}, | ||||||
|         {0x00370042, &APT_U::StoreSysMenuArg, "StoreSysMenuArg"}, |         {0x00370042, &APT_U::StoreSysMenuArg, "StoreSysMenuArg"}, | ||||||
|         {0x00380040, nullptr, "PreloadResidentApplet"}, |         {0x00380040, nullptr, "PreloadResidentApplet"}, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user