Skip to content

Instantly share code, notes, and snippets.

@Subv
Created February 25, 2018 13:53
Show Gist options
  • Save Subv/036b7d4a9885d78fcd6ba5b5cf8b4108 to your computer and use it in GitHub Desktop.
Save Subv/036b7d4a9885d78fcd6ba5b5cf8b4108 to your computer and use it in GitHub Desktop.
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 164c5bb6..3965dee5 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -79,8 +79,18 @@ struct AppletSlotData {
AppletAttributes attributes;
Kernel::SharedPtr<Kernel::Event> notification_event;
Kernel::SharedPtr<Kernel::Event> parameter_event;
+
+ void Reset() {
+ applet_id = AppletId::None;
+ registered = false;
+ attributes.raw = 0;
+ }
};
+/// The parameter signal to send to an application when a running library applet calls
+/// CloseLibraryApplet.
+SignalType library_applet_closing_command = SignalType::None;
+
// Holds data about the concurrently running applets in the system.
static std::array<AppletSlotData, NumAppletSlot> applet_slots = {};
@@ -737,8 +747,9 @@ void CancelParameter(Service::Interface* self) {
rb.Push(RESULT_SUCCESS); // No error
rb.Push(cancellation_success);
- LOG_DEBUG(Service_APT, "called check_sender=%u, sender_appid=0x%08X, "
- "check_receiver=%u, receiver_appid=0x%08X",
+ LOG_DEBUG(Service_APT,
+ "called check_sender=%u, sender_appid=0x%08X, "
+ "check_receiver=%u, receiver_appid=0x%08X",
check_sender, sender_appid, check_receiver, receiver_appid);
}
@@ -954,6 +965,67 @@ void StartLibraryApplet(Service::Interface* self) {
}
}
+void PrepareToCloseLibraryApplet(Service::Interface* self) {
+ IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x25, 3, 0); // 0x002500C0
+ bool not_pause = rp.Pop<bool>();
+ bool exiting = rp.Pop<bool>();
+ bool jump_to_home = rp.Pop<bool>();
+
+ LOG_DEBUG(Service_APT, "called not_pause=%u exiting=%u jump_to_home=%u",
+ static_cast<u32>(not_pause), static_cast<u32>(exiting),
+ static_cast<u32>(jump_to_home));
+
+ if (next_parameter) {
+ IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
+ rb.Push(ResultCode(ErrCodes::ParameterPresent, ErrorModule::Applet,
+ ErrorSummary::InvalidState, ErrorLevel::Status));
+ return;
+ }
+
+ if (!not_pause)
+ library_applet_closing_command = SignalType::WakeupByPause;
+ else if (jump_to_home)
+ library_applet_closing_command = SignalType::WakeupToJumpHome;
+ else if (exiting)
+ library_applet_closing_command = SignalType::WakeupByCancel;
+ else
+ library_applet_closing_command = SignalType::WakeupByExit;
+
+ IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
+ rb.Push(RESULT_SUCCESS);
+}
+
+void CloseLibraryApplet(Service::Interface* self) {
+ IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x28, 1, 4); // 0x00280044
+ u32 parameter_size = rp.Pop<u32>();
+ Kernel::Handle handle = rp.PopHandle();
+ VAddr parameter_addr = rp.PopStaticBuffer(nullptr);
+
+ LOG_DEBUG(Service_APT, "called size=%u handle=%u", parameter_size, static_cast<u32>(handle));
+
+ auto& slot = applet_slots[static_cast<size_t>(AppletSlot::LibraryApplet)];
+
+ MessageParameter param;
+ // TODO(Subv): The destination id should be the "current applet slot id", which changes
+ // constantly depending on what is going on in the system. Most of the time it is the running
+ // application, but it could be something else if a system applet is launched.
+ param.destination_id = static_cast<u32>(AppletId::Application);
+ param.sender_id = static_cast<u32>(slot.applet_id);
+ param.object = Kernel::g_handle_table.GetGeneric(handle);
+ param.signal = static_cast<u32>(library_applet_closing_command);
+ param.buffer.resize(parameter_size);
+ Memory::ReadBlock(parameter_addr, param.buffer.data(), param.buffer.size());
+ SendParameter(param);
+
+ if (library_applet_closing_command != SignalType::WakeupByPause) {
+ // TODO(Subv): Terminate the running applet title
+ slot.Reset();
+ }
+
+ IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
+ rb.Push(RESULT_SUCCESS);
+}
+
void CancelLibraryApplet(Service::Interface* self) {
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x3B, 1, 0); // 0x003B0040
bool exiting = rp.Pop<bool>();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment