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