Răsfoiți Sursa

software_keyboard: Push buffer size to offset 0x4 in output data

Zach Hilman 7 ani în urmă
părinte
comite
6209fe0c27

+ 19 - 11
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<u32>(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<Applets::Applet> applet;
@@ -734,7 +742,7 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) {
     const u64 offset{rp.Pop<u64>()};
     std::size_t size{ctx.GetWriteBufferSize()};
 
-    size = std::min(size, backing.buffer.size() - offset);
+    size = std::min<std::size_t>(size, backing.buffer.size() - offset);
 
     ctx.WriteBuffer(backing.buffer.data() + offset, size);
 

+ 3 - 1
src/core/hle/service/am/applets/applets.h

@@ -22,6 +22,7 @@ class IStorage;
 namespace Applets {
 
 using AppletStorageProxyFunction = std::function<void(IStorage)>;
+using AppletStateProxyFunction = std::function<void()>;
 
 class Applet {
 public:
@@ -34,7 +35,8 @@ public:
     virtual ResultCode GetStatus() const = 0;
     virtual void ReceiveInteractiveData(std::shared_ptr<IStorage> 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;

+ 13 - 5
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<IStorage> storage) {
@@ -92,7 +92,8 @@ void SoftwareKeyboard::ReceiveInteractiveData(std::shared_ptr<IStorage> 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<std::u16string> text) { WriteText(text); },
                          parameters);
 }
@@ -110,6 +112,7 @@ void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) {
     std::vector<u8> output(SWKBD_OUTPUT_BUFFER_SIZE);
 
     if (text.has_value()) {
+        status = RESULT_SUCCESS;
         if (config.text_check) {
             const auto size = static_cast<u32>(text->size() * 2 + 4);
             std::memcpy(output.data(), &size, sizeof(u32));
@@ -117,9 +120,12 @@ void SoftwareKeyboard::WriteText(std::optional<std::u16string> 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<u32>(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<std::u16string> 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

+ 4 - 1
src/core/hle/service/am/applets/software_keyboard.h

@@ -55,7 +55,8 @@ public:
     ResultCode GetStatus() const override;
     void ReceiveInteractiveData(std::shared_ptr<IStorage> storage) override;
     void Execute(AppletStorageProxyFunction out_data,
-                 AppletStorageProxyFunction out_interactive_data) override;
+                 AppletStorageProxyFunction out_interactive_data,
+                 AppletStateProxyFunction state) override;
 
     void WriteText(std::optional<std::u16string> text);
 
@@ -64,9 +65,11 @@ private:
     std::u16string initial_text;
     bool complete = false;
     std::vector<u8> final_data;
+    ResultCode status = ResultCode(-1);
 
     AppletStorageProxyFunction out_data;
     AppletStorageProxyFunction out_interactive_data;
+    AppletStateProxyFunction state;
 };
 
 } // namespace Service::AM::Applets