diff --git a/src/common/platform/user.hpp b/src/common/platform/user.hpp index bf027f72..2bebdf4a 100644 --- a/src/common/platform/user.hpp +++ b/src/common/platform/user.hpp @@ -87,11 +87,26 @@ struct USER_MONITOR { EMULATOR_CAST(uint64_t, HMONITOR) hmon; uint8_t unknown1[0x14]; - RECT monitorRect; - RECT workRect; - uint16_t monitorDpi; - uint16_t nativeDpi; - uint8_t unknown2[0xFF]; + RECT rcMonitor; + RECT rcWork; + union + { + struct + { + uint16_t monitorDpi; + uint16_t nativeDpi; + } b26; + struct + { + uint32_t unknown1; + uint16_t monitorDpi; + uint16_t nativeDpi; + uint16_t cachedDpi; + uint16_t unknown2; + RECT rcMonitorDpiAware; + } b20; + }; + uint8_t unknown4[0xFF]; }; struct USER_WINDOW diff --git a/src/windows-emulator/process_context.cpp b/src/windows-emulator/process_context.cpp index f0fc5443..a16d2156 100644 --- a/src/windows-emulator/process_context.cpp +++ b/src/windows-emulator/process_context.cpp @@ -176,12 +176,36 @@ namespace return env_map; } + + uint32_t read_windows_build(registry_manager& registry) + { + const auto key = registry.get_key({R"(\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion)"}); + + if (!key) + return 0; + + for (size_t i = 0; const auto value = registry.get_value(*key, i); ++i) + { + if (value->type != REG_SZ) + continue; + + if (value->name == "CurrentBuildNumber" || value->name == "CurrentBuild") + { + const auto* s = reinterpret_cast(value->data.data()); + return static_cast(std::wcstoul(reinterpret_cast(s), nullptr, 10)); + } + } + + return 0; + } } void process_context::setup(x86_64_emulator& emu, memory_manager& memory, registry_manager& registry, const application_settings& app_settings, const mapped_module& executable, const mapped_module& ntdll, const apiset::container& apiset_container, const mapped_module* ntdll32) { + this->windows_build_number = read_windows_build(registry); + setup_gdt(emu, memory); this->kusd.setup(); @@ -398,10 +422,20 @@ void process_context::setup(x86_64_emulator& emu, memory_manager& memory, regist this->default_monitor_handle = h; monitor_obj.access([&](USER_MONITOR& monitor) { monitor.hmon = h.bits; - monitor.monitorRect = {.left = 0, .top = 0, .right = 1920, .bottom = 1080}; - monitor.workRect = monitor.monitorRect; - monitor.monitorDpi = 96; - monitor.nativeDpi = monitor.monitorDpi; + monitor.rcMonitor = {.left = 0, .top = 0, .right = 1920, .bottom = 1080}; + monitor.rcWork = monitor.rcMonitor; + if (this->is_older_windows_build()) + { + monitor.b20.monitorDpi = 96; + monitor.b20.nativeDpi = monitor.b20.monitorDpi; + monitor.b20.cachedDpi = monitor.b20.monitorDpi; + monitor.b20.rcMonitorDpiAware = monitor.rcMonitor; + } + else + { + monitor.b26.monitorDpi = 96; + monitor.b26.nativeDpi = monitor.b26.monitorDpi; + } }); const auto user_display_info = this->user_handles.get_display_info(); diff --git a/src/windows-emulator/process_context.hpp b/src/windows-emulator/process_context.hpp index 7fa071d0..360abaa1 100644 --- a/src/windows-emulator/process_context.hpp +++ b/src/windows-emulator/process_context.hpp @@ -87,10 +87,17 @@ struct process_context void serialize(utils::buffer_serializer& buffer) const; void deserialize(utils::buffer_deserializer& buffer); + generic_handle_store* get_handle_store(handle handle); + // WOW64 support flag - set during process setup based on executable architecture bool is_wow64_process{false}; - generic_handle_store* get_handle_store(handle handle); + uint32_t windows_build_number{0}; + + bool is_older_windows_build() const + { + return windows_build_number < 26040; + } callbacks* callbacks_{};