From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/ntdll/unix/process.c | 13 ++++++------- server/process.c | 18 +++++++++++++----- server/protocol.def | 4 ++++ server/thread.c | 1 + 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index 005b90eb05e..8ebb5a3e376 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -877,15 +877,10 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_ SERVER_START_REQ( new_thread ) { req->process = wine_server_obj_handle( process_handle ); - req->access = thread_access; req->flags = thread_flags; req->request_fd = -1; wine_server_add_data( req, objattr, attr_len ); - if (!(status = wine_server_call( req ))) - { - thread_handle = wine_server_ptr_handle( reply->handle ); - id.UniqueThread = ULongToHandle( reply->tid ); - } + status = wine_server_call( req ); } SERVER_END_REQ; free( objattr ); @@ -903,10 +898,14 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_ NtWaitForSingleObject( process_info, FALSE, NULL ); SERVER_START_REQ( get_new_process_info ) { - req->info = wine_server_obj_handle( process_info ); + req->info = wine_server_obj_handle( process_info ); + req->access = thread_access; + req->attributes = thread_attr ? thread_attr->Attributes : 0; wine_server_call( req ); success = reply->success; status = reply->exit_code; + thread_handle = wine_server_ptr_handle( reply->handle ); + id.UniqueThread = ULongToHandle( reply->tid ); } SERVER_END_REQ; diff --git a/server/process.c b/server/process.c index 5e44e6faaa6..78727080e9d 100644 --- a/server/process.c +++ b/server/process.c @@ -1431,14 +1431,22 @@ DECL_HANDLER(new_process) DECL_HANDLER(get_new_process_info) { struct startup_info *info; + struct thread *thread; - if ((info = (struct startup_info *)get_handle_obj( current->process, req->info, - 0, &startup_info_ops ))) + if (!(info = (struct startup_info *)get_handle_obj( current->process, req->info, 0, &startup_info_ops ))) return; + if (!(thread = get_process_first_thread( info->process ))) { - reply->success = is_process_init_done( info->process ); - reply->exit_code = info->process->exit_code; - release_object( info ); + set_error( STATUS_INVALID_PARAMETER ); + goto done; } + + reply->tid = get_thread_id( thread ); + reply->handle = alloc_handle_no_access_check( current->process, thread, req->access, req->attributes ); + reply->success = is_process_init_done( info->process ); + reply->exit_code = info->process->exit_code; + +done: + release_object( info ); } /* Itererate processes using global process list */ diff --git a/server/protocol.def b/server/protocol.def index 64e91bccc87..306031ea289 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1112,7 +1112,11 @@ typedef volatile struct /* Retrieve information about a newly started process */ @REQ(get_new_process_info) obj_handle_t info; /* info handle returned from new_process_request */ + unsigned int access; /* wanted handle access rights */ + unsigned int attributes; /* handle object attributes */ @REPLY + thread_id_t tid; /* main thread id */ + obj_handle_t handle; /* main thread handle (in the current process) */ int success; /* did the process start successfully? */ int exit_code; /* process exit code if failed */ @END diff --git a/server/thread.c b/server/thread.c index ad59361e53b..472fd85790a 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1705,6 +1705,7 @@ DECL_HANDLER(new_thread) { thread->system_regs = current->system_regs; reply->tid = get_thread_id( thread ); + if (request_fd == -1) goto done; /* thread handle will be returned from get_new_process_info */ if ((reply->handle = alloc_handle_no_access_check( current->process, thread, req->access, objattr->attributes ))) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10058