Commit 0fd450af authored by Alexandre Julliard's avatar Alexandre Julliard

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

parent af8f3ae3
......@@ -605,6 +605,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
SERVER_START_REQ( new_thread )
{
req->process = wine_server_obj_handle( process );
req->access = THREAD_ALL_ACCESS;
req->suspend = suspended;
req->request_fd = request_pipe[0];
......
......@@ -766,10 +766,12 @@ struct get_new_process_info_reply
struct new_thread_request
{
struct request_header __header;
obj_handle_t process;
unsigned int access;
int suspend;
int request_fd;
/* VARARG(objattr,object_attributes); */
char __pad_28[4];
};
struct new_thread_reply
{
......@@ -6534,6 +6536,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply;
};
#define SERVER_PROTOCOL_VERSION 561
#define SERVER_PROTOCOL_VERSION 562
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
......@@ -766,8 +766,9 @@ struct rawinput_device
@END
/* Create a new thread from the context of the parent */
/* Create a new thread */
@REQ(new_thread)
obj_handle_t process; /* process in which to create thread */
unsigned int access; /* wanted access rights */
int suspend; /* new thread should be suspended on creation */
int request_fd; /* fd for request pipe */
......
......@@ -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, exit_code) == 12 );
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, suspend) == 16 );
C_ASSERT( FIELD_OFFSET(struct new_thread_request, request_fd) == 20 );
C_ASSERT( sizeof(struct new_thread_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct new_thread_request, process) == 12 );
C_ASSERT( FIELD_OFFSET(struct new_thread_request, access) == 16 );
C_ASSERT( FIELD_OFFSET(struct new_thread_request, suspend) == 20 );
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, handle) == 12 );
C_ASSERT( sizeof(struct new_thread_reply) == 16 );
......
......@@ -1271,19 +1271,40 @@ unsigned int get_supported_cpu_mask(void)
DECL_HANDLER(new_thread)
{
struct thread *thread;
struct process *process;
struct unicode_str name;
const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL );
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 );
set_error( STATUS_INVALID_HANDLE );
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;
if (req->suspend) thread->suspend++;
......@@ -1292,10 +1313,12 @@ DECL_HANDLER(new_thread)
req->access, objattr->attributes )))
{
/* thread object will be released when the thread gets killed */
return;
goto done;
}
kill_thread( thread, 1 );
}
done:
release_object( process );
}
/* initialize a new thread */
......
......@@ -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 )
{
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, ", request_fd=%d", req->request_fd );
dump_varargs_object_attributes( ", objattr=", cur_size );
......
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