From 0fbd563e8c12aa63312e9300d421f17e1e3ea059 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 18 May 2025 09:51:28 +0200 Subject: [PATCH] Support window creation --- src/windows-emulator/emulator_utils.hpp | 15 ++++++- src/windows-emulator/process_context.cpp | 2 + src/windows-emulator/syscalls.cpp | 57 ++++++++++++++---------- src/windows-emulator/windows_objects.hpp | 8 ++-- 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/src/windows-emulator/emulator_utils.hpp b/src/windows-emulator/emulator_utils.hpp index e339d50e..3e4e15c1 100644 --- a/src/windows-emulator/emulator_utils.hpp +++ b/src/windows-emulator/emulator_utils.hpp @@ -161,6 +161,11 @@ class emulator_object return emulator_object(*this->memory_, this->address_ + offset); } + memory_interface* get_memory_interface() const + { + return this->memory_; + } + private: memory_interface* memory_{}; uint64_t address_{}; @@ -310,16 +315,22 @@ class emulator_allocator }; template -std::basic_string read_string(memory_manager& mem, const uint64_t address) +std::basic_string read_string(memory_interface& mem, const uint64_t address, + const std::optional size = {}) { std::basic_string result{}; for (size_t i = 0;; ++i) { + if (size && i >= *size) + { + break; + } + Element element{}; mem.read_memory(address + (i * sizeof(element)), &element, sizeof(element)); - if (!element) + if (!size && !element) { break; } diff --git a/src/windows-emulator/process_context.cpp b/src/windows-emulator/process_context.cpp index 5b565990..affd76a9 100644 --- a/src/windows-emulator/process_context.cpp +++ b/src/windows-emulator/process_context.cpp @@ -271,6 +271,7 @@ void process_context::serialize(utils::buffer_serializer& buffer) const buffer.write(this->semaphores); buffer.write(this->ports); buffer.write(this->mutants); + buffer.write(this->windows); buffer.write(this->registry_keys); buffer.write_map(this->atoms); @@ -309,6 +310,7 @@ void process_context::deserialize(utils::buffer_deserializer& buffer) buffer.read(this->semaphores); buffer.read(this->ports); buffer.read(this->mutants); + buffer.read(this->windows); buffer.read(this->registry_keys); buffer.read_map(this->atoms); diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 095b2fe7..923ddc74 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -733,32 +733,41 @@ namespace syscalls return 0; } - hwnd handle_NtUserCreateWindowEx(const syscall_context& c, const DWORD ex_style, - const emulator_object class_name, - const emulator_object cls_version, - const emulator_object window_name, const DWORD style, const int x, - const int y, const int width, const int height, const hwnd parent, - const hmenu menu, const hinstance instance, const pointer l_param, - const DWORD flags, const pointer acbi_buffer) + std::u16string read_large_string(const emulator_object str_obj) { - (void)c; - (void)ex_style; - (void)class_name; - (void)cls_version; - (void)window_name; - (void)style; - (void)x; - (void)y; - (void)width; - (void)height; - (void)parent; - (void)menu; - (void)instance; - (void)l_param; - (void)flags; - (void)acbi_buffer; + if (!str_obj) + { + return {}; + } - return 1; + const auto str = str_obj.read(); + if (!str.bAnsi) + { + return read_string(*str_obj.get_memory_interface(), str.Buffer, str.Length / 2); + } + + const auto ansi_string = read_string(*str_obj.get_memory_interface(), str.Buffer, str.Length); + return u8_to_u16(ansi_string); + } + + hwnd handle_NtUserCreateWindowEx(const syscall_context& c, const DWORD /*ex_style*/, + const emulator_object class_name, + const emulator_object /*cls_version*/, + const emulator_object window_name, const DWORD /*style*/, + const int x, const int y, const int width, const int height, const hwnd /*parent*/, + const hmenu /*menu*/, const hinstance /*instance*/, const pointer /*l_param*/, + const DWORD /*flags*/, const pointer /*acbi_buffer*/) + { + window win{}; + win.x = x; + win.y = y; + win.width = width; + win.height = height; + win.thread_id = c.win_emu.current_thread().id; + win.class_name = read_large_string(class_name); + win.name = read_large_string(window_name); + + return c.proc.windows.store(std::move(win)).bits; } ULONG handle_NtUserGetRawInputDeviceList() diff --git a/src/windows-emulator/windows_objects.hpp b/src/windows-emulator/windows_objects.hpp index 0795e6e0..2c0bebaf 100644 --- a/src/windows-emulator/windows_objects.hpp +++ b/src/windows-emulator/windows_objects.hpp @@ -44,10 +44,10 @@ struct window : ref_counted_object uint32_t thread_id{}; std::u16string name{}; std::u16string class_name{}; - uint32_t width; - uint32_t height; - uint32_t x; - uint32_t y; + int32_t width; + int32_t height; + int32_t x; + int32_t y; void serialize_object(utils::buffer_serializer& buffer) const override {