diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c index 7da3a27b82..a05804cdb5 100644 --- a/dlls/kernel/process.c +++ b/dlls/kernel/process.c @@ -736,23 +736,18 @@ static void usage(void) * * Fill the RTL_USER_PROCESS_PARAMETERS structure from the server. */ -static RTL_USER_PROCESS_PARAMETERS *init_user_process_params( size_t info_size ) +static BOOL init_user_process_params( RTL_USER_PROCESS_PARAMETERS *params ) { BOOL ret; void *ptr; - DWORD size, env_size; - RTL_USER_PROCESS_PARAMETERS *params; + DWORD size, env_size, info_size; HANDLE hstdin, hstdout, hstderr; - size = info_size; - ptr = NULL; - if (NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &size, - MEM_COMMIT, PAGE_READWRITE ) != STATUS_SUCCESS) - return NULL; + size = info_size = params->AllocationSize; SERVER_START_REQ( get_startup_info ) { - wine_server_set_reply( req, ptr, info_size ); + wine_server_set_reply( req, params, size ); if ((ret = !wine_server_call( req ))) { info_size = wine_server_reply_size( reply ); @@ -764,14 +759,8 @@ static RTL_USER_PROCESS_PARAMETERS *init_user_process_params( size_t info_size ) } } SERVER_END_REQ; - if (!ret) - { - size = 0; - NtFreeVirtualMemory( NtCurrentProcess(), &ptr, &size, MEM_RELEASE ); - return NULL; - } + if (!ret) return ret; - params = ptr; params->AllocationSize = size; if (params->Size > info_size) params->Size = info_size; @@ -791,7 +780,7 @@ static RTL_USER_PROCESS_PARAMETERS *init_user_process_params( size_t info_size ) ptr = NULL; if (NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &env_size, MEM_COMMIT, PAGE_READWRITE ) != STATUS_SUCCESS) - return NULL; + return FALSE; memcpy( ptr, (char *)params + params->Size, info_size - params->Size ); params->Environment = ptr; @@ -818,7 +807,8 @@ static RTL_USER_PROCESS_PARAMETERS *init_user_process_params( size_t info_size ) params->hStdOutput = hstdout; params->hStdError = hstderr; - return RtlNormalizeProcessParams( params ); + RtlNormalizeProcessParams( params ); + return TRUE; } @@ -944,9 +934,8 @@ static BOOL process_init(void) { static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2',0}; BOOL ret; - size_t info_size = 0; - RTL_USER_PROCESS_PARAMETERS *params; PEB *peb = NtCurrentTeb()->Peb; + RTL_USER_PROCESS_PARAMETERS *params = peb->ProcessParameters; extern void __wine_dbg_kernel32_init(void); PTHREAD_Init(); @@ -962,17 +951,14 @@ static BOOL process_init(void) { if ((ret = !wine_server_call_err( req ))) { - info_size = reply->info_size; server_startticks = reply->server_start; } } SERVER_END_REQ; if (!ret) return FALSE; - if (info_size == 0) + if (!params->AllocationSize) { - params = peb->ProcessParameters; - /* This is wine specific: we have no parent (we're started from unix) * so, create a simple console with bare handles to unix stdio * input & output streams (aka simple console) @@ -985,17 +971,13 @@ static BOOL process_init(void) params->CurrentDirectory.DosPath.MaximumLength = RtlGetLongestNtPathLength() * sizeof(WCHAR); params->CurrentDirectory.DosPath.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, params->CurrentDirectory.DosPath.MaximumLength); } - else - { - if (!(params = init_user_process_params( info_size ))) return FALSE; - peb->ProcessParameters = params; - } + else if (!init_user_process_params( params )) return FALSE; kernel32_handle = GetModuleHandleW(kernel32W); LOCALE_Init(); - if (!info_size) + if (!params->AllocationSize) { /* Copy the parent environment */ if (!build_initial_environment( __wine_main_environ )) return FALSE; diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 228cb94e9c..25886cb397 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -2126,9 +2126,22 @@ void __wine_process_init( int argc, char *argv[] ) NTSTATUS status; ANSI_STRING func_name; void (* DECLSPEC_NORETURN init_func)(); + ULONG info_size; extern mode_t FILE_umask; - thread_init(); + info_size = thread_init(); + + if (info_size) + { + RTL_USER_PROCESS_PARAMETERS *params = NULL; + + if (NtAllocateVirtualMemory( NtCurrentProcess(), (void **)¶ms, 0, &info_size, + MEM_COMMIT, PAGE_READWRITE ) == STATUS_SUCCESS) + { + params->AllocationSize = info_size; + NtCurrentTeb()->Peb->ProcessParameters = params; + } + } /* retrieve current umask */ FILE_umask = umask(0777); diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 99b59cbb1f..63c76da7f4 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -48,12 +48,12 @@ extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handl /* init routines */ extern BOOL SIGNAL_Init(void); extern void debug_init(void); -extern void thread_init(void); +extern ULONG thread_init(void); extern void virtual_init(void); /* server support */ extern void server_init_process(void); -extern void server_init_thread( int unix_pid, int unix_tid, void *entry_point ); +extern size_t server_init_thread( int unix_pid, int unix_tid, void *entry_point ); extern void DECLSPEC_NORETURN server_protocol_error( const char *err, ... ); extern void DECLSPEC_NORETURN server_protocol_perror( const char *err ); extern void DECLSPEC_NORETURN server_abort_thread( int status ); diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index b27bc5061c..f68849efdf 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -873,11 +873,12 @@ void server_init_process(void) * * Send an init thread request. Return 0 if OK. */ -void server_init_thread( int unix_pid, int unix_tid, void *entry_point ) +size_t server_init_thread( int unix_pid, int unix_tid, void *entry_point ) { int version, ret; int reply_pipe[2]; struct sigaction sig_act; + size_t info_size; sig_act.sa_handler = SIG_IGN; sig_act.sa_flags = 0; @@ -918,7 +919,8 @@ void server_init_thread( int unix_pid, int unix_tid, void *entry_point ) ret = wine_server_call( req ); NtCurrentTeb()->ClientId.UniqueProcess = (HANDLE)reply->pid; NtCurrentTeb()->ClientId.UniqueThread = (HANDLE)reply->tid; - version = reply->version; + info_size = reply->info_size; + version = reply->version; } SERVER_END_REQ; @@ -930,4 +932,5 @@ void server_init_thread( int unix_pid, int unix_tid, void *entry_point ) "Or maybe the wrong wineserver is still running?\n", version, SERVER_PROTOCOL_VERSION, (version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" ); + return info_size; } diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index f98f3fc04c..c30c02f67a 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -102,11 +102,11 @@ static inline void free_teb( TEB *teb ) * * NOTES: The first allocated TEB on NT is at 0x7ffde000. */ -void thread_init(void) +ULONG thread_init(void) { TEB *teb; void *addr; - ULONG size; + ULONG size, info_size; struct ntdll_thread_data *thread_data; struct wine_pthread_thread_info thread_info; static struct debug_info debug_info; /* debug info for initial thread */ @@ -148,7 +148,7 @@ void thread_init(void) /* setup the server connection */ server_init_process(); - server_init_thread( thread_info.pid, thread_info.tid, NULL ); + info_size = server_init_thread( thread_info.pid, thread_info.tid, NULL ); /* create a memory view for the TEB */ addr = teb; @@ -161,6 +161,7 @@ void thread_init(void) MESSAGE( "wine: failed to create the process heap\n" ); exit(1); } + return info_size; } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 6e76653978..59e1f56641 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -245,7 +245,6 @@ struct init_process_reply { struct reply_header __header; unsigned int server_start; - size_t info_size; }; @@ -304,6 +303,7 @@ struct init_thread_reply struct reply_header __header; process_id_t pid; thread_id_t tid; + size_t info_size; int version; }; @@ -4174,6 +4174,6 @@ union generic_reply struct set_mailslot_info_reply set_mailslot_info_reply; }; -#define SERVER_PROTOCOL_VERSION 185 +#define SERVER_PROTOCOL_VERSION 186 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/process.c b/server/process.c index 4787db7224..99f1476490 100644 --- a/server/process.c +++ b/server/process.c @@ -303,18 +303,18 @@ inline static struct startup_info *find_startup_info( int unix_pid ) } /* initialize the current process and fill in the request */ -void init_process( struct thread *thread ) +size_t init_process( struct thread *thread ) { struct process *process = thread->process; struct thread *parent_thread = NULL; struct process *parent = NULL; struct startup_info *info; - if (process->startup_info) return; /* already initialized */ + if (process->startup_info) return process->startup_info->data_size; /* already initialized */ if ((info = find_startup_info( thread->unix_pid ))) { - if (info->thread) return; /* already initialized */ + if (info->thread) return info->data_size; /* already initialized */ info->thread = (struct thread *)grab_object( thread ); info->process = (struct process *)grab_object( process ); @@ -335,7 +335,7 @@ void init_process( struct thread *thread ) if (!process->handles) { fatal_protocol_error( thread, "Failed to allocate handle table\n" ); - return; + return 0; } /* connect to the window station and desktop */ @@ -343,7 +343,7 @@ void init_process( struct thread *thread ) connect_process_desktop( process, NULL, 0 ); thread->desktop = process->desktop; - if (!info) return; + if (!info) return 0; /* retrieve the main exe file */ if (info->exe_file) process->exe.file = (struct file *)grab_object( info->exe_file ); @@ -369,6 +369,8 @@ void init_process( struct thread *thread ) if (!(process->create_flags & CREATE_NEW_PROCESS_GROUP)) process->group_id = parent->group_id; + + return info->data_size; } /* destroy a process when its refcount is 0 */ @@ -967,8 +969,6 @@ DECL_HANDLER(get_startup_info) DECL_HANDLER(init_process) { reply->server_start = server_start_ticks; - if (current->process->startup_info) - reply->info_size = current->process->startup_info->data_size; } /* signal the end of the process initialization */ diff --git a/server/process.h b/server/process.h index c538bb2a2c..02c36021fe 100644 --- a/server/process.h +++ b/server/process.h @@ -104,7 +104,7 @@ extern unsigned int alloc_ptid( void *ptr ); extern void free_ptid( unsigned int id ); extern void *get_ptid_entry( unsigned int id ); extern struct thread *create_process( int fd ); -extern void init_process( struct thread *thread ); +extern size_t init_process( struct thread *thread ); 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_handle( obj_handle_t handle, unsigned int access ); diff --git a/server/protocol.def b/server/protocol.def index 8882a7adb2..e9458abfd3 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -241,7 +241,6 @@ struct security_descriptor @REQ(init_process) @REPLY unsigned int server_start; /* server start time (GetTickCount) */ - size_t info_size; /* total size of startup info */ @END @@ -284,6 +283,7 @@ struct security_descriptor @REPLY process_id_t pid; /* process id of the new thread's process */ thread_id_t tid; /* thread id of the new thread */ + size_t info_size; /* total size of startup info */ int version; /* protocol version */ @END diff --git a/server/thread.c b/server/thread.c index a05e221b07..f1f4f271a9 100644 --- a/server/thread.c +++ b/server/thread.c @@ -876,7 +876,7 @@ DECL_HANDLER(init_thread) { process->peb = req->peb; process->ldt_copy = req->ldt_copy; - init_process( current ); + reply->info_size = init_process( current ); } else { diff --git a/server/trace.c b/server/trace.c index 998025a08a..03e2a2ae56 100644 --- a/server/trace.c +++ b/server/trace.c @@ -612,8 +612,7 @@ 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, " server_start=%08x,", req->server_start ); - fprintf( stderr, " info_size=%d", req->info_size ); + fprintf( stderr, " server_start=%08x", req->server_start ); } static void dump_get_startup_info_request( const struct get_startup_info_request *req ) @@ -663,6 +662,7 @@ static void dump_init_thread_reply( const struct init_thread_reply *req ) { fprintf( stderr, " pid=%04x,", req->pid ); fprintf( stderr, " tid=%04x,", req->tid ); + fprintf( stderr, " info_size=%d,", req->info_size ); fprintf( stderr, " version=%d", req->version ); }