Commit 33c750f5 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Use NtCreateThreadEx() for remote thread creation.

parent 39e7f25e
...@@ -555,6 +555,7 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result ) ...@@ -555,6 +555,7 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result )
break; break;
case APC_CREATE_THREAD: case APC_CREATE_THREAD:
{ {
PS_ATTRIBUTE_LIST attr = { sizeof(attr) };
CLIENT_ID id; CLIENT_ID id;
HANDLE handle; HANDLE handle;
SIZE_T reserve = call->create_thread.reserve; 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 ) ...@@ -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 && 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) (ULONG_PTR)func == call->create_thread.func && (ULONG_PTR)arg == call->create_thread.arg)
{ {
result->create_thread.status = RtlCreateUserThread( NtCurrentProcess(), NULL, attr.Attributes[0].Attribute = PS_ATTRIBUTE_CLIENT_ID;
call->create_thread.suspend, NULL, attr.Attributes[0].Size = sizeof(id);
reserve, commit, func, arg, &handle, &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.handle = wine_server_obj_handle( handle );
result->create_thread.pid = HandleToULong(id.UniqueProcess);
result->create_thread.tid = HandleToULong(id.UniqueThread); result->create_thread.tid = HandleToULong(id.UniqueThread);
} }
else result->create_thread.status = STATUS_INVALID_PARAMETER; else result->create_thread.status = STATUS_INVALID_PARAMETER;
break; break;
} }
case APC_BREAK_PROCESS: case APC_BREAK_PROCESS:
{
HANDLE handle;
result->type = APC_BREAK_PROCESS; result->type = APC_BREAK_PROCESS;
result->break_process.status = RtlCreateUserThread( NtCurrentProcess(), NULL, FALSE, NULL, 0, 0, result->break_process.status = NtCreateThreadEx( &handle, THREAD_ALL_ACCESS, NULL,
DbgUiRemoteBreakin, NULL, NULL, NULL ); NtCurrentProcess(), DbgUiRemoteBreakin, NULL,
0, 0, 0, 0, NULL );
if (!result->break_process.status) NtClose( handle );
break; break;
}
default: default:
server_protocol_error( "get_apc_request: bad type %d\n", call->type ); server_protocol_error( "get_apc_request: bad type %d\n", call->type );
break; break;
......
...@@ -185,18 +185,22 @@ NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU ...@@ -185,18 +185,22 @@ NTSTATUS CDECL create_thread( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
memset( &call, 0, sizeof(call) ); memset( &call, 0, sizeof(call) );
call.create_thread.type = APC_CREATE_THREAD; call.create_thread.type = APC_CREATE_THREAD;
call.create_thread.flags = flags;
call.create_thread.func = wine_server_client_ptr( start ); call.create_thread.func = wine_server_client_ptr( start );
call.create_thread.arg = wine_server_client_ptr( param ); call.create_thread.arg = wine_server_client_ptr( param );
call.create_thread.reserve = stack_reserve; call.create_thread.reserve = stack_reserve;
call.create_thread.commit = stack_commit; call.create_thread.commit = stack_commit;
call.create_thread.suspend = flags & THREAD_CREATE_FLAGS_CREATE_SUSPENDED;
status = server_queue_process_apc( process, &call, &result ); status = server_queue_process_apc( process, &call, &result );
if (status != STATUS_SUCCESS) return status; if (status != STATUS_SUCCESS) return status;
if (result.create_thread.status == STATUS_SUCCESS) 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 ); *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; return result.create_thread.status;
} }
......
...@@ -557,7 +557,7 @@ typedef union ...@@ -557,7 +557,7 @@ typedef union
struct struct
{ {
enum apc_type type; enum apc_type type;
int suspend; unsigned int flags;
client_ptr_t func; client_ptr_t func;
client_ptr_t arg; client_ptr_t arg;
mem_size_t reserve; mem_size_t reserve;
...@@ -645,6 +645,7 @@ typedef union ...@@ -645,6 +645,7 @@ typedef union
{ {
enum apc_type type; enum apc_type type;
unsigned int status; unsigned int status;
process_id_t pid;
thread_id_t tid; thread_id_t tid;
obj_handle_t handle; obj_handle_t handle;
} create_thread; } create_thread;
...@@ -6683,7 +6684,7 @@ union generic_reply ...@@ -6683,7 +6684,7 @@ union generic_reply
/* ### protocol_version begin ### */ /* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 607 #define SERVER_PROTOCOL_VERSION 608
/* ### protocol_version end ### */ /* ### protocol_version end ### */
......
...@@ -2580,6 +2580,7 @@ NTSYSAPI NTSTATUS WINAPI NtCreateSection(HANDLE*,ACCESS_MASK,const OBJECT_ATTRI ...@@ -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 NtCreateSemaphore(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*,LONG,LONG);
NTSYSAPI NTSTATUS WINAPI NtCreateSymbolicLinkObject(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PUNICODE_STRING); 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 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 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 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*); NTSYSAPI NTSTATUS WINAPI NtDelayExecution(BOOLEAN,const LARGE_INTEGER*);
......
...@@ -573,7 +573,7 @@ typedef union ...@@ -573,7 +573,7 @@ typedef union
struct struct
{ {
enum apc_type type; /* APC_CREATE_THREAD */ 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 func; /* void (__stdcall *func)(void*); start function */
client_ptr_t arg; /* argument for start function */ client_ptr_t arg; /* argument for start function */
mem_size_t reserve; /* reserve size for thread stack */ mem_size_t reserve; /* reserve size for thread stack */
...@@ -661,6 +661,7 @@ typedef union ...@@ -661,6 +661,7 @@ typedef union
{ {
enum apc_type type; /* APC_CREATE_THREAD */ enum apc_type type; /* APC_CREATE_THREAD */
unsigned int status; /* status returned by call */ unsigned int status; /* status returned by call */
process_id_t pid; /* process id */
thread_id_t tid; /* thread id */ thread_id_t tid; /* thread id */
obj_handle_t handle; /* handle to new thread */ obj_handle_t handle; /* handle to new thread */
} create_thread; } create_thread;
......
...@@ -221,7 +221,7 @@ static void dump_apc_call( const char *prefix, const apc_call_t *call ) ...@@ -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( ",arg=", &call->create_thread.arg );
dump_uint64( ",reserve=", &call->create_thread.reserve ); dump_uint64( ",reserve=", &call->create_thread.reserve );
dump_uint64( ",commit=", &call->create_thread.commit ); dump_uint64( ",commit=", &call->create_thread.commit );
fprintf( stderr, ",suspend=%u", call->create_thread.suspend ); fprintf( stderr, ",flags=%x", call->create_thread.flags );
break; break;
case APC_BREAK_PROCESS: case APC_BREAK_PROCESS:
fprintf( stderr, "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 ) ...@@ -302,9 +302,9 @@ static void dump_apc_result( const char *prefix, const apc_result_t *result )
get_status_name( result->unmap_view.status ) ); get_status_name( result->unmap_view.status ) );
break; break;
case APC_CREATE_THREAD: 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 ), 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; break;
case APC_BREAK_PROCESS: case APC_BREAK_PROCESS:
fprintf( stderr, "APC_BREAK_PROCESS,status=%s", get_status_name( result->break_process.status ) ); fprintf( stderr, "APC_BREAK_PROCESS,status=%s", get_status_name( result->break_process.status ) );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment