Moved the fields that depends on startup info from the init_process

request to get_startup_info.
This commit is contained in:
Alexandre Julliard 2005-07-12 20:27:09 +00:00
parent 8c64ebc963
commit 01caa5e645
7 changed files with 115 additions and 119 deletions

View File

@ -739,9 +739,11 @@ static void usage(void)
*/ */
static RTL_USER_PROCESS_PARAMETERS *init_user_process_params( size_t info_size ) static RTL_USER_PROCESS_PARAMETERS *init_user_process_params( size_t info_size )
{ {
BOOL ret;
void *ptr; void *ptr;
DWORD size, env_size; DWORD size, env_size;
RTL_USER_PROCESS_PARAMETERS *params; RTL_USER_PROCESS_PARAMETERS *params;
HANDLE hstdin, hstdout, hstderr;
size = info_size; size = info_size;
ptr = NULL; 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 ) SERVER_START_REQ( get_startup_info )
{ {
wine_server_set_reply( req, ptr, info_size ); wine_server_set_reply( req, ptr, info_size );
wine_server_call( req ); if ((ret = !wine_server_call( req )))
info_size = wine_server_reply_size( reply ); {
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; SERVER_END_REQ;
if (!ret)
{
size = 0;
NtFreeVirtualMemory( NtCurrentProcess(), &ptr, &size, MEM_RELEASE );
return NULL;
}
params = ptr; params = ptr;
params->AllocationSize = size; 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 ); memcpy( ptr, (char *)params + params->Size, info_size - params->Size );
params->Environment = ptr; 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 ); return RtlNormalizeProcessParams( params );
} }
@ -910,7 +948,6 @@ static BOOL process_init(void)
size_t info_size = 0; size_t info_size = 0;
RTL_USER_PROCESS_PARAMETERS *params; RTL_USER_PROCESS_PARAMETERS *params;
PEB *peb = NtCurrentTeb()->Peb; PEB *peb = NtCurrentTeb()->Peb;
HANDLE hstdin, hstdout, hstderr;
extern void __wine_dbg_kernel32_init(void); extern void __wine_dbg_kernel32_init(void);
PTHREAD_Init(); PTHREAD_Init();
@ -928,13 +965,8 @@ static BOOL process_init(void)
req->ldt_copy = &wine_ldt_copy; req->ldt_copy = &wine_ldt_copy;
if ((ret = !wine_server_call_err( req ))) if ((ret = !wine_server_call_err( req )))
{ {
main_exe_file = reply->exe_file;
main_create_flags = reply->create_flags;
info_size = reply->info_size; info_size = reply->info_size;
server_startticks = reply->server_start; server_startticks = reply->server_start;
hstdin = reply->hstdin;
hstdout = reply->hstdout;
hstderr = reply->hstderr;
} }
} }
SERVER_END_REQ; SERVER_END_REQ;
@ -960,29 +992,6 @@ static BOOL process_init(void)
{ {
if (!(params = init_user_process_params( info_size ))) return FALSE; if (!(params = init_user_process_params( info_size ))) return FALSE;
peb->ProcessParameters = params; 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); kernel32_handle = GetModuleHandleW(kernel32W);

View File

@ -185,7 +185,7 @@ struct new_process_request
{ {
struct request_header __header; struct request_header __header;
int inherit_all; int inherit_all;
int create_flags; unsigned int create_flags;
int unix_pid; int unix_pid;
obj_handle_t exe_file; obj_handle_t exe_file;
obj_handle_t hstdin; obj_handle_t hstdin;
@ -258,13 +258,8 @@ struct init_process_request
struct init_process_reply struct init_process_reply
{ {
struct reply_header __header; struct reply_header __header;
int create_flags;
unsigned int server_start; unsigned int server_start;
size_t info_size; 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 get_startup_info_reply
{ {
struct reply_header __header; 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(info,startup_info); */
/* VARARG(env,unicode_str); */ /* VARARG(env,unicode_str); */
}; };
@ -4189,6 +4189,6 @@ union generic_reply
struct set_mailslot_info_reply set_mailslot_info_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 */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -362,6 +362,7 @@ void inherit_console(struct thread *parent_thread, struct process *process, obj_
} }
release_object( console ); release_object( console );
} }
else clear_error(); /* ignore error */
} }
/* otherwise, if parent has a console, attach child to this console */ /* otherwise, if parent has a console, attach child to this console */
if (!done && parent->console) if (!done && parent->console)

View File

