From a77ef5c44345701eca6fbbf065e0de3b8f88b6b1 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 22 Oct 2018 11:44:25 +0200 Subject: [PATCH] server: Add a separate request to exec a new process. Signed-off-by: Alexandre Julliard --- dlls/kernel32/process.c | 3 +-- include/wine/server_protocol.h | 19 ++++++++++++++- server/process.c | 43 ++++++++++++++++++++++++++-------- server/protocol.def | 8 +++++++ server/request.h | 6 +++++ server/trace.c | 10 ++++++++ 6 files changed, 76 insertions(+), 13 deletions(-) diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index c3dc113803d..d0f269c7ef7 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -2228,9 +2228,8 @@ static BOOL create_process( HANDLE hFile, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ { wine_server_send_fd( socketfd[1] ); close( socketfd[1] ); - SERVER_START_REQ( new_process ) + SERVER_START_REQ( exec_process ) { - req->create_flags = flags; req->socket_fd = socketfd[1]; req->exe_file = wine_server_obj_handle( hFile ); req->cpu = pe_info->cpu; diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index d3aa8e2d2b9..76d5f792e92 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -745,6 +745,20 @@ struct new_process_reply +struct exec_process_request +{ + struct request_header __header; + int socket_fd; + obj_handle_t exe_file; + cpu_type_t cpu; +}; +struct exec_process_reply +{ + struct reply_header __header; +}; + + + struct get_new_process_info_request { struct request_header __header; @@ -5632,6 +5646,7 @@ struct terminate_job_reply enum request { REQ_new_process, + REQ_exec_process, REQ_get_new_process_info, REQ_new_thread, REQ_get_startup_info, @@ -5928,6 +5943,7 @@ union generic_request struct request_max_size max_size; struct request_header request_header; struct new_process_request new_process_request; + struct exec_process_request exec_process_request; struct get_new_process_info_request get_new_process_info_request; struct new_thread_request new_thread_request; struct get_startup_info_request get_startup_info_request; @@ -6222,6 +6238,7 @@ union generic_reply struct request_max_size max_size; struct reply_header reply_header; struct new_process_reply new_process_reply; + struct exec_process_reply exec_process_reply; struct get_new_process_info_reply get_new_process_info_reply; struct new_thread_reply new_thread_reply; struct get_startup_info_reply get_startup_info_reply; @@ -6512,6 +6529,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; }; -#define SERVER_PROTOCOL_VERSION 567 +#define SERVER_PROTOCOL_VERSION 568 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/process.c b/server/process.c index b512141048a..b609a62e0e9 100644 --- a/server/process.c +++ b/server/process.c @@ -1112,16 +1112,6 @@ DECL_HANDLER(new_process) return; } - if (!req->info_size) /* create an orphaned process */ - { - if ((process = create_process( socket_fd, NULL, 0, sd ))) - { - create_thread( -1, process, NULL ); - release_object( process ); - } - return; - } - /* build the startup info for a new process */ if (!(info = alloc_object( &startup_info_ops ))) { @@ -1238,6 +1228,39 @@ DECL_HANDLER(new_process) release_object( info ); } +/* execute a new process, replacing the existing one */ +DECL_HANDLER(exec_process) +{ + struct process *process; + int socket_fd = thread_get_inflight_fd( current, req->socket_fd ); + + if (socket_fd == -1) + { + set_error( STATUS_INVALID_PARAMETER ); + return; + } + if (fcntl( socket_fd, F_SETFL, O_NONBLOCK ) == -1) + { + set_error( STATUS_INVALID_HANDLE ); + close( socket_fd ); + return; + } + if (shutdown_stage) + { + set_error( STATUS_SHUTDOWN_IN_PROGRESS ); + close( socket_fd ); + return; + } + if (!is_cpu_supported( req->cpu )) + { + close( socket_fd ); + return; + } + if (!(process = create_process( socket_fd, NULL, 0, NULL ))) return; + create_thread( -1, process, NULL ); + release_object( process ); +} + /* Retrieve information about a newly started process */ DECL_HANDLER(get_new_process_info) { diff --git a/server/protocol.def b/server/protocol.def index d849f7385e1..96cb2d31d50 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -754,6 +754,14 @@ struct rawinput_device @END +/* Execute a process, replacing the current one */ +@REQ(exec_process) + int socket_fd; /* file descriptor for process socket */ + obj_handle_t exe_file; /* file handle for main exe */ + cpu_type_t cpu; /* CPU that the new process will use */ +@END + + /* Retrieve information about a newly started process */ @REQ(get_new_process_info) obj_handle_t info; /* info handle returned from new_process_request */ diff --git a/server/request.h b/server/request.h index 5044bf3e4ea..3719bbdc055 100644 --- a/server/request.h +++ b/server/request.h @@ -113,6 +113,7 @@ static inline void set_reply_data_ptr( void *data, data_size_t size ) /* ### make_requests begin ### */ DECL_HANDLER(new_process); +DECL_HANDLER(exec_process); DECL_HANDLER(get_new_process_info); DECL_HANDLER(new_thread); DECL_HANDLER(get_startup_info); @@ -408,6 +409,7 @@ typedef void (*req_handler)( const void *req, void *reply ); static const req_handler req_handlers[REQ_NB_REQUESTS] = { (req_handler)req_new_process, + (req_handler)req_exec_process, (req_handler)req_get_new_process_info, (req_handler)req_new_thread, (req_handler)req_get_startup_info, @@ -740,6 +742,10 @@ C_ASSERT( FIELD_OFFSET(struct new_process_reply, info) == 8 ); C_ASSERT( FIELD_OFFSET(struct new_process_reply, pid) == 12 ); C_ASSERT( FIELD_OFFSET(struct new_process_reply, handle) == 16 ); C_ASSERT( sizeof(struct new_process_reply) == 24 ); +C_ASSERT( FIELD_OFFSET(struct exec_process_request, socket_fd) == 12 ); +C_ASSERT( FIELD_OFFSET(struct exec_process_request, exe_file) == 16 ); +C_ASSERT( FIELD_OFFSET(struct exec_process_request, cpu) == 20 ); +C_ASSERT( sizeof(struct exec_process_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct get_new_process_info_request, info) == 12 ); C_ASSERT( sizeof(struct get_new_process_info_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_new_process_info_reply, success) == 8 ); diff --git a/server/trace.c b/server/trace.c index 36d30213bd7..087e3dd312d 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1246,6 +1246,13 @@ static void dump_new_process_reply( const struct new_process_reply *req ) fprintf( stderr, ", handle=%04x", req->handle ); } +static void dump_exec_process_request( const struct exec_process_request *req ) +{ + fprintf( stderr, " socket_fd=%d", req->socket_fd ); + fprintf( stderr, ", exe_file=%04x", req->exe_file ); + dump_cpu_type( ", cpu=", &req->cpu ); +} + static void dump_get_new_process_info_request( const struct get_new_process_info_request *req ) { fprintf( stderr, " info=%04x", req->info ); @@ -4529,6 +4536,7 @@ static void dump_terminate_job_request( const struct terminate_job_request *req static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_new_process_request, + (dump_func)dump_exec_process_request, (dump_func)dump_get_new_process_info_request, (dump_func)dump_new_thread_request, (dump_func)dump_get_startup_info_request, @@ -4821,6 +4829,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_new_process_reply, + NULL, (dump_func)dump_get_new_process_info_reply, (dump_func)dump_new_thread_reply, (dump_func)dump_get_startup_info_reply, @@ -5113,6 +5122,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { static const char * const req_names[REQ_NB_REQUESTS] = { "new_process", + "exec_process", "get_new_process_info", "new_thread", "get_startup_info",