diff --git a/src/common/platform/primitives.hpp b/src/common/platform/primitives.hpp index 2a5d6de5..ad5fa657 100644 --- a/src/common/platform/primitives.hpp +++ b/src/common/platform/primitives.hpp @@ -23,6 +23,7 @@ using DWORD64 = std::uint64_t; using ULONGLONG = DWORD64; using LONGLONG = std::int64_t; using UINT = std::uint32_t; +using BOOL = std::int32_t; typedef union _ULARGE_INTEGER { diff --git a/src/common/platform/status.hpp b/src/common/platform/status.hpp index 7c2fd78e..ce3b27f3 100644 --- a/src/common/platform/status.hpp +++ b/src/common/platform/status.hpp @@ -23,7 +23,6 @@ using NTSTATUS = std::uint32_t; #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #define STATUS_WAIT_1 ((NTSTATUS)0x00000001L) -#define STATUS_UNSUCCESSFUL ((NTSTATUS)0x00000001L) #define STATUS_ALERTED ((NTSTATUS)0x00000101L) #define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS)0x40000000L) @@ -31,6 +30,7 @@ using NTSTATUS = std::uint32_t; #define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L) #define STATUS_NO_MORE_ENTRIES ((NTSTATUS)0x8000001AL) +#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) diff --git a/src/common/platform/window.hpp b/src/common/platform/window.hpp index 1bf72168..9e02d09b 100644 --- a/src/common/platform/window.hpp +++ b/src/common/platform/window.hpp @@ -41,4 +41,14 @@ struct msg #endif }; +struct EMU_DISPLAY_DEVICEW +{ + DWORD cb; + char16_t DeviceName[32]; + char16_t DeviceString[128]; + DWORD StateFlags; + char16_t DeviceID[128]; + char16_t DeviceKey[128]; +}; + // NOLINTEND(modernize-use-using,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) diff --git a/src/common/utils/string.hpp b/src/common/utils/string.hpp index 5f59bde6..5d88643a 100644 --- a/src/common/utils/string.hpp +++ b/src/common/utils/string.hpp @@ -4,9 +4,33 @@ #include #include #include +#include namespace utils::string { + template + requires(std::is_trivially_copyable_v) + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + void copy(T (&array)[Size], const std::basic_string_view str) + { + if constexpr (Size == 0) + { + return; + } + + const auto size = std::min(Size, str.size()); + memcpy(array, str.data(), size * sizeof(T)); + array[std::min(Size - 1, size)] = {}; + } + + template + requires(std::is_trivially_copyable_v) + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + void copy(T (&array)[Size], const T* str) + { + copy(array, std::basic_string_view(str)); + } + inline char char_to_lower(const char val) { return static_cast(std::tolower(static_cast(val))); diff --git a/src/windows-emulator/process_context.cpp b/src/windows-emulator/process_context.cpp index a41abcf1..5b565990 100644 --- a/src/windows-emulator/process_context.cpp +++ b/src/windows-emulator/process_context.cpp @@ -363,20 +363,20 @@ handle process_context::create_thread(memory_manager& memory, const uint64_t sta uint16_t process_context::add_or_find_atom(std::u16string name) { - uint16_t index = 0; - if (!atoms.empty()) + uint16_t index = 1; + if (!this->atoms.empty()) { - auto i = atoms.end(); + auto i = this->atoms.end(); --i; index = i->first + 1; } std::optional last_entry{}; - for (auto& entry : atoms) + for (auto& entry : this->atoms) { if (entry.second.name == name) { - entry.second.ref_count++; + ++entry.second.ref_count; return entry.first; } @@ -384,7 +384,7 @@ uint16_t process_context::add_or_find_atom(std::u16string name) { if (!last_entry) { - index = 0; + index = 1; } else { @@ -421,7 +421,7 @@ bool process_context::delete_atom(const std::u16string& name) return false; } -bool process_context::delete_atom(uint16_t atom_id) +bool process_context::delete_atom(const uint16_t atom_id) { const auto it = atoms.find(atom_id); if (it == atoms.end()) @@ -437,7 +437,7 @@ bool process_context::delete_atom(uint16_t atom_id) return true; } -const std::u16string* process_context::get_atom_name(uint16_t atom_id) const +const std::u16string* process_context::get_atom_name(const uint16_t atom_id) const { const auto it = atoms.find(atom_id); if (it == atoms.end()) diff --git a/src/windows-emulator/syscall_utils.hpp b/src/windows-emulator/syscall_utils.hpp index d87995d0..a4585d1c 100644 --- a/src/windows-emulator/syscall_utils.hpp +++ b/src/windows-emulator/syscall_utils.hpp @@ -153,7 +153,8 @@ inline void write_syscall_result(const syscall_context& c, const uint64_t result } } -inline void forward_syscall(const syscall_context& c, NTSTATUS (*handler)()) +template +void forward_syscall(const syscall_context& c, Result (*handler)()) { const auto ip = c.emu.read_instruction_pointer(); diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index e3203b3b..095b2fe7 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -718,6 +718,21 @@ namespace syscalls return STATUS_NOT_SUPPORTED; } + NTSTATUS handle_NtUserMapVirtualKeyEx() + { + return 0; + } + + NTSTATUS handle_NtUserToUnicodeEx() + { + return 0; + } + + NTSTATUS handle_NtUserSetProcessDpiAwarenessContext() + { + return 0; + } + hwnd handle_NtUserCreateWindowEx(const syscall_context& c, const DWORD ex_style, const emulator_object class_name, const emulator_object cls_version, @@ -743,19 +758,29 @@ namespace syscalls (void)flags; (void)acbi_buffer; - return STATUS_NOT_SUPPORTED; + return 1; } - NTSTATUS handle_NtUserShowWindow(const syscall_context& c, const hwnd hwnd, const LONG cmd_show) + ULONG handle_NtUserGetRawInputDeviceList() + { + return 0; + } + + ULONG handle_NtUserGetKeyboardType() + { + return 0; + } + + BOOL handle_NtUserShowWindow(const syscall_context& c, const hwnd hwnd, const LONG cmd_show) { (void)c; (void)hwnd; (void)cmd_show; - return STATUS_NOT_SUPPORTED; + return TRUE; } - NTSTATUS handle_NtUserGetMessage(const syscall_context& c, const emulator_object message, const hwnd hwnd, - const UINT msg_filter_min, const UINT msg_filter_max) + BOOL handle_NtUserGetMessage(const syscall_context& c, const emulator_object message, const hwnd hwnd, + const UINT msg_filter_min, const UINT msg_filter_max) { (void)c; (void)message; @@ -763,7 +788,49 @@ namespace syscalls (void)msg_filter_min; (void)msg_filter_max; - return STATUS_NOT_SUPPORTED; + return TRUE; + } + + BOOL handle_NtUserPeekMessage(const syscall_context& c, const emulator_object message, const hwnd hwnd, + const UINT msg_filter_min, const UINT msg_filter_max, const UINT remove_message) + { + (void)c; + (void)message; + (void)hwnd; + (void)msg_filter_min; + (void)msg_filter_max; + (void)remove_message; + + return FALSE; + } + + NTSTATUS handle_NtUserEnumDisplayDevices(const syscall_context& /*c*/, + const emulator_object>> str_device, + const DWORD dev_num, + const emulator_object display_device, + const DWORD /*flags*/) + { + if (str_device && dev_num != 0) + { + return STATUS_UNSUCCESSFUL; + } + + if (dev_num > 0) + { + return STATUS_UNSUCCESSFUL; + } + + display_device.access([&](EMU_DISPLAY_DEVICEW& dev) { + dev.StateFlags = 0; + utils::string::copy(dev.DeviceName, u"\\\\.\\DISPLAY1"); + utils::string::copy(dev.DeviceID, u"PCI\\VEN_10DE&DEV_0000&SUBSYS_00000000&REV_A1"); + utils::string::copy(dev.DeviceString, u"Emulator Display"); + utils::string::copy(dev.DeviceKey, + u"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\{00000001-" + u"0002-0003-0004-000000000005}\\0001"); + }); + + return STATUS_SUCCESS; } } @@ -929,6 +996,13 @@ void syscall_dispatcher::add_handlers(std::map& ha add_handler(NtUserCreateWindowEx); add_handler(NtUserShowWindow); add_handler(NtUserGetMessage); + add_handler(NtUserPeekMessage); + add_handler(NtUserMapVirtualKeyEx); + add_handler(NtUserToUnicodeEx); + add_handler(NtUserSetProcessDpiAwarenessContext); + add_handler(NtUserGetRawInputDeviceList); + add_handler(NtUserGetKeyboardType); + add_handler(NtUserEnumDisplayDevices); #undef add_handler }