From 1d30bac773ba95fdb49ff4ca15ab5ea810f6a05f Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 14 Oct 2021 15:20:42 +0200 Subject: [PATCH] win32u: Move NtUserCreateWindowStation implementation from user32. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/user32/winstation.c | 37 ++++++------------ dlls/win32u/syscall.c | 1 + dlls/win32u/win32u.spec | 2 +- dlls/win32u/winstation.c | 28 +++++++++++++ dlls/wow64win/syscall.h | 1 + dlls/wow64win/user.c | 17 ++++++++ dlls/wow64win/wow64win_private.h | 67 ++++++++++++++++++++++++++++++++ include/ntuser.h | 2 + 8 files changed, 128 insertions(+), 27 deletions(-) diff --git a/dlls/user32/winstation.c b/dlls/user32/winstation.c index e2c4f0f251f..c619d3d4658 100644 --- a/dlls/user32/winstation.c +++ b/dlls/user32/winstation.c @@ -125,33 +125,18 @@ HWINSTA WINAPI CreateWindowStationA( LPCSTR name, DWORD flags, ACCESS_MASK acces HWINSTA WINAPI CreateWindowStationW( LPCWSTR name, DWORD flags, ACCESS_MASK access, LPSECURITY_ATTRIBUTES sa ) { - HANDLE ret; - DWORD len = name ? lstrlenW(name) : 0; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING str; - if (len >= MAX_PATH) - { - SetLastError( ERROR_FILENAME_EXCED_RANGE ); - return 0; - } - if (!len) - { - name = get_winstation_default_name(); - len = lstrlenW( name ); - } - SERVER_START_REQ( create_winstation ) - { - req->flags = 0; - req->access = access; - req->attributes = OBJ_CASE_INSENSITIVE | - ((flags & CWF_CREATE_ONLY) ? 0 : OBJ_OPENIF) | - ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0); - req->rootdir = wine_server_obj_handle( get_winstations_dir_handle() ); - 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 ); + if (!str.Length) RtlInitUnicodeString( &str, get_winstation_default_name() ); + + InitializeObjectAttributes( &attr, &str, OBJ_CASE_INSENSITIVE, + get_winstations_dir_handle(), sa ); + if (!(flags & CWF_CREATE_ONLY)) attr.Attributes |= OBJ_OPENIF; + if (sa && sa->bInheritHandle) attr.Attributes |= OBJ_INHERIT; + + return NtUserCreateWindowStation( &attr, access, 0, 0, 0, 0, 0 ); } diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index f54098c5d4f..fb1bcfef093 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -96,6 +96,7 @@ static void * const syscalls[] = NtGdiTransformPoints, NtUserCloseDesktop, NtUserCloseWindowStation, + NtUserCreateWindowStation, NtUserGetObjectInformation, NtUserGetProcessWindowStation, NtUserGetThreadDesktop, diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index c82e974be04..013e8b89694 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -816,7 +816,7 @@ @ stub NtUserCreatePalmRejectionDelayZone @ stub NtUserCreateWindowEx @ stub NtUserCreateWindowGroup -@ stub NtUserCreateWindowStation +@ stdcall -syscall NtUserCreateWindowStation(ptr long long long long long long) @ stub NtUserCtxDisplayIOCtl @ stub NtUserDdeInitialize @ stub NtUserDefSetText diff --git a/dlls/win32u/winstation.c b/dlls/win32u/winstation.c index e787cc3884c..a0afe3a9606 100644 --- a/dlls/win32u/winstation.c +++ b/dlls/win32u/winstation.c @@ -33,6 +33,34 @@ WINE_DEFAULT_DEBUG_CHANNEL(winstation); +/*********************************************************************** + * NtUserCreateWindowStation (win32u.@) + */ +HWINSTA WINAPI NtUserCreateWindowStation( OBJECT_ATTRIBUTES *attr, ACCESS_MASK access, ULONG arg3, + ULONG arg4, ULONG arg5, ULONG arg6, ULONG arg7 ) +{ + HANDLE ret; + + if (attr->ObjectName->Length >= MAX_PATH * sizeof(WCHAR)) + { + SetLastError( ERROR_FILENAME_EXCED_RANGE ); + return 0; + } + + SERVER_START_REQ( create_winstation ) + { + req->flags = 0; + req->access = access; + req->attributes = attr->Attributes; + req->rootdir = wine_server_obj_handle( attr->RootDirectory ); + 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; +} + /*********************************************************************** * NtUserCloseWindowStation (win32u.@) */ diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index 303bdf08c57..66b48f47154 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( NtUserCreateWindowStation ) \ SYSCALL_ENTRY( NtUserGetProcessWindowStation ) \ SYSCALL_ENTRY( NtUserGetThreadDesktop ) \ SYSCALL_ENTRY( NtUserOpenInputDesktop ) \ diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 59286969283..bab04018163 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -27,6 +27,23 @@ #include "ntuser.h" #include "wow64win_private.h" + +NTSTATUS WINAPI wow64_NtUserCreateWindowStation( UINT *args ) +{ + OBJECT_ATTRIBUTES32 *attr32 = get_ptr( &args ); + ACCESS_MASK access = get_ulong( &args ); + ULONG arg3 = get_ulong( &args ); + ULONG arg4 = get_ulong( &args ); + ULONG arg5 = get_ulong( &args ); + ULONG arg6 = get_ulong( &args ); + ULONG arg7 = get_ulong( &args ); + + struct object_attr64 attr; + + return HandleToUlong( NtUserCreateWindowStation( objattr_32to64( &attr, attr32 ), access, + arg3, arg4, arg5, arg6, arg7 )); +} + NTSTATUS WINAPI wow64_NtUserCloseWindowStation( UINT *args ) { HWINSTA handle = get_handle( &args ); diff --git a/dlls/wow64win/wow64win_private.h b/dlls/wow64win/wow64win_private.h index 3d32955a9d6..3a6156f41b2 100644 --- a/dlls/wow64win/wow64win_private.h +++ b/dlls/wow64win/wow64win_private.h @@ -27,6 +27,23 @@ ALL_WIN32_SYSCALLS #undef SYSCALL_ENTRY +struct object_attr64 +{ + OBJECT_ATTRIBUTES attr; + UNICODE_STRING str; + SECURITY_DESCRIPTOR sd; +}; + +typedef struct +{ + ULONG Length; + ULONG RootDirectory; + ULONG ObjectName; + ULONG Attributes; + ULONG SecurityDescriptor; + ULONG SecurityQualityOfService; +} OBJECT_ATTRIBUTES32; + static inline ULONG get_ulong( UINT **args ) { return *(*args)++; } static inline HANDLE get_handle( UINT **args ) { return LongToHandle( *(*args)++ ); } static inline void *get_ptr( UINT **args ) { return ULongToPtr( *(*args)++ ); } @@ -55,4 +72,54 @@ static inline void put_size( ULONG *size32, SIZE_T size ) if (size32) *size32 = min( size, MAXDWORD ); } +static inline UNICODE_STRING *unicode_str_32to64( UNICODE_STRING *str, const UNICODE_STRING32 *str32 ) +{ + if (!str32) return NULL; + str->Length = str32->Length; + str->MaximumLength = str32->MaximumLength; + str->Buffer = ULongToPtr( str32->Buffer ); + return str; +} + +static inline SECURITY_DESCRIPTOR *secdesc_32to64( SECURITY_DESCRIPTOR *out, const SECURITY_DESCRIPTOR *in ) +{ + /* relative descr has the same layout for 32 and 64 */ + const SECURITY_DESCRIPTOR_RELATIVE *sd = (const SECURITY_DESCRIPTOR_RELATIVE *)in; + + if (!in) return NULL; + out->Revision = sd->Revision; + out->Sbz1 = sd->Sbz1; + out->Control = sd->Control & ~SE_SELF_RELATIVE; + if (sd->Control & SE_SELF_RELATIVE) + { + if (sd->Owner) out->Owner = (PSID)((BYTE *)sd + sd->Owner); + if (sd->Group) out->Group = (PSID)((BYTE *)sd + sd->Group); + if ((sd->Control & SE_SACL_PRESENT) && sd->Sacl) out->Sacl = (PSID)((BYTE *)sd + sd->Sacl); + if ((sd->Control & SE_DACL_PRESENT) && sd->Dacl) out->Dacl = (PSID)((BYTE *)sd + sd->Dacl); + } + else + { + out->Owner = ULongToPtr( sd->Owner ); + out->Group = ULongToPtr( sd->Group ); + if (sd->Control & SE_SACL_PRESENT) out->Sacl = ULongToPtr( sd->Sacl ); + if (sd->Control & SE_DACL_PRESENT) out->Dacl = ULongToPtr( sd->Dacl ); + } + return out; +} + +static inline OBJECT_ATTRIBUTES *objattr_32to64( struct object_attr64 *out, const OBJECT_ATTRIBUTES32 *in ) +{ + memset( out, 0, sizeof(*out) ); + if (!in) return NULL; + if (in->Length != sizeof(*in)) return &out->attr; + + out->attr.Length = sizeof(out->attr); + out->attr.RootDirectory = LongToHandle( in->RootDirectory ); + out->attr.Attributes = in->Attributes; + out->attr.ObjectName = unicode_str_32to64( &out->str, ULongToPtr( in->ObjectName )); + out->attr.SecurityQualityOfService = ULongToPtr( in->SecurityQualityOfService ); + out->attr.SecurityDescriptor = secdesc_32to64( &out->sd, ULongToPtr( in->SecurityDescriptor )); + return &out->attr; +} + #endif /* __WOW64WIN_PRIVATE_H */ diff --git a/include/ntuser.h b/include/ntuser.h index e5d16afdd53..c0976cac73d 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -24,6 +24,8 @@ BOOL WINAPI NtUserCloseDesktop( HDESK handle ); BOOL WINAPI NtUserCloseWindowStation( HWINSTA handle ); +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, DWORD len, DWORD *needed ); HWINSTA WINAPI NtUserGetProcessWindowStation(void);