Return the startup info size in the init_thread request, and allocate
the process parameters structure in ntdll instead of kernel.
This commit is contained in:
parent
b220ce1343
commit
11ad6a0ac4
|
@ -736,23 +736,18 @@ static void usage(void)
|
||||||
*
|
*
|
||||||
* Fill the RTL_USER_PROCESS_PARAMETERS structure from the server.
|
* 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;
|
BOOL ret;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
DWORD size, env_size;
|
DWORD size, env_size, info_size;
|
||||||
RTL_USER_PROCESS_PARAMETERS *params;
|
|
||||||
HANDLE hstdin, hstdout, hstderr;
|
HANDLE hstdin, hstdout, hstderr;
|
||||||
|
|
||||||
size = info_size;
|
size = info_size = params->AllocationSize;
|
||||||
ptr = NULL;
|
|
||||||
if (NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &size,
|
|
||||||
MEM_COMMIT, PAGE_READWRITE ) != STATUS_SUCCESS)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
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, params, size );
|
||||||
if ((ret = !wine_server_call( req )))
|
if ((ret = !wine_server_call( req )))
|
||||||
{
|
{
|
||||||
info_size = wine_server_reply_size( reply );
|
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;
|
SERVER_END_REQ;
|
||||||
if (!ret)
|
if (!ret) return ret;
|
||||||
{
|
|
||||||
size = 0;
|
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), &ptr, &size, MEM_RELEASE );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
params = ptr;
|
|
||||||
params->AllocationSize = size;
|
params->AllocationSize = size;
|
||||||
if (params->Size > info_size) params->Size = info_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;
|
ptr = NULL;
|
||||||
if (NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &env_size,
|
if (NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &env_size,
|
||||||
MEM_COMMIT, PAGE_READWRITE ) != STATUS_SUCCESS)
|
MEM_COMMIT, PAGE_READWRITE ) != STATUS_SUCCESS)
|
||||||
return NULL;
|
return FALSE;
|
||||||
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;
|
||||||
|
|
||||||
|
@ -818,7 +807,8 @@ static RTL_USER_PROCESS_PARAMETERS *init_user_process_params( size_t info_size )
|
||||||
params->hStdOutput = hstdout;
|
params->hStdOutput = hstdout;
|
||||||
params->hStdError = hstderr;
|
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};
|
static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2',0};
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
size_t info_size = 0;
|
|
||||||
RTL_USER_PROCESS_PARAMETERS *params;
|
|
||||||
PEB *peb = NtCurrentTeb()->Peb;
|
PEB *peb = NtCurrentTeb()->Peb;
|
||||||
|
RTL_USER_PROCESS_PARAMETERS *params = peb->ProcessParameters;
|
||||||
extern void __wine_dbg_kernel32_init(void);
|
extern void __wine_dbg_kernel32_init(void);
|
||||||
|
|
||||||
PTHREAD_Init();
|
PTHREAD_Init();
|
||||||
|
@ -962,17 +951,14 @@ static BOOL process_init(void)
|
||||||
{
|
{
|
||||||
if ((ret = !wine_server_call_err( req )))
|
if ((ret = !wine_server_call_err( req )))
|
||||||
{
|
{
|
||||||
info_size = reply->info_size;
|
|
||||||
server_startticks = reply->server_start;
|
server_startticks = reply->server_start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
if (!ret) return FALSE;
|
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)
|
/* This is wine specific: we have no parent (we're started from unix)
|
||||||
* so, create a simple console with bare handles to unix stdio
|
* so, create a simple console with bare handles to unix stdio
|
||||||
* input & output streams (aka simple console)
|
* 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.MaximumLength = RtlGetLongestNtPathLength() * sizeof(WCHAR);
|
||||||
params->CurrentDirectory.DosPath.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, params->CurrentDirectory.DosPath.MaximumLength);
|
params->CurrentDirectory.DosPath.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, params->CurrentDirectory.DosPath.MaximumLength);
|
||||||
}
|
}
|
||||||
else
|
else if (!init_user_process_params( params )) return FALSE;
|
||||||
{
|
|
||||||
if (!(params = init_user_process_params( info_size ))) return FALSE;
|
|
||||||
peb->ProcessParameters = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
kernel32_handle = GetModuleHandleW(kernel32W);
|
kernel32_handle = GetModuleHandleW(kernel32W);
|
||||||
|
|
||||||
LOCALE_Init();
|
LOCALE_Init();
|
||||||
|
|
||||||
if (!info_size)
|
if (!params->AllocationSize)
|
||||||
{
|
{
|
||||||
/* Copy the parent environment */
|
/* Copy the parent environment */
|
||||||
if (!build_initial_environment( __wine_main_environ )) return FALSE;
|
if (!build_initial_environment( __wine_main_environ )) return FALSE;
|
||||||
|
|
|
@ -2126,9 +2126,22 @@ void __wine_process_init( int argc, char *argv[] )
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
ANSI_STRING func_name;
|
ANSI_STRING func_name;
|
||||||
void (* DECLSPEC_NORETURN init_func)();
|
void (* DECLSPEC_NORETURN init_func)();
|
||||||
|
ULONG info_size;
|
||||||
extern mode_t FILE_umask;
|
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 */
|
/* retrieve current umask */
|
||||||
FILE_umask = umask(0777);
|
FILE_umask = umask(0777);
|
||||||
|
|
|
@ -48,12 +48,12 @@ extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handl
|
||||||
/* init routines */
|
/* init routines */
|
||||||
extern BOOL SIGNAL_Init(void);
|
extern BOOL SIGNAL_Init(void);
|
||||||
extern void debug_init(void);
|
extern void debug_init(void);
|
||||||
extern void thread_init(void);
|
extern ULONG thread_init(void);
|
||||||
extern void virtual_init(void);
|
extern void virtual_init(void);
|
||||||
|
|
||||||
/* server support */
|
/* server support */
|
||||||
extern void server_init_process(void);
|
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_error( const char *err, ... );
|
||||||
extern void DECLSPEC_NORETURN server_protocol_perror( const char *err );
|
extern void DECLSPEC_NORETURN server_protocol_perror( const char *err );
|
||||||
extern void DECLSPEC_NORETURN server_abort_thread( int status );
|
extern void DECLSPEC_NORETURN server_abort_thread( int status );
|
||||||
|
|
|
@ -873,11 +873,12 @@ void server_init_process(void)
|
||||||
*
|
*
|
||||||
* Send an init thread request. Return 0 if OK.
|
* 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 version, ret;
|
||||||
int reply_pipe[2];
|
int reply_pipe[2];
|
||||||
struct sigaction sig_act;
|
struct sigaction sig_act;
|
||||||
|
size_t info_size;
|
||||||
|
|
||||||
sig_act.sa_handler = SIG_IGN;
|
sig_act.sa_handler = SIG_IGN;
|
||||||
sig_act.sa_flags = 0;
|
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 );
|
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;
|
||||||
version = reply->version;
|
info_size = reply->info_size;
|
||||||
|
version = reply->version;
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
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",
|
"Or maybe the wrong wineserver is still running?\n",
|
||||||
version, SERVER_PROTOCOL_VERSION,
|
version, SERVER_PROTOCOL_VERSION,
|
||||||
(version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" );
|
(version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" );
|
||||||
|
return info_size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,11 +102,11 @@ static inline void free_teb( TEB *teb )
|
||||||
*
|
*
|
||||||
* NOTES: The first allocated TEB on NT is at 0x7ffde000.
|
* NOTES: The first allocated TEB on NT is at 0x7ffde000.
|
||||||
*/
|
*/
|
||||||
void thread_init(void)
|
ULONG thread_init(void)
|
||||||
{
|
{
|
||||||
TEB *teb;
|
TEB *teb;
|
||||||
void *addr;
|
void *addr;
|
||||||
ULONG size;
|
ULONG size, info_size;
|
||||||
struct ntdll_thread_data *thread_data;
|
struct ntdll_thread_data *thread_data;
|
||||||
struct wine_pthread_thread_info thread_info;
|
struct wine_pthread_thread_info thread_info;
|
||||||
static struct debug_info debug_info; /* debug info for initial thread */
|
static struct debug_info debug_info; /* debug info for initial thread */
|
||||||
|
@ -148,7 +148,7 @@ void thread_init(void)
|
||||||
|
|
||||||
/* setup the server connection */
|
/* setup the server connection */
|
||||||
server_init_process();
|
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 */
|
/* create a memory view for the TEB */
|
||||||
addr = teb;
|
addr = teb;
|
||||||
|
@ -161,6 +161,7 @@ void thread_init(void)
|
||||||
MESSAGE( "wine: failed to create the process heap\n" );
|
MESSAGE( "wine: failed to create the process heap\n" );
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
return info_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,6 @@ struct init_process_reply
|
||||||
{
|
{
|
||||||
struct reply_header __header;
|
struct reply_header __header;
|
||||||
unsigned int server_start;
|
unsigned int server_start;
|
||||||
size_t info_size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -304,6 +303,7 @@ 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;
|
||||||
|
size_t info_size;
|
||||||
int version;
|
int version;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4174,6 +4174,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 185
|
#define SERVER_PROTOCOL_VERSION 186
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -303,18 +303,18 @@ 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 */
|
||||||
void init_process( struct thread *thread )
|
size_t init_process( struct thread *thread )
|
||||||
{
|
{
|
||||||
struct process *process = thread->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;
|
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 = 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->thread = (struct thread *)grab_object( thread );
|
||||||
info->process = (struct process *)grab_object( process );
|
info->process = (struct process *)grab_object( process );
|
||||||
|
@ -335,7 +335,7 @@ void init_process( struct thread *thread )
|
||||||
if (!process->handles)
|
if (!process->handles)
|
||||||
{
|
{
|
||||||
fatal_protocol_error( thread, "Failed to allocate handle table\n" );
|
fatal_protocol_error( thread, "Failed to allocate handle table\n" );
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* connect to the window station and desktop */
|
/* connect to the window station and desktop */
|
||||||
|
@ -343,7 +343,7 @@ void init_process( struct thread *thread )
|
||||||
connect_process_desktop( process, NULL, 0 );
|
connect_process_desktop( process, NULL, 0 );
|
||||||
thread->desktop = process->desktop;
|
thread->desktop = process->desktop;
|
||||||
|
|
||||||
if (!info) return;
|
if (!info) return 0;
|
||||||
|
|
||||||
/* retrieve the main exe file */
|
/* retrieve the main exe file */
|
||||||
if (info->exe_file) process->exe.file = (struct file *)grab_object( info->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))
|
if (!(process->create_flags & CREATE_NEW_PROCESS_GROUP))
|
||||||
process->group_id = parent->group_id;
|
process->group_id = parent->group_id;
|
||||||
|
|
||||||
|
return info->data_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* destroy a process when its refcount is 0 */
|
/* destroy a process when its refcount is 0 */
|
||||||
|
@ -967,8 +969,6 @@ DECL_HANDLER(get_startup_info)
|
||||||
DECL_HANDLER(init_process)
|
DECL_HANDLER(init_process)
|
||||||
{
|
{
|
||||||
reply->server_start = server_start_ticks;
|
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 */
|
/* signal the end of the process initialization */
|
||||||
|
|
|
@ -104,7 +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 size_t 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 );
|
||||||
|
|
|
@ -241,7 +241,6 @@ struct security_descriptor
|
||||||
@REQ(init_process)
|
@REQ(init_process)
|
||||||
@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 */
|
|
||||||
@END
|
@END
|
||||||
|
|
||||||
|
|
||||||
|
@ -284,6 +283,7 @@ struct security_descriptor
|
||||||
@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 */
|
||||||
|
size_t info_size; /* total size of startup info */
|
||||||
int version; /* protocol version */
|
int version; /* protocol version */
|
||||||
@END
|
@END
|
||||||
|
|
||||||
|
|
|
@ -876,7 +876,7 @@ DECL_HANDLER(init_thread)
|
||||||
{
|
{
|
||||||
process->peb = req->peb;
|
process->peb = req->peb;
|
||||||
process->ldt_copy = req->ldt_copy;
|
process->ldt_copy = req->ldt_copy;
|
||||||
init_process( current );
|
reply->info_size = init_process( current );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 )
|
static void dump_init_process_reply( const struct init_process_reply *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " server_start=%08x,", req->server_start );
|
fprintf( stderr, " server_start=%08x", req->server_start );
|
||||||
fprintf( stderr, " info_size=%d", req->info_size );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 )
|
||||||
|
@ -663,6 +662,7 @@ 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, " info_size=%d,", req->info_size );
|
||||||
fprintf( stderr, " version=%d", req->version );
|
fprintf( stderr, " version=%d", req->version );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue