[PATCH v4 0/2] MR4786: win32u: Query virtual desktop status from the registry.
Checking flags of the thread desktop to determine whether virtual desktop is on is unreliable. For example, CEF applications create their own desktop and so is_virtual_desktop() could incorrectly report that virtual desktop is off. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55810 -- v4: server: inherit wine internal desktop flags when creating desktops. https://gitlab.winehq.org/wine/wine/-/merge_requests/4786
From: Zhiyi Zhang <zzhang(a)codeweavers.com> --- dlls/user32/winstation.c | 2 +- dlls/win32u/winstation.c | 6 +++--- include/ntuser.h | 2 +- programs/explorer/desktop.c | 2 +- server/winstation.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dlls/user32/winstation.c b/dlls/user32/winstation.c index 62593ca046f..c433ea6ec88 100644 --- a/dlls/user32/winstation.c +++ b/dlls/user32/winstation.c @@ -256,7 +256,7 @@ HDESK WINAPI CreateDesktopW( LPCWSTR name, LPCWSTR device, LPDEVMODEW devmode, OBJECT_ATTRIBUTES attr; UNICODE_STRING str; - if (device || (devmode && !(flags & DF_WINE_CREATE_DESKTOP))) + if (device || (devmode && !(flags & DF_WINE_VIRTUAL_DESKTOP))) { SetLastError( ERROR_INVALID_PARAMETER ); return 0; diff --git a/dlls/win32u/winstation.c b/dlls/win32u/winstation.c index b187b246941..9df27517a43 100644 --- a/dlls/win32u/winstation.c +++ b/dlls/win32u/winstation.c @@ -47,7 +47,7 @@ BOOL is_virtual_desktop(void) DWORD len; if (!NtUserGetObjectInformation( desktop, UOI_FLAGS, &flags, sizeof(flags), &len )) return FALSE; - return !!(flags.dwFlags & DF_WINE_CREATE_DESKTOP); + return !!(flags.dwFlags & DF_WINE_VIRTUAL_DESKTOP); } /*********************************************************************** @@ -154,7 +154,7 @@ HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *dev WCHAR buffer[MAX_PATH]; HANDLE ret; - if ((device && device->Length) || (devmode && !(flags & DF_WINE_CREATE_DESKTOP))) + if ((device && device->Length) || (devmode && !(flags & DF_WINE_VIRTUAL_DESKTOP))) { RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); return 0; @@ -184,7 +184,7 @@ HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *dev } /* force update display cache to use virtual desktop display settings */ - if (flags & DF_WINE_CREATE_DESKTOP) update_display_cache( TRUE ); + if (flags & DF_WINE_VIRTUAL_DESKTOP) update_display_cache( TRUE ); return ret; } diff --git a/include/ntuser.h b/include/ntuser.h index f23249ace5a..a694fddf9d3 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -294,7 +294,7 @@ struct unpack_dde_message_params #define SPY_RESULT_DEFWND 0x0002 /* CreateDesktop wine specific flag */ -#define DF_WINE_CREATE_DESKTOP 0x80000000 +#define DF_WINE_VIRTUAL_DESKTOP 0x80000000 /* NtUserMessageCall codes */ enum diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index 9a58f13d887..e89addf5727 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -1066,7 +1066,7 @@ void manage_desktop( WCHAR *arg ) DEVMODEW devmode = {.dmPelsWidth = width, .dmPelsHeight = height}; /* magic: desktop "root" means use the root window */ if ((using_root = !wcsicmp( name, L"root" ))) desktop = CreateDesktopW( name, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ); - else desktop = CreateDesktopW( name, NULL, &devmode, DF_WINE_CREATE_DESKTOP, DESKTOP_ALL_ACCESS, NULL ); + else desktop = CreateDesktopW( name, NULL, &devmode, DF_WINE_VIRTUAL_DESKTOP, DESKTOP_ALL_ACCESS, NULL ); if (!desktop) { ERR( "failed to create desktop %s error %ld\n", debugstr_w(name), GetLastError() ); diff --git a/server/winstation.c b/server/winstation.c index 5903497d61e..5c59fbffae1 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -243,7 +243,7 @@ static struct desktop *create_desktop( const struct unicode_str *name, unsigned } else { - desktop->flags |= (flags & DF_WINE_CREATE_DESKTOP); + desktop->flags |= (flags & DF_WINE_VIRTUAL_DESKTOP); clear_error(); } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4786
From: Zhiyi Zhang <zzhang(a)codeweavers.com> Based on Rémi's idea. CEF applications create their own desktops and so is_virtual_desktop() could incorrectly report that virtual desktop is off if DF_WINE_VIRTUAL_DESKTOP is not inherited. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55810 --- dlls/user32/winstation.c | 3 ++- include/ntuser.h | 1 + programs/explorer/desktop.c | 2 +- server/winstation.c | 14 ++++++++++++-- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/dlls/user32/winstation.c b/dlls/user32/winstation.c index c433ea6ec88..ec8be243b32 100644 --- a/dlls/user32/winstation.c +++ b/dlls/user32/winstation.c @@ -256,7 +256,8 @@ HDESK WINAPI CreateDesktopW( LPCWSTR name, LPCWSTR device, LPDEVMODEW devmode, OBJECT_ATTRIBUTES attr; UNICODE_STRING str; - if (device || (devmode && !(flags & DF_WINE_VIRTUAL_DESKTOP))) + if (device || (devmode && !(flags & DF_WINE_VIRTUAL_DESKTOP)) + || (flags & DF_WINE_ROOT_DESKTOP && flags & DF_WINE_VIRTUAL_DESKTOP)) { SetLastError( ERROR_INVALID_PARAMETER ); return 0; diff --git a/include/ntuser.h b/include/ntuser.h index a694fddf9d3..9043772dcd3 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -294,6 +294,7 @@ struct unpack_dde_message_params #define SPY_RESULT_DEFWND 0x0002 /* CreateDesktop wine specific flag */ +#define DF_WINE_ROOT_DESKTOP 0x40000000 #define DF_WINE_VIRTUAL_DESKTOP 0x80000000 /* NtUserMessageCall codes */ diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index e89addf5727..ae017533fc9 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -1065,7 +1065,7 @@ void manage_desktop( WCHAR *arg ) { DEVMODEW devmode = {.dmPelsWidth = width, .dmPelsHeight = height}; /* magic: desktop "root" means use the root window */ - if ((using_root = !wcsicmp( name, L"root" ))) desktop = CreateDesktopW( name, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ); + if ((using_root = !wcsicmp( name, L"root" ))) desktop = CreateDesktopW( name, NULL, NULL, DF_WINE_ROOT_DESKTOP, DESKTOP_ALL_ACCESS, NULL ); else desktop = CreateDesktopW( name, NULL, &devmode, DF_WINE_VIRTUAL_DESKTOP, DESKTOP_ALL_ACCESS, NULL ); if (!desktop) { diff --git a/server/winstation.c b/server/winstation.c index 5c59fbffae1..930c5c90d97 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -221,14 +221,24 @@ struct desktop *get_desktop_obj( struct process *process, obj_handle_t handle, u static struct desktop *create_desktop( const struct unicode_str *name, unsigned int attr, unsigned int flags, struct winstation *winstation ) { - struct desktop *desktop; + struct desktop *desktop, *current_desktop; if ((desktop = create_named_object( &winstation->obj, &desktop_ops, name, attr, NULL ))) { if (get_error() != STATUS_OBJECT_NAME_EXISTS) { /* initialize it if it didn't already exist */ + desktop->flags = flags; + + /* inherit DF_WINE_*_DESKTOP flags if none of them are specified */ + if (!(flags & (DF_WINE_ROOT_DESKTOP | DF_WINE_VIRTUAL_DESKTOP)) + && (current_desktop = get_thread_desktop( current, 0 ))) + { + desktop->flags |= current_desktop->flags & (DF_WINE_VIRTUAL_DESKTOP | DF_WINE_ROOT_DESKTOP); + release_object( current_desktop ); + } + desktop->winstation = (struct winstation *)grab_object( winstation ); desktop->top_window = NULL; desktop->msg_window = NULL; @@ -243,7 +253,7 @@ static struct desktop *create_desktop( const struct unicode_str *name, unsigned } else { - desktop->flags |= (flags & DF_WINE_VIRTUAL_DESKTOP); + desktop->flags |= flags & (DF_WINE_VIRTUAL_DESKTOP | DF_WINE_ROOT_DESKTOP); clear_error(); } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4786
Rémi Bernon (@rbernon) commented about dlls/user32/winstation.c:
OBJECT_ATTRIBUTES attr; UNICODE_STRING str;
- if (device || (devmode && !(flags & DF_WINE_VIRTUAL_DESKTOP))) + if (device || (devmode && !(flags & DF_WINE_VIRTUAL_DESKTOP)) + || (flags & DF_WINE_ROOT_DESKTOP && flags & DF_WINE_VIRTUAL_DESKTOP))
This one place still feels unnecessary to check, but things looks good otherwise. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4786#note_57197
This merge request was approved by Rémi Bernon. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4786
@julliard Hi, should I do something about this? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/4786#note_60415
participants (3)
-
Rémi Bernon -
Zhiyi Zhang -
Zhiyi Zhang (@zhiyi)