From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/winstation.c | 2 +- dlls/win32u/driver.c | 12 ++++++++++++ dlls/win32u/winstation.c | 12 +++++++++++- include/ntuser.h | 3 +++ include/wine/gdi_driver.h | 1 + programs/explorer/desktop.c | 6 ++++-- 6 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/winstation.c b/dlls/user32/winstation.c index 23844482f2c..62593ca046f 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) + if (device || (devmode && !(flags & DF_WINE_CREATE_DESKTOP))) { SetLastError( ERROR_INVALID_PARAMETER ); return 0; diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 2d5d987652c..7a2e4c3bcdd 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -783,6 +783,11 @@ static BOOL nulldrv_UpdateDisplayDevices( const struct gdi_device_manager *manag return FALSE; }
+static BOOL nulldrv_CreateDesktop( const WCHAR *name, UINT width, UINT height ) +{ + return TRUE; +} + static BOOL nodrv_CreateWindow( HWND hwnd ) { static int warned; @@ -1149,6 +1154,11 @@ static BOOL loaderdrv_UpdateDisplayDevices( const struct gdi_device_manager *man return load_driver()->pUpdateDisplayDevices( manager, force, param ); }
+static BOOL loaderdrv_CreateDesktop( const WCHAR *name, UINT width, UINT height ) +{ + return load_driver()->pCreateDesktop( name, width, height ); +} + static BOOL loaderdrv_CreateWindow( HWND hwnd ) { return load_driver()->pCreateWindow( hwnd ); @@ -1222,6 +1232,7 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_GetDisplayDepth, loaderdrv_UpdateDisplayDevices, /* windowing functions */ + loaderdrv_CreateDesktop, loaderdrv_CreateWindow, nulldrv_DesktopWindowProc, nulldrv_DestroyWindow, @@ -1300,6 +1311,7 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(GetCurrentDisplaySettings); SET_USER_FUNC(GetDisplayDepth); SET_USER_FUNC(UpdateDisplayDevices); + SET_USER_FUNC(CreateDesktop); SET_USER_FUNC(CreateWindow); SET_USER_FUNC(DesktopWindowProc); SET_USER_FUNC(DestroyWindow); diff --git a/dlls/win32u/winstation.c b/dlls/win32u/winstation.c index 4db639b2327..466b2e6262c 100644 --- a/dlls/win32u/winstation.c +++ b/dlls/win32u/winstation.c @@ -141,9 +141,10 @@ HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *dev DEVMODEW *devmode, DWORD flags, ACCESS_MASK access, ULONG heap_size ) { + WCHAR buffer[MAX_PATH]; HANDLE ret;
- if ((device && device->Length) || devmode) + if ((device && device->Length) || (devmode && !(flags & DF_WINE_CREATE_DESKTOP))) { RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); return 0; @@ -163,6 +164,15 @@ HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *dev ret = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; + if (!devmode) return ret; + + lstrcpynW( buffer, attr->ObjectName->Buffer, attr->ObjectName->Length / sizeof(WCHAR) + 1 ); + if (!user_driver->pCreateDesktop( buffer, devmode->dmPelsWidth, devmode->dmPelsHeight )) + { + NtUserCloseDesktop( ret ); + return 0; + } + return ret; }
diff --git a/include/ntuser.h b/include/ntuser.h index 28ce230334a..49360dabd72 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -286,6 +286,9 @@ struct unpack_dde_message_params #define SPY_RESULT_OK 0x0001 #define SPY_RESULT_DEFWND 0x0002
+/* CreateDesktop wine specific flag */ +#define DF_WINE_CREATE_DESKTOP 0x80000000 + /* NtUserMessageCall codes */ enum { diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 4177eb3a81f..8561d0fc52b 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -307,6 +307,7 @@ struct user_driver_funcs INT (*pGetDisplayDepth)(LPCWSTR,BOOL); BOOL (*pUpdateDisplayDevices)(const struct gdi_device_manager *,BOOL,void*); /* windowing functions */ + BOOL (*pCreateDesktop)(const WCHAR *,UINT,UINT); BOOL (*pCreateWindow)(HWND); LRESULT (*pDesktopWindowProc)(HWND,UINT,WPARAM,LPARAM); void (*pDestroyWindow)(HWND); diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index 5c265b9c56b..66b48d32c31 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -1089,9 +1089,11 @@ void manage_desktop( WCHAR *arg )
if (name && width && height) { + DEVMODEW devmode = {.dmPelsWidth = width, .dmPelsHeight = height}; /* magic: desktop "root" means use the root window */ - using_root = !wcsicmp( name, L"root" ); - if (!(desktop = CreateDesktopW( name, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ))) + 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 ); + if (!desktop) { WINE_ERR( "failed to create desktop %s error %ld\n", wine_dbgstr_w(name), GetLastError() ); ExitProcess( 1 );