mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-11-03 23:28:48 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									182ffa4243
								
							
						
					
					
						commit
						21fb9d63f4
					
				
					 7 changed files with 177 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -31,6 +31,8 @@
 | 
			
		|||
#include "core/hle/kernel/kernel.h"
 | 
			
		||||
#include "core/hle/kernel/process.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/gsp/gsp.h"
 | 
			
		||||
#include "core/hle/service/pm/pm_app.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -561,9 +563,20 @@ void System::Reset() {
 | 
			
		|||
    // reloading.
 | 
			
		||||
    // 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();
 | 
			
		||||
    // Reload the system with the same setting
 | 
			
		||||
    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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -498,6 +498,7 @@ ResultCode AppletManager::PrepareToDoApplicationJump(u64 title_id, FS::MediaType
 | 
			
		|||
    app_jump_parameters.current_media_type = FS::MediaType::NAND;
 | 
			
		||||
    app_jump_parameters.next_title_id = title_id;
 | 
			
		||||
    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
 | 
			
		||||
    // 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultCode AppletManager::DoApplicationJump() {
 | 
			
		||||
ResultCode AppletManager::DoApplicationJump(DeliverArg arg) {
 | 
			
		||||
    // 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
 | 
			
		||||
    // 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.
 | 
			
		||||
 | 
			
		||||
    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();
 | 
			
		||||
 | 
			
		||||
    // TODO(Subv): Set the delivery parameters.
 | 
			
		||||
    // Set the delivery parameters.
 | 
			
		||||
    deliver_arg = std::move(arg);
 | 
			
		||||
 | 
			
		||||
    // TODO(Subv): Terminate the current Application.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,9 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <optional>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <boost/serialization/array.hpp>
 | 
			
		||||
#include <boost/serialization/optional.hpp>
 | 
			
		||||
| 
						 | 
				
			
			@ -158,7 +160,30 @@ public:
 | 
			
		|||
 | 
			
		||||
    ResultCode PrepareToDoApplicationJump(u64 title_id, FS::MediaType media_type,
 | 
			
		||||
                                          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 {
 | 
			
		||||
        u64 title_id;
 | 
			
		||||
| 
						 | 
				
			
			@ -173,15 +198,19 @@ public:
 | 
			
		|||
    struct ApplicationJumpParameters {
 | 
			
		||||
        u64 next_title_id;
 | 
			
		||||
        FS::MediaType next_media_type;
 | 
			
		||||
        ApplicationJumpFlags flags;
 | 
			
		||||
 | 
			
		||||
        u64 current_title_id;
 | 
			
		||||
        FS::MediaType current_media_type;
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        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_media_type;
 | 
			
		||||
            if (file_version > 0) {
 | 
			
		||||
                ar& flags;
 | 
			
		||||
            }
 | 
			
		||||
            ar& current_title_id;
 | 
			
		||||
            ar& current_media_type;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -242,6 +271,7 @@ private:
 | 
			
		|||
    };
 | 
			
		||||
 | 
			
		||||
    ApplicationJumpParameters app_jump_parameters{};
 | 
			
		||||
    boost::optional<DeliverArg> deliver_arg{};
 | 
			
		||||
 | 
			
		||||
    // Holds data about the concurrently running applets in the system.
 | 
			
		||||
    std::array<AppletSlotData, NumAppletSlot> applet_slots = {};
 | 
			
		||||
| 
						 | 
				
			
			@ -259,9 +289,12 @@ private:
 | 
			
		|||
 | 
			
		||||
private:
 | 
			
		||||
    template <class Archive>
 | 
			
		||||
    void serialize(Archive& ar, const unsigned int) {
 | 
			
		||||
    void serialize(Archive& ar, const unsigned int file_version) {
 | 
			
		||||
        ar& next_parameter;
 | 
			
		||||
        ar& app_jump_parameters;
 | 
			
		||||
        if (file_version > 0) {
 | 
			
		||||
            ar& deliver_arg;
 | 
			
		||||
        }
 | 
			
		||||
        ar& applet_slots;
 | 
			
		||||
        ar& library_applet_closing_command;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -270,4 +303,7 @@ private:
 | 
			
		|||
 | 
			
		||||
} // namespace Service::APT
 | 
			
		||||
 | 
			
		||||
BOOST_CLASS_VERSION(Service::APT::AppletManager::ApplicationJumpParameters, 1)
 | 
			
		||||
BOOST_CLASS_VERSION(Service::APT::AppletManager, 1)
 | 
			
		||||
 | 
			
		||||
SERVICE_CONSTRUCT(Service::APT::AppletManager)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,6 +56,10 @@ Module::NSInterface::NSInterface(std::shared_ptr<Module> apt, const char* name,
 | 
			
		|||
 | 
			
		||||
Module::NSInterface::~NSInterface() = default;
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Module> Module::NSInterface::GetModule() const {
 | 
			
		||||
    return apt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Module::NSInterface::SetWirelessRebootInfo(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp(ctx, 0x06, 1, 2); // 0x00060042
 | 
			
		||||
    u32 size = rp.Pop<u32>();
 | 
			
		||||
| 
						 | 
				
			
			@ -476,19 +480,32 @@ void Module::APTInterface::PrepareToDoApplicationJump(Kernel::HLERequestContext&
 | 
			
		|||
 | 
			
		||||
void Module::APTInterface::DoApplicationJump(Kernel::HLERequestContext& ctx) {
 | 
			
		||||
    IPC::RequestParser rp(ctx, 0x32, 2, 4); // 0x00320084
 | 
			
		||||
    const auto param_size = rp.Pop<u32>();
 | 
			
		||||
    const auto hmac_size = rp.Pop<u32>();
 | 
			
		||||
    auto param_size = rp.Pop<u32>();
 | 
			
		||||
    auto hmac_size = rp.Pop<u32>();
 | 
			
		||||
 | 
			
		||||
    [[maybe_unused]] const auto param = rp.PopStaticBuffer();
 | 
			
		||||
    [[maybe_unused]] const auto hmac = rp.PopStaticBuffer();
 | 
			
		||||
    constexpr u32 max_param_size{0x300};
 | 
			
		||||
    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,
 | 
			
		||||
                hmac_size);
 | 
			
		||||
    auto param = rp.PopStaticBuffer();
 | 
			
		||||
    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);
 | 
			
		||||
    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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -506,6 +523,25 @@ void Module::APTInterface::GetProgramIdOnApplicationJump(Kernel::HLERequestConte
 | 
			
		|||
    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) {
 | 
			
		||||
    IPC::RequestParser rp(ctx, 0x15, 5, 0); // 0x00150140
 | 
			
		||||
    u32 title_info1 = rp.Pop<u32>();
 | 
			
		||||
| 
						 | 
				
			
			@ -809,6 +845,9 @@ void Module::APTInterface::GetStartupArgument(Kernel::HLERequestContext& ctx) {
 | 
			
		|||
    constexpr u32 max_parameter_size{0x1000};
 | 
			
		||||
    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) {
 | 
			
		||||
        LOG_ERROR(Service_APT,
 | 
			
		||||
                  "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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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}",
 | 
			
		||||
                static_cast<u32>(startup_argument_type), parameter_size);
 | 
			
		||||
    if (auto arg = apt->applet_manager->ReceiveDeliverArg()) {
 | 
			
		||||
        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);
 | 
			
		||||
    rb.Push(RESULT_SUCCESS);
 | 
			
		||||
    rb.Push<u32>(0);
 | 
			
		||||
    rb.PushStaticBuffer(std::move(parameter), 0);
 | 
			
		||||
    rb.Push(exists);
 | 
			
		||||
    rb.PushStaticBuffer(std::move(param), 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Module> Module::APTInterface::GetModule() const {
 | 
			
		||||
    return apt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Module::Module(Core::System& system) : system(system) {
 | 
			
		||||
    applet_manager = std::make_shared<AppletManager>(system);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -982,6 +1046,17 @@ Module::Module(Core::System& system) : system(system) {
 | 
			
		|||
 | 
			
		||||
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) {
 | 
			
		||||
    auto& service_manager = system.ServiceManager();
 | 
			
		||||
    auto apt = std::make_shared<Module>(system);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,11 +65,15 @@ public:
 | 
			
		|||
    explicit Module(Core::System& system);
 | 
			
		||||
    ~Module();
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<AppletManager> GetAppletManager() const;
 | 
			
		||||
 | 
			
		||||
    class NSInterface : public ServiceFramework<NSInterface> {
 | 
			
		||||
    public:
 | 
			
		||||
        NSInterface(std::shared_ptr<Module> apt, const char* name, u32 max_session);
 | 
			
		||||
        ~NSInterface();
 | 
			
		||||
 | 
			
		||||
        std::shared_ptr<Module> GetModule() const;
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
        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> GetModule() const;
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
        /**
 | 
			
		||||
         * APT::Initialize service function
 | 
			
		||||
| 
						 | 
				
			
			@ -505,6 +511,23 @@ public:
 | 
			
		|||
         */
 | 
			
		||||
        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
 | 
			
		||||
         *  Inputs:
 | 
			
		||||
| 
						 | 
				
			
			@ -725,6 +748,8 @@ private:
 | 
			
		|||
    friend class boost::serialization::access;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Module> GetModule(Core::System& system);
 | 
			
		||||
 | 
			
		||||
void InstallInterfaces(Core::System& system);
 | 
			
		||||
 | 
			
		||||
} // namespace Service::APT
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,7 +62,7 @@ APT_A::APT_A(std::shared_ptr<Module> apt)
 | 
			
		|||
        {0x00320084, &APT_A::DoApplicationJump, "DoApplicationJump"},
 | 
			
		||||
        {0x00330000, &APT_A::GetProgramIdOnApplicationJump, "GetProgramIdOnApplicationJump"},
 | 
			
		||||
        {0x00340084, nullptr, "SendDeliverArg"},
 | 
			
		||||
        {0x00350080, nullptr, "ReceiveDeliverArg"},
 | 
			
		||||
        {0x00350080, &APT_A::ReceiveDeliverArg, "ReceiveDeliverArg"},
 | 
			
		||||
        {0x00360040, nullptr, "LoadSysMenuArg"},
 | 
			
		||||
        {0x00370042, nullptr, "StoreSysMenuArg"},
 | 
			
		||||
        {0x00380040, nullptr, "PreloadResidentApplet"},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,7 +62,7 @@ APT_U::APT_U(std::shared_ptr<Module> apt)
 | 
			
		|||
        {0x00320084, &APT_U::DoApplicationJump, "DoApplicationJump"},
 | 
			
		||||
        {0x00330000, &APT_U::GetProgramIdOnApplicationJump, "GetProgramIdOnApplicationJump"},
 | 
			
		||||
        {0x00340084, nullptr, "SendDeliverArg"},
 | 
			
		||||
        {0x00350080, nullptr, "ReceiveDeliverArg"},
 | 
			
		||||
        {0x00350080, &APT_U::ReceiveDeliverArg, "ReceiveDeliverArg"},
 | 
			
		||||
        {0x00360040, &APT_U::LoadSysMenuArg, "LoadSysMenuArg"},
 | 
			
		||||
        {0x00370042, &APT_U::StoreSysMenuArg, "StoreSysMenuArg"},
 | 
			
		||||
        {0x00380040, nullptr, "PreloadResidentApplet"},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue