diff --git a/dlls/user32/winstation.c b/dlls/user32/winstation.c index ab1beed3c32..98afc499234 100644 --- a/dlls/user32/winstation.c +++ b/dlls/user32/winstation.c @@ -253,31 +253,20 @@ HDESK WINAPI CreateDesktopA( LPCSTR name, LPCSTR device, LPDEVMODEA devmode, HDESK WINAPI CreateDesktopW( LPCWSTR name, LPCWSTR device, LPDEVMODEW devmode, DWORD flags, ACCESS_MASK access, LPSECURITY_ATTRIBUTES sa ) { - HANDLE ret; - DWORD len = name ? lstrlenW(name) : 0; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING str; if (device || devmode) { SetLastError( ERROR_INVALID_PARAMETER ); return 0; } - if (len >= MAX_PATH) - { - SetLastError( ERROR_FILENAME_EXCED_RANGE ); - return 0; - } - SERVER_START_REQ( create_desktop ) - { - req->flags = flags; - req->access = access; - req->attributes = OBJ_CASE_INSENSITIVE | OBJ_OPENIF | - ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0); - wine_server_add_data( req, name, len * sizeof(WCHAR) ); - wine_server_call_err( req ); - ret = wine_server_ptr_handle( reply->handle ); - } - SERVER_END_REQ; - return ret; + + RtlInitUnicodeString( &str, name ); + InitializeObjectAttributes( &attr, &str, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, + get_winstations_dir_handle(), NULL ); + if (sa && sa->bInheritHandle) attr.Attributes |= OBJ_INHERIT; + return NtUserCreateDesktopEx( &attr, NULL, devmode, flags, access, 0 ); } diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index e8c904f9f02..b4d5d718bf5 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -96,6 +96,7 @@ static void * const syscalls[] = NtGdiTransformPoints, NtUserCloseDesktop, NtUserCloseWindowStation, + NtUserCreateDesktopEx, NtUserCreateWindowStation, NtUserGetObjectInformation, NtUserGetProcessWindowStation, diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 860b3626931..bb800830f3d 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -809,7 +809,7 @@ @ stub NtUserCreateActivationObject @ stub NtUserCreateCaret @ stub NtUserCreateDCompositionHwndTarget -@ stub NtUserCreateDesktopEx +@ stdcall -syscall NtUserCreateDesktopEx(ptr ptr ptr long long long) @ stub NtUserCreateEmptyCursorObject @ stub NtUserCreateInputContext @ stub NtUserCreateLocalMemHandle diff --git a/dlls/win32u/winstation.c b/dlls/win32u/winstation.c index bd8420df05f..0d0eefcf629 100644 --- a/dlls/win32u/winstation.c +++ b/dlls/win32u/winstation.c @@ -127,6 +127,38 @@ BOOL WINAPI NtUserSetProcessWindowStation( HWINSTA handle ) return ret; } +/*********************************************************************** + * NtUserCreateDesktopEx (win32u.@) + */ +HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *device, + DEVMODEW *devmode, DWORD flags, ACCESS_MASK access, + ULONG heap_size ) +{ + HANDLE ret; + + if ((device && device->Length) || devmode) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return 0; + } + if (attr->ObjectName->Length >= MAX_PATH * sizeof(WCHAR)) + { + SetLastError( ERROR_FILENAME_EXCED_RANGE ); + return 0; + } + SERVER_START_REQ( create_desktop ) + { + req->flags = flags; + req->access = access; + req->attributes = attr->Attributes; + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); + wine_server_call_err( req ); + ret = wine_server_ptr_handle( reply->handle ); + } + SERVER_END_REQ; + return ret; +} + /*********************************************************************** * NtUserCloseDesktop (win32u.@) */ diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index 371ce3665fd..a1dc08103d4 100644 --- a/dlls/wow64win/syscall.h +++ b/dlls/wow64win/syscall.h @@ -83,6 +83,7 @@ SYSCALL_ENTRY( NtGdiTransformPoints ) \ SYSCALL_ENTRY( NtUserCloseDesktop ) \ SYSCALL_ENTRY( NtUserCloseWindowStation ) \ + SYSCALL_ENTRY( NtUserCreateDesktopEx ) \ SYSCALL_ENTRY( NtUserCreateWindowStation ) \ SYSCALL_ENTRY( NtUserGetProcessWindowStation ) \ SYSCALL_ENTRY( NtUserGetThreadDesktop ) \ diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 80e85f8a631..b20ff3f887b 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -73,6 +73,25 @@ NTSTATUS WINAPI wow64_NtUserSetProcessWindowStation( UINT *args ) return NtUserSetProcessWindowStation( handle ); } +NTSTATUS WINAPI wow64_NtUserCreateDesktopEx( UINT *args ) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + UNICODE_STRING32 *device32 = get_ptr( &args ); + DEVMODEW *devmode = get_ptr( &args ); + DWORD flags = get_ulong( &args ); + ACCESS_MASK access = get_ulong( &args ); + ULONG heap_size = get_ulong( &args ); + + struct object_attr64 attr; + UNICODE_STRING device; + HANDLE ret; + + ret = NtUserCreateDesktopEx( objattr_32to64( &attr, attr32 ), + unicode_str_32to64( &device, device32 ), + devmode, flags, access, heap_size ); + return HandleToUlong( ret ); +} + NTSTATUS WINAPI wow64_NtUserCloseDesktop( UINT *args ) { HDESK handle = get_handle( &args ); diff --git a/include/ntuser.h b/include/ntuser.h index 648d4a3350d..8687a6bbc59 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -20,10 +20,14 @@ #define _NTUSER_ #include +#include #include BOOL WINAPI NtUserCloseDesktop( HDESK handle ); BOOL WINAPI NtUserCloseWindowStation( HWINSTA handle ); +HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *device, + DEVMODEW *devmode, DWORD flags, ACCESS_MASK access, + ULONG heap_size ); HWINSTA WINAPI NtUserCreateWindowStation( OBJECT_ATTRIBUTES *attr, ACCESS_MASK mask, ULONG arg3, ULONG arg4, ULONG arg5, ULONG arg6, ULONG arg7 ); BOOL WINAPI NtUserGetObjectInformation( HANDLE handle, INT index, void *info,