server: Specify the process in which to create a new thread.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2018-09-20 13:19:49 +02:00
parent af8f3ae333
commit 0fd450af5b
6 changed files with 40 additions and 11 deletions

View File

@ -605,6 +605,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
SERVER_START_REQ( new_thread ) SERVER_START_REQ( new_thread )
{ {
req->process = wine_server_obj_handle( process );
req->access = THREAD_ALL_ACCESS; req->access = THREAD_ALL_ACCESS;
req->suspend = suspended; req->suspend = suspended;
req->request_fd = request_pipe[0]; req->request_fd = request_pipe[0];

View File

@ -766,10 +766,12 @@ struct get_new_process_info_reply
struct new_thread_request struct new_thread_request
{ {
struct request_header __header; struct request_header __header;
obj_handle_t process;
unsigned int access; unsigned int access;
int suspend; int suspend;
int request_fd; int request_fd;
/* VARARG(objattr,object_attributes); */ /* VARARG(objattr,object_attributes); */
char __pad_28[4];
}; };
struct new_thread_reply struct new_thread_reply
{ {
@ -6534,6 +6536,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply; struct terminate_job_reply terminate_job_reply;
}; };
#define SERVER_PROTOCOL_VERSION 561 #define SERVER_PROTOCOL_VERSION 562
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -766,8 +766,9 @@ struct rawinput_device
@END @END
/* Create a new thread from the context of the parent */ /* Create a new thread */
@REQ(new_thread) @REQ(new_thread)
obj_handle_t process; /* process in which to create thread */
unsigned int access; /* wanted access rights */ unsigned int access; /* wanted access rights */
int suspend; /* new thread should be suspended on creation */ int suspend; /* new thread should be suspended on creation */
int request_fd; /* fd for request pipe */ int request_fd; /* fd for request pipe */

View File

@ -752,10 +752,11 @@ C_ASSERT( sizeof(struct get_new_process_info_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_new_process_info_reply, success) == 8 ); C_ASSERT( FIELD_OFFSET(struct get_new_process_info_reply, success) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_new_process_info_reply, exit_code) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_new_process_info_reply, exit_code) == 12 );
C_ASSERT( sizeof(struct get_new_process_info_reply) == 16 ); C_ASSERT( sizeof(struct get_new_process_info_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct new_thread_request, access) == 12 ); C_ASSERT( FIELD_OFFSET(struct new_thread_request, process) == 12 );
C_ASSERT( FIELD_OFFSET(struct new_thread_request, suspend) == 16 ); C_ASSERT( FIELD_OFFSET(struct new_thread_request, access) == 16 );
C_ASSERT( FIELD_OFFSET(struct new_thread_request, request_fd) == 20 ); C_ASSERT( FIELD_OFFSET(struct new_thread_request, suspend) == 20 );
C_ASSERT( sizeof(struct new_thread_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct new_thread_request, request_fd) == 24 );
C_ASSERT( sizeof(struct new_thread_request) == 32 );
C_ASSERT( FIELD_OFFSET(struct new_thread_reply, tid) == 8 ); C_ASSERT( FIELD_OFFSET(struct new_thread_reply, tid) == 8 );
C_ASSERT( FIELD_OFFSET(struct new_thread_reply, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct new_thread_reply, handle) == 12 );
C_ASSERT( sizeof(struct new_thread_reply) == 16 ); C_ASSERT( sizeof(struct new_thread_reply) == 16 );

View File

@ -1271,19 +1271,40 @@ unsigned int get_supported_cpu_mask(void)
DECL_HANDLER(new_thread) DECL_HANDLER(new_thread)
{ {
struct thread *thread; struct thread *thread;
struct process *process;
struct unicode_str name; struct unicode_str name;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL ); const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL );
int request_fd = thread_get_inflight_fd( current, req->request_fd ); int request_fd = thread_get_inflight_fd( current, req->request_fd );
if (request_fd == -1 || fcntl( request_fd, F_SETFL, O_NONBLOCK ) == -1) if (!(process = get_process_from_handle( req->process, PROCESS_CREATE_THREAD )))
{ {
if (request_fd != -1) close( request_fd ); if (request_fd != -1) close( request_fd );
set_error( STATUS_INVALID_HANDLE );
return; return;
} }
if ((thread = create_thread( request_fd, current->process, sd ))) if (process != current->process)
{
if (request_fd != -1) /* can't create a request fd in a different process */
{
close( request_fd );
set_error( STATUS_INVALID_PARAMETER );
goto done;
}
if (process->running_threads) /* only the initial thread can be created in another process */
{
set_error( STATUS_ACCESS_DENIED );
goto done;
}
}
else if (request_fd == -1 || fcntl( request_fd, F_SETFL, O_NONBLOCK ) == -1)
{
if (request_fd != -1) close( request_fd );
set_error( STATUS_INVALID_HANDLE );
goto done;
}
if ((thread = create_thread( request_fd, process, sd )))
{ {
thread->system_regs = current->system_regs; thread->system_regs = current->system_regs;
if (req->suspend) thread->suspend++; if (req->suspend) thread->suspend++;
@ -1292,10 +1313,12 @@ DECL_HANDLER(new_thread)
req->access, objattr->attributes ))) req->access, objattr->attributes )))
{ {
/* thread object will be released when the thread gets killed */ /* thread object will be released when the thread gets killed */
return; goto done;
} }
kill_thread( thread, 1 ); kill_thread( thread, 1 );
} }
done:
release_object( process );
} }
/* initialize a new thread */ /* initialize a new thread */

View File

@ -1261,7 +1261,8 @@ static void dump_get_new_process_info_reply( const struct get_new_process_info_r
static void dump_new_thread_request( const struct new_thread_request *req ) static void dump_new_thread_request( const struct new_thread_request *req )
{ {
fprintf( stderr, " access=%08x", req->access ); fprintf( stderr, " process=%04x", req->process );
fprintf( stderr, ", access=%08x", req->access );
fprintf( stderr, ", suspend=%d", req->suspend ); fprintf( stderr, ", suspend=%d", req->suspend );
fprintf( stderr, ", request_fd=%d", req->request_fd ); fprintf( stderr, ", request_fd=%d", req->request_fd );
dump_varargs_object_attributes( ", objattr=", cur_size ); dump_varargs_object_attributes( ", objattr=", cur_size );