Alexandre Julliard : ntdll: Return the TEB pointer in NtCreateThreadEx().

Alexandre Julliard julliard at winehq.org
Mon Jul 13 16:08:49 CDT 2020


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Jul 13 18:36:56 2020 +0200

ntdll: Return the TEB pointer in NtCreateThreadEx().

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/server.c       | 19 ++++++++++++++-----
 dlls/ntdll/unix/thread.c       | 13 ++++++++++---
 include/wine/server_protocol.h |  3 ++-
 server/protocol.def            |  1 +
 4 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
index 4e65b0eab2..9a593f7725 100644
--- a/dlls/ntdll/unix/server.c
+++ b/dlls/ntdll/unix/server.c
@@ -533,9 +533,11 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result )
         break;
     case APC_CREATE_THREAD:
     {
-        PS_ATTRIBUTE_LIST attr = { sizeof(attr) };
+        ULONG_PTR buffer[offsetof( PS_ATTRIBUTE_LIST, Attributes[2] ) / sizeof(ULONG_PTR)];
+        PS_ATTRIBUTE_LIST *attr = (PS_ATTRIBUTE_LIST *)buffer;
         CLIENT_ID id;
         HANDLE handle;
+        TEB *teb;
         SIZE_T reserve = call->create_thread.reserve;
         SIZE_T commit = call->create_thread.commit;
         void *func = wine_server_get_ptr( call->create_thread.func );
@@ -545,16 +547,23 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result )
         if (reserve == call->create_thread.reserve && commit == call->create_thread.commit &&
             (ULONG_PTR)func == call->create_thread.func && (ULONG_PTR)arg == call->create_thread.arg)
         {
-            attr.Attributes[0].Attribute = PS_ATTRIBUTE_CLIENT_ID;
-            attr.Attributes[0].Size      = sizeof(id);
-            attr.Attributes[0].ValuePtr  = &id;
+            attr->TotalLength = sizeof(buffer);
+            attr->Attributes[0].Attribute    = PS_ATTRIBUTE_CLIENT_ID;
+            attr->Attributes[0].Size         = sizeof(id);
+            attr->Attributes[0].ValuePtr     = &id;
+            attr->Attributes[0].ReturnLength = NULL;
+            attr->Attributes[1].Attribute    = PS_ATTRIBUTE_TEB_ADDRESS;
+            attr->Attributes[1].Size         = sizeof(teb);
+            attr->Attributes[1].ValuePtr     = &teb;
+            attr->Attributes[1].ReturnLength = NULL;
             result->create_thread.status = NtCreateThreadEx( &handle, THREAD_ALL_ACCESS, NULL,
                                                              NtCurrentProcess(), func, arg,
                                                              call->create_thread.flags, 0,
-                                                             commit, reserve, &attr );
+                                                             commit, reserve, attr );
             result->create_thread.handle = wine_server_obj_handle( handle );
             result->create_thread.pid = HandleToULong(id.UniqueProcess);
             result->create_thread.tid = HandleToULong(id.UniqueThread);
+            result->create_thread.teb = wine_server_client_ptr( teb );
         }
         else result->create_thread.status = STATUS_INVALID_PARAMETER;
         break;
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
index 78da6ae638..6c64eecf1f 100644
--- a/dlls/ntdll/unix/thread.c
+++ b/dlls/ntdll/unix/thread.c
@@ -123,7 +123,7 @@ static void start_thread( TEB *teb )
  *
  * Update the output attributes.
  */
-static void update_attr_list( PS_ATTRIBUTE_LIST *attr, const CLIENT_ID *id )
+static void update_attr_list( PS_ATTRIBUTE_LIST *attr, const CLIENT_ID *id, TEB *teb )
 {
     SIZE_T i, count = (attr->TotalLength - sizeof(attr->TotalLength)) / sizeof(PS_ATTRIBUTE);
 
@@ -135,6 +135,12 @@ static void update_attr_list( PS_ATTRIBUTE_LIST *attr, const CLIENT_ID *id )
             memcpy( attr->Attributes[i].ValuePtr, id, size );
             if (attr->Attributes[i].ReturnLength) *attr->Attributes[i].ReturnLength = size;
         }
+        else if (attr->Attributes[i].Attribute == PS_ATTRIBUTE_TEB_ADDRESS)
+        {
+            SIZE_T size = min( attr->Attributes[i].Size, sizeof(teb) );
+            memcpy( attr->Attributes[i].ValuePtr, &teb, size );
+            if (attr->Attributes[i].ReturnLength) *attr->Attributes[i].ReturnLength = size;
+        }
     }
 }
 
@@ -181,10 +187,11 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
 
         if (result.create_thread.status == STATUS_SUCCESS)
         {
+            TEB *teb = wine_server_get_ptr( result.create_thread.teb );
             *handle = wine_server_ptr_handle( result.create_thread.handle );
             client_id.UniqueProcess = ULongToHandle( result.create_thread.pid );
             client_id.UniqueThread  = ULongToHandle( result.create_thread.tid );
-            if (attr_list) update_attr_list( attr_list, &client_id );
+            if (attr_list) update_attr_list( attr_list, &client_id, teb );
         }
         return result.create_thread.status;
     }
@@ -275,7 +282,7 @@ done:
         close( request_pipe[1] );
         return status;
     }
-    if (attr_list) update_attr_list( attr_list, &client_id );
+    if (attr_list) update_attr_list( attr_list, &client_id, teb );
     return STATUS_SUCCESS;
 }
 
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 8a282155eb..730e368f0c 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -647,6 +647,7 @@ typedef union
         unsigned int     status;
         process_id_t     pid;
         thread_id_t      tid;
+        client_ptr_t     teb;
         obj_handle_t     handle;
     } create_thread;
     struct
@@ -6481,7 +6482,7 @@ union generic_reply
 
 /* ### protocol_version begin ### */
 
-#define SERVER_PROTOCOL_VERSION 624
+#define SERVER_PROTOCOL_VERSION 625
 
 /* ### protocol_version end ### */
 
diff --git a/server/protocol.def b/server/protocol.def
index 36e674f086..90c695ec0b 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -663,6 +663,7 @@ typedef union
         unsigned int     status;    /* status returned by call */
         process_id_t     pid;       /* process id */
         thread_id_t      tid;       /* thread id */
+        client_ptr_t     teb;       /* thread teb (in process address space) */
         obj_handle_t     handle;    /* handle to new thread */
     } create_thread;
     struct




More information about the wine-cvs mailing list