forked from suyu/suyu
Merge pull request #2953 from Subv/applet_launch
HLE/APT: Always set up the APT parameter when starting a library applet.
This commit is contained in:
commit
84c344b9b1
2 changed files with 47 additions and 30 deletions
|
@ -171,7 +171,11 @@ void SendParameter(const MessageParameter& parameter) {
|
||||||
next_parameter = parameter;
|
next_parameter = parameter;
|
||||||
// Signal the event to let the receiver know that a new parameter is ready to be read
|
// Signal the event to let the receiver know that a new parameter is ready to be read
|
||||||
auto* const slot_data = GetAppletSlotData(static_cast<AppletId>(parameter.destination_id));
|
auto* const slot_data = GetAppletSlotData(static_cast<AppletId>(parameter.destination_id));
|
||||||
ASSERT(slot_data);
|
if (slot_data == nullptr) {
|
||||||
|
LOG_DEBUG(Service_APT, "No applet was registered with the id %03X",
|
||||||
|
parameter.destination_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
slot_data->parameter_event->Signal();
|
slot_data->parameter_event->Signal();
|
||||||
}
|
}
|
||||||
|
@ -505,9 +509,6 @@ void SendParameter(Service::Interface* self) {
|
||||||
size_t size;
|
size_t size;
|
||||||
VAddr buffer = rp.PopStaticBuffer(&size);
|
VAddr buffer = rp.PopStaticBuffer(&size);
|
||||||
|
|
||||||
std::shared_ptr<HLE::Applets::Applet> dest_applet =
|
|
||||||
HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id));
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_APT,
|
LOG_DEBUG(Service_APT,
|
||||||
"called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
|
"called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
|
||||||
"buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X",
|
"buffer_size=0x%08X, handle=0x%08X, size=0x%08zX, in_param_buffer_ptr=0x%08X",
|
||||||
|
@ -522,12 +523,6 @@ void SendParameter(Service::Interface* self) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dest_applet == nullptr) {
|
|
||||||
LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id);
|
|
||||||
rb.Push<u32>(-1); // TODO(Subv): Find the right error code
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageParameter param;
|
MessageParameter param;
|
||||||
param.destination_id = dst_app_id;
|
param.destination_id = dst_app_id;
|
||||||
param.sender_id = src_app_id;
|
param.sender_id = src_app_id;
|
||||||
|
@ -536,7 +531,14 @@ void SendParameter(Service::Interface* self) {
|
||||||
param.buffer.resize(buffer_size);
|
param.buffer.resize(buffer_size);
|
||||||
Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size());
|
Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size());
|
||||||
|
|
||||||
|
SendParameter(param);
|
||||||
|
|
||||||
|
// If the applet is running in HLE mode, use the HLE interface to communicate with it.
|
||||||
|
if (auto dest_applet = HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id))) {
|
||||||
rb.Push(dest_applet->ReceiveParameter(param));
|
rb.Push(dest_applet->ReceiveParameter(param));
|
||||||
|
} else {
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReceiveParameter(Service::Interface* self) {
|
void ReceiveParameter(Service::Interface* self) {
|
||||||
|
@ -765,7 +767,12 @@ void PrepareToStartLibraryApplet(Service::Interface* self) {
|
||||||
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x18, 1, 0); // 0x180040
|
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x18, 1, 0); // 0x180040
|
||||||
AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
|
AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||||
|
|
||||||
|
// TODO(Subv): Launch the requested applet application.
|
||||||
|
|
||||||
auto applet = HLE::Applets::Applet::Get(applet_id);
|
auto applet = HLE::Applets::Applet::Get(applet_id);
|
||||||
if (applet) {
|
if (applet) {
|
||||||
LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id);
|
LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id);
|
||||||
|
@ -773,7 +780,6 @@ void PrepareToStartLibraryApplet(Service::Interface* self) {
|
||||||
} else {
|
} else {
|
||||||
rb.Push(HLE::Applets::Applet::Create(applet_id));
|
rb.Push(HLE::Applets::Applet::Create(applet_id));
|
||||||
}
|
}
|
||||||
LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrepareToStartNewestHomeMenu(Service::Interface* self) {
|
void PrepareToStartNewestHomeMenu(Service::Interface* self) {
|
||||||
|
@ -794,7 +800,12 @@ void PreloadLibraryApplet(Service::Interface* self) {
|
||||||
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040
|
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040
|
||||||
AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
|
AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||||
|
|
||||||
|
// TODO(Subv): Launch the requested applet application.
|
||||||
|
|
||||||
auto applet = HLE::Applets::Applet::Get(applet_id);
|
auto applet = HLE::Applets::Applet::Get(applet_id);
|
||||||
if (applet) {
|
if (applet) {
|
||||||
LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id);
|
LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id);
|
||||||
|
@ -802,34 +813,40 @@ void PreloadLibraryApplet(Service::Interface* self) {
|
||||||
} else {
|
} else {
|
||||||
rb.Push(HLE::Applets::Applet::Create(applet_id));
|
rb.Push(HLE::Applets::Applet::Create(applet_id));
|
||||||
}
|
}
|
||||||
LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartLibraryApplet(Service::Interface* self) {
|
void StartLibraryApplet(Service::Interface* self) {
|
||||||
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1E, 2, 4); // 0x1E0084
|
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1E, 2, 4); // 0x1E0084
|
||||||
AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
|
AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
|
||||||
std::shared_ptr<HLE::Applets::Applet> applet = HLE::Applets::Applet::Get(applet_id);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
|
|
||||||
|
|
||||||
if (applet == nullptr) {
|
|
||||||
LOG_ERROR(Service_APT, "unknown applet id=%08X", applet_id);
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0, false);
|
|
||||||
rb.Push<u32>(-1); // TODO(Subv): Find the right error code
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t buffer_size = rp.Pop<u32>();
|
size_t buffer_size = rp.Pop<u32>();
|
||||||
Kernel::Handle handle = rp.PopHandle();
|
Kernel::Handle handle = rp.PopHandle();
|
||||||
VAddr buffer_addr = rp.PopStaticBuffer();
|
VAddr buffer_addr = rp.PopStaticBuffer();
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
|
||||||
|
|
||||||
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||||
|
|
||||||
|
// Send the Wakeup signal to the applet
|
||||||
|
MessageParameter param;
|
||||||
|
param.destination_id = static_cast<u32>(applet_id);
|
||||||
|
param.sender_id = static_cast<u32>(AppletId::Application);
|
||||||
|
param.object = Kernel::g_handle_table.GetGeneric(handle);
|
||||||
|
param.signal = static_cast<u32>(SignalType::Wakeup);
|
||||||
|
param.buffer.resize(buffer_size);
|
||||||
|
Memory::ReadBlock(buffer_addr, param.buffer.data(), param.buffer.size());
|
||||||
|
SendParameter(param);
|
||||||
|
|
||||||
|
// In case the applet is being HLEd, attempt to communicate with it.
|
||||||
|
if (auto applet = HLE::Applets::Applet::Get(applet_id)) {
|
||||||
AppletStartupParameter parameter;
|
AppletStartupParameter parameter;
|
||||||
parameter.object = Kernel::g_handle_table.GetGeneric(handle);
|
parameter.object = Kernel::g_handle_table.GetGeneric(handle);
|
||||||
parameter.buffer.resize(buffer_size);
|
parameter.buffer.resize(buffer_size);
|
||||||
Memory::ReadBlock(buffer_addr, parameter.buffer.data(), parameter.buffer.size());
|
Memory::ReadBlock(buffer_addr, parameter.buffer.data(), parameter.buffer.size());
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
|
||||||
rb.Push(applet->Start(parameter));
|
rb.Push(applet->Start(parameter));
|
||||||
|
} else {
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CancelLibraryApplet(Service::Interface* self) {
|
void CancelLibraryApplet(Service::Interface* self) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ const Interface::FunctionInfo FunctionTable[] = {
|
||||||
{0x00090040, IsRegistered, "IsRegistered"},
|
{0x00090040, IsRegistered, "IsRegistered"},
|
||||||
{0x000A0040, nullptr, "GetAttribute"},
|
{0x000A0040, nullptr, "GetAttribute"},
|
||||||
{0x000B0040, InquireNotification, "InquireNotification"},
|
{0x000B0040, InquireNotification, "InquireNotification"},
|
||||||
{0x000C0104, nullptr, "SendParameter"},
|
{0x000C0104, SendParameter, "SendParameter"},
|
||||||
{0x000D0080, ReceiveParameter, "ReceiveParameter"},
|
{0x000D0080, ReceiveParameter, "ReceiveParameter"},
|
||||||
{0x000E0080, GlanceParameter, "GlanceParameter"},
|
{0x000E0080, GlanceParameter, "GlanceParameter"},
|
||||||
{0x000F0100, nullptr, "CancelParameter"},
|
{0x000F0100, nullptr, "CancelParameter"},
|
||||||
|
@ -38,7 +38,7 @@ const Interface::FunctionInfo FunctionTable[] = {
|
||||||
{0x001B00C4, nullptr, "StartApplication"},
|
{0x001B00C4, nullptr, "StartApplication"},
|
||||||
{0x001C0000, nullptr, "WakeupApplication"},
|
{0x001C0000, nullptr, "WakeupApplication"},
|
||||||
{0x001D0000, nullptr, "CancelApplication"},
|
{0x001D0000, nullptr, "CancelApplication"},
|
||||||
{0x001E0084, nullptr, "StartLibraryApplet"},
|
{0x001E0084, StartLibraryApplet, "StartLibraryApplet"},
|
||||||
{0x001F0084, nullptr, "StartSystemApplet"},
|
{0x001F0084, nullptr, "StartSystemApplet"},
|
||||||
{0x00200044, nullptr, "StartNewestHomeMenu"},
|
{0x00200044, nullptr, "StartNewestHomeMenu"},
|
||||||
{0x00210000, nullptr, "OrderToCloseApplication"},
|
{0x00210000, nullptr, "OrderToCloseApplication"},
|
||||||
|
|
Loading…
Reference in a new issue