Fix a regression that Office 2016/365 has a 640x480 main window.
Office 2016/365 hooks NtOpenKeyEx() and prevents access to SetupAPI device properties. After querying monitor information from SetupAPI failed, EnumDisplayMonitors() reports a fallback monitor of size 640x480.
As to why store the monitor information in the wineserver, it seems that EnumDisplayMonitors() reports monitors connected to current user logon session. For instance, EnumDisplayMonitors() always report one monitor when called by services.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/winemac.drv/display.c | 65 ++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 14 deletions(-)
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 6706c88341c..2b672ffe74b 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -32,6 +32,7 @@ #include "setupapi.h" #define WIN32_NO_STATUS #include "winternl.h" +#include "wine/server.h" #include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(display); @@ -57,8 +58,6 @@ DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_OUTPUT_ID, 0xca085853, 0x16ce, 0x48aa, 0xb1
/* Wine specific monitor properties */ DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2); -DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3); -DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCWORK, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 4); DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 5);
static const char initial_mode_key[] = "Initial Display Mode"; @@ -1628,10 +1627,11 @@ static BOOL macdrv_init_monitor(HDEVINFO devinfo, const struct macdrv_monitor *m int video_index, const LUID *gpu_luid, UINT output_id) { SP_DEVINFO_DATA device_data = {sizeof(SP_DEVINFO_DATA)}; + RECT monitor_rect, work_rect; WCHAR nameW[MAX_PATH]; WCHAR bufferW[MAX_PATH]; + DWORD size; HKEY hkey; - RECT rect; BOOL ret = FALSE;
/* Create GUID_DEVCLASS_MONITOR instance */ @@ -1666,22 +1666,35 @@ static BOOL macdrv_init_monitor(HDEVINFO devinfo, const struct macdrv_monitor *m if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, DEVPROP_TYPE_UINT32, (const BYTE *)&monitor->state_flags, sizeof(monitor->state_flags), 0)) goto done; - /* RcMonitor */ - rect = rect_from_cgrect(monitor->rc_monitor); - if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, DEVPROP_TYPE_BINARY, - (const BYTE *)&rect, sizeof(rect), 0)) - goto done; - /* RcWork */ - rect = rect_from_cgrect(monitor->rc_work); - if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCWORK, DEVPROP_TYPE_BINARY, - (const BYTE *)&rect, sizeof(rect), 0)) - goto done; /* Adapter name */ sprintfW(bufferW, adapter_name_fmtW, video_index + 1); + size = (lstrlenW(bufferW) + 1) * sizeof(WCHAR); if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, DEVPROP_TYPE_STRING, - (const BYTE *)bufferW, (lstrlenW(bufferW) + 1) * sizeof(WCHAR), 0)) + (const BYTE *)bufferW, size, 0)) goto done;
+ /* EnumDisplayMonitors() doesn't enumerate mirrored replicas and inactive monitors */ + if (monitor_index == 0 && monitor->state_flags & DISPLAY_DEVICE_ACTIVE) + { + SERVER_START_REQ(create_monitor) + { + monitor_rect = rect_from_cgrect(monitor->rc_monitor); + req->monitor_rect.top = monitor_rect.top; + req->monitor_rect.left = monitor_rect.left; + req->monitor_rect.right = monitor_rect.right; + req->monitor_rect.bottom = monitor_rect.bottom; + work_rect = rect_from_cgrect(monitor->rc_work); + req->work_rect.top = work_rect.top; + req->work_rect.left = work_rect.left; + req->work_rect.right = work_rect.right; + req->work_rect.bottom = work_rect.bottom; + wine_server_add_data(req, bufferW, size); + if (wine_server_call(req)) + goto done; + } + SERVER_END_REQ; + } + ret = TRUE; done: if (!ret) @@ -1693,7 +1706,9 @@ static void prepare_devices(HKEY video_hkey) { static const BOOL not_present = FALSE; SP_DEVINFO_DATA device_data = {sizeof(device_data)}; + HMONITOR monitor = NULL; HDEVINFO devinfo; + NTSTATUS status; DWORD i = 0;
/* Remove all monitors */ @@ -1705,6 +1720,28 @@ static void prepare_devices(HKEY video_hkey) } SetupDiDestroyDeviceInfoList(devinfo);
+ while (TRUE) + { + SERVER_START_REQ(enum_monitor) + { + req->index = 0; + if (!(status = wine_server_call(req))) + monitor = wine_server_ptr_handle(reply->handle); + } + SERVER_END_REQ; + + if (status) + break; + + SERVER_START_REQ(destroy_monitor) + { + req->handle = wine_server_user_handle(monitor); + if (wine_server_call(req)) + ERR("Failed to destroy monitor.\n"); + } + SERVER_END_REQ; + } + /* Clean up old adapter keys for reinitialization */ RegDeleteTreeW(video_hkey, NULL);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=86102
Your paranoid android.
=== debiant2 (32 bit report) ===
user32: win.c:3058: Test failed: got error 0 in EnableWindow call win.c:3079: Test succeeded inside todo block: Focus should be on child 00080102, not 00080102
=== debiant2 (32 bit Chinese:China report) ===
user32: clipboard.c:717: Test failed: 7: gle 5 clipboard.c:719: Test failed: 7: gle 1418 clipboard.c:746: Test failed: 7: count 3 clipboard.c:749: Test failed: 7: gle 1418 clipboard.c:765: Test failed: 7.0: got 0008 instead of 0011 win.c:3058: Test failed: got error 0 in EnableWindow call win.c:3079: Test succeeded inside todo block: Focus should be on child 00080102, not 00080102