ntdll: Return the TEB pointer in NtCreateThreadEx().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0e46dd09e5
commit
c6fea822a9
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ### */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue