diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/service/am/am.cpp | 89 |
1 files changed, 75 insertions, 14 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 416c5239a..4c8216b47 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -619,16 +619,20 @@ std::size_t AppletMessageQueue::GetMessageCount() const { return messages.size(); } +void AppletMessageQueue::RequestExit() { + PushMessage(AppletMessage::ExitRequested); +} + +void AppletMessageQueue::FocusStateChanged() { + PushMessage(AppletMessage::FocusStateChanged); +} + void AppletMessageQueue::OperationModeChanged() { PushMessage(AppletMessage::OperationModeChanged); PushMessage(AppletMessage::PerformanceModeChanged); on_operation_mode_changed->GetWritableEvent()->Signal(); } -void AppletMessageQueue::RequestExit() { - PushMessage(AppletMessage::ExitRequested); -} - ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr<AppletMessageQueue> msg_queue_) : ServiceFramework{system_, "ICommonStateGetter"}, msg_queue{std::move(msg_queue_)} { @@ -971,7 +975,7 @@ private: auto storage = applet->GetBroker().PopNormalDataToGame(); if (storage == nullptr) { - LOG_ERROR(Service_AM, + LOG_DEBUG(Service_AM, "storage is a nullptr. There is no data in the current normal channel"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ERR_NO_DATA_IN_CHANNEL); @@ -1002,7 +1006,7 @@ private: auto storage = applet->GetBroker().PopInteractiveDataToGame(); if (storage == nullptr) { - LOG_ERROR(Service_AM, + LOG_DEBUG(Service_AM, "storage is a nullptr. There is no data in the current interactive channel"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ERR_NO_DATA_IN_CHANNEL); @@ -1125,7 +1129,7 @@ ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_) {2, nullptr, "AreAnyLibraryAppletsLeft"}, {10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"}, {11, &ILibraryAppletCreator::CreateTransferMemoryStorage, "CreateTransferMemoryStorage"}, - {12, nullptr, "CreateHandleStorage"}, + {12, &ILibraryAppletCreator::CreateHandleStorage, "CreateHandleStorage"}, }; RegisterHandlers(functions); } @@ -1134,14 +1138,15 @@ ILibraryAppletCreator::~ILibraryAppletCreator() = default; void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; + const auto applet_id = rp.PopRaw<Applets::AppletId>(); - const auto applet_mode = rp.PopRaw<u32>(); + const auto applet_mode = rp.PopRaw<Applets::LibraryAppletMode>(); LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id, applet_mode); const auto& applet_manager{system.GetAppletManager()}; - const auto applet = applet_manager.GetApplet(applet_id); + const auto applet = applet_manager.GetApplet(applet_id, applet_mode); if (applet == nullptr) { LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); @@ -1159,9 +1164,18 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - const u64 size{rp.Pop<u64>()}; + + const s64 size{rp.Pop<s64>()}; + LOG_DEBUG(Service_AM, "called, size={}", size); + if (size <= 0) { + LOG_ERROR(Service_AM, "size is less than or equal to 0"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_UNKNOWN); + return; + } + std::vector<u8> buffer(size); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; @@ -1170,18 +1184,65 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) { } void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_AM, "called"); + IPC::RequestParser rp{ctx}; + + struct Parameters { + u8 permissions; + s64 size; + }; + + const auto parameters{rp.PopRaw<Parameters>()}; + const auto handle{ctx.GetCopyHandle(0)}; + + LOG_DEBUG(Service_AM, "called, permissions={}, size={}, handle={:08X}", parameters.permissions, + parameters.size, handle); + + if (parameters.size <= 0) { + LOG_ERROR(Service_AM, "size is less than or equal to 0"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_UNKNOWN); + return; + } + + auto transfer_mem = + system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle); + + if (transfer_mem == nullptr) { + LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_UNKNOWN); + return; + } + const u8* const mem_begin = transfer_mem->GetPointer(); + const u8* const mem_end = mem_begin + transfer_mem->GetSize(); + std::vector<u8> memory{mem_begin, mem_end}; + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IStorage>(system, std::move(memory)); +} + +void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - rp.SetCurrentOffset(3); - const auto handle{rp.Pop<Kernel::Handle>()}; + const s64 size{rp.Pop<s64>()}; + const auto handle{ctx.GetCopyHandle(0)}; + + LOG_DEBUG(Service_AM, "called, size={}, handle={:08X}", size, handle); + + if (size <= 0) { + LOG_ERROR(Service_AM, "size is less than or equal to 0"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_UNKNOWN); + return; + } auto transfer_mem = system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle); if (transfer_mem == nullptr) { - LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle); + LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_UNKNOWN); return; |