Jacek Caban : win32u: Move NtUserCreateWindowStation implementation from user32.

Alexandre Julliard julliard at winehq.org
Thu Oct 14 15:09:34 CDT 2021


Module: wine
Branch: master
Commit: 1d30bac773ba95fdb49ff4ca15ab5ea810f6a05f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1d30bac773ba95fdb49ff4ca15ab5ea810f6a05f

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Oct 14 15:20:42 2021 +0200

win32u: Move NtUserCreateWindowStation implementation from user32.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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);




More information about the wine-cvs mailing list