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

This commit is contained in:
Zach Hilman 2018-11-16 22:20:09 -05:00
parent 8b433beff3
commit 6209fe0c27
4 changed files with 39 additions and 18 deletions

View file

@ -583,31 +583,38 @@ private:
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(state_changed_event); rb.PushCopyObjects(state_changed_event);
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_DEBUG(Service_AM, "called");
} }
void IsCompleted(Kernel::HLERequestContext& ctx) { void IsCompleted(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3}; IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.Push<u32>(applet->TransactionComplete()); rb.Push<u32>(applet->TransactionComplete());
LOG_DEBUG(Service_AM, "called");
} }
void GetResult(Kernel::HLERequestContext& ctx) { void GetResult(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(applet->GetStatus()); rb.Push(applet->GetStatus());
LOG_DEBUG(Service_AM, "called");
} }
void Start(Kernel::HLERequestContext& ctx) { void Start(Kernel::HLERequestContext& ctx) {
ASSERT(applet != nullptr); ASSERT(applet != nullptr);
applet->Initialize(storage_stack); applet->Initialize(storage_stack);
applet->Execute( storage_stack.clear();
[this](IStorage storage) { AppletStorageProxyOutData(storage); }, interactive_storage_stack.clear();
[this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); }); applet->Execute([this](IStorage storage) { AppletStorageProxyOutData(storage); },
state_changed_event->Signal(); [this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); },
[this] { state_changed_event->Signal(); });
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
LOG_DEBUG(Service_AM, "called");
} }
void PushInData(Kernel::HLERequestContext& ctx) { void PushInData(Kernel::HLERequestContext& ctx) {
@ -636,10 +643,9 @@ private:
ASSERT(applet->IsInitialized()); ASSERT(applet->IsInitialized());
applet->ReceiveInteractiveData(interactive_storage_stack.back()); applet->ReceiveInteractiveData(interactive_storage_stack.back());
applet->Execute( applet->Execute([this](IStorage storage) { AppletStorageProxyOutData(storage); },
[this](IStorage storage) { AppletStorageProxyOutData(storage); }, [this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); },
[this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); }); [this] { state_changed_event->Signal(); });
state_changed_event->Signal();
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
@ -661,6 +667,8 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(pop_out_data_event); rb.PushCopyObjects(pop_out_data_event);
LOG_DEBUG(Service_AM, "called");
} }
void GetPopInteractiveOutDataEvent(Kernel::HLERequestContext& ctx) { void GetPopInteractiveOutDataEvent(Kernel::HLERequestContext& ctx) {
@ -668,7 +676,7 @@ private:
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(pop_interactive_out_data_event); rb.PushCopyObjects(pop_interactive_out_data_event);
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_DEBUG(Service_AM, "called");
} }
std::shared_ptr<Applets::Applet> applet; std::shared_ptr<Applets::Applet> applet;
@ -734,7 +742,7 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) {
const u64 offset{rp.Pop<u64>()}; const u64 offset{rp.Pop<u64>()};
std::size_t size{ctx.GetWriteBufferSize()}; 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); ctx.WriteBuffer(backing.buffer.data() + offset, size);

View file

@ -22,6 +22,7 @@ class IStorage;
namespace Applets { namespace Applets {
using AppletStorageProxyFunction = std::function<void(IStorage)>; using AppletStorageProxyFunction = std::function<void(IStorage)>;
using AppletStateProxyFunction = std::function<void()>;
class Applet { class Applet {
public: public:
@ -34,7 +35,8 @@ public:
virtual ResultCode GetStatus() const = 0; virtual ResultCode GetStatus() const = 0;
virtual void ReceiveInteractiveData(std::shared_ptr<IStorage> storage) = 0; virtual void ReceiveInteractiveData(std::shared_ptr<IStorage> storage) = 0;
virtual void Execute(AppletStorageProxyFunction out_data, virtual void Execute(AppletStorageProxyFunction out_data,
AppletStorageProxyFunction out_interactive_data) = 0; AppletStorageProxyFunction out_interactive_data,
AppletStateProxyFunction state) = 0;
bool IsInitialized() const { bool IsInitialized() const {
return initialized; return initialized;

View file

@ -69,7 +69,7 @@ bool SoftwareKeyboard::TransactionComplete() const {
} }
ResultCode SoftwareKeyboard::GetStatus() const { ResultCode SoftwareKeyboard::GetStatus() const {
return RESULT_SUCCESS; return status;
} }
void SoftwareKeyboard::ReceiveInteractiveData(std::shared_ptr<IStorage> storage) { 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, void SoftwareKeyboard::Execute(AppletStorageProxyFunction out_data,
AppletStorageProxyFunction out_interactive_data) { AppletStorageProxyFunction out_interactive_data,
AppletStateProxyFunction state) {
if (complete) if (complete)
return; return;
@ -102,6 +103,7 @@ void SoftwareKeyboard::Execute(AppletStorageProxyFunction out_data,
this->out_data = out_data; this->out_data = out_data;
this->out_interactive_data = out_interactive_data; this->out_interactive_data = out_interactive_data;
this->state = state;
frontend.RequestText([this](std::optional<std::u16string> text) { WriteText(text); }, frontend.RequestText([this](std::optional<std::u16string> text) { WriteText(text); },
parameters); parameters);
} }
@ -110,6 +112,7 @@ void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) {
std::vector<u8> output(SWKBD_OUTPUT_BUFFER_SIZE); std::vector<u8> output(SWKBD_OUTPUT_BUFFER_SIZE);
if (text.has_value()) { if (text.has_value()) {
status = RESULT_SUCCESS;
if (config.text_check) { if (config.text_check) {
const auto size = static_cast<u32>(text->size() * 2 + 4); const auto size = static_cast<u32>(text->size() * 2 + 4);
std::memcpy(output.data(), &size, sizeof(u32)); std::memcpy(output.data(), &size, sizeof(u32));
@ -117,9 +120,12 @@ void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) {
output[0] = 1; output[0] = 1;
} }
std::memcpy(output.data() + 4, text->data(), const auto size = static_cast<u32>(text->size());
std::min(text->size() * 2, SWKBD_OUTPUT_BUFFER_SIZE - 4)); 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 { } else {
status = ResultCode(-1);
complete = true; complete = true;
out_data(IStorage{output}); out_data(IStorage{output});
return; return;
@ -127,6 +133,8 @@ void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) {
complete = !config.text_check; 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 } // namespace Service::AM::Applets

View file

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