Moved the fields that depends on startup info from the init_process
request to get_startup_info.
This commit is contained in:
parent
8c64ebc963
commit
01caa5e645
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
120
server/process.c
120
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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue