Transfer the full process startup info as well as the command-line through the server.
diff --git a/server/process.c b/server/process.c index d1acd70..8de97b0 100644 --- a/server/process.c +++ b/server/process.c
@@ -77,17 +77,17 @@ { struct object obj; /* object header */ int inherit_all; /* inherit all handles from parent */ + int use_handles; /* use stdio handles */ int create_flags; /* creation flags */ - int start_flags; /* flags from startup info */ handle_t hstdin; /* handle for stdin */ handle_t hstdout; /* handle for stdout */ handle_t hstderr; /* handle for stderr */ - int cmd_show; /* main window show mode */ struct file *exe_file; /* file handle for main exe */ - char *filename; /* file name for main exe */ struct thread *owner; /* owner thread (the one that created the new process) */ struct process *process; /* created process */ struct thread *thread; /* created thread */ + size_t data_size; /* size of startup data */ + startup_info_t *data; /* data for startup info */ }; static void startup_info_dump( struct object *obj, int verbose ); @@ -128,12 +128,11 @@ * physical console */ inherit_console( parent_thread, process, - (info->inherit_all || (info->start_flags & STARTF_USESTDHANDLES)) ? - info->hstdin : 0 ); + (info->inherit_all || info->use_handles) ? info->hstdin : 0 ); } if (parent_thread) { - if (!info->inherit_all && !(info->start_flags & STARTF_USESTDHANDLES)) + if (!info->inherit_all && !info->use_handles) { /* duplicate the handle from the parent into this process */ reply->hstdin = duplicate_handle( parent_thread->process, info->hstdin, process, @@ -234,7 +233,7 @@ } /* initialize the current process and fill in the request */ -static void init_process( int ppid, struct init_process_reply *reply ) +static struct startup_info *init_process( int ppid, struct init_process_reply *reply ) { struct process *process = current->process; struct thread *parent_thread = get_thread_from_pid( ppid ); @@ -248,12 +247,12 @@ if (!info) { fatal_protocol_error( current, "init_process: parent but no info\n" ); - return; + return NULL; } if (info->thread) { fatal_protocol_error( current, "init_process: called twice?\n" ); - return; + return NULL; } process->parent = (struct process *)grab_object( parent ); } @@ -266,7 +265,7 @@ process->handles = copy_handle_table( process, parent ); else process->handles = alloc_handle_table( process, 0 ); - if (!process->handles) return; + if (!process->handles) return NULL; /* retrieve the main exe file */ reply->exe_file = 0; @@ -274,11 +273,11 @@ { process->exe.file = (struct file *)grab_object( info->exe_file ); if (!(reply->exe_file = alloc_handle( process, process->exe.file, GENERIC_READ, 0 ))) - return; + return NULL; } /* set the process console */ - if (!set_process_console( process, parent_thread, info, reply )) return; + if (!set_process_console( process, parent_thread, info, reply )) return NULL; if (parent) { @@ -294,22 +293,14 @@ if (info) { - size_t size = strlen(info->filename); - if (size > get_reply_max_size()) size = get_reply_max_size(); - reply->start_flags = info->start_flags; - reply->cmd_show = info->cmd_show; - set_reply_data( info->filename, size ); + reply->info_size = info->data_size; info->process = (struct process *)grab_object( process ); info->thread = (struct thread *)grab_object( current ); wake_up( &info->obj, 0 ); } - else - { - reply->start_flags = STARTF_USESTDHANDLES; - reply->cmd_show = 0; - } reply->create_flags = process->create_flags; reply->server_start = server_start_ticks; + return info ? (struct startup_info *)grab_object( info ) : NULL; } /* destroy a process when its refcount is 0 */ @@ -363,7 +354,7 @@ { struct startup_info *info = (struct startup_info *)obj; assert( obj->ops == &startup_info_ops ); - if (info->filename) free( info->filename ); + if (info->data) free( info->data ); if (info->exe_file) release_object( info->exe_file ); if (info->process) release_object( info->process ); if (info->thread) release_object( info->thread ); @@ -379,8 +370,8 @@ struct startup_info *info = (struct startup_info *)obj; assert( obj->ops == &startup_info_ops ); - fprintf( stderr, "Startup info flags=%x in=%d out=%d err=%d name='%s'\n", - info->start_flags, info->hstdin, info->hstdout, info->hstderr, info->filename ); + fprintf( stderr, "Startup info flags=%x in=%d out=%d err=%d\n", + info->create_flags, info->hstdin, info->hstdout, info->hstderr ); } static int startup_info_signaled( struct object *obj, struct thread *thread ) @@ -770,7 +761,6 @@ /* create a new process */ DECL_HANDLER(new_process) { - size_t len = get_req_data_size(); struct startup_info *info; if (current->info) @@ -782,26 +772,24 @@ /* build the startup info for a new process */ if (!(info = alloc_object( &startup_info_ops, -1 ))) return; info->inherit_all = req->inherit_all; + info->use_handles = req->use_handles; info->create_flags = req->create_flags; - info->start_flags = req->start_flags; info->hstdin = req->hstdin; info->hstdout = req->hstdout; info->hstderr = req->hstderr; - info->cmd_show = req->cmd_show; info->exe_file = NULL; - info->filename = NULL; info->owner = (struct thread *)grab_object( current ); info->process = NULL; info->thread = NULL; + info->data_size = get_req_data_size(); + info->data = NULL; if (req->exe_file && !(info->exe_file = get_file_obj( current->process, req->exe_file, GENERIC_READ ))) goto done; - if (!(info->filename = mem_alloc( len + 1 ))) goto done; - - memcpy( info->filename, get_req_data(), len ); - info->filename[len] = 0; + if (!(info->data = mem_alloc( info->data_size ))) goto done; + memcpy( info->data, get_req_data(), info->data_size ); current->info = info; reply->info = alloc_handle( current->process, info, SYNCHRONIZE, FALSE ); @@ -839,16 +827,46 @@ } } +/* Retrieve the new process startup info */ +DECL_HANDLER(get_startup_info) +{ + struct startup_info *info; + + if ((info = (struct startup_info *)get_handle_obj( current->process, req->info, + 0, &startup_info_ops ))) + { + size_t size = info->data_size; + if (size > get_reply_max_size()) size = get_reply_max_size(); + if (req->close) + { + set_reply_data_ptr( info->data, size ); + info->data = NULL; + close_handle( current->process, req->info, NULL ); + } + else set_reply_data( info->data, size ); + release_object( info ); + } +} + + /* initialize a new process */ DECL_HANDLER(init_process) { + struct startup_info *info; + + reply->info = 0; + reply->info_size = 0; if (!current->unix_pid) { fatal_protocol_error( current, "init_process: init_thread not called yet\n" ); return; } current->process->ldt_copy = req->ldt_copy; - init_process( req->ppid, reply ); + if ((info = init_process( req->ppid, reply ))) + { + reply->info = alloc_handle( current->process, info, 0, FALSE ); + release_object( info ); + } } /* signal the end of the process initialization */
diff --git a/server/protocol.def b/server/protocol.def index 7d3b3e8..0cc3f26 100644 --- a/server/protocol.def +++ b/server/protocol.def
@@ -145,6 +145,29 @@ int signaled; /* wait result */ }; +/* structure for process startup info */ +typedef struct +{ + size_t size; /* size of this structure */ + size_t filename_len; /* length of filename */ + size_t cmdline_len; /* length of cmd line */ + size_t desktop_len; /* length of desktop name */ + size_t title_len; /* length of title */ + int x; /* window position */ + int y; + int cx; /* window size */ + int cy; + int x_chars; /* console size */ + int y_chars; + int attribute; /* console attributes */ + int cmd_show; /* main window show mode */ + unsigned int flags; /* info flags */ + /* char filename[...]; */ + /* char cmdline[...]; */ + /* char desktop[...]; */ + /* char title[...]; */ +} startup_info_t; + /* structure returned in the list of window properties */ typedef struct { @@ -175,14 +198,13 @@ /* Create a new process from the context of the parent */ @REQ(new_process) int inherit_all; /* inherit all handles from parent */ + int use_handles; /* use stdio handles */ int create_flags; /* creation flags */ - int start_flags; /* flags from startup info */ handle_t exe_file; /* file handle for main exe */ handle_t hstdin; /* handle for stdin */ handle_t hstdout; /* handle for stdout */ handle_t hstderr; /* handle for stderr */ - int cmd_show; /* main window show mode */ - VARARG(filename,string); /* file name of main exe */ + VARARG(info,startup_info); /* startup information */ @REPLY handle_t info; /* new process info handle */ @END @@ -225,14 +247,22 @@ int ppid; /* parent Unix pid */ @REPLY int create_flags; /* creation flags */ - int start_flags; /* flags from startup info */ unsigned int server_start; /* server start time (GetTickCount) */ + handle_t info; /* handle to startup info */ + size_t info_size; /* total size of startup info */ handle_t exe_file; /* file handle for main exe */ handle_t hstdin; /* handle for stdin */ handle_t hstdout; /* handle for stdout */ handle_t hstderr; /* handle for stderr */ - int cmd_show; /* main window show mode */ - VARARG(filename,string); /* file name of main exe */ +@END + + +/* Retrieve the new process startup info */ +@REQ(get_startup_info) + handle_t info; /* handle to startup info */ + int close; /* should we close the handle at the same time? */ +@REPLY + VARARG(info,startup_info); /* startup information */ @END
diff --git a/server/request.h b/server/request.h index 9a1350e..7e3b507 100644 --- a/server/request.h +++ b/server/request.h
@@ -106,6 +106,7 @@ DECL_HANDLER(new_thread); DECL_HANDLER(boot_done); DECL_HANDLER(init_process); +DECL_HANDLER(get_startup_info); DECL_HANDLER(init_process_done); DECL_HANDLER(init_thread); DECL_HANDLER(terminate_process); @@ -264,6 +265,7 @@ (req_handler)req_new_thread, (req_handler)req_boot_done, (req_handler)req_init_process, + (req_handler)req_get_startup_info, (req_handler)req_init_process_done, (req_handler)req_init_thread, (req_handler)req_terminate_process,
diff --git a/server/trace.c b/server/trace.c index 93a33af..a8844f1 100644 --- a/server/trace.c +++ b/server/trace.c
@@ -269,6 +269,43 @@ remove_data( size ); } +static void dump_varargs_startup_info( size_t size ) +{ + const startup_info_t *ptr = cur_data; + startup_info_t info; + + if (size < sizeof(info.size)) + { + fprintf( stderr, "{}" ); + return; + } + if (size > ptr->size) size = ptr->size; + memset( &info, 0, sizeof(info) ); + memcpy( &info, ptr, min( size, sizeof(info) )); + + fprintf( stderr, "{size=%d", info.size ); + fprintf( stderr, ",x=%d", info.x ); + fprintf( stderr, ",y=%d", info.y ); + fprintf( stderr, ",cx=%d", info.cx ); + fprintf( stderr, ",cy=%d", info.cy ); + fprintf( stderr, ",x_chars=%d", info.x_chars ); + fprintf( stderr, ",y_chars=%d", info.y_chars ); + fprintf( stderr, ",attr=%d", info.attribute ); + fprintf( stderr, ",cmd_show=%d", info.cmd_show ); + fprintf( stderr, ",flags=%x", info.flags ); + remove_data( size ); + fprintf( stderr, ",filename=" ); + /* FIXME: these should be unicode */ + dump_varargs_string( min(cur_size,info.filename_len) ); + fprintf( stderr, ",cmdline=" ); + dump_varargs_string( min(cur_size,info.cmdline_len) ); + fprintf( stderr, ",desktop=" ); + dump_varargs_string( min(cur_size,info.desktop_len) ); + fprintf( stderr, ",title=" ); + dump_varargs_string( min(cur_size,info.title_len) ); + fputc( '}', stderr ); +} + static void dump_varargs_input_records( size_t size ) { const INPUT_RECORD *rec = cur_data; @@ -310,15 +347,14 @@ static void dump_new_process_request( const struct new_process_request *req ) { fprintf( stderr, " inherit_all=%d,", req->inherit_all ); + fprintf( stderr, " use_handles=%d,", req->use_handles ); fprintf( stderr, " create_flags=%d,", req->create_flags ); - fprintf( stderr, " start_flags=%d,", req->start_flags ); fprintf( stderr, " exe_file=%d,", req->exe_file ); fprintf( stderr, " hstdin=%d,", req->hstdin ); fprintf( stderr, " hstdout=%d,", req->hstdout ); fprintf( stderr, " hstderr=%d,", req->hstderr ); - fprintf( stderr, " cmd_show=%d,", req->cmd_show ); - fprintf( stderr, " filename=" ); - dump_varargs_string( cur_size ); + fprintf( stderr, " info=" ); + dump_varargs_startup_info( cur_size ); } static void dump_new_process_reply( const struct new_process_reply *req ) @@ -369,15 +405,25 @@ static void dump_init_process_reply( const struct init_process_reply *req ) { fprintf( stderr, " create_flags=%d,", req->create_flags ); - fprintf( stderr, " start_flags=%d,", req->start_flags ); fprintf( stderr, " server_start=%08x,", req->server_start ); + fprintf( stderr, " info=%d,", req->info ); + fprintf( stderr, " info_size=%d,", req->info_size ); fprintf( stderr, " exe_file=%d,", req->exe_file ); fprintf( stderr, " hstdin=%d,", req->hstdin ); fprintf( stderr, " hstdout=%d,", req->hstdout ); - fprintf( stderr, " hstderr=%d,", req->hstderr ); - fprintf( stderr, " cmd_show=%d,", req->cmd_show ); - fprintf( stderr, " filename=" ); - dump_varargs_string( cur_size ); + fprintf( stderr, " hstderr=%d", req->hstderr ); +} + +static void dump_get_startup_info_request( const struct get_startup_info_request *req ) +{ + fprintf( stderr, " info=%d,", req->info ); + fprintf( stderr, " close=%d", req->close ); +} + +static void dump_get_startup_info_reply( const struct get_startup_info_reply *req ) +{ + fprintf( stderr, " info=" ); + dump_varargs_startup_info( cur_size ); } static void dump_init_process_done_request( const struct init_process_done_request *req ) @@ -2112,6 +2158,7 @@ (dump_func)dump_new_thread_request, (dump_func)dump_boot_done_request, (dump_func)dump_init_process_request, + (dump_func)dump_get_startup_info_request, (dump_func)dump_init_process_done_request, (dump_func)dump_init_thread_request, (dump_func)dump_terminate_process_request, @@ -2267,6 +2314,7 @@ (dump_func)dump_new_thread_reply, (dump_func)0, (dump_func)dump_init_process_reply, + (dump_func)dump_get_startup_info_reply, (dump_func)dump_init_process_done_reply, (dump_func)dump_init_thread_reply, (dump_func)dump_terminate_process_reply, @@ -2422,6 +2470,7 @@ "new_thread", "boot_done", "init_process", + "get_startup_info", "init_process_done", "init_thread", "terminate_process",