From 6209fe0c27a5557c20ff6350a94f6e074e0285dc Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 16 Nov 2018 22:20:09 -0500 Subject: [PATCH] software_keyboard: Push buffer size to offset 0x4 in output data --- src/core/hle/service/am/am.cpp | 30 ++++++++++++------- src/core/hle/service/am/applets/applets.h | 4 ++- .../service/am/applets/software_keyboard.cpp | 18 +++++++---- .../service/am/applets/software_keyboard.h | 5 +++- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index d040d4776c..470253ef1d 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -583,31 +583,38 @@ private: rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(state_changed_event); - LOG_WARNING(Service_AM, "(STUBBED) called"); + LOG_DEBUG(Service_AM, "called"); } void IsCompleted(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(applet->TransactionComplete()); + + LOG_DEBUG(Service_AM, "called"); } void GetResult(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(applet->GetStatus()); + + LOG_DEBUG(Service_AM, "called"); } void Start(Kernel::HLERequestContext& ctx) { ASSERT(applet != nullptr); applet->Initialize(storage_stack); - applet->Execute( - [this](IStorage storage) { AppletStorageProxyOutData(storage); }, - [this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); }); - state_changed_event->Signal(); + storage_stack.clear(); + interactive_storage_stack.clear(); + applet->Execute([this](IStorage storage) { AppletStorageProxyOutData(storage); }, + [this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); }, + [this] { state_changed_event->Signal(); }); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); + + LOG_DEBUG(Service_AM, "called"); } void PushInData(Kernel::HLERequestContext& ctx) { @@ -636,10 +643,9 @@ private: ASSERT(applet->IsInitialized()); applet->ReceiveInteractiveData(interactive_storage_stack.back()); - applet->Execute( - [this](IStorage storage) { AppletStorageProxyOutData(storage); }, - [this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); }); - state_changed_event->Signal(); + applet->Execute([this](IStorage storage) { AppletStorageProxyOutData(storage); }, + [this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); }, + [this] { state_changed_event->Signal(); }); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -661,6 +667,8 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(pop_out_data_event); + + LOG_DEBUG(Service_AM, "called"); } void GetPopInteractiveOutDataEvent(Kernel::HLERequestContext& ctx) { @@ -668,7 +676,7 @@ private: rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(pop_interactive_out_data_event); - LOG_WARNING(Service_AM, "(STUBBED) called"); + LOG_DEBUG(Service_AM, "called"); } std::shared_ptr applet; @@ -734,7 +742,7 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) { const u64 offset{rp.Pop()}; std::size_t size{ctx.GetWriteBufferSize()}; - size = std::min(size, backing.buffer.size() - offset); + size = std::min(size, backing.buffer.size() - offset); ctx.WriteBuffer(backing.buffer.data() + offset, size); diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 7fbaaf2f36..1ffa094208 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h @@ -22,6 +22,7 @@ class IStorage; namespace Applets { using AppletStorageProxyFunction = std::function; +using AppletStateProxyFunction = std::function; class Applet { public: @@ -34,7 +35,8 @@ public: virtual ResultCode GetStatus() const = 0; virtual void ReceiveInteractiveData(std::shared_ptr storage) = 0; virtual void Execute(AppletStorageProxyFunction out_data, - AppletStorageProxyFunction out_interactive_data) = 0; + AppletStorageProxyFunction out_interactive_data, + AppletStateProxyFunction state) = 0; bool IsInitialized() const { return initialized; diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp index 66b34d5ac8..bb28a2e8db 100644 --- a/src/core/hle/service/am/applets/software_keyboard.cpp +++ b/src/core/hle/service/am/applets/software_keyboard.cpp @@ -69,7 +69,7 @@ bool SoftwareKeyboard::TransactionComplete() const { } ResultCode SoftwareKeyboard::GetStatus() const { - return RESULT_SUCCESS; + return status; } void SoftwareKeyboard::ReceiveInteractiveData(std::shared_ptr storage) { @@ -92,7 +92,8 @@ void SoftwareKeyboard::ReceiveInteractiveData(std::shared_ptr storage) } void SoftwareKeyboard::Execute(AppletStorageProxyFunction out_data, - AppletStorageProxyFunction out_interactive_data) { + AppletStorageProxyFunction out_interactive_data, + AppletStateProxyFunction state) { if (complete) return; @@ -102,6 +103,7 @@ void SoftwareKeyboard::Execute(AppletStorageProxyFunction out_data, this->out_data = out_data; this->out_interactive_data = out_interactive_data; + this->state = state; frontend.RequestText([this](std::optional text) { WriteText(text); }, parameters); } @@ -110,6 +112,7 @@ void SoftwareKeyboard::WriteText(std::optional text) { std::vector output(SWKBD_OUTPUT_BUFFER_SIZE); if (text.has_value()) { + status = RESULT_SUCCESS; if (config.text_check) { const auto size = static_cast(text->size() * 2 + 4); std::memcpy(output.data(), &size, sizeof(u32)); @@ -117,9 +120,12 @@ void SoftwareKeyboard::WriteText(std::optional text) { output[0] = 1; } - std::memcpy(output.data() + 4, text->data(), - std::min(text->size() * 2, SWKBD_OUTPUT_BUFFER_SIZE - 4)); + const auto size = static_cast(text->size()); + std::memcpy(output.data() + 4, &size, sizeof(u32)); + std::memcpy(output.data() + 8, text->data(), + std::min(text->size() * 2, SWKBD_OUTPUT_BUFFER_SIZE - 8)); } else { + status = ResultCode(-1); complete = true; out_data(IStorage{output}); return; @@ -127,6 +133,8 @@ void SoftwareKeyboard::WriteText(std::optional text) { complete = !config.text_check; - (complete ? out_data : out_interactive_data)(IStorage{output}); + out_data(IStorage{output}); + out_interactive_data(IStorage{output}); + state(); } } // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/software_keyboard.h b/src/core/hle/service/am/applets/software_keyboard.h index b08bff3d74..9629f64085 100644 --- a/src/core/hle/service/am/applets/software_keyboard.h +++ b/src/core/hle/service/am/applets/software_keyboard.h @@ -55,7 +55,8 @@ public: ResultCode GetStatus() const override; void ReceiveInteractiveData(std::shared_ptr storage) override; void Execute(AppletStorageProxyFunction out_data, - AppletStorageProxyFunction out_interactive_data) override; + AppletStorageProxyFunction out_interactive_data, + AppletStateProxyFunction state) override; void WriteText(std::optional text); @@ -64,9 +65,11 @@ private: std::u16string initial_text; bool complete = false; std::vector final_data; + ResultCode status = ResultCode(-1); AppletStorageProxyFunction out_data; AppletStorageProxyFunction out_interactive_data; + AppletStateProxyFunction state; }; } // namespace Service::AM::Applets