Transfer the full process startup info as well as the command-line
through the server.

diff --git a/include/wine/server.h b/include/wine/server.h
index c8fc370..45ae227 100644
--- a/include/wine/server.h
+++ b/include/wine/server.h
@@ -34,7 +34,7 @@
     unsigned int size;
 };
 
-#define __SERVER_MAX_DATA 4
+#define __SERVER_MAX_DATA 5
 
 struct __server_request_info
 {
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index d51a10f..d9a3796 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -132,6 +132,29 @@
 
 typedef struct
 {
+    size_t       size;
+    size_t       filename_len;
+    size_t       cmdline_len;
+    size_t       desktop_len;
+    size_t       title_len;
+    int          x;
+    int          y;
+    int          cx;
+    int          cy;
+    int          x_chars;
+    int          y_chars;
+    int          attribute;
+    int          cmd_show;
+    unsigned int flags;
+
+
+
+
+} startup_info_t;
+
+
+typedef struct
+{
     atom_t         atom;
     short          string;
     handle_t       handle;
@@ -161,14 +184,13 @@
 {
     struct request_header __header;
     int          inherit_all;
+    int          use_handles;
     int          create_flags;
-    int          start_flags;
     handle_t     exe_file;
     handle_t     hstdin;
     handle_t     hstdout;
     handle_t     hstderr;
-    int          cmd_show;
-    /* VARARG(filename,string); */
+    /* VARARG(info,startup_info); */
 };
 struct new_process_reply
 {
@@ -235,14 +257,27 @@
 {
     struct reply_header __header;
     int          create_flags;
-    int          start_flags;
     unsigned int server_start;
+    handle_t     info;
+    size_t       info_size;
     handle_t     exe_file;
     handle_t     hstdin;
     handle_t     hstdout;
     handle_t     hstderr;
-    int          cmd_show;
-    /* VARARG(filename,string); */
+};
+
+
+
+struct get_startup_info_request
+{
+    struct request_header __header;
+    handle_t     info;
+    int          close;
+};
+struct get_startup_info_reply
+{
+    struct reply_header __header;
+    /* VARARG(info,startup_info); */
 };
 
 
@@ -2663,6 +2698,7 @@
     REQ_new_thread,
     REQ_boot_done,
     REQ_init_process,
+    REQ_get_startup_info,
     REQ_init_process_done,
     REQ_init_thread,
     REQ_terminate_process,
@@ -2822,6 +2858,7 @@
     struct new_thread_request new_thread_request;
     struct boot_done_request boot_done_request;
     struct init_process_request init_process_request;
+    struct get_startup_info_request get_startup_info_request;
     struct init_process_done_request init_process_done_request;
     struct init_thread_request init_thread_request;
     struct terminate_process_request terminate_process_request;
@@ -2979,6 +3016,7 @@
     struct new_thread_reply new_thread_reply;
     struct boot_done_reply boot_done_reply;
     struct init_process_reply init_process_reply;
+    struct get_startup_info_reply get_startup_info_reply;
     struct init_process_done_reply init_process_done_reply;
     struct init_thread_reply init_thread_reply;
     struct terminate_process_reply terminate_process_reply;
@@ -3128,6 +3166,6 @@
     struct get_window_properties_reply get_window_properties_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 75
+#define SERVER_PROTOCOL_VERSION 76
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/memory/environ.c b/memory/environ.c
index 2e4aec5..de8674d 100644
--- a/memory/environ.c
+++ b/memory/environ.c
@@ -28,6 +28,7 @@
 #include "winerror.h"
 
 #include "wine/winbase16.h"
+#include "wine/server.h"
 #include "heap.h"
 #include "ntddk.h"
 #include "selectors.h"
@@ -145,11 +146,11 @@
 
 
 /***********************************************************************
- *           ENV_BuildEnvironment
+ *           build_environment
  *
  * Build the environment for the initial process
  */
-ENVDB *ENV_BuildEnvironment(void)
+static BOOL build_environment(void)
 {
     extern char **environ;
     LPSTR p, *e;
@@ -162,7 +163,7 @@
 
     /* Now allocate the environment */
 
-    if (!(p = HeapAlloc( GetProcessHeap(), 0, size ))) return NULL;
+    if (!(p = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
     current_envdb.environ = p;
     env_sel = SELECTOR_AllocBlock( p, 0x10000, WINE_LDT_FLAGS_DATA );
 
@@ -177,6 +178,102 @@
     /* Now add the program name */
 
     FILL_EXTRA_ENV( p );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           copy_str
+ *
+ * Small helper for ENV_InitStartupInfo.
+ */
+inline static char *copy_str( char **dst, const char **src, size_t len )
+{
+    char *ret;
+
+    if (!len) return NULL;
+    ret = *dst;
+    memcpy( ret, *src, len );
+    ret[len] = 0;
+    *dst += len + 1;
+    *src += len;
+    return ret;
+}
+
+
+/***********************************************************************
+ *           ENV_InitStartupInfo
+ *
+ * Fill the startup info structure from the server.
+ */
+ENVDB *ENV_InitStartupInfo( handle_t info_handle, size_t info_size,
+                            char *main_exe_name, size_t main_exe_size )
+{
+    startup_info_t info;
+    void *data;
+    char *dst;
+    const char *src;
+    size_t len;
+
+    if (!build_environment()) return NULL;
+    if (!info_size) return &current_envdb;  /* nothing to retrieve */
+
+    if (!(data = HeapAlloc( GetProcessHeap(), 0, info_size ))) return NULL;
+
+    SERVER_START_REQ( get_startup_info )
+    {
+        req->info = info_handle;
+        req->close = TRUE;
+        wine_server_set_reply( req, data, info_size );
+        wine_server_call( req );
+        info_size = wine_server_reply_size( reply );
+    }
+    SERVER_END_REQ;
+    if (info_size < sizeof(info.size)) goto done;
+    len = min( info_size, ((startup_info_t *)data)->size );
+    memset( &info, 0, sizeof(info) );
+    memcpy( &info, data, len );
+    src = (char *)data + len;
+    info_size -= len;
+
+    /* fixup the lengths */
+    if (info.filename_len > info_size) info.filename_len = info_size;
+    info_size -= info.filename_len;
+    if (info.cmdline_len > info_size) info.cmdline_len = info_size;
+    info_size -= info.cmdline_len;
+    if (info.desktop_len > info_size) info.desktop_len = info_size;
+    info_size -= info.desktop_len;
+    if (info.title_len > info_size) info.title_len = info_size;
+
+    /* store the filename */
+    if (info.filename_len)
+    {
+        len = min( info.filename_len, main_exe_size-1 );
+        memcpy( main_exe_name, src, len );
+        main_exe_name[len] = 0;
+        src += info.filename_len;
+    }
+
+    /* copy the other strings */
+    len = info.cmdline_len + info.desktop_len + info.title_len;
+    if (len && (dst = HeapAlloc( GetProcessHeap(), 0, len + 3 )))
+    {
+        current_envdb.cmd_line = copy_str( &dst, &src, info.cmdline_len );
+        current_startupinfo.lpDesktop = copy_str( &dst, &src, info.desktop_len );
+        current_startupinfo.lpTitle = copy_str( &dst, &src, info.title_len );
+    }
+
+    current_startupinfo.dwX             = info.x;
+    current_startupinfo.dwY             = info.y;
+    current_startupinfo.dwXSize         = info.cx;
+    current_startupinfo.dwYSize         = info.cy;
+    current_startupinfo.dwXCountChars   = info.x_chars;
+    current_startupinfo.dwYCountChars   = info.y_chars;
+    current_startupinfo.dwFillAttribute = info.attribute;
+    current_startupinfo.wShowWindow     = info.cmd_show;
+    current_startupinfo.dwFlags         = info.flags;
+ done:
+    HeapFree( GetProcessHeap(), 0, data );
     return &current_envdb;
 }
 
@@ -208,6 +305,8 @@
     int len;
     char *p, **arg;
 
+    if (current_envdb.cmd_line) goto done;  /* already got it from the server */
+
     len = 0;
     for (arg = argv; *arg; arg++)
     {
@@ -304,6 +403,7 @@
     *p = '\0';
 
     /* now allocate the Unicode version */
+ done:
     len = MultiByteToWideChar( CP_ACP, 0, current_envdb.cmd_line, -1, NULL, 0 );
     if (!(cmdlineW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
         return FALSE;
diff --git a/scheduler/process.c b/scheduler/process.c
index 8cf22a1..e127ca2 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -116,7 +116,8 @@
 unsigned int server_startticks;
 
 /* memory/environ.c */
-extern struct _ENVDB *ENV_BuildEnvironment(void);
+extern struct _ENVDB *ENV_InitStartupInfo( handle_t info_handle, size_t info_size,
+                                           char *main_exe_name, size_t main_exe_size );
 extern BOOL ENV_BuildCommandLine( char **argv );
 extern STARTUPINFOA current_startupinfo;
 
@@ -243,6 +244,8 @@
 {
     BOOL ret;
     int create_flags = 0;
+    size_t info_size = 0;
+    handle_t info = 0;
 
     /* store the program name */
     argv0 = argv[0];
@@ -271,9 +274,9 @@
             main_exe_name[len] = 0;
             main_exe_file = reply->exe_file;
             create_flags  = reply->create_flags;
-            current_startupinfo.dwFlags     = reply->start_flags;
+            info_size     = reply->info_size;
+            info          = reply->info;
             server_startticks               = reply->server_start;
-            current_startupinfo.wShowWindow = reply->cmd_show;
             current_startupinfo.hStdInput   = reply->hstdin;
             current_startupinfo.hStdOutput  = reply->hstdout;
             current_startupinfo.hStdError   = reply->hstderr;
@@ -308,7 +311,9 @@
     PTHREAD_init_done();
 
     /* Copy the parent environment */
-    if (!(current_process.env_db = ENV_BuildEnvironment())) return FALSE;
+    if (!(current_process.env_db = ENV_InitStartupInfo( info, info_size,
+                                                        main_exe_name, sizeof(main_exe_name) )))
+        return FALSE;
 
     /* Parse command line arguments */
     OPTIONS_ParseOptions( argv );
@@ -861,6 +866,7 @@
     DOS_FULL_NAME full_dir, full_name;
     HANDLE load_done_evt = 0;
     HANDLE process_info;
+    startup_info_t startup_info;
 
     info->hThread = info->hProcess = 0;
     info->dwProcessId = info->dwThreadId = 0;
@@ -880,15 +886,33 @@
         }
     }
 
+    /* fill the startup info structure */
+
+    startup_info.size        = sizeof(startup_info);
+    /* startup_info.filename_len is set below */
+    startup_info.cmdline_len = cmd_line ? strlen(cmd_line) : 0;
+    startup_info.desktop_len = startup->lpDesktop ? strlen(startup->lpDesktop) : 0;
+    startup_info.title_len   = startup->lpTitle ? strlen(startup->lpTitle) : 0;
+    startup_info.x           = startup->dwX;
+    startup_info.y           = startup->dwY;
+    startup_info.cx          = startup->dwXSize;
+    startup_info.cy          = startup->dwYSize;
+    startup_info.x_chars     = startup->dwXCountChars;
+    startup_info.y_chars     = startup->dwYCountChars;
+    startup_info.attribute   = startup->dwFillAttribute;
+    startup_info.cmd_show    = startup->wShowWindow;
+    startup_info.flags       = startup->dwFlags;
+
     /* create the process on the server side */
 
     SERVER_START_REQ( new_process )
     {
         char buf[MAX_PATH];
+        LPCSTR nameptr;
 
         req->inherit_all  = inherit;
         req->create_flags = flags;
-        req->start_flags  = startup->dwFlags;
+        req->use_handles  = (startup->dwFlags & STARTF_USESTDHANDLES) != 0;
         req->exe_file     = hFile;
         if (startup->dwFlags & STARTF_USESTDHANDLES)
         {
@@ -902,22 +926,28 @@
             req->hstdout = GetStdHandle( STD_OUTPUT_HANDLE );
             req->hstderr = GetStdHandle( STD_ERROR_HANDLE );
         }
-        req->cmd_show = startup->wShowWindow;
 
         if (!hFile)  /* unix process */
         {
             unixfilename = filename;
             if (DOSFS_GetFullName( filename, TRUE, &full_name ))
                 unixfilename = full_name.long_name;
-            wine_server_add_data( req, unixfilename, strlen(unixfilename) );
+            nameptr = unixfilename;
         }
         else  /* new wine process */
         {
             if (GetLongPathNameA( filename, buf, MAX_PATH ))
-                wine_server_add_data( req, buf, strlen(buf) );
+                nameptr = buf;
             else
-                wine_server_add_data( req, filename, strlen(filename) );
+                nameptr = filename;
         }
+        startup_info.filename_len = strlen(nameptr);
+        wine_server_add_data( req, &startup_info, sizeof(startup_info) );
+        wine_server_add_data( req, nameptr, startup_info.filename_len );
+        wine_server_add_data( req, cmd_line, startup_info.cmdline_len );
+        wine_server_add_data( req, startup->lpDesktop, startup_info.desktop_len );
+        wine_server_add_data( req, startup->lpTitle, startup_info.title_len );
+
         ret = !wine_server_call_err( req );
         process_info = reply->info;
     }
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",