Alexandre Julliard : server: Add a separate request to exec a new process.

Alexandre Julliard julliard at winehq.org
Mon Oct 22 15:38:44 CDT 2018


Module: wine
Branch: master
Commit: a77ef5c44345701eca6fbbf065e0de3b8f88b6b1
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=a77ef5c44345701eca6fbbf065e0de3b8f88b6b1

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Oct 22 11:44:25 2018 +0200

server: Add a separate request to exec a new process.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 c3dc113..d0f269c 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 d3aa8e2..76d5f79 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 b512141..b609a62 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 d849f73..96cb2d3 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -754,6 +754,14 @@ struct rawinput_device
 @END
 
 
+/* Execute a process, replacing the current one */
+ at 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 */
+ at 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 5044bf3..3719bbd 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 36d3021..087e3dd 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",




More information about the wine-cvs mailing list