diff --git a/src/common/platform/window.hpp b/src/common/platform/window.hpp index 9e02d09b..b5bbee90 100644 --- a/src/common/platform/window.hpp +++ b/src/common/platform/window.hpp @@ -24,6 +24,7 @@ typedef struct _LARGE_STRING pointer Buffer; } LARGE_STRING; +using hdc = pointer; using hwnd = pointer; using hmenu = pointer; using hinstance = pointer; diff --git a/src/windows-emulator/process_context.cpp b/src/windows-emulator/process_context.cpp index affd76a9..d8aaf239 100644 --- a/src/windows-emulator/process_context.cpp +++ b/src/windows-emulator/process_context.cpp @@ -363,6 +363,20 @@ handle process_context::create_thread(memory_manager& memory, const uint64_t sta return h; } +std::optional process_context::find_atom(const std::u16string_view name) +{ + for (auto& entry : this->atoms) + { + if (entry.second.name == name) + { + ++entry.second.ref_count; + return entry.first; + } + } + + return {}; +} + uint16_t process_context::add_or_find_atom(std::u16string name) { uint16_t index = 1; diff --git a/src/windows-emulator/process_context.hpp b/src/windows-emulator/process_context.hpp index 8d4c8855..155a1d7e 100644 --- a/src/windows-emulator/process_context.hpp +++ b/src/windows-emulator/process_context.hpp @@ -67,6 +67,7 @@ struct process_context handle create_thread(memory_manager& memory, uint64_t start_address, uint64_t argument, uint64_t stack_size, bool suspended); + std::optional find_atom(std::u16string_view name); uint16_t add_or_find_atom(std::u16string name); bool delete_atom(const std::u16string& name); bool delete_atom(uint16_t atom_id); diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 5872a974..5ba2bbcf 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -574,6 +574,24 @@ namespace syscalls return STATUS_SUCCESS; } + NTSTATUS handle_NtFindAtom(const syscall_context& c, const uint64_t atom_name, const ULONG length, + const emulator_object atom) + { + const auto name = read_string(c.emu, atom_name, length / 2); + const auto index = c.proc.find_atom(name); + if (!index) + { + return STATUS_OBJECT_NAME_NOT_FOUND; + } + + if (atom) + { + atom.write(*index); + } + + return STATUS_SUCCESS; + } + NTSTATUS handle_NtUserGetAtomName(const syscall_context& c, const RTL_ATOM atom, const emulator_object>> atom_name) { @@ -611,14 +629,15 @@ namespace syscalls return 96; } - NTSTATUS handle_NtUserGetDCEx() + hdc handle_NtUserGetDCEx(const syscall_context& /*c*/, const hwnd window, const uint64_t /*clip_region*/, + const ULONG /*flags*/) { - return 1; + return window; } - NTSTATUS handle_NtUserGetDC() + hdc handle_NtUserGetDC(const syscall_context& c, const hwnd window) { - return handle_NtUserGetDCEx(); + return handle_NtUserGetDCEx(c, window, 0, 0); } NTSTATUS handle_NtUserGetWindowDC() @@ -770,6 +789,11 @@ namespace syscalls return c.proc.windows.store(std::move(win)).bits; } + BOOL handle_NtUserDestroyWindow(const syscall_context& c, const hwnd window) + { + return c.proc.windows.erase(window); + } + BOOL handle_NtUserSetProp(const syscall_context& c, const hwnd window, const uint16_t atom, const uint64_t data) { auto* win = c.proc.windows.get(window); @@ -942,6 +966,7 @@ void syscall_dispatcher::add_handlers(std::map& ha add_handler(NtDxgkIsFeatureEnabled); add_handler(NtAddAtomEx); add_handler(NtAddAtom); + add_handler(NtFindAtom); add_handler(NtDeleteAtom); add_handler(NtUserGetAtomName); add_handler(NtInitializeNlsFiles); @@ -1050,6 +1075,7 @@ void syscall_dispatcher::add_handlers(std::map& ha add_handler(NtUserSetProp); add_handler(NtUserSetProp2); add_handler(NtUserChangeWindowMessageFilterEx); + add_handler(NtUserDestroyWindow); #undef add_handler }