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
|
@ -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