Commit 0424f381 authored by Alexandre Julliard's avatar Alexandre Julliard

Already initialize the process in the first init_thread request

instead of waiting for the init_process request.
parent c976db1a
...@@ -961,8 +961,6 @@ static BOOL process_init(void) ...@@ -961,8 +961,6 @@ static BOOL process_init(void)
/* Retrieve startup info from the server */ /* Retrieve startup info from the server */
SERVER_START_REQ( init_process ) SERVER_START_REQ( init_process )
{ {
req->peb = peb;
req->ldt_copy = &wine_ldt_copy;
if ((ret = !wine_server_call_err( req ))) if ((ret = !wine_server_call_err( req )))
{ {
info_size = reply->info_size; info_size = reply->info_size;
......
...@@ -909,9 +909,12 @@ void server_init_thread( int unix_pid, int unix_tid, void *entry_point ) ...@@ -909,9 +909,12 @@ void server_init_thread( int unix_pid, int unix_tid, void *entry_point )
req->unix_pid = unix_pid; req->unix_pid = unix_pid;
req->unix_tid = unix_tid; req->unix_tid = unix_tid;
req->teb = NtCurrentTeb(); req->teb = NtCurrentTeb();
req->peb = NtCurrentTeb()->Peb;
req->entry = entry_point; req->entry = entry_point;
req->ldt_copy = &wine_ldt_copy;
req->reply_fd = reply_pipe[1]; req->reply_fd = reply_pipe[1];
req->wait_fd = ntdll_get_thread_data()->wait_fd[1]; req->wait_fd = ntdll_get_thread_data()->wait_fd[1];
req->debug_level = (TRACE_ON(server) != 0);
ret = wine_server_call( req ); ret = wine_server_call( req );
NtCurrentTeb()->ClientId.UniqueProcess = (HANDLE)reply->pid; NtCurrentTeb()->ClientId.UniqueProcess = (HANDLE)reply->pid;
NtCurrentTeb()->ClientId.UniqueThread = (HANDLE)reply->tid; NtCurrentTeb()->ClientId.UniqueThread = (HANDLE)reply->tid;
......
...@@ -252,8 +252,6 @@ struct boot_done_reply ...@@ -252,8 +252,6 @@ struct boot_done_reply
struct init_process_request struct init_process_request
{ {
struct request_header __header; struct request_header __header;
void* peb;
void* ldt_copy;
}; };
struct init_process_reply struct init_process_reply
{ {
...@@ -306,16 +304,18 @@ struct init_thread_request ...@@ -306,16 +304,18 @@ struct init_thread_request
int unix_pid; int unix_pid;
int unix_tid; int unix_tid;
void* teb; void* teb;
void* peb;
void* entry; void* entry;
void* ldt_copy;
int reply_fd; int reply_fd;
int wait_fd; int wait_fd;
int debug_level;
}; };
struct init_thread_reply struct init_thread_reply
{ {
struct reply_header __header; struct reply_header __header;
process_id_t pid; process_id_t pid;
thread_id_t tid; thread_id_t tid;
int boot;
int version; int version;
}; };
...@@ -4189,6 +4189,6 @@ union generic_reply ...@@ -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 183 #define SERVER_PROTOCOL_VERSION 184
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -303,45 +303,56 @@ inline static struct startup_info *find_startup_info( int unix_pid ) ...@@ -303,45 +303,56 @@ 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 size_t init_process(void) void init_process( struct thread *thread )
{ {
struct process *process = current->process; struct process *process = thread->process;
struct thread *parent_thread = NULL; struct thread *parent_thread = NULL;
struct process *parent = NULL; struct process *parent = NULL;
struct startup_info *info = find_startup_info( current->unix_pid ); struct startup_info *info;
if (process->startup_info) return; /* already initialized */
if (info) if ((info = find_startup_info( thread->unix_pid )))
{ {
if (info->thread) if (info->thread) return; /* already initialized */
{
fatal_protocol_error( current, "init_process: called twice?\n" ); info->thread = (struct thread *)grab_object( thread );
return 0; info->process = (struct process *)grab_object( process );
} process->startup_info = (struct startup_info *)grab_object( info );
parent_thread = info->owner; parent_thread = info->owner;
parent = parent_thread->process; parent = parent_thread->process;
process->parent = (struct process *)grab_object( parent ); process->parent = (struct process *)grab_object( parent );
}
/* set the process flags */ /* set the process flags */
process->create_flags = info ? info->create_flags : 0; process->create_flags = info->create_flags;
/* create the handle table */ if (info->inherit_all) process->handles = copy_handle_table( process, parent );
if (info && info->inherit_all) }
process->handles = copy_handle_table( process, parent );
else
process->handles = alloc_handle_table( process, 0 );
if (!process->handles) return 0;
/* retrieve the main exe file */ /* create the handle table */
if (info && info->exe_file) process->exe.file = (struct file *)grab_object( info->exe_file ); if (!process->handles) process->handles = alloc_handle_table( process, 0 );
if (!process->handles)
{
fatal_protocol_error( thread, "Failed to allocate handle table\n" );
return;
}
/* 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 );
connect_process_desktop( process, NULL, 0 ); connect_process_desktop( process, NULL, 0 );
current->desktop = process->desktop; thread->desktop = process->desktop;
if (!info) return;
/* retrieve the main exe file */
if (info->exe_file) process->exe.file = (struct file *)grab_object( info->exe_file );
/* thread will be actually suspended in init_done */
if (info->create_flags & CREATE_SUSPENDED) thread->suspend++;
/* set the process console */ /* set the process console */
if (info && !(info->create_flags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE))) if (!(info->create_flags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)))
{ {
/* FIXME: some better error checking should be done... /* FIXME: some better error checking should be done...
* like if hConOut and hConIn are console handles, then they should be on the same * like if hConOut and hConIn are console handles, then they should be on the same
...@@ -350,28 +361,14 @@ static size_t init_process(void) ...@@ -350,28 +361,14 @@ static size_t init_process(void)
inherit_console( parent_thread, process, info->inherit_all ? info->hstdin : 0 ); inherit_console( parent_thread, process, info->inherit_all ? info->hstdin : 0 );
} }
if (parent) /* attach to the debugger if requested */
{ if (process->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
/* attach to the debugger if requested */ set_process_debugger( process, parent_thread );
if (process->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) else if (parent->debugger && !(parent->create_flags & DEBUG_ONLY_THIS_PROCESS))
set_process_debugger( process, parent_thread ); set_process_debugger( process, parent->debugger );
else if (parent->debugger && !(parent->create_flags & DEBUG_ONLY_THIS_PROCESS))
set_process_debugger( process, parent->debugger );
if (!(process->create_flags & CREATE_NEW_PROCESS_GROUP))
process->group_id = parent->group_id;
}
/* thread will be actually suspended in init_done */
if (process->create_flags & CREATE_SUSPENDED) current->suspend++;
if (info) if (!(process->create_flags & CREATE_NEW_PROCESS_GROUP))
{ process->group_id = parent->group_id;
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;
}
return 0;
} }
/* destroy a process when its refcount is 0 */ /* destroy a process when its refcount is 0 */
...@@ -969,30 +966,9 @@ DECL_HANDLER(get_startup_info) ...@@ -969,30 +966,9 @@ DECL_HANDLER(get_startup_info)
/* initialize a new process */ /* initialize a new process */
DECL_HANDLER(init_process) DECL_HANDLER(init_process)
{ {
if (current->unix_pid == -1)
{
fatal_protocol_error( current, "init_process: init_thread not called yet\n" );
return;
}
if (current->process->startup_info)
{
fatal_protocol_error( current, "init_process: called twice\n" );
return;
}
if (!req->peb || (unsigned int)req->peb % sizeof(int))
{
fatal_protocol_error( current, "init_process: bad peb address\n" );
return;
}
if (!req->ldt_copy || (unsigned int)req->ldt_copy % sizeof(int))
{
fatal_protocol_error( current, "init_process: bad ldt_copy address\n" );
return;
}
current->process->peb = req->peb;
current->process->ldt_copy = req->ldt_copy;
reply->server_start = server_start_ticks; reply->server_start = server_start_ticks;
reply->info_size = init_process(); if (current->process->startup_info)
reply->info_size = current->process->startup_info->data_size;
} }
/* signal the end of the process initialization */ /* signal the end of the process initialization */
......
...@@ -104,6 +104,7 @@ extern unsigned int alloc_ptid( void *ptr ); ...@@ -104,6 +104,7 @@ extern unsigned int alloc_ptid( void *ptr );
extern void free_ptid( unsigned int id ); extern void free_ptid( unsigned int id );
extern void *get_ptid_entry( unsigned int id ); extern void *get_ptid_entry( unsigned int id );
extern struct thread *create_process( int fd ); extern struct thread *create_process( int fd );
extern void init_process( struct thread *thread );
extern struct thread *get_process_first_thread( struct process *process ); extern struct thread *get_process_first_thread( struct process *process );
extern struct process *get_process_from_id( process_id_t id ); extern struct process *get_process_from_id( process_id_t id );
extern struct process *get_process_from_handle( obj_handle_t handle, unsigned int access ); extern struct process *get_process_from_handle( obj_handle_t handle, unsigned int access );
......
...@@ -245,8 +245,6 @@ struct security_descriptor ...@@ -245,8 +245,6 @@ struct security_descriptor
/* Initialize a process; called from the new process context */ /* Initialize a process; called from the new process context */
@REQ(init_process) @REQ(init_process)
void* peb; /* addr of PEB */
void* ldt_copy; /* addr of LDT copy */
@REPLY @REPLY
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 */
...@@ -283,13 +281,15 @@ struct security_descriptor ...@@ -283,13 +281,15 @@ struct security_descriptor
int unix_pid; /* Unix pid of new thread */ int unix_pid; /* Unix pid of new thread */
int unix_tid; /* Unix tid of new thread */ int unix_tid; /* Unix tid of new thread */
void* teb; /* TEB of new thread (in thread address space) */ void* teb; /* TEB of new thread (in thread address space) */
void* peb; /* address of PEB (in thread address space) */
void* entry; /* thread entry point (in thread address space) */ void* entry; /* thread entry point (in thread address space) */
void* ldt_copy; /* address of LDT copy (in thread address space) */
int reply_fd; /* fd for reply pipe */ int reply_fd; /* fd for reply pipe */
int wait_fd; /* fd for blocking calls pipe */ int wait_fd; /* fd for blocking calls pipe */
int debug_level; /* new debug level */
@REPLY @REPLY
process_id_t pid; /* process id of the new thread's process */ process_id_t pid; /* process id of the new thread's process */
thread_id_t tid; /* thread id of the new thread */ thread_id_t tid; /* thread id of the new thread */
int boot; /* is this the boot thread? */
int version; /* protocol version */ int version; /* protocol version */
@END @END
......
...@@ -150,6 +150,12 @@ inline static void init_thread_structure( struct thread *thread ) ...@@ -150,6 +150,12 @@ inline static void init_thread_structure( struct thread *thread )
thread->inflight[i].server = thread->inflight[i].client = -1; thread->inflight[i].server = thread->inflight[i].client = -1;
} }
/* check if address looks valid for a client-side data structure (TEB etc.) */
static inline int is_valid_address( void *addr )
{
return addr && !((unsigned int)addr % sizeof(int));
}
/* create a new thread */ /* create a new thread */
struct thread *create_thread( int fd, struct process *process ) struct thread *create_thread( int fd, struct process *process )
{ {
...@@ -814,7 +820,6 @@ struct token *thread_get_impersonation_token( struct thread *thread ) ...@@ -814,7 +820,6 @@ struct token *thread_get_impersonation_token( struct thread *thread )
/* signal that we are finished booting on the client side */ /* signal that we are finished booting on the client side */
DECL_HANDLER(boot_done) DECL_HANDLER(boot_done)
{ {
debug_level = max( debug_level, req->debug_level );
if (current == booting_thread) if (current == booting_thread)
{ {
booting_thread = (struct thread *)~0UL; /* make sure it doesn't match other threads */ booting_thread = (struct thread *)~0UL; /* make sure it doesn't match other threads */
...@@ -852,6 +857,7 @@ DECL_HANDLER(new_thread) ...@@ -852,6 +857,7 @@ DECL_HANDLER(new_thread)
/* initialize a new thread */ /* initialize a new thread */
DECL_HANDLER(init_thread) DECL_HANDLER(init_thread)
{ {
struct process *process = current->process;
int reply_fd = thread_get_inflight_fd( current, req->reply_fd ); int reply_fd = thread_get_inflight_fd( current, req->reply_fd );
int wait_fd = thread_get_inflight_fd( current, req->wait_fd ); int wait_fd = thread_get_inflight_fd( current, req->wait_fd );
...@@ -879,17 +885,31 @@ DECL_HANDLER(init_thread) ...@@ -879,17 +885,31 @@ DECL_HANDLER(init_thread)
if (!(current->wait_fd = create_anonymous_fd( &thread_fd_ops, wait_fd, &current->obj ))) if (!(current->wait_fd = create_anonymous_fd( &thread_fd_ops, wait_fd, &current->obj )))
return; return;
if (!is_valid_address(req->teb) || !is_valid_address(req->peb) || !is_valid_address(req->ldt_copy))
{
set_error( STATUS_INVALID_PARAMETER );
return;
}
current->unix_pid = req->unix_pid; current->unix_pid = req->unix_pid;
current->unix_tid = req->unix_tid; current->unix_tid = req->unix_tid;
current->teb = req->teb; current->teb = req->teb;
if (current->suspend + current->process->suspend > 0) stop_thread( current ); if (!process->peb) /* first thread, initialize the process too */
if (current->process->running_threads > 1) {
process->peb = req->peb;
process->ldt_copy = req->ldt_copy;
init_process( current );
}
else
{
if (current->suspend + process->suspend > 0) stop_thread( current );
generate_debug_event( current, CREATE_THREAD_DEBUG_EVENT, req->entry ); generate_debug_event( current, CREATE_THREAD_DEBUG_EVENT, req->entry );
}
debug_level = max( debug_level, req->debug_level );
reply->pid = get_process_id( current->process ); reply->pid = get_process_id( process );
reply->tid = get_thread_id( current ); reply->tid = get_thread_id( current );
reply->boot = (current == booting_thread);
reply->version = SERVER_PROTOCOL_VERSION; reply->version = SERVER_PROTOCOL_VERSION;
return; return;
......
...@@ -613,8 +613,6 @@ static void dump_boot_done_request( const struct boot_done_request *req ) ...@@ -613,8 +613,6 @@ static void dump_boot_done_request( const struct boot_done_request *req )
static void dump_init_process_request( const struct init_process_request *req ) static void dump_init_process_request( const struct init_process_request *req )
{ {
fprintf( stderr, " peb=%p,", req->peb );
fprintf( stderr, " ldt_copy=%p", req->ldt_copy );
} }
static void dump_init_process_reply( const struct init_process_reply *req ) static void dump_init_process_reply( const struct init_process_reply *req )
...@@ -658,16 +656,18 @@ static void dump_init_thread_request( const struct init_thread_request *req ) ...@@ -658,16 +656,18 @@ static void dump_init_thread_request( const struct init_thread_request *req )
fprintf( stderr, " unix_pid=%d,", req->unix_pid ); fprintf( stderr, " unix_pid=%d,", req->unix_pid );
fprintf( stderr, " unix_tid=%d,", req->unix_tid ); fprintf( stderr, " unix_tid=%d,", req->unix_tid );
fprintf( stderr, " teb=%p,", req->teb ); fprintf( stderr, " teb=%p,", req->teb );
fprintf( stderr, " peb=%p,", req->peb );
fprintf( stderr, " entry=%p,", req->entry ); fprintf( stderr, " entry=%p,", req->entry );
fprintf( stderr, " ldt_copy=%p,", req->ldt_copy );
fprintf( stderr, " reply_fd=%d,", req->reply_fd ); fprintf( stderr, " reply_fd=%d,", req->reply_fd );
fprintf( stderr, " wait_fd=%d", req->wait_fd ); fprintf( stderr, " wait_fd=%d,", req->wait_fd );
fprintf( stderr, " debug_level=%d", req->debug_level );
} }
static void dump_init_thread_reply( const struct init_thread_reply *req ) static void dump_init_thread_reply( const struct init_thread_reply *req )
{ {
fprintf( stderr, " pid=%04x,", req->pid ); fprintf( stderr, " pid=%04x,", req->pid );
fprintf( stderr, " tid=%04x,", req->tid ); fprintf( stderr, " tid=%04x,", req->tid );
fprintf( stderr, " boot=%d,", req->boot );
fprintf( stderr, " version=%d", req->version ); fprintf( stderr, " version=%d", req->version );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment