From 01caa5e645f8c6ea5c98601f379687e8d05b92e7 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 12 Jul 2005 20:27:09 +0000 Subject: [PATCH] Moved the fields that depends on startup info from the init_process request to get_startup_info. --- dlls/kernel/process.c | 71 ++++++++++--------- include/wine/server_protocol.h | 14 ++-- server/console.c | 1 + server/process.c | 120 +++++++++++++++------------------ server/process.h | 2 +- server/protocol.def | 12 ++-- server/trace.c | 14 ++-- 7 files changed, 115 insertions(+), 119 deletions(-) diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c index 739fadb37ce..a46aaf624e0 100644 --- a/dlls/kernel/process.c +++ b/dlls/kernel/process.c @@ -739,9 +739,11 @@ static void usage(void) */ static RTL_USER_PROCESS_PARAMETERS *init_user_process_params( size_t info_size ) { + BOOL ret; void *ptr; DWORD size, env_size; RTL_USER_PROCESS_PARAMETERS *params; + HANDLE hstdin, hstdout, hstderr; size = info_size; ptr = NULL; @@ -752,10 +754,23 @@ static RTL_USER_PROCESS_PARAMETERS *init_user_process_params( size_t info_size ) SERVER_START_REQ( get_startup_info ) { wine_server_set_reply( req, ptr, info_size ); - wine_server_call( req ); - info_size = wine_server_reply_size( reply ); + if ((ret = !wine_server_call( req ))) + { + info_size = wine_server_reply_size( reply ); + main_create_flags = reply->create_flags; + main_exe_file = reply->exe_file; + hstdin = reply->hstdin; + hstdout = reply->hstdout; + hstderr = reply->hstderr; + } } SERVER_END_REQ; + if (!ret) + { + size = 0; + NtFreeVirtualMemory( NtCurrentProcess(), &ptr, &size, MEM_RELEASE ); + return NULL; + } params = ptr; params->AllocationSize = size; @@ -781,6 +796,29 @@ static RTL_USER_PROCESS_PARAMETERS *init_user_process_params( size_t info_size ) memcpy( ptr, (char *)params + params->Size, info_size - params->Size ); params->Environment = ptr; + /* convert value from server: + * + 0 => INVALID_HANDLE_VALUE + * + console handle needs to be mapped + */ + if (!hstdin) + hstdin = INVALID_HANDLE_VALUE; + else if (VerifyConsoleIoHandle(console_handle_map(hstdin))) + hstdin = console_handle_map(hstdin); + + if (!hstdout) + hstdout = INVALID_HANDLE_VALUE; + else if (VerifyConsoleIoHandle(console_handle_map(hstdout))) + hstdout = console_handle_map(hstdout); + + if (!hstderr) + hstderr = INVALID_HANDLE_VALUE; + else if (VerifyConsoleIoHandle(console_handle_map(hstderr))) + hstderr = console_handle_map(hstderr); + + params->hStdInput = hstdin; + params->hStdOutput = hstdout; + params->hStdError = hstderr; + return RtlNormalizeProcessParams( params ); } @@ -910,7 +948,6 @@ static BOOL process_init(void) size_t info_size = 0; RTL_USER_PROCESS_PARAMETERS *params; PEB *peb = NtCurrentTeb()->Peb; - HANDLE hstdin, hstdout, hstderr; extern void __wine_dbg_kernel32_init(void); PTHREAD_Init(); @@ -928,13 +965,8 @@ static BOOL process_init(void) req->ldt_copy = &wine_ldt_copy; if ((ret = !wine_server_call_err( req ))) { - main_exe_file = reply->exe_file; - main_create_flags = reply->create_flags; info_size = reply->info_size; server_startticks = reply->server_start; - hstdin = reply->hstdin; - hstdout = reply->hstdout; - hstderr = reply->hstderr; } } SERVER_END_REQ; @@ -960,29 +992,6 @@ static BOOL process_init(void) { if (!(params = init_user_process_params( info_size ))) return FALSE; peb->ProcessParameters = params; - - /* convert value from server: - * + 0 => INVALID_HANDLE_VALUE - * + console handle need to be mapped - */ - if (!hstdin) - hstdin = INVALID_HANDLE_VALUE; - else if (VerifyConsoleIoHandle(console_handle_map(hstdin))) - hstdin = console_handle_map(hstdin); - - if (!hstdout) - hstdout = INVALID_HANDLE_VALUE; - else if (VerifyConsoleIoHandle(console_handle_map(hstdout))) - hstdout = console_handle_map(hstdout); - - if (!hstderr) - hstderr = INVALID_HANDLE_VALUE; - else if (VerifyConsoleIoHandle(console_handle_map(hstderr))) - hstderr = console_handle_map(hstderr); - - params->hStdInput = hstdin; - params->hStdOutput = hstdout; - params->hStdError = hstderr; } kernel32_handle = GetModuleHandleW(kernel32W); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 79fd0a98c06..9555889f76b 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -185,7 +185,7 @@ struct new_process_request { struct request_header __header; int inherit_all; - int create_flags; + unsigned int create_flags; int unix_pid; obj_handle_t exe_file; obj_handle_t hstdin; @@ -258,13 +258,8 @@ struct init_process_request struct init_process_reply { struct reply_header __header; - int create_flags; unsigned int server_start; size_t info_size; - obj_handle_t exe_file; - obj_handle_t hstdin; - obj_handle_t hstdout; - obj_handle_t hstderr; }; @@ -276,6 +271,11 @@ struct get_startup_info_request struct get_startup_info_reply { struct reply_header __header; + unsigned int create_flags; + obj_handle_t exe_file; + obj_handle_t hstdin; + obj_handle_t hstdout; + obj_handle_t hstderr; /* VARARG(info,startup_info); */ /* VARARG(env,unicode_str); */ }; @@ -4189,6 +4189,6 @@ union generic_reply struct set_mailslot_info_reply set_mailslot_info_reply; }; -#define SERVER_PROTOCOL_VERSION 182 +#define SERVER_PROTOCOL_VERSION 183 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/console.c b/server/console.c index 871a66ebb49..bbadc1b39e1 100644 --- a/server/console.c +++ b/server/console.c @@ -362,6 +362,7 @@ void inherit_console(struct thread *parent_thread, struct process *process, obj_ } release_object( console ); } + else clear_error(); /* ignore error */ } /* otherwise, if parent has a console, attach child to this console */ if (!done && parent->console) diff --git a/server/process.c b/server/process.c index 863c41588c8..ad3d7ec364c 100644 --- a/server/process.c +++ b/server/process.c @@ -92,7 +92,7 @@ struct startup_info struct object obj; /* object header */ struct list entry; /* entry in list of startup infos */ int inherit_all; /* inherit all handles from parent */ - int create_flags; /* creation flags */ + unsigned int create_flags; /* creation flags */ int unix_pid; /* Unix pid of new process */ obj_handle_t hstdin; /* handle for stdin */ obj_handle_t hstdout; /* handle for stdout */ @@ -219,43 +219,6 @@ static void set_process_startup_state( struct process *process, enum startup_sta } } -/* set the console and stdio handles for a newly created process */ -static int set_process_console( struct process *process, struct thread *parent_thread, - struct startup_info *info, struct init_process_reply *reply ) -{ - if (info) - { - if (!(process->create_flags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE))) - { - /* FIXME: some better error checking should be done... - * like if hConOut and hConIn are console handles, then they should be on the same - * physical console - */ - inherit_console( parent_thread, process, info->inherit_all ? info->hstdin : 0 ); - } - if (!info->inherit_all && !(process->create_flags & CREATE_NEW_CONSOLE)) - { - reply->hstdin = duplicate_handle( parent_thread->process, info->hstdin, process, - 0, TRUE, DUPLICATE_SAME_ACCESS ); - reply->hstdout = duplicate_handle( parent_thread->process, info->hstdout, process, - 0, TRUE, DUPLICATE_SAME_ACCESS ); - reply->hstderr = duplicate_handle( parent_thread->process, info->hstderr, process, - 0, TRUE, DUPLICATE_SAME_ACCESS ); - } - else - { - reply->hstdin = info->hstdin; - reply->hstdout = info->hstdout; - reply->hstderr = info->hstderr; - } - } - else reply->hstdin = reply->hstdout = reply->hstderr = 0; - /* some handles above may have been invalid; this is not an error */ - if (get_error() == STATUS_INVALID_HANDLE || - get_error() == STATUS_OBJECT_TYPE_MISMATCH) clear_error(); - return 1; -} - /* create a new process and its main thread */ struct thread *create_process( int fd ) { @@ -288,7 +251,6 @@ struct thread *create_process( int fd ) process->exe.dbg_size = 0; process->exe.namelen = 0; process->exe.filename = NULL; - process->group_id = 0; process->token = token_create_admin(); list_init( &process->thread_list ); list_init( &process->locks ); @@ -298,7 +260,7 @@ struct thread *create_process( int fd ) gettimeofday( &process->start_time, NULL ); list_add_head( &process_list, &process->entry ); - if (!(process->id = alloc_ptid( process ))) goto error; + if (!(process->id = process->group_id = alloc_ptid( process ))) goto error; if (!(process->msg_fd = create_anonymous_fd( &process_fd_ops, fd, &process->obj ))) goto error; /* create the main thread */ @@ -341,7 +303,7 @@ inline static struct startup_info *find_startup_info( int unix_pid ) } /* initialize the current process and fill in the request */ -static struct startup_info *init_process( struct init_process_reply *reply ) +static size_t init_process(void) { struct process *process = current->process; struct thread *parent_thread = NULL; @@ -353,7 +315,7 @@ static struct startup_info *init_process( struct init_process_reply *reply ) if (info->thread) { fatal_protocol_error( current, "init_process: called twice?\n" ); - return NULL; + return 0; } parent_thread = info->owner; parent = parent_thread->process; @@ -368,16 +330,10 @@ static struct startup_info *init_process( struct init_process_reply *reply ) process->handles = copy_handle_table( process, parent ); else process->handles = alloc_handle_table( process, 0 ); - if (!process->handles) return NULL; + if (!process->handles) return 0; /* retrieve the main exe file */ - reply->exe_file = 0; - if (info && info->exe_file) - { - process->exe.file = (struct file *)grab_object( info->exe_file ); - if (!(reply->exe_file = alloc_handle( process, process->exe.file, GENERIC_READ, 0 ))) - return NULL; - } + if (info && info->exe_file) process->exe.file = (struct file *)grab_object( info->exe_file ); /* connect to the window station and desktop */ connect_process_winstation( process, NULL, 0 ); @@ -385,9 +341,15 @@ static struct startup_info *init_process( struct init_process_reply *reply ) current->desktop = process->desktop; /* set the process console */ - if (!set_process_console( process, parent_thread, info, reply )) return NULL; + if (info && !(info->create_flags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE))) + { + /* FIXME: some better error checking should be done... + * like if hConOut and hConIn are console handles, then they should be on the same + * physical console + */ + inherit_console( parent_thread, process, info->inherit_all ? info->hstdin : 0 ); + } - process->group_id = get_process_id( process ); if (parent) { /* attach to the debugger if requested */ @@ -404,13 +366,12 @@ static struct startup_info *init_process( struct init_process_reply *reply ) if (info) { - reply->info_size = info->data_size; info->process = (struct process *)grab_object( process ); info->thread = (struct thread *)grab_object( current ); + process->startup_info = (struct startup_info *)grab_object( info ); + return info->data_size; } - reply->create_flags = process->create_flags; - reply->server_start = server_start_ticks; - return info ? (struct startup_info *)grab_object( info ) : NULL; + return 0; } /* destroy a process when its refcount is 0 */ @@ -965,18 +926,43 @@ DECL_HANDLER(get_new_process_info) /* Retrieve the new process startup info */ DECL_HANDLER(get_startup_info) { - struct startup_info *info; + struct process *process = current->process; + struct startup_info *info = process->startup_info; + size_t size; - if ((info = current->process->startup_info)) + if (!info) return; + + reply->create_flags = info->create_flags; + + if (info->exe_file && + !(reply->exe_file = alloc_handle( process, info->exe_file, GENERIC_READ, 0 ))) return; + + if (!info->inherit_all && !(info->create_flags & CREATE_NEW_CONSOLE)) { - size_t size = info->data_size; - if (size > get_reply_max_size()) size = get_reply_max_size(); - - /* we return the data directly without making a copy so this can only be called once */ - set_reply_data_ptr( info->data, size ); - info->data = NULL; - info->data_size = 0; + struct process *parent_process = info->owner->process; + reply->hstdin = duplicate_handle( parent_process, info->hstdin, process, + 0, TRUE, DUPLICATE_SAME_ACCESS ); + reply->hstdout = duplicate_handle( parent_process, info->hstdout, process, + 0, TRUE, DUPLICATE_SAME_ACCESS ); + reply->hstderr = duplicate_handle( parent_process, info->hstderr, process, + 0, TRUE, DUPLICATE_SAME_ACCESS ); + /* some handles above may have been invalid; this is not an error */ + if (get_error() == STATUS_INVALID_HANDLE || + get_error() == STATUS_OBJECT_TYPE_MISMATCH) clear_error(); } + else + { + reply->hstdin = info->hstdin; + reply->hstdout = info->hstdout; + reply->hstderr = info->hstderr; + } + + /* we return the data directly without making a copy so this can only be called once */ + size = info->data_size; + if (size > get_reply_max_size()) size = get_reply_max_size(); + set_reply_data_ptr( info->data, size ); + info->data = NULL; + info->data_size = 0; } @@ -1003,10 +989,10 @@ DECL_HANDLER(init_process) fatal_protocol_error( current, "init_process: bad ldt_copy address\n" ); return; } - reply->info_size = 0; current->process->peb = req->peb; current->process->ldt_copy = req->ldt_copy; - current->process->startup_info = init_process( reply ); + reply->server_start = server_start_ticks; + reply->info_size = init_process(); } /* signal the end of the process initialization */ diff --git a/server/process.h b/server/process.h index 3949bc48564..359b33a784b 100644 --- a/server/process.h +++ b/server/process.h @@ -64,7 +64,7 @@ struct process int priority; /* priority class */ int affinity; /* process affinity mask */ int suspend; /* global process suspend count */ - int create_flags; /* process creation flags */ + unsigned int create_flags; /* process creation flags */ struct list locks; /* list of file locks owned by the process */ struct list classes; /* window classes owned by the process */ struct console_input*console; /* console input */ diff --git a/server/protocol.def b/server/protocol.def index a2e558fe31b..4d6ed4d413f 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -199,7 +199,7 @@ struct security_descriptor /* Create a new process from the context of the parent */ @REQ(new_process) int inherit_all; /* inherit all handles from parent */ - int create_flags; /* creation flags */ + unsigned int create_flags; /* creation flags */ int unix_pid; /* Unix pid of new process */ obj_handle_t exe_file; /* file handle for main exe */ obj_handle_t hstdin; /* handle for stdin */ @@ -248,19 +248,19 @@ struct security_descriptor void* peb; /* addr of PEB */ void* ldt_copy; /* addr of LDT copy */ @REPLY - int create_flags; /* creation flags */ unsigned int server_start; /* server start time (GetTickCount) */ size_t info_size; /* total size of startup info */ - obj_handle_t exe_file; /* file handle for main exe */ - obj_handle_t hstdin; /* handle for stdin */ - obj_handle_t hstdout; /* handle for stdout */ - obj_handle_t hstderr; /* handle for stderr */ @END /* Retrieve the new process startup info */ @REQ(get_startup_info) @REPLY + unsigned int create_flags; /* creation flags */ + obj_handle_t exe_file; /* file handle for main exe */ + obj_handle_t hstdin; /* handle for stdin */ + obj_handle_t hstdout; /* handle for stdout */ + obj_handle_t hstderr; /* handle for stderr */ VARARG(info,startup_info); /* startup information */ VARARG(env,unicode_str); /* environment */ @END diff --git a/server/trace.c b/server/trace.c index b2844334650..c9edc518ad1 100644 --- a/server/trace.c +++ b/server/trace.c @@ -559,7 +559,7 @@ typedef void (*dump_func)( const void *req ); static void dump_new_process_request( const struct new_process_request *req ) { fprintf( stderr, " inherit_all=%d,", req->inherit_all ); - fprintf( stderr, " create_flags=%d,", req->create_flags ); + fprintf( stderr, " create_flags=%08x,", req->create_flags ); fprintf( stderr, " unix_pid=%d,", req->unix_pid ); fprintf( stderr, " exe_file=%p,", req->exe_file ); fprintf( stderr, " hstdin=%p,", req->hstdin ); @@ -619,13 +619,8 @@ static void dump_init_process_request( const struct init_process_request *req ) static void dump_init_process_reply( const struct init_process_reply *req ) { - fprintf( stderr, " create_flags=%d,", req->create_flags ); fprintf( stderr, " server_start=%08x,", req->server_start ); - fprintf( stderr, " info_size=%d,", req->info_size ); - fprintf( stderr, " exe_file=%p,", req->exe_file ); - fprintf( stderr, " hstdin=%p,", req->hstdin ); - fprintf( stderr, " hstdout=%p,", req->hstdout ); - fprintf( stderr, " hstderr=%p", req->hstderr ); + fprintf( stderr, " info_size=%d", req->info_size ); } static void dump_get_startup_info_request( const struct get_startup_info_request *req ) @@ -634,6 +629,11 @@ static void dump_get_startup_info_request( const struct get_startup_info_request static void dump_get_startup_info_reply( const struct get_startup_info_reply *req ) { + fprintf( stderr, " create_flags=%08x,", req->create_flags ); + fprintf( stderr, " exe_file=%p,", req->exe_file ); + fprintf( stderr, " hstdin=%p,", req->hstdin ); + fprintf( stderr, " hstdout=%p,", req->hstdout ); + fprintf( stderr, " hstderr=%p,", req->hstderr ); fprintf( stderr, " info=" ); dump_varargs_startup_info( cur_size ); fputc( ',', stderr );