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 )
|
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];
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
Loading…
Reference in New Issue