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",