Module: wine Branch: master Commit: c6fea822a99ca4b5c82e5217a0a631434ad52c29 URL: https://source.winehq.org/git/wine.git/?a=commit;h=c6fea822a99ca4b5c82e5217a...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Jul 13 18:36:56 2020 +0200
ntdll: Return the TEB pointer in NtCreateThreadEx().
Signed-off-by: Alexandre Julliard julliard@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