From 8970e280311db0795c1f50c7536165052a841ea8 Mon Sep 17 00:00:00 2001 From: wwylele Date: Sat, 3 Feb 2018 13:49:23 +0200 Subject: [PATCH 1/3] APT: convert to ServiceFramework --- src/core/hle/service/apt/apt.cpp | 405 ++++++-------- src/core/hle/service/apt/apt.h | 823 ++++++++++++++++------------- src/core/hle/service/apt/apt_a.cpp | 193 ++++--- src/core/hle/service/apt/apt_a.h | 12 +- src/core/hle/service/apt/apt_s.cpp | 193 ++++--- src/core/hle/service/apt/apt_s.h | 12 +- src/core/hle/service/apt/apt_u.cpp | 187 ++++--- src/core/hle/service/apt/apt_u.h | 12 +- src/core/hle/service/service.cpp | 3 +- 9 files changed, 903 insertions(+), 937 deletions(-) diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index c88e14560..2cd7af9a3 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -9,7 +9,6 @@ #include "core/file_sys/file_backend.h" #include "core/hle/applets/applet.h" #include "core/hle/kernel/mutex.h" -#include "core/hle/kernel/process.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/romfs.h" #include "core/hle/service/apt/applet_manager.h" @@ -28,31 +27,15 @@ namespace Service { namespace APT { -/// Handle to shared memory region designated to for shared system font -static Kernel::SharedPtr shared_font_mem; -static bool shared_font_loaded = false; -static bool shared_font_relocated = false; - -static Kernel::SharedPtr lock; - -static u32 cpu_percent; ///< CPU time available to the running application - -// APT::CheckNew3DSApp will check this unknown_ns_state_field to determine processing mode -static u8 unknown_ns_state_field; - -static ScreencapPostPermission screen_capture_post_permission; - -static std::shared_ptr applet_manager; - -void Initialize(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x2, 2, 0); // 0x20080 +void Module::Interface::Initialize(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x2, 2, 0); // 0x20080 AppletId app_id = rp.PopEnum(); u32 attributes = rp.Pop(); LOG_DEBUG(Service_APT, "called app_id=0x%08X, attributes=0x%08X", static_cast(app_id), attributes); - auto result = applet_manager->Initialize(app_id, attributes); + auto result = apt->applet_manager->Initialize(app_id, attributes); if (result.Failed()) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(result.Code()); @@ -60,8 +43,7 @@ void Initialize(Service::Interface* self) { auto events = std::move(result).Unwrap(); IPC::RequestBuilder rb = rp.MakeBuilder(1, 3); rb.Push(RESULT_SUCCESS); - rb.PushCopyHandles(Kernel::g_handle_table.Create(events.notification_event).Unwrap(), - Kernel::g_handle_table.Create(events.parameter_event).Unwrap()); + rb.PushCopyObjects(events.notification_event, events.parameter_event); } } @@ -119,7 +101,7 @@ static u32 DecompressLZ11(const u8* in, u8* out) { return decompressed_size; } -static bool LoadSharedFont() { +bool Module::LoadSharedFont() { u8 font_region_code; switch (CFG::GetRegionValue()) { case 4: // CHN @@ -184,7 +166,7 @@ static bool LoadSharedFont() { return true; } -static bool LoadLegacySharedFont() { +bool Module::LoadLegacySharedFont() { // This is the legacy method to load shared font. // The expected format is a decrypted, uncompressed BCFNT file with the 0x80 byte header // generated by the APT:U service. The best way to get is by dumping it from RAM. We've provided @@ -202,21 +184,21 @@ static bool LoadLegacySharedFont() { return false; } -void GetSharedFont(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x44, 0, 0); // 0x00440000 +void Module::Interface::GetSharedFont(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x44, 0, 0); // 0x00440000 IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); // Log in telemetry if the game uses the shared font Core::Telemetry().AddField(Telemetry::FieldType::Session, "RequiresSharedFont", true); - if (!shared_font_loaded) { + if (!apt->shared_font_loaded) { // On real 3DS, font loading happens on booting. However, we load it on demand to coordinate // with CFG region auto configuration, which happens later than APT initialization. - if (LoadSharedFont()) { - shared_font_loaded = true; - } else if (LoadLegacySharedFont()) { + if (apt->LoadSharedFont()) { + apt->shared_font_loaded = true; + } else if (apt->LoadLegacySharedFont()) { LOG_WARNING(Service_APT, "Loaded shared font by legacy method"); - shared_font_loaded = true; + apt->shared_font_loaded = true; } else { LOG_ERROR(Service_APT, "shared font file missing - go dump it from your 3ds"); rb.Push(-1); // TODO: Find the right error code @@ -229,10 +211,10 @@ void GetSharedFont(Service::Interface* self) { // The shared font has to be relocated to the new address before being passed to the // application. VAddr target_address = - Memory::PhysicalToVirtualAddress(shared_font_mem->linear_heap_phys_address).value(); - if (!shared_font_relocated) { - BCFNT::RelocateSharedFont(shared_font_mem, target_address); - shared_font_relocated = true; + Memory::PhysicalToVirtualAddress(apt->shared_font_mem->linear_heap_phys_address).value(); + if (!apt->shared_font_relocated) { + BCFNT::RelocateSharedFont(apt->shared_font_mem, target_address); + apt->shared_font_relocated = true; } rb.Push(RESULT_SUCCESS); // No error @@ -240,19 +222,19 @@ void GetSharedFont(Service::Interface* self) { // allocated, the real APT service calculates this address by scanning the entire address space // (using svcQueryMemory) and searches for an allocation of the same size as the Shared Font. rb.Push(target_address); - rb.PushCopyHandles(Kernel::g_handle_table.Create(shared_font_mem).Unwrap()); + rb.PushCopyObjects(apt->shared_font_mem); } -void NotifyToWait(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x43, 1, 0); // 0x430040 +void Module::Interface::NotifyToWait(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x43, 1, 0); // 0x430040 u32 app_id = rp.Pop(); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(RESULT_SUCCESS); // No error LOG_WARNING(Service_APT, "(STUBBED) app_id=%u", app_id); } -void GetLockHandle(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1, 1, 0); // 0x10040 +void Module::Interface::GetLockHandle(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x1, 1, 0); // 0x10040 // Bits [0:2] are the applet type (System, Library, etc) // Bit 5 tells the application that there's a pending APT parameter, @@ -267,25 +249,23 @@ void GetLockHandle(Service::Interface* self) { rb.Push(applet_attributes); // Applet Attributes, this value is passed to Enable. rb.Push(0); // Least significant bit = power button state - Kernel::Handle handle_copy = Kernel::g_handle_table.Create(lock).Unwrap(); - rb.PushCopyHandles(handle_copy); + rb.PushCopyObjects(apt->lock); - LOG_WARNING(Service_APT, "(STUBBED) called handle=0x%08X applet_attributes=0x%08X", handle_copy, - applet_attributes); + LOG_WARNING(Service_APT, "(STUBBED) called applet_attributes=0x%08X", applet_attributes); } -void Enable(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x3, 1, 0); // 0x30040 +void Module::Interface::Enable(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x3, 1, 0); // 0x30040 u32 attributes = rp.Pop(); LOG_DEBUG(Service_APT, "called attributes=0x%08X", attributes); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); - rb.Push(applet_manager->Enable(attributes)); + rb.Push(apt->applet_manager->Enable(attributes)); } -void GetAppletManInfo(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x5, 1, 0); // 0x50040 +void Module::Interface::GetAppletManInfo(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x5, 1, 0); // 0x50040 u32 unk = rp.Pop(); IPC::RequestBuilder rb = rp.MakeBuilder(5, 0); rb.Push(RESULT_SUCCESS); // No error @@ -297,18 +277,18 @@ void GetAppletManInfo(Service::Interface* self) { LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk); } -void IsRegistered(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x9, 1, 0); // 0x90040 - AppletId app_id = static_cast(rp.Pop()); +void Module::Interface::IsRegistered(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x9, 1, 0); // 0x90040 + AppletId app_id = rp.PopEnum(); IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); rb.Push(RESULT_SUCCESS); // No error - rb.Push(applet_manager->IsRegistered(app_id)); + rb.Push(apt->applet_manager->IsRegistered(app_id)); LOG_DEBUG(Service_APT, "called app_id=0x%08X", static_cast(app_id)); } -void InquireNotification(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xB, 1, 0); // 0xB0040 +void Module::Interface::InquireNotification(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0xB, 1, 0); // 0xB0040 u32 app_id = rp.Pop(); IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); rb.Push(RESULT_SUCCESS); // No error @@ -316,52 +296,41 @@ void InquireNotification(Service::Interface* self) { LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id); } -void SendParameter(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xC, 4, 4); // 0xC0104 +void Module::Interface::SendParameter(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0xC, 4, 4); // 0xC0104 AppletId src_app_id = rp.PopEnum(); AppletId dst_app_id = rp.PopEnum(); SignalType signal_type = rp.PopEnum(); u32 buffer_size = rp.Pop(); - Kernel::Handle handle = rp.PopHandle(); - size_t size; - VAddr buffer = rp.PopStaticBuffer(&size); + Kernel::SharedPtr object = rp.PopGenericObject(); + std::vector buffer = rp.PopStaticBuffer(); - LOG_DEBUG(Service_APT, - "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", + LOG_DEBUG(Service_APT, "called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X," + "buffer_size=0x%08X", static_cast(src_app_id), static_cast(dst_app_id), - static_cast(signal_type), buffer_size, handle, size, buffer); + static_cast(signal_type), buffer_size); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); MessageParameter param; param.destination_id = dst_app_id; param.sender_id = src_app_id; - param.object = Kernel::g_handle_table.GetGeneric(handle); + param.object = std::move(object); param.signal = signal_type; - param.buffer.resize(buffer_size); - Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size()); + param.buffer = std::move(buffer); - rb.Push(applet_manager->SendParameter(param)); + rb.Push(apt->applet_manager->SendParameter(param)); } -void ReceiveParameter(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xD, 2, 0); // 0xD0080 +void Module::Interface::ReceiveParameter(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0xD, 2, 0); // 0xD0080 AppletId app_id = rp.PopEnum(); u32 buffer_size = rp.Pop(); - size_t static_buff_size; - VAddr buffer = rp.PeekStaticBuffer(0, &static_buff_size); - if (buffer_size > static_buff_size) - LOG_WARNING( - Service_APT, - "buffer_size is bigger than the size in the buffer descriptor (0x%08X > 0x%08zX)", - buffer_size, static_buff_size); - LOG_DEBUG(Service_APT, "called app_id=0x%08X, buffer_size=0x%08X", static_cast(app_id), buffer_size); - auto next_parameter = applet_manager->ReceiveParameter(app_id); + auto next_parameter = apt->applet_manager->ReceiveParameter(app_id); if (next_parameter.Failed()) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); @@ -376,33 +345,20 @@ void ReceiveParameter(Service::Interface* self) { rb.PushEnum(next_parameter->signal); // Signal type ASSERT_MSG(next_parameter->buffer.size() <= buffer_size, "Input static buffer is too small !"); rb.Push(static_cast(next_parameter->buffer.size())); // Parameter buffer size - - rb.PushMoveHandles((next_parameter->object != nullptr) - ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap() - : 0); - - rb.PushStaticBuffer(buffer, next_parameter->buffer.size(), 0); - - Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size()); + rb.PushMoveObjects(next_parameter->object); + next_parameter->buffer.resize(buffer_size, 0); // APT always push a buffer with the maximum size + rb.PushStaticBuffer(next_parameter->buffer, 0); } -void GlanceParameter(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xE, 2, 0); // 0xE0080 +void Module::Interface::GlanceParameter(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0xE, 2, 0); // 0xE0080 AppletId app_id = rp.PopEnum(); u32 buffer_size = rp.Pop(); - size_t static_buff_size; - VAddr buffer = rp.PeekStaticBuffer(0, &static_buff_size); - if (buffer_size > static_buff_size) - LOG_WARNING( - Service_APT, - "buffer_size is bigger than the size in the buffer descriptor (0x%08X > 0x%08zX)", - buffer_size, static_buff_size); - LOG_DEBUG(Service_APT, "called app_id=0x%08X, buffer_size=0x%08X", static_cast(app_id), buffer_size); - auto next_parameter = applet_manager->GlanceParameter(app_id); + auto next_parameter = apt->applet_manager->GlanceParameter(app_id); if (next_parameter.Failed()) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); @@ -416,18 +372,13 @@ void GlanceParameter(Service::Interface* self) { rb.PushEnum(next_parameter->signal); // Signal type ASSERT_MSG(next_parameter->buffer.size() <= buffer_size, "Input static buffer is too small !"); rb.Push(static_cast(next_parameter->buffer.size())); // Parameter buffer size - - rb.PushMoveHandles((next_parameter->object != nullptr) - ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap() - : 0); - - rb.PushStaticBuffer(buffer, next_parameter->buffer.size(), 0); - - Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size()); + rb.PushMoveObjects(next_parameter->object); + next_parameter->buffer.resize(buffer_size, 0); // APT always push a buffer with the maximum size + rb.PushStaticBuffer(next_parameter->buffer, 0); } -void CancelParameter(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xF, 4, 0); // 0xF0100 +void Module::Interface::CancelParameter(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0xF, 4, 0); // 0xF0100 bool check_sender = rp.Pop(); AppletId sender_appid = rp.PopEnum(); @@ -437,8 +388,8 @@ void CancelParameter(Service::Interface* self) { IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); rb.Push(RESULT_SUCCESS); // No error - rb.Push(applet_manager->CancelParameter(check_sender, sender_appid, check_receiver, - receiver_appid)); + rb.Push(apt->applet_manager->CancelParameter(check_sender, sender_appid, check_receiver, + receiver_appid)); LOG_DEBUG(Service_APT, "called check_sender=%u, sender_appid=0x%08X, " "check_receiver=%u, receiver_appid=0x%08X", @@ -446,8 +397,8 @@ void CancelParameter(Service::Interface* self) { static_cast(receiver_appid)); } -void PrepareToStartApplication(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x15, 5, 0); // 0x00150140 +void Module::Interface::PrepareToStartApplication(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x15, 5, 0); // 0x00150140 u32 title_info1 = rp.Pop(); u32 title_info2 = rp.Pop(); u32 title_info3 = rp.Pop(); @@ -455,7 +406,7 @@ void PrepareToStartApplication(Service::Interface* self) { u32 flags = rp.Pop(); if (flags & 0x00000100) { - unknown_ns_state_field = 1; + apt->unknown_ns_state_field = 1; } IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); @@ -467,49 +418,43 @@ void PrepareToStartApplication(Service::Interface* self) { title_info1, title_info2, title_info3, title_info4, flags); } -void StartApplication(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1B, 3, 4); // 0x001B00C4 +void Module::Interface::StartApplication(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x1B, 3, 4); // 0x001B00C4 u32 buffer1_size = rp.Pop(); u32 buffer2_size = rp.Pop(); u32 flag = rp.Pop(); - size_t size1; - VAddr buffer1_ptr = rp.PopStaticBuffer(&size1); - size_t size2; - VAddr buffer2_ptr = rp.PopStaticBuffer(&size2); + std::vector buffer1 = rp.PopStaticBuffer(); + std::vector buffer2 = rp.PopStaticBuffer(); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(RESULT_SUCCESS); // No error LOG_WARNING(Service_APT, - "(STUBBED) called buffer1_size=0x%08X, buffer2_size=0x%08X, flag=0x%08X," - "size1=0x%08zX, buffer1_ptr=0x%08X, size2=0x%08zX, buffer2_ptr=0x%08X", - buffer1_size, buffer2_size, flag, size1, buffer1_ptr, size2, buffer2_ptr); + "(STUBBED) called buffer1_size=0x%08X, buffer2_size=0x%08X, flag=0x%08X", + buffer1_size, buffer2_size, flag); } -void AppletUtility(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x4B, 3, 2); // 0x004B00C2 +void Module::Interface::AppletUtility(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x4B, 3, 2); // 0x004B00C2 // These are from 3dbrew - I'm not really sure what they're used for. u32 utility_command = rp.Pop(); u32 input_size = rp.Pop(); u32 output_size = rp.Pop(); - VAddr input_addr = rp.PopStaticBuffer(nullptr); - - VAddr output_addr = rp.PeekStaticBuffer(0); + std::vector input = rp.PopStaticBuffer(); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(RESULT_SUCCESS); // No error LOG_WARNING(Service_APT, - "(STUBBED) called command=0x%08X, input_size=0x%08X, output_size=0x%08X, " - "input_addr=0x%08X, output_addr=0x%08X", - utility_command, input_size, output_size, input_addr, output_addr); + "(STUBBED) called command=0x%08X, input_size=0x%08X, output_size=0x%08X", + utility_command, input_size, output_size); } -void SetAppCpuTimeLimit(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x4F, 2, 0); // 0x4F0080 +void Module::Interface::SetAppCpuTimeLimit(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x4F, 2, 0); // 0x4F0080 u32 value = rp.Pop(); - cpu_percent = rp.Pop(); + apt->cpu_percent = rp.Pop(); if (value != 1) { LOG_ERROR(Service_APT, "This value should be one, but is actually %u!", value); @@ -518,11 +463,11 @@ void SetAppCpuTimeLimit(Service::Interface* self) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(RESULT_SUCCESS); // No error - LOG_WARNING(Service_APT, "(STUBBED) called cpu_percent=%u, value=%u", cpu_percent, value); + LOG_WARNING(Service_APT, "(STUBBED) called cpu_percent=%u, value=%u", apt->cpu_percent, value); } -void GetAppCpuTimeLimit(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x50, 1, 0); // 0x500040 +void Module::Interface::GetAppCpuTimeLimit(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x50, 1, 0); // 0x500040 u32 value = rp.Pop(); if (value != 1) { @@ -531,23 +476,23 @@ void GetAppCpuTimeLimit(Service::Interface* self) { IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); rb.Push(RESULT_SUCCESS); // No error - rb.Push(cpu_percent); + rb.Push(apt->cpu_percent); LOG_WARNING(Service_APT, "(STUBBED) called value=%u", value); } -void PrepareToStartLibraryApplet(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x18, 1, 0); // 0x180040 - AppletId applet_id = static_cast(rp.Pop()); +void Module::Interface::PrepareToStartLibraryApplet(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x18, 1, 0); // 0x180040 + AppletId applet_id = rp.PopEnum(); LOG_DEBUG(Service_APT, "called applet_id=%08X", static_cast(applet_id)); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); - rb.Push(applet_manager->PrepareToStartLibraryApplet(applet_id)); + rb.Push(apt->applet_manager->PrepareToStartLibraryApplet(applet_id)); } -void PrepareToStartNewestHomeMenu(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1A, 0, 0); // 0x1A0000 +void Module::Interface::PrepareToStartNewestHomeMenu(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x1A, 0, 0); // 0x1A0000 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); // TODO(Subv): This command can only be called by a System Applet (return 0xC8A0CC04 otherwise). @@ -560,47 +505,42 @@ void PrepareToStartNewestHomeMenu(Service::Interface* self) { LOG_DEBUG(Service_APT, "called"); } -void PreloadLibraryApplet(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040 - AppletId applet_id = static_cast(rp.Pop()); +void Module::Interface::PreloadLibraryApplet(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x16, 1, 0); // 0x160040 + AppletId applet_id = rp.PopEnum(); LOG_DEBUG(Service_APT, "called applet_id=%08X", static_cast(applet_id)); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); - rb.Push(applet_manager->PreloadLibraryApplet(applet_id)); + rb.Push(apt->applet_manager->PreloadLibraryApplet(applet_id)); } -void FinishPreloadingLibraryApplet(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x17, 1, 0); // 0x00170040 - AppletId applet_id = static_cast(rp.Pop()); +void Module::Interface::FinishPreloadingLibraryApplet(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x17, 1, 0); // 0x00170040 + AppletId applet_id = rp.PopEnum(); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); - rb.Push(applet_manager->FinishPreloadingLibraryApplet(applet_id)); + rb.Push(apt->applet_manager->FinishPreloadingLibraryApplet(applet_id)); LOG_WARNING(Service_APT, "(STUBBED) called applet_id=%03X", static_cast(applet_id)); } -void StartLibraryApplet(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1E, 2, 4); // 0x1E0084 - AppletId applet_id = static_cast(rp.Pop()); +void Module::Interface::StartLibraryApplet(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x1E, 2, 4); // 0x1E0084 + AppletId applet_id = rp.PopEnum(); size_t buffer_size = rp.Pop(); - Kernel::Handle handle = rp.PopHandle(); - VAddr buffer_addr = rp.PopStaticBuffer(nullptr); + Kernel::SharedPtr object = rp.PopGenericObject(); + std::vector buffer = rp.PopStaticBuffer(); LOG_DEBUG(Service_APT, "called applet_id=%08X", static_cast(applet_id)); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); - - std::vector buffer(buffer_size); - Memory::ReadBlock(buffer_addr, buffer.data(), buffer.size()); - - rb.Push(applet_manager->StartLibraryApplet(applet_id, Kernel::g_handle_table.GetGeneric(handle), - buffer)); + rb.Push(apt->applet_manager->StartLibraryApplet(applet_id, object, buffer)); } -void CancelLibraryApplet(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x3B, 1, 0); // 0x003B0040 +void Module::Interface::CancelLibraryApplet(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x3B, 1, 0); // 0x003B0040 bool exiting = rp.Pop(); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); @@ -609,34 +549,34 @@ void CancelLibraryApplet(Service::Interface* self) { LOG_WARNING(Service_APT, "(STUBBED) called exiting=%d", exiting); } -void SetScreenCapPostPermission(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x55, 1, 0); // 0x00550040 +void Module::Interface::SetScreenCapPostPermission(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x55, 1, 0); // 0x00550040 - screen_capture_post_permission = static_cast(rp.Pop() & 0xF); + apt->screen_capture_post_permission = static_cast(rp.Pop() & 0xF); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(RESULT_SUCCESS); // No error LOG_WARNING(Service_APT, "(STUBBED) screen_capture_post_permission=%u", - static_cast(screen_capture_post_permission)); + static_cast(apt->screen_capture_post_permission)); } -void GetScreenCapPostPermission(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x56, 0, 0); // 0x00560000 +void Module::Interface::GetScreenCapPostPermission(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x56, 0, 0); // 0x00560000 IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); rb.Push(RESULT_SUCCESS); // No error - rb.Push(static_cast(screen_capture_post_permission)); + rb.Push(static_cast(apt->screen_capture_post_permission)); LOG_WARNING(Service_APT, "(STUBBED) screen_capture_post_permission=%u", - static_cast(screen_capture_post_permission)); + static_cast(apt->screen_capture_post_permission)); } -void GetAppletInfo(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x6, 1, 0); // 0x60040 - auto app_id = static_cast(rp.Pop()); +void Module::Interface::GetAppletInfo(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x6, 1, 0); // 0x60040 + auto app_id = rp.PopEnum(); LOG_DEBUG(Service_APT, "called appid=%u", static_cast(app_id)); - auto info = applet_manager->GetAppletInfo(app_id); + auto info = apt->applet_manager->GetAppletInfo(app_id); if (info.Failed()) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(info.Code()); @@ -651,8 +591,8 @@ void GetAppletInfo(Service::Interface* self) { } } -void GetStartupArgument(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x51, 2, 0); // 0x00510080 +void Module::Interface::GetStartupArgument(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x51, 2, 0); // 0x00510080 u32 parameter_size = rp.Pop(); StartupArgumentType startup_argument_type = static_cast(rp.Pop()); @@ -664,17 +604,7 @@ void GetStartupArgument(Service::Interface* self) { return; } - size_t static_buff_size; - VAddr addr = rp.PeekStaticBuffer(0, &static_buff_size); - if (parameter_size > static_buff_size) - LOG_WARNING( - Service_APT, - "parameter_size is bigger than the size in the buffer descriptor (0x%08X > 0x%08zX)", - parameter_size, static_buff_size); - - if (addr && parameter_size) { - Memory::ZeroBlock(addr, parameter_size); - } + std::vector parameter(parameter_size, 0); LOG_WARNING(Service_APT, "(stubbed) called startup_argument_type=%u , parameter_size=0x%08x", static_cast(startup_argument_type), parameter_size); @@ -682,21 +612,19 @@ void GetStartupArgument(Service::Interface* self) { IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); rb.Push(RESULT_SUCCESS); rb.Push(0); - rb.PushStaticBuffer(addr, parameter_size, 0); + rb.PushStaticBuffer(parameter, 0); } -void Wrap(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x46, 4, 4); +void Module::Interface::Wrap(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x46, 4, 4); const u32 output_size = rp.Pop(); const u32 input_size = rp.Pop(); const u32 nonce_offset = rp.Pop(); u32 nonce_size = rp.Pop(); - size_t desc_size; - IPC::MappedBufferPermissions desc_permission; - const VAddr input = rp.PopMappedBuffer(&desc_size, &desc_permission); - ASSERT(desc_size == input_size && desc_permission == IPC::MappedBufferPermissions::R); - const VAddr output = rp.PopMappedBuffer(&desc_size, &desc_permission); - ASSERT(desc_size == output_size && desc_permission == IPC::MappedBufferPermissions::W); + auto& input = rp.PopMappedBuffer(); + ASSERT(input.GetSize() == input_size); + auto& output = rp.PopMappedBuffer(); + ASSERT(output.GetSize() == output_size); // Note: real 3DS still returns SUCCESS when the sizes don't match. It seems that it doesn't // check the buffer size and writes data with potential overflow. @@ -711,40 +639,37 @@ void Wrap(Service::Interface* self) { // Reads nonce and concatenates the rest of the input as plaintext HW::AES::CCMNonce nonce{}; - Memory::ReadBlock(input + nonce_offset, nonce.data(), nonce_size); + input.Read(nonce.data(), nonce_offset, nonce_size); u32 pdata_size = input_size - nonce_size; std::vector pdata(pdata_size); - Memory::ReadBlock(input, pdata.data(), nonce_offset); - Memory::ReadBlock(input + nonce_offset + nonce_size, pdata.data() + nonce_offset, - pdata_size - nonce_offset); + input.Read(pdata.data(), 0, nonce_offset); + input.Read(pdata.data() + nonce_offset, nonce_offset + nonce_size, pdata_size - nonce_offset); // Encrypts the plaintext using AES-CCM auto cipher = HW::AES::EncryptSignCCM(pdata, nonce, HW::AES::KeySlotID::APTWrap); // Puts the nonce to the beginning of the output, with ciphertext followed - Memory::WriteBlock(output, nonce.data(), nonce_size); - Memory::WriteBlock(output + nonce_size, cipher.data(), cipher.size()); + output.Write(nonce.data(), 0, nonce_size); + output.Write(cipher.data(), nonce_size, cipher.size()); IPC::RequestBuilder rb = rp.MakeBuilder(1, 4); rb.Push(RESULT_SUCCESS); // Unmap buffer - rb.PushMappedBuffer(input, input_size, IPC::MappedBufferPermissions::R); - rb.PushMappedBuffer(output, output_size, IPC::MappedBufferPermissions::W); + rb.PushMappedBuffer(input); + rb.PushMappedBuffer(output); } -void Unwrap(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x47, 4, 4); +void Module::Interface::Unwrap(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x47, 4, 4); const u32 output_size = rp.Pop(); const u32 input_size = rp.Pop(); const u32 nonce_offset = rp.Pop(); u32 nonce_size = rp.Pop(); - size_t desc_size; - IPC::MappedBufferPermissions desc_permission; - const VAddr input = rp.PopMappedBuffer(&desc_size, &desc_permission); - ASSERT(desc_size == input_size && desc_permission == IPC::MappedBufferPermissions::R); - const VAddr output = rp.PopMappedBuffer(&desc_size, &desc_permission); - ASSERT(desc_size == output_size && desc_permission == IPC::MappedBufferPermissions::W); + auto& input = rp.PopMappedBuffer(); + ASSERT(input.GetSize() == input_size); + auto& output = rp.PopMappedBuffer(); + ASSERT(output.GetSize() == output_size); // Note: real 3DS still returns SUCCESS when the sizes don't match. It seems that it doesn't // check the buffer size and writes data with potential overflow. @@ -759,10 +684,10 @@ void Unwrap(Service::Interface* self) { // Reads nonce and cipher text HW::AES::CCMNonce nonce{}; - Memory::ReadBlock(input, nonce.data(), nonce_size); + input.Read(nonce.data(), 0, nonce_size); u32 cipher_size = input_size - nonce_size; std::vector cipher(cipher_size); - Memory::ReadBlock(input + nonce_size, cipher.data(), cipher_size); + input.Read(cipher.data(), nonce_size, cipher_size); // Decrypts the ciphertext using AES-CCM auto pdata = HW::AES::DecryptVerifyCCM(cipher, nonce, HW::AES::KeySlotID::APTWrap); @@ -770,10 +695,10 @@ void Unwrap(Service::Interface* self) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 4); if (!pdata.empty()) { // Splits the plaintext and put the nonce in between - Memory::WriteBlock(output, pdata.data(), nonce_offset); - Memory::WriteBlock(output + nonce_offset, nonce.data(), nonce_size); - Memory::WriteBlock(output + nonce_offset + nonce_size, pdata.data() + nonce_offset, - pdata.size() - nonce_offset); + output.Write(pdata.data(), 0, nonce_offset); + output.Write(nonce.data(), nonce_offset, nonce_size); + output.Write(pdata.data() + nonce_offset, nonce_offset + nonce_size, + pdata.size() - nonce_offset); rb.Push(RESULT_SUCCESS); } else { LOG_ERROR(Service_APT, "Failed to decrypt data"); @@ -782,15 +707,15 @@ void Unwrap(Service::Interface* self) { } // Unmap buffer - rb.PushMappedBuffer(input, input_size, IPC::MappedBufferPermissions::R); - rb.PushMappedBuffer(output, output_size, IPC::MappedBufferPermissions::W); + rb.PushMappedBuffer(input); + rb.PushMappedBuffer(output); } -void CheckNew3DSApp(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x101, 0, 0); // 0x01010000 +void Module::Interface::CheckNew3DSApp(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x101, 0, 0); // 0x01010000 IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); - if (unknown_ns_state_field) { + if (apt->unknown_ns_state_field) { rb.Push(RESULT_SUCCESS); rb.Push(0); } else { @@ -800,8 +725,8 @@ void CheckNew3DSApp(Service::Interface* self) { LOG_WARNING(Service_APT, "(STUBBED) called"); } -void CheckNew3DS(Service::Interface* self) { - IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x102, 0, 0); // 0x01020000 +void Module::Interface::CheckNew3DS(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x102, 0, 0); // 0x01020000 IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); PTM::CheckNew3DS(rb); @@ -809,11 +734,12 @@ void CheckNew3DS(Service::Interface* self) { LOG_WARNING(Service_APT, "(STUBBED) called"); } -void Init() { - AddService(new APT_A_Interface); - AddService(new APT_S_Interface); - AddService(new APT_U_Interface); +Module::Interface::Interface(std::shared_ptr apt, const char* name, u32 max_session) + : ServiceFramework(name, max_session), apt(std::move(apt)) {} +Module::Interface::~Interface() = default; + +Module::Module() { applet_manager = std::make_shared(); using Kernel::MemoryPermission; @@ -823,20 +749,15 @@ void Init() { Kernel::MemoryRegion::SYSTEM, "APT:SharedFont"); lock = Kernel::Mutex::Create(false, "APT_U:Lock"); - - cpu_percent = 0; - unknown_ns_state_field = 0; - screen_capture_post_permission = - ScreencapPostPermission::CleanThePermission; // TODO(JamePeng): verify the initial value } -void Shutdown() { - shared_font_mem = nullptr; - shared_font_loaded = false; - shared_font_relocated = false; - lock = nullptr; +Module::~Module() {} - applet_manager = nullptr; +void InstallInterfaces(SM::ServiceManager& service_manager) { + auto apt = std::make_shared(); + std::make_shared(apt)->InstallAsService(service_manager); + std::make_shared(apt)->InstallAsService(service_manager); + std::make_shared(apt)->InstallAsService(service_manager); } } // namespace APT diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 9e5e3d430..f3df7ae29 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -9,13 +9,18 @@ #include "common/common_types.h" #include "common/swap.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/service/service.h" + +namespace Kernel { +class Mutex; +class SharedMemory; +} namespace Service { - -class Interface; - namespace APT { +class AppletManager; + /// Each APT service can only have up to 2 sessions connected at the same time. static const u32 MaxAPTSessions = 2; @@ -46,416 +51,472 @@ enum class ScreencapPostPermission : u32 { DisableScreenshotPostingToMiiverse = 3 }; -/** - * APT::Initialize service function - * Service function that initializes the APT process for the running application - * Outputs: - * 1 : Result of the function, 0 on success, otherwise error code - * 3 : Handle to the notification event - * 4 : Handle to the pause event - */ -void Initialize(Service::Interface* self); +class Module final { +public: + Module(); + ~Module(); -/** - * APT::GetSharedFont service function - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Virtual address of where shared font will be loaded in memory - * 4 : Handle to shared font memory - */ -void GetSharedFont(Service::Interface* self); + class Interface : public ServiceFramework { + public: + Interface(std::shared_ptr apt, const char* name, u32 max_session); + ~Interface(); -/** - * APT::Wrap service function - * Inputs: - * 1 : Output buffer size - * 2 : Input buffer size - * 3 : Nonce offset to the input buffer - * 4 : Nonce size - * 5 : Buffer mapping descriptor ((input_buffer_size << 4) | 0xA) - * 6 : Input buffer address - * 7 : Buffer mapping descriptor ((input_buffer_size << 4) | 0xC) - * 8 : Output buffer address - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Buffer unmapping descriptor ((input_buffer_size << 4) | 0xA) - * 3 : Input buffer address - * 4 : Buffer unmapping descriptor ((input_buffer_size << 4) | 0xC) - * 5 : Output buffer address - */ -void Wrap(Service::Interface* self); + protected: + /** + * APT::Initialize service function + * Service function that initializes the APT process for the running application + * Outputs: + * 1 : Result of the function, 0 on success, otherwise error code + * 3 : Handle to the notification event + * 4 : Handle to the pause event + */ + void Initialize(Kernel::HLERequestContext& ctx); -/** - * APT::Unwrap service function - * Inputs: - * 1 : Output buffer size - * 2 : Input buffer size - * 3 : Nonce offset to the output buffer - * 4 : Nonce size - * 5 : Buffer mapping descriptor ((input_buffer_size << 4) | 0xA) - * 6 : Input buffer address - * 7 : Buffer mapping descriptor ((input_buffer_size << 4) | 0xC) - * 8 : Output buffer address - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Buffer unmapping descriptor ((input_buffer_size << 4) | 0xA) - * 3 : Input buffer address - * 4 : Buffer unmapping descriptor ((input_buffer_size << 4) | 0xC) - * 5 : Output buffer address - */ -void Unwrap(Service::Interface* self); + /** + * APT::GetSharedFont service function + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Virtual address of where shared font will be loaded in memory + * 4 : Handle to shared font memory + */ + void GetSharedFont(Kernel::HLERequestContext& ctx); -/** - * APT::NotifyToWait service function - * Inputs: - * 1 : AppID - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -void NotifyToWait(Service::Interface* self); + /** + * APT::Wrap service function + * Inputs: + * 1 : Output buffer size + * 2 : Input buffer size + * 3 : Nonce offset to the input buffer + * 4 : Nonce size + * 5 : Buffer mapping descriptor ((input_buffer_size << 4) | 0xA) + * 6 : Input buffer address + * 7 : Buffer mapping descriptor ((input_buffer_size << 4) | 0xC) + * 8 : Output buffer address + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Buffer unmapping descriptor ((input_buffer_size << 4) | 0xA) + * 3 : Input buffer address + * 4 : Buffer unmapping descriptor ((input_buffer_size << 4) | 0xC) + * 5 : Output buffer address + */ + void Wrap(Kernel::HLERequestContext& ctx); -/** - * APT::GetLockHandle service function - * Inputs: - * 1 : Applet attributes - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Applet attributes - * 3 : Power button state - * 4 : IPC handle descriptor - * 5 : APT mutex handle - */ -void GetLockHandle(Service::Interface* self); + /** + * APT::Unwrap service function + * Inputs: + * 1 : Output buffer size + * 2 : Input buffer size + * 3 : Nonce offset to the output buffer + * 4 : Nonce size + * 5 : Buffer mapping descriptor ((input_buffer_size << 4) | 0xA) + * 6 : Input buffer address + * 7 : Buffer mapping descriptor ((input_buffer_size << 4) | 0xC) + * 8 : Output buffer address + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Buffer unmapping descriptor ((input_buffer_size << 4) | 0xA) + * 3 : Input buffer address + * 4 : Buffer unmapping descriptor ((input_buffer_size << 4) | 0xC) + * 5 : Output buffer address + */ + void Unwrap(Kernel::HLERequestContext& ctx); -/** - * APT::Enable service function - * Inputs: - * 1 : Applet attributes - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -void Enable(Service::Interface* self); + /** + * APT::NotifyToWait service function + * Inputs: + * 1 : AppID + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ + void NotifyToWait(Kernel::HLERequestContext& ctx); -/** - * APT::GetAppletManInfo service function. - * Inputs: - * 1 : Unknown - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Unknown u32 value - * 3 : Unknown u8 value - * 4 : Home Menu AppId - * 5 : AppID of currently active app - */ -void GetAppletManInfo(Service::Interface* self); + /** + * APT::GetLockHandle service function + * Inputs: + * 1 : Applet attributes + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Applet attributes + * 3 : Power button state + * 4 : IPC handle descriptor + * 5 : APT mutex handle + */ + void GetLockHandle(Kernel::HLERequestContext& ctx); -/** - * APT::GetAppletInfo service function. - * Inputs: - * 1 : AppId - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2-3 : Title ID - * 4 : Media Type - * 5 : Registered - * 6 : Loaded - * 7 : Attributes - */ -void GetAppletInfo(Service::Interface* self); + /** + * APT::Enable service function + * Inputs: + * 1 : Applet attributes + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ + void Enable(Kernel::HLERequestContext& ctx); -/** - * APT::IsRegistered service function. This returns whether the specified AppID is registered with - * NS yet. An AppID is "registered" once the process associated with the AppID uses APT:Enable. Home - * Menu uses this command to determine when the launched process is running and to determine when to - * stop using GSP, etc., while displaying the "Nintendo 3DS" loading screen. - * - * Inputs: - * 1 : AppID - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Output, 0 = not registered, 1 = registered. - */ -void IsRegistered(Service::Interface* self); + /** + * APT::GetAppletManInfo service function. + * Inputs: + * 1 : Unknown + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Unknown u32 value + * 3 : Unknown u8 value + * 4 : Home Menu AppId + * 5 : AppID of currently active app + */ + void GetAppletManInfo(Kernel::HLERequestContext& ctx); -void InquireNotification(Service::Interface* self); + /** + * APT::GetAppletInfo service function. + * Inputs: + * 1 : AppId + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2-3 : Title ID + * 4 : Media Type + * 5 : Registered + * 6 : Loaded + * 7 : Attributes + */ + void GetAppletInfo(Kernel::HLERequestContext& ctx); -/** - * APT::SendParameter service function. This sets the parameter data state. - * Inputs: - * 1 : Source AppID - * 2 : Destination AppID - * 3 : Signal type - * 4 : Parameter buffer size, max size is 0x1000 (this can be zero) - * 5 : Value - * 6 : Handle to the destination process, likely used for shared memory (this can be zero) - * 7 : (Size<<14) | 2 - * 8 : Input parameter buffer ptr - * Outputs: - * 0 : Return Header - * 1 : Result of function, 0 on success, otherwise error code -*/ -void SendParameter(Service::Interface* self); + /** + * APT::IsRegistered service function. This returns whether the specified AppID is + * registered with + * NS yet. An AppID is "registered" once the process associated with the AppID uses + * APT:Enable. Home + * Menu uses this command to determine when the launched process is running and to determine + * when to + * stop using GSP, etc., while displaying the "Nintendo 3DS" loading screen. + * + * Inputs: + * 1 : AppID + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Output, 0 = not registered, 1 = registered. + */ + void IsRegistered(Kernel::HLERequestContext& ctx); -/** - * APT::ReceiveParameter service function. This returns the current parameter data from NS state, - * from the source process which set the parameters. Once finished, NS will clear a flag in the NS - * state so that this command will return an error if this command is used again if parameters were - * not set again. This is called when the second Initialize event is triggered. It returns a signal - * type indicating why it was triggered. - * Inputs: - * 1 : AppID - * 2 : Parameter buffer size, max size is 0x1000 - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : AppID of the process which sent these parameters - * 3 : Signal type - * 4 : Actual parameter buffer size, this is <= to the the input size - * 5 : Value - * 6 : Handle from the source process which set the parameters, likely used for shared memory - * 7 : Size - * 8 : Output parameter buffer ptr - */ -void ReceiveParameter(Service::Interface* self); + void InquireNotification(Kernel::HLERequestContext& ctx); -/** - * APT::GlanceParameter service function. This is exactly the same as APT_U::ReceiveParameter - * (except for the word value prior to the output handle), except this will not clear the flag - * (except when responseword[3]==8 || responseword[3]==9) in NS state. - * Inputs: - * 1 : AppID - * 2 : Parameter buffer size, max size is 0x1000 - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Unknown, for now assume AppID of the process which sent these parameters - * 3 : Unknown, for now assume Signal type - * 4 : Actual parameter buffer size, this is <= to the the input size - * 5 : Value - * 6 : Handle from the source process which set the parameters, likely used for shared memory - * 7 : Size - * 8 : Output parameter buffer ptr - */ -void GlanceParameter(Service::Interface* self); + /** + * APT::SendParameter service function. This sets the parameter data state. + * Inputs: + * 1 : Source AppID + * 2 : Destination AppID + * 3 : Signal type + * 4 : Parameter buffer size, max size is 0x1000 (this can be zero) + * 5 : Value + * 6 : Handle to the destination process, likely used for shared memory (this can be + * zero) + * 7 : (Size<<14) | 2 + * 8 : Input parameter buffer ptr + * Outputs: + * 0 : Return Header + * 1 : Result of function, 0 on success, otherwise error code + */ + void SendParameter(Kernel::HLERequestContext& ctx); -/** - * APT::CancelParameter service function. When the parameter data is available, and when the above - * specified fields match the ones in NS state(for the ones where the checks are enabled), this - * clears the flag which indicates that parameter data is available - * (same flag cleared by APT:ReceiveParameter). - * Inputs: - * 1 : Flag, when non-zero NS will compare the word after this one with a field in the NS - * state. - * 2 : Unknown, this is the same as the first unknown field returned by APT:ReceiveParameter. - * 3 : Flag, when non-zero NS will compare the word after this one with a field in the NS - * state. - * 4 : AppID - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Status flag, 0 = failure due to no parameter data being available, or the above enabled - * fields don't match the fields in NS state. 1 = success. - */ -void CancelParameter(Service::Interface* self); + /** + * APT::ReceiveParameter service function. This returns the current parameter data from NS + * state, + * from the source process which set the parameters. Once finished, NS will clear a flag in + * the NS + * state so that this command will return an error if this command is used again if + * parameters were + * not set again. This is called when the second Initialize event is triggered. It returns a + * signal + * type indicating why it was triggered. + * Inputs: + * 1 : AppID + * 2 : Parameter buffer size, max size is 0x1000 + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : AppID of the process which sent these parameters + * 3 : Signal type + * 4 : Actual parameter buffer size, this is <= to the the input size + * 5 : Value + * 6 : Handle from the source process which set the parameters, likely used for shared + * memory + * 7 : Size + * 8 : Output parameter buffer ptr + */ + void ReceiveParameter(Kernel::HLERequestContext& ctx); -/** - * APT::PrepareToStartApplication service function. When the input title-info programID is zero, - * NS will load the actual program ID via AMNet:GetTitleIDList. After doing some checks with the - * programID, NS will then set a NS state flag to value 1, then set the programID for AppID - * 0x300(application) to the input program ID(or the one from GetTitleIDList). A media-type field - * in the NS state is also set to the input media-type value - * (other state fields are set at this point as well). With 8.0.0-18, NS will set an u8 NS state - * field to value 1 when input flags bit8 is set - * Inputs: - * 1-4 : 0x10-byte title-info struct - * 4 : Flags - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - */ -void PrepareToStartApplication(Service::Interface* self); + /** + * APT::GlanceParameter service function. This is exactly the same as + * APT_U::ReceiveParameter + * (except for the word value prior to the output handle), except this will not clear the + * flag + * (except when responseword[3]==8 || responseword[3]==9) in NS state. + * Inputs: + * 1 : AppID + * 2 : Parameter buffer size, max size is 0x1000 + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Unknown, for now assume AppID of the process which sent these parameters + * 3 : Unknown, for now assume Signal type + * 4 : Actual parameter buffer size, this is <= to the the input size + * 5 : Value + * 6 : Handle from the source process which set the parameters, likely used for shared + * memory + * 7 : Size + * 8 : Output parameter buffer ptr + */ + void GlanceParameter(Kernel::HLERequestContext& ctx); -/** - * APT::StartApplication service function. Buf0 is copied to NS FIRMparams+0x0, then Buf1 is copied - * to the NS FIRMparams+0x480. Then the application is launched. - * Inputs: - * 1 : Buffer 0 size, max size is 0x300 - * 2 : Buffer 1 size, max size is 0x20 (this can be zero) - * 3 : u8 flag - * 4 : (Size0<<14) | 2 - * 5 : Buffer 0 pointer - * 6 : (Size1<<14) | 0x802 - * 7 : Buffer 1 pointer - * Outputs: - * 0 : Return Header - * 1 : Result of function, 0 on success, otherwise error code -*/ -void StartApplication(Service::Interface* self); + /** + * APT::CancelParameter service function. When the parameter data is available, and when the + * above + * specified fields match the ones in NS state(for the ones where the checks are enabled), + * this + * clears the flag which indicates that parameter data is available + * (same flag cleared by APT:ReceiveParameter). + * Inputs: + * 1 : Flag, when non-zero NS will compare the word after this one with a field in the + * NS + * state. + * 2 : Unknown, this is the same as the first unknown field returned by + * APT:ReceiveParameter. + * 3 : Flag, when non-zero NS will compare the word after this one with a field in the + * NS + * state. + * 4 : AppID + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Status flag, 0 = failure due to no parameter data being available, or the above + * enabled + * fields don't match the fields in NS state. 1 = success. + */ + void CancelParameter(Kernel::HLERequestContext& ctx); -/** - * APT::AppletUtility service function - * Inputs: - * 1 : Unknown, but clearly used for something - * 2 : Buffer 1 size (purpose is unknown) - * 3 : Buffer 2 size (purpose is unknown) - * 5 : Buffer 1 address (purpose is unknown) - * 65 : Buffer 2 address (purpose is unknown) - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -void AppletUtility(Service::Interface* self); + /** + * APT::PrepareToStartApplication service function. When the input title-info programID is + * zero, + * NS will load the actual program ID via AMNet:GetTitleIDList. After doing some checks with + * the + * programID, NS will then set a NS state flag to value 1, then set the programID for AppID + * 0x300(application) to the input program ID(or the one from GetTitleIDList). A media-type + * field + * in the NS state is also set to the input media-type value + * (other state fields are set at this point as well). With 8.0.0-18, NS will set an u8 NS + * state + * field to value 1 when input flags bit8 is set + * Inputs: + * 1-4 : 0x10-byte title-info struct + * 4 : Flags + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void PrepareToStartApplication(Kernel::HLERequestContext& ctx); -/** - * APT::SetAppCpuTimeLimit service function - * Inputs: - * 1 : Value, must be one - * 2 : Percentage of CPU time from 5 to 80 - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -void SetAppCpuTimeLimit(Service::Interface* self); + /** + * APT::StartApplication service function. Buf0 is copied to NS FIRMparams+0x0, then Buf1 is + * copied + * to the NS FIRMparams+0x480. Then the application is launched. + * Inputs: + * 1 : Buffer 0 size, max size is 0x300 + * 2 : Buffer 1 size, max size is 0x20 (this can be zero) + * 3 : u8 flag + * 4 : (Size0<<14) | 2 + * 5 : Buffer 0 pointer + * 6 : (Size1<<14) | 0x802 + * 7 : Buffer 1 pointer + * Outputs: + * 0 : Return Header + * 1 : Result of function, 0 on success, otherwise error code + */ + void StartApplication(Kernel::HLERequestContext& ctx); -/** - * APT::GetAppCpuTimeLimit service function - * Inputs: - * 1 : Value, must be one - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - * 2 : System core CPU time percentage - */ -void GetAppCpuTimeLimit(Service::Interface* self); + /** + * APT::AppletUtility service function + * Inputs: + * 1 : Unknown, but clearly used for something + * 2 : Buffer 1 size (purpose is unknown) + * 3 : Buffer 2 size (purpose is unknown) + * 5 : Buffer 1 address (purpose is unknown) + * 65 : Buffer 2 address (purpose is unknown) + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ + void AppletUtility(Kernel::HLERequestContext& ctx); -/** - * APT::PrepareToStartLibraryApplet service function - * Inputs: - * 0 : Command header [0x00180040] - * 1 : Id of the applet to start - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - */ -void PrepareToStartLibraryApplet(Service::Interface* self); + /** + * APT::SetAppCpuTimeLimit service function + * Inputs: + * 1 : Value, must be one + * 2 : Percentage of CPU time from 5 to 80 + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ + void SetAppCpuTimeLimit(Kernel::HLERequestContext& ctx); -/** - * APT::PrepareToStartNewestHomeMenu service function - * Inputs: - * 0 : Command header [0x001A0000] - * Outputs: - * 0 : Return header - * 1 : Result of function - */ -void PrepareToStartNewestHomeMenu(Service::Interface* self); + /** + * APT::GetAppCpuTimeLimit service function + * Inputs: + * 1 : Value, must be one + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + * 2 : System core CPU time percentage + */ + void GetAppCpuTimeLimit(Kernel::HLERequestContext& ctx); -/** - * APT::PreloadLibraryApplet service function - * Inputs: - * 0 : Command header [0x00160040] - * 1 : Id of the applet to start - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - */ -void PreloadLibraryApplet(Service::Interface* self); + /** + * APT::PrepareToStartLibraryApplet service function + * Inputs: + * 0 : Command header [0x00180040] + * 1 : Id of the applet to start + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void PrepareToStartLibraryApplet(Kernel::HLERequestContext& ctx); -/** - * APT::FinishPreloadingLibraryApplet service function - * Inputs: - * 0 : Command header [0x00170040] - * 1 : Id of the applet - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - */ -void FinishPreloadingLibraryApplet(Service::Interface* self); + /** + * APT::PrepareToStartNewestHomeMenu service function + * Inputs: + * 0 : Command header [0x001A0000] + * Outputs: + * 0 : Return header + * 1 : Result of function + */ + void PrepareToStartNewestHomeMenu(Kernel::HLERequestContext& ctx); -/** - * APT::StartLibraryApplet service function - * Inputs: - * 0 : Command header [0x001E0084] - * 1 : Id of the applet to start - * 2 : Buffer size - * 3 : Always 0? - * 4 : Handle passed to the applet - * 5 : (Size << 14) | 2 - * 6 : Input buffer virtual address - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - */ -void StartLibraryApplet(Service::Interface* self); + /** + * APT::PreloadLibraryApplet service function + * Inputs: + * 0 : Command header [0x00160040] + * 1 : Id of the applet to start + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void PreloadLibraryApplet(Kernel::HLERequestContext& ctx); -/** - * APT::CancelLibraryApplet service function - * Inputs: - * 0 : Command header [0x003B0040] - * 1 : u8, Application exiting (0 = not exiting, 1 = exiting) - * Outputs: - * 0 : Header code - * 1 : Result code - */ -void CancelLibraryApplet(Service::Interface* self); + /** + * APT::FinishPreloadingLibraryApplet service function + * Inputs: + * 0 : Command header [0x00170040] + * 1 : Id of the applet + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void FinishPreloadingLibraryApplet(Kernel::HLERequestContext& ctx); -/** - * APT::GetStartupArgument service function - * Inputs: - * 1 : Parameter Size (capped to 0x300) - * 2 : StartupArgumentType - * 65 : Output buffer for startup argument - * Outputs: - * 0 : Return header - * 1 : Result of function, 0 on success, otherwise error code - * 2 : u8, Exists (0 = does not exist, 1 = exists) - */ -void GetStartupArgument(Service::Interface* self); + /** + * APT::StartLibraryApplet service function + * Inputs: + * 0 : Command header [0x001E0084] + * 1 : Id of the applet to start + * 2 : Buffer size + * 3 : Always 0? + * 4 : Handle passed to the applet + * 5 : (Size << 14) | 2 + * 6 : Input buffer virtual address + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + */ + void StartLibraryApplet(Kernel::HLERequestContext& ctx); -/** - * APT::SetScreenCapPostPermission service function - * Inputs: - * 0 : Header Code[0x00550040] - * 1 : u8 The screenshot posting permission - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -void SetScreenCapPostPermission(Service::Interface* self); + /** + * APT::CancelLibraryApplet service function + * Inputs: + * 0 : Command header [0x003B0040] + * 1 : u8, Application exiting (0 = not exiting, 1 = exiting) + * Outputs: + * 0 : Header code + * 1 : Result code + */ + void CancelLibraryApplet(Kernel::HLERequestContext& ctx); -/** - * APT::GetScreenCapPostPermission service function - * Inputs: - * 0 : Header Code[0x00560000] - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : u8 The screenshot posting permission - */ -void GetScreenCapPostPermission(Service::Interface* self); + /** + * APT::GetStartupArgument service function + * Inputs: + * 1 : Parameter Size (capped to 0x300) + * 2 : StartupArgumentType + * 65 : Output buffer for startup argument + * Outputs: + * 0 : Return header + * 1 : Result of function, 0 on success, otherwise error code + * 2 : u8, Exists (0 = does not exist, 1 = exists) + */ + void GetStartupArgument(Kernel::HLERequestContext& ctx); -/** - * APT::CheckNew3DSApp service function - * Outputs: - * 1: Result code, 0 on success, otherwise error code - * 2: u8 output: 0 = Old3DS, 1 = New3DS. - * Note: - * This uses PTMSYSM:CheckNew3DS. - * When a certain NS state field is non-zero, the output value is zero, - * Otherwise the output is from PTMSYSM:CheckNew3DS. - * Normally this NS state field is zero, however this state field is set to 1 - * when APT:PrepareToStartApplication is used with flags bit8 is set. - */ -void CheckNew3DSApp(Service::Interface* self); + /** + * APT::SetScreenCapPostPermission service function + * Inputs: + * 0 : Header Code[0x00550040] + * 1 : u8 The screenshot posting permission + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ + void SetScreenCapPostPermission(Kernel::HLERequestContext& ctx); -/** - * Wrapper for PTMSYSM:CheckNew3DS - * APT::CheckNew3DS service function - * Outputs: - * 1: Result code, 0 on success, otherwise error code - * 2: u8 output: 0 = Old3DS, 1 = New3DS. - */ -void CheckNew3DS(Service::Interface* self); + /** + * APT::GetScreenCapPostPermission service function + * Inputs: + * 0 : Header Code[0x00560000] + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : u8 The screenshot posting permission + */ + void GetScreenCapPostPermission(Kernel::HLERequestContext& ctx); -/// Initialize the APT service -void Init(); + /** + * APT::CheckNew3DSApp service function + * Outputs: + * 1: Result code, 0 on success, otherwise error code + * 2: u8 output: 0 = Old3DS, 1 = New3DS. + * Note: + * This uses PTMSYSM:CheckNew3DS. + * When a certain NS state field is non-zero, the output value is zero, + * Otherwise the output is from PTMSYSM:CheckNew3DS. + * Normally this NS state field is zero, however this state field is set to 1 + * when APT:PrepareToStartApplication is used with flags bit8 is set. + */ + void CheckNew3DSApp(Kernel::HLERequestContext& ctx); -/// Shutdown the APT service -void Shutdown(); + /** + * Wrapper for PTMSYSM:CheckNew3DS + * APT::CheckNew3DS service function + * Outputs: + * 1: Result code, 0 on success, otherwise error code + * 2: u8 output: 0 = Old3DS, 1 = New3DS. + */ + void CheckNew3DS(Kernel::HLERequestContext& ctx); + + private: + std::shared_ptr apt; + }; + +private: + bool LoadSharedFont(); + bool LoadLegacySharedFont(); + + /// Handle to shared memory region designated to for shared system font + Kernel::SharedPtr shared_font_mem; + bool shared_font_loaded = false; + bool shared_font_relocated = false; + + Kernel::SharedPtr lock; + + u32 cpu_percent = 0; ///< CPU time available to the running application + + // APT::CheckNew3DSApp will check this unknown_ns_state_field to determine processing mode + u8 unknown_ns_state_field = 0; + + ScreencapPostPermission screen_capture_post_permission = + ScreencapPostPermission::CleanThePermission; // TODO(JamePeng): verify the initial value + + std::shared_ptr applet_manager; +}; + +void InstallInterfaces(SM::ServiceManager& service_manager); } // namespace APT } // namespace Service diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp index c496cba8d..e9f0459c2 100644 --- a/src/core/hle/service/apt/apt_a.cpp +++ b/src/core/hle/service/apt/apt_a.cpp @@ -2,108 +2,107 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/apt/apt.h" #include "core/hle/service/apt/apt_a.h" namespace Service { namespace APT { -const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, GetLockHandle, "GetLockHandle"}, - {0x00020080, Initialize, "Initialize"}, - {0x00030040, Enable, "Enable"}, - {0x00040040, nullptr, "Finalize"}, - {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, - {0x00060040, GetAppletInfo, "GetAppletInfo"}, - {0x00070000, nullptr, "GetLastSignaledAppletId"}, - {0x00080000, nullptr, "CountRegisteredApplet"}, - {0x00090040, IsRegistered, "IsRegistered"}, - {0x000A0040, nullptr, "GetAttribute"}, - {0x000B0040, InquireNotification, "InquireNotification"}, - {0x000C0104, SendParameter, "SendParameter"}, - {0x000D0080, ReceiveParameter, "ReceiveParameter"}, - {0x000E0080, GlanceParameter, "GlanceParameter"}, - {0x000F0100, CancelParameter, "CancelParameter"}, - {0x001000C2, nullptr, "DebugFunc"}, - {0x001100C0, nullptr, "MapProgramIdForDebug"}, - {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"}, - {0x00130000, nullptr, "GetPreparationState"}, - {0x00140040, nullptr, "SetPreparationState"}, - {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"}, - {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, - {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, - {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, - {0x00190040, nullptr, "PrepareToStartSystemApplet"}, - {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, - {0x001B00C4, nullptr, "StartApplication"}, - {0x001C0000, nullptr, "WakeupApplication"}, - {0x001D0000, nullptr, "CancelApplication"}, - {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, - {0x001F0084, nullptr, "StartSystemApplet"}, - {0x00200044, nullptr, "StartNewestHomeMenu"}, - {0x00210000, nullptr, "OrderToCloseApplication"}, - {0x00220040, nullptr, "PrepareToCloseApplication"}, - {0x00230040, nullptr, "PrepareToJumpToApplication"}, - {0x00240044, nullptr, "JumpToApplication"}, - {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, - {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, - {0x00270044, nullptr, "CloseApplication"}, - {0x00280044, nullptr, "CloseLibraryApplet"}, - {0x00290044, nullptr, "CloseSystemApplet"}, - {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, - {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"}, - {0x002C0044, nullptr, "JumpToHomeMenu"}, - {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"}, - {0x002E0044, nullptr, "LeaveHomeMenu"}, - {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, - {0x00300044, nullptr, "LeaveResidentApplet"}, - {0x00310100, nullptr, "PrepareToDoApplicationJump"}, - {0x00320084, nullptr, "DoApplicationJump"}, - {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, - {0x00340084, nullptr, "SendDeliverArg"}, - {0x00350080, nullptr, "ReceiveDeliverArg"}, - {0x00360040, nullptr, "LoadSysMenuArg"}, - {0x00370042, nullptr, "StoreSysMenuArg"}, - {0x00380040, nullptr, "PreloadResidentApplet"}, - {0x00390040, nullptr, "PrepareToStartResidentApplet"}, - {0x003A0044, nullptr, "StartResidentApplet"}, - {0x003B0040, CancelLibraryApplet, "CancelLibraryApplet"}, - {0x003C0042, nullptr, "SendDspSleep"}, - {0x003D0042, nullptr, "SendDspWakeUp"}, - {0x003E0080, nullptr, "ReplySleepQuery"}, - {0x003F0040, nullptr, "ReplySleepNotificationComplete"}, - {0x00400042, nullptr, "SendCaptureBufferInfo"}, - {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, - {0x00420080, nullptr, "SleepSystem"}, - {0x00430040, NotifyToWait, "NotifyToWait"}, - {0x00440000, GetSharedFont, "GetSharedFont"}, - {0x00450040, nullptr, "GetWirelessRebootInfo"}, - {0x00460104, Wrap, "Wrap"}, - {0x00470104, Unwrap, "Unwrap"}, - {0x00480100, nullptr, "GetProgramInfo"}, - {0x00490180, nullptr, "Reboot"}, - {0x004A0040, nullptr, "GetCaptureInfo"}, - {0x004B00C2, AppletUtility, "AppletUtility"}, - {0x004C0000, nullptr, "SetFatalErrDispMode"}, - {0x004D0080, nullptr, "GetAppletProgramInfo"}, - {0x004E0000, nullptr, "HardwareResetAsync"}, - {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, - {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, - {0x00510080, GetStartupArgument, "GetStartupArgument"}, - {0x00520104, nullptr, "Wrap1"}, - {0x00530104, nullptr, "Unwrap1"}, - {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"}, - {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"}, - {0x00570044, nullptr, "WakeupApplication2"}, - {0x00580002, nullptr, "GetProgramID"}, - {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, - {0x01020000, CheckNew3DS, "CheckNew3DS"}, - {0x01040000, nullptr, "IsStandardMemoryLayout"}, - {0x01050100, nullptr, "IsTitleAllowed"}, -}; - -APT_A_Interface::APT_A_Interface() : Interface(MaxAPTSessions) { - Register(FunctionTable); +APT_A::APT_A(std::shared_ptr apt) + : Module::Interface(std::move(apt), "APT:A", MaxAPTSessions) { + static const FunctionInfo functions[] = { + {0x00010040, &APT_A::GetLockHandle, "GetLockHandle"}, + {0x00020080, &APT_A::Initialize, "Initialize"}, + {0x00030040, &APT_A::Enable, "Enable"}, + {0x00040040, nullptr, "Finalize"}, + {0x00050040, &APT_A::GetAppletManInfo, "GetAppletManInfo"}, + {0x00060040, &APT_A::GetAppletInfo, "GetAppletInfo"}, + {0x00070000, nullptr, "GetLastSignaledAppletId"}, + {0x00080000, nullptr, "CountRegisteredApplet"}, + {0x00090040, &APT_A::IsRegistered, "IsRegistered"}, + {0x000A0040, nullptr, "GetAttribute"}, + {0x000B0040, &APT_A::InquireNotification, "InquireNotification"}, + {0x000C0104, &APT_A::SendParameter, "SendParameter"}, + {0x000D0080, &APT_A::ReceiveParameter, "ReceiveParameter"}, + {0x000E0080, &APT_A::GlanceParameter, "GlanceParameter"}, + {0x000F0100, &APT_A::CancelParameter, "CancelParameter"}, + {0x001000C2, nullptr, "DebugFunc"}, + {0x001100C0, nullptr, "MapProgramIdForDebug"}, + {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"}, + {0x00130000, nullptr, "GetPreparationState"}, + {0x00140040, nullptr, "SetPreparationState"}, + {0x00150140, &APT_A::PrepareToStartApplication, "PrepareToStartApplication"}, + {0x00160040, &APT_A::PreloadLibraryApplet, "PreloadLibraryApplet"}, + {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, + {0x00180040, &APT_A::PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, + {0x00190040, nullptr, "PrepareToStartSystemApplet"}, + {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, + {0x001B00C4, nullptr, "StartApplication"}, + {0x001C0000, nullptr, "WakeupApplication"}, + {0x001D0000, nullptr, "CancelApplication"}, + {0x001E0084, &APT_A::StartLibraryApplet, "StartLibraryApplet"}, + {0x001F0084, nullptr, "StartSystemApplet"}, + {0x00200044, nullptr, "StartNewestHomeMenu"}, + {0x00210000, nullptr, "OrderToCloseApplication"}, + {0x00220040, nullptr, "PrepareToCloseApplication"}, + {0x00230040, nullptr, "PrepareToJumpToApplication"}, + {0x00240044, nullptr, "JumpToApplication"}, + {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, + {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, + {0x00270044, nullptr, "CloseApplication"}, + {0x00280044, nullptr, "CloseLibraryApplet"}, + {0x00290044, nullptr, "CloseSystemApplet"}, + {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, + {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"}, + {0x002C0044, nullptr, "JumpToHomeMenu"}, + {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"}, + {0x002E0044, nullptr, "LeaveHomeMenu"}, + {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, + {0x00300044, nullptr, "LeaveResidentApplet"}, + {0x00310100, nullptr, "PrepareToDoApplicationJump"}, + {0x00320084, nullptr, "DoApplicationJump"}, + {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, + {0x00340084, nullptr, "SendDeliverArg"}, + {0x00350080, nullptr, "ReceiveDeliverArg"}, + {0x00360040, nullptr, "LoadSysMenuArg"}, + {0x00370042, nullptr, "StoreSysMenuArg"}, + {0x00380040, nullptr, "PreloadResidentApplet"}, + {0x00390040, nullptr, "PrepareToStartResidentApplet"}, + {0x003A0044, nullptr, "StartResidentApplet"}, + {0x003B0040, &APT_A::CancelLibraryApplet, "CancelLibraryApplet"}, + {0x003C0042, nullptr, "SendDspSleep"}, + {0x003D0042, nullptr, "SendDspWakeUp"}, + {0x003E0080, nullptr, "ReplySleepQuery"}, + {0x003F0040, nullptr, "ReplySleepNotificationComplete"}, + {0x00400042, nullptr, "SendCaptureBufferInfo"}, + {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, + {0x00420080, nullptr, "SleepSystem"}, + {0x00430040, &APT_A::NotifyToWait, "NotifyToWait"}, + {0x00440000, &APT_A::GetSharedFont, "GetSharedFont"}, + {0x00450040, nullptr, "GetWirelessRebootInfo"}, + {0x00460104, &APT_A::Wrap, "Wrap"}, + {0x00470104, &APT_A::Unwrap, "Unwrap"}, + {0x00480100, nullptr, "GetProgramInfo"}, + {0x00490180, nullptr, "Reboot"}, + {0x004A0040, nullptr, "GetCaptureInfo"}, + {0x004B00C2, &APT_A::AppletUtility, "AppletUtility"}, + {0x004C0000, nullptr, "SetFatalErrDispMode"}, + {0x004D0080, nullptr, "GetAppletProgramInfo"}, + {0x004E0000, nullptr, "HardwareResetAsync"}, + {0x004F0080, &APT_A::SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, + {0x00500040, &APT_A::GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, + {0x00510080, &APT_A::GetStartupArgument, "GetStartupArgument"}, + {0x00520104, nullptr, "Wrap1"}, + {0x00530104, nullptr, "Unwrap1"}, + {0x00550040, &APT_A::SetScreenCapPostPermission, "SetScreenCapPostPermission"}, + {0x00560000, &APT_A::GetScreenCapPostPermission, "GetScreenCapPostPermission"}, + {0x00570044, nullptr, "WakeupApplication2"}, + {0x00580002, nullptr, "GetProgramID"}, + {0x01010000, &APT_A::CheckNew3DSApp, "CheckNew3DSApp"}, + {0x01020000, &APT_A::CheckNew3DS, "CheckNew3DS"}, + {0x01040000, nullptr, "IsStandardMemoryLayout"}, + {0x01050100, nullptr, "IsTitleAllowed"}, + }; + RegisterHandlers(functions); } } // namespace APT diff --git a/src/core/hle/service/apt/apt_a.h b/src/core/hle/service/apt/apt_a.h index 331fb5586..f4bed80bb 100644 --- a/src/core/hle/service/apt/apt_a.h +++ b/src/core/hle/service/apt/apt_a.h @@ -4,19 +4,15 @@ #pragma once -#include "core/hle/service/service.h" +#include "core/hle/service/apt/apt.h" namespace Service { namespace APT { -class APT_A_Interface : public Service::Interface { +class APT_A final : public Module::Interface { public: - APT_A_Interface(); - - std::string GetPortName() const override { - return "APT:A"; - } + explicit APT_A(std::shared_ptr apt); }; } // namespace APT -} // namespace Service \ No newline at end of file +} // namespace Service diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index eb15f82f4..d8c1c2230 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -2,108 +2,107 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/apt/apt.h" #include "core/hle/service/apt/apt_s.h" namespace Service { namespace APT { -const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, GetLockHandle, "GetLockHandle"}, - {0x00020080, Initialize, "Initialize"}, - {0x00030040, Enable, "Enable"}, - {0x00040040, nullptr, "Finalize"}, - {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, - {0x00060040, GetAppletInfo, "GetAppletInfo"}, - {0x00070000, nullptr, "GetLastSignaledAppletId"}, - {0x00080000, nullptr, "CountRegisteredApplet"}, - {0x00090040, IsRegistered, "IsRegistered"}, - {0x000A0040, nullptr, "GetAttribute"}, - {0x000B0040, InquireNotification, "InquireNotification"}, - {0x000C0104, SendParameter, "SendParameter"}, - {0x000D0080, ReceiveParameter, "ReceiveParameter"}, - {0x000E0080, GlanceParameter, "GlanceParameter"}, - {0x000F0100, nullptr, "CancelParameter"}, - {0x001000C2, nullptr, "DebugFunc"}, - {0x001100C0, nullptr, "MapProgramIdForDebug"}, - {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"}, - {0x00130000, nullptr, "GetPreparationState"}, - {0x00140040, nullptr, "SetPreparationState"}, - {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"}, - {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, - {0x00170040, FinishPreloadingLibraryApplet, "FinishPreloadingLibraryApplet"}, - {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, - {0x00190040, nullptr, "PrepareToStartSystemApplet"}, - {0x001A0000, PrepareToStartNewestHomeMenu, "PrepareToStartNewestHomeMenu"}, - {0x001B00C4, nullptr, "StartApplication"}, - {0x001C0000, nullptr, "WakeupApplication"}, - {0x001D0000, nullptr, "CancelApplication"}, - {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, - {0x001F0084, nullptr, "StartSystemApplet"}, - {0x00200044, nullptr, "StartNewestHomeMenu"}, - {0x00210000, nullptr, "OrderToCloseApplication"}, - {0x00220040, nullptr, "PrepareToCloseApplication"}, - {0x00230040, nullptr, "PrepareToJumpToApplication"}, - {0x00240044, nullptr, "JumpToApplication"}, - {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, - {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, - {0x00270044, nullptr, "CloseApplication"}, - {0x00280044, nullptr, "CloseLibraryApplet"}, - {0x00290044, nullptr, "CloseSystemApplet"}, - {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, - {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"}, - {0x002C0044, nullptr, "JumpToHomeMenu"}, - {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"}, - {0x002E0044, nullptr, "LeaveHomeMenu"}, - {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, - {0x00300044, nullptr, "LeaveResidentApplet"}, - {0x00310100, nullptr, "PrepareToDoApplicationJump"}, - {0x00320084, nullptr, "DoApplicationJump"}, - {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, - {0x00340084, nullptr, "SendDeliverArg"}, - {0x00350080, nullptr, "ReceiveDeliverArg"}, - {0x00360040, nullptr, "LoadSysMenuArg"}, - {0x00370042, nullptr, "StoreSysMenuArg"}, - {0x00380040, nullptr, "PreloadResidentApplet"}, - {0x00390040, nullptr, "PrepareToStartResidentApplet"}, - {0x003A0044, nullptr, "StartResidentApplet"}, - {0x003B0040, nullptr, "CancelLibraryApplet"}, - {0x003C0042, nullptr, "SendDspSleep"}, - {0x003D0042, nullptr, "SendDspWakeUp"}, - {0x003E0080, nullptr, "ReplySleepQuery"}, - {0x003F0040, nullptr, "ReplySleepNotificationComplete"}, - {0x00400042, nullptr, "SendCaptureBufferInfo"}, - {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, - {0x00420080, nullptr, "SleepSystem"}, - {0x00430040, NotifyToWait, "NotifyToWait"}, - {0x00440000, GetSharedFont, "GetSharedFont"}, - {0x00450040, nullptr, "GetWirelessRebootInfo"}, - {0x00460104, Wrap, "Wrap"}, - {0x00470104, Unwrap, "Unwrap"}, - {0x00480100, nullptr, "GetProgramInfo"}, - {0x00490180, nullptr, "Reboot"}, - {0x004A0040, nullptr, "GetCaptureInfo"}, - {0x004B00C2, AppletUtility, "AppletUtility"}, - {0x004C0000, nullptr, "SetFatalErrDispMode"}, - {0x004D0080, nullptr, "GetAppletProgramInfo"}, - {0x004E0000, nullptr, "HardwareResetAsync"}, - {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, - {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, - {0x00510080, GetStartupArgument, "GetStartupArgument"}, - {0x00520104, nullptr, "Wrap1"}, - {0x00530104, nullptr, "Unwrap1"}, - {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"}, - {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"}, - {0x00570044, nullptr, "WakeupApplication2"}, - {0x00580002, nullptr, "GetProgramID"}, - {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, - {0x01020000, CheckNew3DS, "CheckNew3DS"}, - {0x01040000, nullptr, "IsStandardMemoryLayout"}, - {0x01050100, nullptr, "IsTitleAllowed"}, -}; - -APT_S_Interface::APT_S_Interface() : Interface(MaxAPTSessions) { - Register(FunctionTable); +APT_S::APT_S(std::shared_ptr apt) + : Module::Interface(std::move(apt), "APT:S", MaxAPTSessions) { + static const FunctionInfo functions[] = { + {0x00010040, &APT_S::GetLockHandle, "GetLockHandle"}, + {0x00020080, &APT_S::Initialize, "Initialize"}, + {0x00030040, &APT_S::Enable, "Enable"}, + {0x00040040, nullptr, "Finalize"}, + {0x00050040, &APT_S::GetAppletManInfo, "GetAppletManInfo"}, + {0x00060040, &APT_S::GetAppletInfo, "GetAppletInfo"}, + {0x00070000, nullptr, "GetLastSignaledAppletId"}, + {0x00080000, nullptr, "CountRegisteredApplet"}, + {0x00090040, &APT_S::IsRegistered, "IsRegistered"}, + {0x000A0040, nullptr, "GetAttribute"}, + {0x000B0040, &APT_S::InquireNotification, "InquireNotification"}, + {0x000C0104, &APT_S::SendParameter, "SendParameter"}, + {0x000D0080, &APT_S::ReceiveParameter, "ReceiveParameter"}, + {0x000E0080, &APT_S::GlanceParameter, "GlanceParameter"}, + {0x000F0100, nullptr, "CancelParameter"}, + {0x001000C2, nullptr, "DebugFunc"}, + {0x001100C0, nullptr, "MapProgramIdForDebug"}, + {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"}, + {0x00130000, nullptr, "GetPreparationState"}, + {0x00140040, nullptr, "SetPreparationState"}, + {0x00150140, &APT_S::PrepareToStartApplication, "PrepareToStartApplication"}, + {0x00160040, &APT_S::PreloadLibraryApplet, "PreloadLibraryApplet"}, + {0x00170040, &APT_S::FinishPreloadingLibraryApplet, "FinishPreloadingLibraryApplet"}, + {0x00180040, &APT_S::PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, + {0x00190040, nullptr, "PrepareToStartSystemApplet"}, + {0x001A0000, &APT_S::PrepareToStartNewestHomeMenu, "PrepareToStartNewestHomeMenu"}, + {0x001B00C4, nullptr, "StartApplication"}, + {0x001C0000, nullptr, "WakeupApplication"}, + {0x001D0000, nullptr, "CancelApplication"}, + {0x001E0084, &APT_S::StartLibraryApplet, "StartLibraryApplet"}, + {0x001F0084, nullptr, "StartSystemApplet"}, + {0x00200044, nullptr, "StartNewestHomeMenu"}, + {0x00210000, nullptr, "OrderToCloseApplication"}, + {0x00220040, nullptr, "PrepareToCloseApplication"}, + {0x00230040, nullptr, "PrepareToJumpToApplication"}, + {0x00240044, nullptr, "JumpToApplication"}, + {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, + {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, + {0x00270044, nullptr, "CloseApplication"}, + {0x00280044, nullptr, "CloseLibraryApplet"}, + {0x00290044, nullptr, "CloseSystemApplet"}, + {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, + {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"}, + {0x002C0044, nullptr, "JumpToHomeMenu"}, + {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"}, + {0x002E0044, nullptr, "LeaveHomeMenu"}, + {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, + {0x00300044, nullptr, "LeaveResidentApplet"}, + {0x00310100, nullptr, "PrepareToDoApplicationJump"}, + {0x00320084, nullptr, "DoApplicationJump"}, + {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, + {0x00340084, nullptr, "SendDeliverArg"}, + {0x00350080, nullptr, "ReceiveDeliverArg"}, + {0x00360040, nullptr, "LoadSysMenuArg"}, + {0x00370042, nullptr, "StoreSysMenuArg"}, + {0x00380040, nullptr, "PreloadResidentApplet"}, + {0x00390040, nullptr, "PrepareToStartResidentApplet"}, + {0x003A0044, nullptr, "StartResidentApplet"}, + {0x003B0040, nullptr, "CancelLibraryApplet"}, + {0x003C0042, nullptr, "SendDspSleep"}, + {0x003D0042, nullptr, "SendDspWakeUp"}, + {0x003E0080, nullptr, "ReplySleepQuery"}, + {0x003F0040, nullptr, "ReplySleepNotificationComplete"}, + {0x00400042, nullptr, "SendCaptureBufferInfo"}, + {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, + {0x00420080, nullptr, "SleepSystem"}, + {0x00430040, &APT_S::NotifyToWait, "NotifyToWait"}, + {0x00440000, &APT_S::GetSharedFont, "GetSharedFont"}, + {0x00450040, nullptr, "GetWirelessRebootInfo"}, + {0x00460104, &APT_S::Wrap, "Wrap"}, + {0x00470104, &APT_S::Unwrap, "Unwrap"}, + {0x00480100, nullptr, "GetProgramInfo"}, + {0x00490180, nullptr, "Reboot"}, + {0x004A0040, nullptr, "GetCaptureInfo"}, + {0x004B00C2, &APT_S::AppletUtility, "AppletUtility"}, + {0x004C0000, nullptr, "SetFatalErrDispMode"}, + {0x004D0080, nullptr, "GetAppletProgramInfo"}, + {0x004E0000, nullptr, "HardwareResetAsync"}, + {0x004F0080, &APT_S::SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, + {0x00500040, &APT_S::GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, + {0x00510080, &APT_S::GetStartupArgument, "GetStartupArgument"}, + {0x00520104, nullptr, "Wrap1"}, + {0x00530104, nullptr, "Unwrap1"}, + {0x00550040, &APT_S::SetScreenCapPostPermission, "SetScreenCapPostPermission"}, + {0x00560000, &APT_S::GetScreenCapPostPermission, "GetScreenCapPostPermission"}, + {0x00570044, nullptr, "WakeupApplication2"}, + {0x00580002, nullptr, "GetProgramID"}, + {0x01010000, &APT_S::CheckNew3DSApp, "CheckNew3DSApp"}, + {0x01020000, &APT_S::CheckNew3DS, "CheckNew3DS"}, + {0x01040000, nullptr, "IsStandardMemoryLayout"}, + {0x01050100, nullptr, "IsTitleAllowed"}, + }; + RegisterHandlers(functions); } } // namespace APT diff --git a/src/core/hle/service/apt/apt_s.h b/src/core/hle/service/apt/apt_s.h index 8e87b69af..20b6c814a 100644 --- a/src/core/hle/service/apt/apt_s.h +++ b/src/core/hle/service/apt/apt_s.h @@ -4,7 +4,7 @@ #pragma once -#include "core/hle/service/service.h" +#include "core/hle/service/apt/apt.h" namespace Service { namespace APT { @@ -16,14 +16,10 @@ namespace APT { // svcBreak when the command isn't accessible). See http://3dbrew.org/wiki/NS#APT_Services. /// Interface to "APT:S" service -class APT_S_Interface : public Service::Interface { +class APT_S final : public Module::Interface { public: - APT_S_Interface(); - - std::string GetPortName() const override { - return "APT:S"; - } + explicit APT_S(std::shared_ptr apt); }; } // namespace APT -} // namespace Service \ No newline at end of file +} // namespace Service diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index 12eb206ca..8475827e2 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp @@ -2,105 +2,104 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/apt/apt.h" #include "core/hle/service/apt/apt_u.h" namespace Service { namespace APT { -const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, GetLockHandle, "GetLockHandle"}, - {0x00020080, Initialize, "Initialize"}, - {0x00030040, Enable, "Enable"}, - {0x00040040, nullptr, "Finalize"}, - {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, - {0x00060040, GetAppletInfo, "GetAppletInfo"}, - {0x00070000, nullptr, "GetLastSignaledAppletId"}, - {0x00080000, nullptr, "CountRegisteredApplet"}, - {0x00090040, IsRegistered, "IsRegistered"}, - {0x000A0040, nullptr, "GetAttribute"}, - {0x000B0040, InquireNotification, "InquireNotification"}, - {0x000C0104, SendParameter, "SendParameter"}, - {0x000D0080, ReceiveParameter, "ReceiveParameter"}, - {0x000E0080, GlanceParameter, "GlanceParameter"}, - {0x000F0100, CancelParameter, "CancelParameter"}, - {0x001000C2, nullptr, "DebugFunc"}, - {0x001100C0, nullptr, "MapProgramIdForDebug"}, - {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"}, - {0x00130000, nullptr, "GetPreparationState"}, - {0x00140040, nullptr, "SetPreparationState"}, - {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"}, - {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, - {0x00170040, FinishPreloadingLibraryApplet, "FinishPreloadingLibraryApplet"}, - {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, - {0x00190040, nullptr, "PrepareToStartSystemApplet"}, - {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, - {0x001B00C4, nullptr, "StartApplication"}, - {0x001C0000, nullptr, "WakeupApplication"}, - {0x001D0000, nullptr, "CancelApplication"}, - {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, - {0x001F0084, nullptr, "StartSystemApplet"}, - {0x00200044, nullptr, "StartNewestHomeMenu"}, - {0x00210000, nullptr, "OrderToCloseApplication"}, - {0x00220040, nullptr, "PrepareToCloseApplication"}, - {0x00230040, nullptr, "PrepareToJumpToApplication"}, - {0x00240044, nullptr, "JumpToApplication"}, - {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, - {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, - {0x00270044, nullptr, "CloseApplication"}, - {0x00280044, nullptr, "CloseLibraryApplet"}, - {0x00290044, nullptr, "CloseSystemApplet"}, - {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, - {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"}, - {0x002C0044, nullptr, "JumpToHomeMenu"}, - {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"}, - {0x002E0044, nullptr, "LeaveHomeMenu"}, - {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, - {0x00300044, nullptr, "LeaveResidentApplet"}, - {0x00310100, nullptr, "PrepareToDoApplicationJump"}, - {0x00320084, nullptr, "DoApplicationJump"}, - {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, - {0x00340084, nullptr, "SendDeliverArg"}, - {0x00350080, nullptr, "ReceiveDeliverArg"}, - {0x00360040, nullptr, "LoadSysMenuArg"}, - {0x00370042, nullptr, "StoreSysMenuArg"}, - {0x00380040, nullptr, "PreloadResidentApplet"}, - {0x00390040, nullptr, "PrepareToStartResidentApplet"}, - {0x003A0044, nullptr, "StartResidentApplet"}, - {0x003B0040, CancelLibraryApplet, "CancelLibraryApplet"}, - {0x003C0042, nullptr, "SendDspSleep"}, - {0x003D0042, nullptr, "SendDspWakeUp"}, - {0x003E0080, nullptr, "ReplySleepQuery"}, - {0x003F0040, nullptr, "ReplySleepNotificationComplete"}, - {0x00400042, nullptr, "SendCaptureBufferInfo"}, - {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, - {0x00420080, nullptr, "SleepSystem"}, - {0x00430040, NotifyToWait, "NotifyToWait"}, - {0x00440000, GetSharedFont, "GetSharedFont"}, - {0x00450040, nullptr, "GetWirelessRebootInfo"}, - {0x00460104, Wrap, "Wrap"}, - {0x00470104, Unwrap, "Unwrap"}, - {0x00480100, nullptr, "GetProgramInfo"}, - {0x00490180, nullptr, "Reboot"}, - {0x004A0040, nullptr, "GetCaptureInfo"}, - {0x004B00C2, AppletUtility, "AppletUtility"}, - {0x004C0000, nullptr, "SetFatalErrDispMode"}, - {0x004D0080, nullptr, "GetAppletProgramInfo"}, - {0x004E0000, nullptr, "HardwareResetAsync"}, - {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, - {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, - {0x00510080, GetStartupArgument, "GetStartupArgument"}, - {0x00520104, nullptr, "Wrap1"}, - {0x00530104, nullptr, "Unwrap1"}, - {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"}, - {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"}, - {0x00580002, nullptr, "GetProgramID"}, - {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, - {0x01020000, CheckNew3DS, "CheckNew3DS"}, -}; - -APT_U_Interface::APT_U_Interface() : Interface(MaxAPTSessions) { - Register(FunctionTable); +APT_U::APT_U(std::shared_ptr apt) + : Module::Interface(std::move(apt), "APT:U", MaxAPTSessions) { + static const FunctionInfo functions[] = { + {0x00010040, &APT_U::GetLockHandle, "GetLockHandle"}, + {0x00020080, &APT_U::Initialize, "Initialize"}, + {0x00030040, &APT_U::Enable, "Enable"}, + {0x00040040, nullptr, "Finalize"}, + {0x00050040, &APT_U::GetAppletManInfo, "GetAppletManInfo"}, + {0x00060040, &APT_U::GetAppletInfo, "GetAppletInfo"}, + {0x00070000, nullptr, "GetLastSignaledAppletId"}, + {0x00080000, nullptr, "CountRegisteredApplet"}, + {0x00090040, &APT_U::IsRegistered, "IsRegistered"}, + {0x000A0040, nullptr, "GetAttribute"}, + {0x000B0040, &APT_U::InquireNotification, "InquireNotification"}, + {0x000C0104, &APT_U::SendParameter, "SendParameter"}, + {0x000D0080, &APT_U::ReceiveParameter, "ReceiveParameter"}, + {0x000E0080, &APT_U::GlanceParameter, "GlanceParameter"}, + {0x000F0100, &APT_U::CancelParameter, "CancelParameter"}, + {0x001000C2, nullptr, "DebugFunc"}, + {0x001100C0, nullptr, "MapProgramIdForDebug"}, + {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"}, + {0x00130000, nullptr, "GetPreparationState"}, + {0x00140040, nullptr, "SetPreparationState"}, + {0x00150140, &APT_U::PrepareToStartApplication, "PrepareToStartApplication"}, + {0x00160040, &APT_U::PreloadLibraryApplet, "PreloadLibraryApplet"}, + {0x00170040, &APT_U::FinishPreloadingLibraryApplet, "FinishPreloadingLibraryApplet"}, + {0x00180040, &APT_U::PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, + {0x00190040, nullptr, "PrepareToStartSystemApplet"}, + {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, + {0x001B00C4, nullptr, "StartApplication"}, + {0x001C0000, nullptr, "WakeupApplication"}, + {0x001D0000, nullptr, "CancelApplication"}, + {0x001E0084, &APT_U::StartLibraryApplet, "StartLibraryApplet"}, + {0x001F0084, nullptr, "StartSystemApplet"}, + {0x00200044, nullptr, "StartNewestHomeMenu"}, + {0x00210000, nullptr, "OrderToCloseApplication"}, + {0x00220040, nullptr, "PrepareToCloseApplication"}, + {0x00230040, nullptr, "PrepareToJumpToApplication"}, + {0x00240044, nullptr, "JumpToApplication"}, + {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, + {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, + {0x00270044, nullptr, "CloseApplication"}, + {0x00280044, nullptr, "CloseLibraryApplet"}, + {0x00290044, nullptr, "CloseSystemApplet"}, + {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, + {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"}, + {0x002C0044, nullptr, "JumpToHomeMenu"}, + {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"}, + {0x002E0044, nullptr, "LeaveHomeMenu"}, + {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, + {0x00300044, nullptr, "LeaveResidentApplet"}, + {0x00310100, nullptr, "PrepareToDoApplicationJump"}, + {0x00320084, nullptr, "DoApplicationJump"}, + {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, + {0x00340084, nullptr, "SendDeliverArg"}, + {0x00350080, nullptr, "ReceiveDeliverArg"}, + {0x00360040, nullptr, "LoadSysMenuArg"}, + {0x00370042, nullptr, "StoreSysMenuArg"}, + {0x00380040, nullptr, "PreloadResidentApplet"}, + {0x00390040, nullptr, "PrepareToStartResidentApplet"}, + {0x003A0044, nullptr, "StartResidentApplet"}, + {0x003B0040, &APT_U::CancelLibraryApplet, "CancelLibraryApplet"}, + {0x003C0042, nullptr, "SendDspSleep"}, + {0x003D0042, nullptr, "SendDspWakeUp"}, + {0x003E0080, nullptr, "ReplySleepQuery"}, + {0x003F0040, nullptr, "ReplySleepNotificationComplete"}, + {0x00400042, nullptr, "SendCaptureBufferInfo"}, + {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, + {0x00420080, nullptr, "SleepSystem"}, + {0x00430040, &APT_U::NotifyToWait, "NotifyToWait"}, + {0x00440000, &APT_U::GetSharedFont, "GetSharedFont"}, + {0x00450040, nullptr, "GetWirelessRebootInfo"}, + {0x00460104, &APT_U::Wrap, "Wrap"}, + {0x00470104, &APT_U::Unwrap, "Unwrap"}, + {0x00480100, nullptr, "GetProgramInfo"}, + {0x00490180, nullptr, "Reboot"}, + {0x004A0040, nullptr, "GetCaptureInfo"}, + {0x004B00C2, &APT_U::AppletUtility, "AppletUtility"}, + {0x004C0000, nullptr, "SetFatalErrDispMode"}, + {0x004D0080, nullptr, "GetAppletProgramInfo"}, + {0x004E0000, nullptr, "HardwareResetAsync"}, + {0x004F0080, &APT_U::SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, + {0x00500040, &APT_U::GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, + {0x00510080, &APT_U::GetStartupArgument, "GetStartupArgument"}, + {0x00520104, nullptr, "Wrap1"}, + {0x00530104, nullptr, "Unwrap1"}, + {0x00550040, &APT_U::SetScreenCapPostPermission, "SetScreenCapPostPermission"}, + {0x00560000, &APT_U::GetScreenCapPostPermission, "GetScreenCapPostPermission"}, + {0x00580002, nullptr, "GetProgramID"}, + {0x01010000, &APT_U::CheckNew3DSApp, "CheckNew3DSApp"}, + {0x01020000, &APT_U::CheckNew3DS, "CheckNew3DS"}, + }; + RegisterHandlers(functions); } } // namespace APT diff --git a/src/core/hle/service/apt/apt_u.h b/src/core/hle/service/apt/apt_u.h index 8c7fe0ccb..4a0d8fe08 100644 --- a/src/core/hle/service/apt/apt_u.h +++ b/src/core/hle/service/apt/apt_u.h @@ -4,7 +4,7 @@ #pragma once -#include "core/hle/service/service.h" +#include "core/hle/service/apt/apt.h" namespace Service { namespace APT { @@ -16,14 +16,10 @@ namespace APT { // svcBreak when the command isn't accessible). See http://3dbrew.org/wiki/NS#APT_Services. /// Interface to "APT:U" service -class APT_U_Interface : public Service::Interface { +class APT_U final : public Module::Interface { public: - APT_U_Interface(); - - std::string GetPortName() const override { - return "APT:U"; - } + explicit APT_U(std::shared_ptr apt); }; } // namespace APT -} // namespace Service \ No newline at end of file +} // namespace Service diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index ccbb398b5..133e14d5e 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -269,7 +269,7 @@ void Init() { FS::ArchiveInit(); ACT::Init(); AM::Init(); - APT::Init(); + APT::InstallInterfaces(*SM::g_service_manager); BOSS::Init(); CAM::InstallInterfaces(*SM::g_service_manager); CECD::Init(); @@ -311,7 +311,6 @@ void Shutdown() { CFG::Shutdown(); CECD::Shutdown(); BOSS::Shutdown(); - APT::Shutdown(); AM::Shutdown(); FS::ArchiveShutdown(); From 66141ed00426197eeb7a9c3be1fb90bf01bd84ef Mon Sep 17 00:00:00 2001 From: wwylele Date: Fri, 9 Feb 2018 18:10:46 +0200 Subject: [PATCH 2/3] apt: fix doc format --- src/core/hle/service/apt/apt.h | 56 +++++++++++++--------------------- 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index f3df7ae29..c80658edf 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -181,12 +181,10 @@ public: /** * APT::IsRegistered service function. This returns whether the specified AppID is - * registered with - * NS yet. An AppID is "registered" once the process associated with the AppID uses - * APT:Enable. Home - * Menu uses this command to determine when the launched process is running and to determine - * when to - * stop using GSP, etc., while displaying the "Nintendo 3DS" loading screen. + * registered with NS yet. An AppID is "registered" once the process associated with the + * AppID uses APT:Enable. Home Menu uses this command to determine when the launched process + * is running and to determine when to stop using GSP, etc., while displaying the "Nintendo + * 3DS" loading screen. * * Inputs: * 1 : AppID @@ -219,14 +217,10 @@ public: /** * APT::ReceiveParameter service function. This returns the current parameter data from NS - * state, - * from the source process which set the parameters. Once finished, NS will clear a flag in - * the NS - * state so that this command will return an error if this command is used again if - * parameters were - * not set again. This is called when the second Initialize event is triggered. It returns a - * signal - * type indicating why it was triggered. + * state, from the source process which set the parameters. Once finished, NS will clear a + * flag in the NS state so that this command will return an error if this command is used + * again if parameters were not set again. This is called when the second Initialize event + * is triggered. It returns a signal type indicating why it was triggered. * Inputs: * 1 : AppID * 2 : Parameter buffer size, max size is 0x1000 @@ -245,10 +239,9 @@ public: /** * APT::GlanceParameter service function. This is exactly the same as - * APT_U::ReceiveParameter - * (except for the word value prior to the output handle), except this will not clear the - * flag - * (except when responseword[3]==8 || responseword[3]==9) in NS state. + * APT_U::ReceiveParameter (except for the word value prior to the output handle), except + * this will not clear the flag (except when responseword[3]==8 || responseword[3]==9) in NS + * state. * Inputs: * 1 : AppID * 2 : Parameter buffer size, max size is 0x1000 @@ -267,11 +260,9 @@ public: /** * APT::CancelParameter service function. When the parameter data is available, and when the - * above - * specified fields match the ones in NS state(for the ones where the checks are enabled), - * this - * clears the flag which indicates that parameter data is available - * (same flag cleared by APT:ReceiveParameter). + * above specified fields match the ones in NS state(for the ones where the checks are + * enabled), this clears the flag which indicates that parameter data is available (same + * flag cleared by APT:ReceiveParameter). * Inputs: * 1 : Flag, when non-zero NS will compare the word after this one with a field in the * NS @@ -293,16 +284,12 @@ public: /** * APT::PrepareToStartApplication service function. When the input title-info programID is - * zero, - * NS will load the actual program ID via AMNet:GetTitleIDList. After doing some checks with - * the - * programID, NS will then set a NS state flag to value 1, then set the programID for AppID - * 0x300(application) to the input program ID(or the one from GetTitleIDList). A media-type - * field - * in the NS state is also set to the input media-type value - * (other state fields are set at this point as well). With 8.0.0-18, NS will set an u8 NS - * state - * field to value 1 when input flags bit8 is set + * zero, NS will load the actual program ID via AMNet:GetTitleIDList. After doing some + * checks with the programID, NS will then set a NS state flag to value 1, then set the + * programID for AppID 0x300(application) to the input program ID(or the one from + * GetTitleIDList). A media-type field in the NS state is also set to the input media-type + * value (other state fields are set at this point as well). With 8.0.0-18, NS will set an + * u8 NS state field to value 1 when input flags bit8 is set. * Inputs: * 1-4 : 0x10-byte title-info struct * 4 : Flags @@ -314,8 +301,7 @@ public: /** * APT::StartApplication service function. Buf0 is copied to NS FIRMparams+0x0, then Buf1 is - * copied - * to the NS FIRMparams+0x480. Then the application is launched. + * copied to the NS FIRMparams+0x480. Then the application is launched. * Inputs: * 1 : Buffer 0 size, max size is 0x300 * 2 : Buffer 1 size, max size is 0x20 (this can be zero) From c4db298a7d439bc03052b01b328792d7277a1c25 Mon Sep 17 00:00:00 2001 From: wwylele Date: Sun, 11 Feb 2018 00:09:52 +0200 Subject: [PATCH 3/3] HLE/IPC: remove assertion on empty buffer. Some service functions do require to push an empty buffer in some cases. See APT:ReceiveParameter/GlanceParameter --- src/core/hle/kernel/hle_ipc.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 5b76a92cd..61b4b8e46 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -52,7 +52,6 @@ void HLERequestContext::ClearIncomingObjects() { } const std::vector& HLERequestContext::GetStaticBuffer(u8 buffer_id) const { - ASSERT_MSG(!static_buffers[buffer_id].empty(), "Empty static buffer!"); return static_buffers[buffer_id]; }