server: Specify the process in which to create a new thread.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
af8f3ae333
commit
0fd450af5b
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue