Module: wine Branch: master Commit: 33c750f50ff8b6f1eae63140e8287c49a5130a60 URL: https://source.winehq.org/git/wine.git/?a=commit;h=33c750f50ff8b6f1eae63140e...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Jun 5 15:23:37 2020 +0200
ntdll: Use NtCreateThreadEx() for remote thread creation.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/unix/server.c | 22 +++++++++++++++++----- dlls/ntdll/unix/thread.c | 8 ++++++-- include/wine/server_protocol.h | 5 +++-- include/winternl.h | 1 + server/protocol.def | 3 ++- server/trace.c | 6 +++--- 6 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index 4b38a73039..a7592f5e15 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -555,6 +555,7 @@ 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) }; CLIENT_ID id; HANDLE handle; SIZE_T reserve = call->create_thread.reserve; @@ -566,20 +567,31 @@ 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) { - result->create_thread.status = RtlCreateUserThread( NtCurrentProcess(), NULL, - call->create_thread.suspend, NULL, - reserve, commit, func, arg, &handle, &id ); + attr.Attributes[0].Attribute = PS_ATTRIBUTE_CLIENT_ID; + attr.Attributes[0].Size = sizeof(id); + attr.Attributes[0].ValuePtr = &id; + result->create_thread.status = NtCreateThreadEx( &handle, THREAD_ALL_ACCESS, NULL, + NtCurrentProcess(), func, arg, + call->create_thread.flags, 0, + 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); } else result->create_thread.status = STATUS_INVALID_PARAMETER; break; } case APC_BREAK_PROCESS: + { + HANDLE handle; + result->type = APC_BREAK_PROCESS; - result->break_process.status = RtlCreateUserThread( NtCurrentProcess(), NULL, FALSE, NULL, 0, 0, - DbgUiRemoteBreakin, NULL, NULL, NULL ); + result->break_process.status = NtCreateThreadEx( &handle, THREAD_ALL_ACCESS, NULL, + NtCurrentProcess(), DbgUiRemoteBreakin, NULL, + 0, 0, 0, 0, NULL ); + if (!result->break_process.status) NtClose( handle ); break; + } default: server_protocol_error( "get_apc_request: bad type %d\n", call->type ); break; diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 602e0930ab..ec8f1cf8c4 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -185,18 +185,22 @@ NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU memset( &call, 0, sizeof(call) );
call.create_thread.type = APC_CREATE_THREAD; + call.create_thread.flags = flags; call.create_thread.func = wine_server_client_ptr( start ); call.create_thread.arg = wine_server_client_ptr( param ); call.create_thread.reserve = stack_reserve; call.create_thread.commit = stack_commit; - call.create_thread.suspend = flags & THREAD_CREATE_FLAGS_CREATE_SUSPENDED; status = server_queue_process_apc( process, &call, &result ); if (status != STATUS_SUCCESS) return status;
if (result.create_thread.status == STATUS_SUCCESS) { - if (id) id->UniqueThread = ULongToHandle( result.create_thread.tid ); *handle = wine_server_ptr_handle( result.create_thread.handle ); + if (id) + { + id->UniqueProcess = ULongToHandle( result.create_thread.pid ); + id->UniqueThread = ULongToHandle( result.create_thread.tid ); + } } return result.create_thread.status; } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 520251fd3d..4b40ba7772 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -557,7 +557,7 @@ typedef union struct { enum apc_type type; - int suspend; + unsigned int flags; client_ptr_t func; client_ptr_t arg; mem_size_t reserve; @@ -645,6 +645,7 @@ typedef union { enum apc_type type; unsigned int status; + process_id_t pid; thread_id_t tid; obj_handle_t handle; } create_thread; @@ -6683,7 +6684,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 607 +#define SERVER_PROTOCOL_VERSION 608
/* ### protocol_version end ### */
diff --git a/include/winternl.h b/include/winternl.h index 2342835911..ad64df9d2e 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2580,6 +2580,7 @@ NTSYSAPI NTSTATUS WINAPI NtCreateSection(HANDLE*,ACCESS_MASK,const OBJECT_ATTRI NTSYSAPI NTSTATUS WINAPI NtCreateSemaphore(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*,LONG,LONG); NTSYSAPI NTSTATUS WINAPI NtCreateSymbolicLinkObject(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PUNICODE_STRING); NTSYSAPI NTSTATUS WINAPI NtCreateThread(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,HANDLE,PCLIENT_ID,PCONTEXT,PINITIAL_TEB,BOOLEAN); +NTSYSAPI NTSTATUS WINAPI NtCreateThreadEx(HANDLE*,ACCESS_MASK,OBJECT_ATTRIBUTES*,HANDLE,PRTL_THREAD_START_ROUTINE,void*,ULONG,SIZE_T,SIZE_T,SIZE_T,PS_ATTRIBUTE_LIST*); NTSYSAPI NTSTATUS WINAPI NtCreateTimer(HANDLE*, ACCESS_MASK, const OBJECT_ATTRIBUTES*, TIMER_TYPE); NTSYSAPI NTSTATUS WINAPI NtCreateToken(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,TOKEN_TYPE,PLUID,PLARGE_INTEGER,PTOKEN_USER,PTOKEN_GROUPS,PTOKEN_PRIVILEGES,PTOKEN_OWNER,PTOKEN_PRIMARY_GROUP,PTOKEN_DEFAULT_DACL,PTOKEN_SOURCE); NTSYSAPI NTSTATUS WINAPI NtDelayExecution(BOOLEAN,const LARGE_INTEGER*); diff --git a/server/protocol.def b/server/protocol.def index 632c996dc0..95a3021ee8 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -573,7 +573,7 @@ typedef union struct { enum apc_type type; /* APC_CREATE_THREAD */ - int suspend; /* suspended thread? */ + unsigned int flags; /* creation flags */ client_ptr_t func; /* void (__stdcall *func)(void*); start function */ client_ptr_t arg; /* argument for start function */ mem_size_t reserve; /* reserve size for thread stack */ @@ -661,6 +661,7 @@ typedef union { enum apc_type type; /* APC_CREATE_THREAD */ unsigned int status; /* status returned by call */ + process_id_t pid; /* process id */ thread_id_t tid; /* thread id */ obj_handle_t handle; /* handle to new thread */ } create_thread; diff --git a/server/trace.c b/server/trace.c index 555e697657..83db655d3e 100644 --- a/server/trace.c +++ b/server/trace.c @@ -221,7 +221,7 @@ static void dump_apc_call( const char *prefix, const apc_call_t *call ) dump_uint64( ",arg=", &call->create_thread.arg ); dump_uint64( ",reserve=", &call->create_thread.reserve ); dump_uint64( ",commit=", &call->create_thread.commit ); - fprintf( stderr, ",suspend=%u", call->create_thread.suspend ); + fprintf( stderr, ",flags=%x", call->create_thread.flags ); break; case APC_BREAK_PROCESS: fprintf( stderr, "APC_BREAK_PROCESS" ); @@ -302,9 +302,9 @@ static void dump_apc_result( const char *prefix, const apc_result_t *result ) get_status_name( result->unmap_view.status ) ); break; case APC_CREATE_THREAD: - fprintf( stderr, "APC_CREATE_THREAD,status=%s,tid=%04x,handle=%04x", + fprintf( stderr, "APC_CREATE_THREAD,status=%s,pid=%04x,tid=%04x,handle=%04x", get_status_name( result->create_thread.status ), - result->create_thread.tid, result->create_thread.handle ); + result->create_thread.pid, result->create_thread.tid, result->create_thread.handle ); break; case APC_BREAK_PROCESS: fprintf( stderr, "APC_BREAK_PROCESS,status=%s", get_status_name( result->break_process.status ) );