@ -92,7 +92,7 @@ struct startup_info
struct object obj; /* object header */ struct object obj; /* object header */
struct list entry; /* entry in list of startup infos */ struct list entry; /* entry in list of startup infos */
int inherit_all; /* inherit all handles from parent */ 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 */ int unix_pid; /* Unix pid of new process */
obj_handle_t hstdin; /* handle for stdin */ obj_handle_t hstdin; /* handle for stdin */
obj_handle_t hstdout; /* handle for stdout */ 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 */ /* create a new process and its main thread */
struct thread *create_process( int fd ) struct thread *create_process( int fd )
{ {
@ -288,7 +251,6 @@ struct thread *create_process( int fd )
process->exe.dbg_size = 0; process->exe.dbg_size = 0;
process->exe.namelen = 0; process->exe.namelen = 0;
process->exe.filename = NULL; process->exe.filename = NULL;
process->group_id = 0;
process->token = token_create_admin(); process->token = token_create_admin();
list_init( &process->thread_list ); list_init( &process->thread_list );
list_init( &process->locks ); list_init( &process->locks );
@ -298,7 +260,7 @@ struct thread *create_process( int fd )
gettimeofday( &process->start_time, NULL ); gettimeofday( &process->start_time, NULL );
list_add_head( &process_list, &process->entry ); 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; if (!(process->msg_fd = create_anonymous_fd( &process_fd_ops, fd, &process->obj ))) goto error;
/* create the main thread */ /* 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 */ /* 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 process *process = current->process;
struct thread *parent_thread = NULL; struct thread *parent_thread = NULL;
@ -353,7 +315,7 @@ static struct startup_info *init_process( struct init_process_reply *reply )
if (info->thread) if (info->thread)
{ {
fatal_protocol_error( current, "init_process: called twice?\n" ); fatal_protocol_error( current, "init_process: called twice?\n" );
return NULL; return 0;
} }
parent_thread = info->owner; parent_thread = info->owner;
parent = parent_thread->process; 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 ); process->handles = copy_handle_table( process, parent );
else else
process->handles = alloc_handle_table( process, 0 ); process->handles = alloc_handle_table( process, 0 );
if (!process->handles) return NULL; if (!process->handles) return 0;
/* retrieve the main exe file */ /* 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 (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;
}
/* connect to the window station and desktop */ /* connect to the window station and desktop */
connect_process_winstation( process, NULL, 0 ); 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; current->desktop = process->desktop;
/* set the process console */ /* 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) if (parent)
{ {
/* attach to the debugger if requested */ /* attach to the debugger if requested */
@ -404,13 +366,12 @@ static struct startup_info *init_process( struct init_process_reply *reply )
if (info) if (info)
{ {
reply->info_size = info->data_size;
info->process = (struct process *)grab_object( process ); info->process = (struct process *)grab_object( process );
info->thread = (struct thread *)grab_object( current ); 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; return 0;
reply->server_start = server_start_ticks;
return info ? (struct startup_info *)grab_object( info ) : NULL;
} }
/* destroy a process when its refcount is 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 */ /* Retrieve the new process startup info */
DECL_HANDLER(get_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; struct process *parent_process = info->owner->process;
if (size > get_reply_max_size()) size = get_reply_max_size(); reply->hstdin = duplicate_handle( parent_process, info->hstdin, process,
0, TRUE, DUPLICATE_SAME_ACCESS );
/* we return the data directly without making a copy so this can only be called once */ reply->hstdout = duplicate_handle( parent_process, info->hstdout, process,
set_reply_data_ptr( info->data, size ); 0, TRUE, DUPLICATE_SAME_ACCESS );
info->data = NULL; reply->hstderr = duplicate_handle( parent_process, info->hstderr, process,
info->data_size = 0; 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" ); fatal_protocol_error( current, "init_process: bad ldt_copy address\n" );
return; return;
} }
reply->info_size = 0;
current->process->peb = req->peb; current->process->peb = req->peb;
current->process->ldt_copy = req->ldt_copy; 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 */ /* signal the end of the process initialization */

View File

@ -64,7 +64,7 @@ struct process
int priority; /* priority class */ int priority; /* priority class */
int affinity; /* process affinity mask */ int affinity; /* process affinity mask */
int suspend; /* global process suspend count */ 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 locks; /* list of file locks owned by the process */
struct list classes; /* window classes owned by the process */ struct list classes; /* window classes owned by the process */
struct console_input*console; /* console input */ struct console_input*console; /* console input */

View File

@ -199,7 +199,7 @@ struct security_descriptor
/* Create a new process from the context of the parent */ /* Create a new process from the context of the parent */
@REQ(new_process) @REQ(new_process)
int inherit_all; /* inherit all handles from parent */ 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 */ int unix_pid; /* Unix pid of new process */
obj_handle_t exe_file; /* file handle for main exe */ obj_handle_t exe_file; /* file handle for main exe */
obj_handle_t hstdin; /* handle for stdin */ obj_handle_t hstdin; /* handle for stdin */
@ -248,19 +248,19 @@ struct security_descriptor
void* peb; /* addr of PEB */ void* peb; /* addr of PEB */
void* ldt_copy; /* addr of LDT copy */ void* ldt_copy; /* addr of LDT copy */
@REPLY @REPLY
int create_flags; /* creation flags */
unsigned int server_start; /* server start time (GetTickCount) */ unsigned int server_start; /* server start time (GetTickCount) */
size_t info_size; /* total size of startup info */ 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 @END
/* Retrieve the new process startup info */ /* Retrieve the new process startup info */
@REQ(get_startup_info) @REQ(get_startup_info)
@REPLY @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(info,startup_info); /* startup information */
VARARG(env,unicode_str); /* environment */ VARARG(env,unicode_str); /* environment */
@END @END

View File

@ -559,7 +559,7 @@ typedef void (*dump_func)( const void *req );
static void dump_new_process_request( const struct new_process_request *req ) static void dump_new_process_request( const struct new_process_request *req )
{ {
fprintf( stderr, " inherit_all=%d,", req->inherit_all ); 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, " unix_pid=%d,", req->unix_pid );
fprintf( stderr, " exe_file=%p,", req->exe_file ); fprintf( stderr, " exe_file=%p,", req->exe_file );
fprintf( stderr, " hstdin=%p,", req->hstdin ); 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 ) 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, " server_start=%08x,", req->server_start );
fprintf( stderr, " info_size=%d,", req->info_size ); 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 );
} }
static void dump_get_startup_info_request( const struct get_startup_info_request *req ) 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 ) 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=" ); fprintf( stderr, " info=" );
dump_varargs_startup_info( cur_size ); dump_varargs_startup_info( cur_size );
fputc( ',', stderr ); fputc( ',', stderr );