diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index d93b4bcb25..07c5ff5d3a 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -670,6 +670,37 @@ void Module::APTInterface::CloseLibraryApplet(Kernel::HLERequestContext& ctx) { rb.Push(apt->applet_manager->CloseLibraryApplet(std::move(object), std::move(buffer))); } +void Module::APTInterface::LoadSysMenuArg(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x36, 1, 0); // 0x00360040 + const auto size = std::min(std::size_t{rp.Pop()}, SysMenuArgSize); + + // This service function does not clear the buffer. + + std::vector buffer(size); + std::copy_n(apt->sys_menu_arg_buffer.cbegin(), size, buffer.begin()); + + IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); + rb.Push(RESULT_SUCCESS); + rb.PushStaticBuffer(std::move(buffer), 0); + + LOG_DEBUG(Service_APT, "called"); +} + +void Module::APTInterface::StoreSysMenuArg(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x37, 1, 2); // 0x00370042 + const auto size = std::min(std::size_t{rp.Pop()}, SysMenuArgSize); + const auto& buffer = rp.PopStaticBuffer(); + + ASSERT_MSG(buffer.size() >= size, "Buffer too small to hold requested data"); + + std::copy_n(buffer.cbegin(), size, apt->sys_menu_arg_buffer.begin()); + + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(RESULT_SUCCESS); + + LOG_DEBUG(Service_APT, "called"); +} + void Module::APTInterface::SendCaptureBufferInfo(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x40, 1, 2); // 0x00400042 u32 size = rp.Pop(); diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 8b01d3b8eb..25cac13578 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include "common/archives.h" @@ -44,6 +45,8 @@ struct CaptureBufferInfo { }; static_assert(sizeof(CaptureBufferInfo) == 0x20, "CaptureBufferInfo struct has incorrect size"); +constexpr std::size_t SysMenuArgSize = 0x40; + enum class StartupArgumentType : u32 { OtherApp = 0, Restart = 1, @@ -520,6 +523,32 @@ public: */ void CloseLibraryApplet(Kernel::HLERequestContext& ctx); + /** + * APT::LoadSysMenuArg service function + * Inputs: + * 0 : Command header [0x00360040] + * 1 : Buffer size + * Outputs: + * 0 : Header code + * 1 : Result code + * 64 : Size << 14 | 2 + * 65 : void* Output Buffer + */ + void LoadSysMenuArg(Kernel::HLERequestContext& ctx); + + /** + * APT::StoreSysMenuArg service function + * Inputs: + * 0 : Command header [0x00370042] + * 1 : Buffer size + * 2 : (Size << 14) | 2 + * 3 : Input buffer virtual address + * Outputs: + * 0 : Header code + * 1 : Result code + */ + void StoreSysMenuArg(Kernel::HLERequestContext& ctx); + /** * APT::SendCaptureBufferInfo service function * Inputs: @@ -634,6 +663,7 @@ private: u8 unknown_ns_state_field = 0; std::vector screen_capture_buffer; + std::array sys_menu_arg_buffer; ScreencapPostPermission screen_capture_post_permission = ScreencapPostPermission::CleanThePermission; // TODO(JamePeng): verify the initial value diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index d0e5f55266..f66c67af8f 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -63,8 +63,8 @@ APT_S::APT_S(std::shared_ptr apt) {0x00330000, &APT_S::GetProgramIdOnApplicationJump, "GetProgramIdOnApplicationJump"}, {0x00340084, nullptr, "SendDeliverArg"}, {0x00350080, nullptr, "ReceiveDeliverArg"}, - {0x00360040, nullptr, "LoadSysMenuArg"}, - {0x00370042, nullptr, "StoreSysMenuArg"}, + {0x00360040, &APT_S::LoadSysMenuArg, "LoadSysMenuArg"}, + {0x00370042, &APT_S::StoreSysMenuArg, "StoreSysMenuArg"}, {0x00380040, nullptr, "PreloadResidentApplet"}, {0x00390040, nullptr, "PrepareToStartResidentApplet"}, {0x003A0044, nullptr, "StartResidentApplet"}, diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index 05f531a833..03795c94cd 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp @@ -63,8 +63,8 @@ APT_U::APT_U(std::shared_ptr apt) {0x00330000, &APT_U::GetProgramIdOnApplicationJump, "GetProgramIdOnApplicationJump"}, {0x00340084, nullptr, "SendDeliverArg"}, {0x00350080, nullptr, "ReceiveDeliverArg"}, - {0x00360040, nullptr, "LoadSysMenuArg"}, - {0x00370042, nullptr, "StoreSysMenuArg"}, + {0x00360040, &APT_U::LoadSysMenuArg, "LoadSysMenuArg"}, + {0x00370042, &APT_U::StoreSysMenuArg, "StoreSysMenuArg"}, {0x00380040, nullptr, "PreloadResidentApplet"}, {0x00390040, nullptr, "PrepareToStartResidentApplet"}, {0x003A0044, nullptr, "StartResidentApplet"},