kernel: Moved the get_startup_info call to ntdll.
This commit is contained in:
parent
e27358ea5c
commit
477b3bf566
|
@ -64,7 +64,6 @@ typedef struct
|
||||||
|
|
||||||
static UINT process_error_mode;
|
static UINT process_error_mode;
|
||||||
|
|
||||||
static HANDLE main_exe_file;
|
|
||||||
static DWORD shutdown_flags = 0;
|
static DWORD shutdown_flags = 0;
|
||||||
static DWORD shutdown_priority = 0x280;
|
static DWORD shutdown_priority = 0x280;
|
||||||
static DWORD process_dword;
|
static DWORD process_dword;
|
||||||
|
@ -637,28 +636,6 @@ static BOOL build_command_line( WCHAR **argv )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* make sure the unicode string doesn't point beyond the end pointer */
|
|
||||||
static inline void fix_unicode_string( UNICODE_STRING *str, char *end_ptr )
|
|
||||||
{
|
|
||||||
if ((char *)str->Buffer >= end_ptr)
|
|
||||||
{
|
|
||||||
str->Length = str->MaximumLength = 0;
|
|
||||||
str->Buffer = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((char *)str->Buffer + str->MaximumLength > end_ptr)
|
|
||||||
{
|
|
||||||
str->MaximumLength = (end_ptr - (char *)str->Buffer) & ~(sizeof(WCHAR) - 1);
|
|
||||||
}
|
|
||||||
if (str->Length >= str->MaximumLength)
|
|
||||||
{
|
|
||||||
if (str->MaximumLength >= sizeof(WCHAR))
|
|
||||||
str->Length = str->MaximumLength - sizeof(WCHAR);
|
|
||||||
else
|
|
||||||
str->Length = str->MaximumLength = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void version(void)
|
static void version(void)
|
||||||
{
|
{
|
||||||
MESSAGE( "%s\n", PACKAGE_STRING );
|
MESSAGE( "%s\n", PACKAGE_STRING );
|
||||||
|
@ -675,87 +652,6 @@ static void usage(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* init_user_process_params
|
|
||||||
*
|
|
||||||
* Fill the RTL_USER_PROCESS_PARAMETERS structure from the server.
|
|
||||||
*/
|
|
||||||
static BOOL init_user_process_params( RTL_USER_PROCESS_PARAMETERS *params )
|
|
||||||
{
|
|
||||||
BOOL ret;
|
|
||||||
void *ptr;
|
|
||||||
SIZE_T size, env_size, info_size;
|
|
||||||
HANDLE hstdin, hstdout, hstderr;
|
|
||||||
|
|
||||||
size = info_size = params->AllocationSize;
|
|
||||||
if (!size) return TRUE; /* no parameters received from parent */
|
|
||||||
|
|
||||||
SERVER_START_REQ( get_startup_info )
|
|
||||||
{
|
|
||||||
wine_server_set_reply( req, params, size );
|
|
||||||
if ((ret = !wine_server_call( req )))
|
|
||||||
{
|
|
||||||
info_size = wine_server_reply_size( reply );
|
|
||||||
main_exe_file = reply->exe_file;
|
|
||||||
hstdin = reply->hstdin;
|
|
||||||
hstdout = reply->hstdout;
|
|
||||||
hstderr = reply->hstderr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SERVER_END_REQ;
|
|
||||||
if (!ret) return ret;
|
|
||||||
|
|
||||||
params->AllocationSize = size;
|
|
||||||
if (params->Size > info_size) params->Size = info_size;
|
|
||||||
|
|
||||||
/* make sure the strings are valid */
|
|
||||||
fix_unicode_string( ¶ms->CurrentDirectory.DosPath, (char *)info_size );
|
|
||||||
fix_unicode_string( ¶ms->DllPath, (char *)info_size );
|
|
||||||
fix_unicode_string( ¶ms->ImagePathName, (char *)info_size );
|
|
||||||
fix_unicode_string( ¶ms->CommandLine, (char *)info_size );
|
|
||||||
fix_unicode_string( ¶ms->WindowTitle, (char *)info_size );
|
|
||||||
fix_unicode_string( ¶ms->Desktop, (char *)info_size );
|
|
||||||
fix_unicode_string( ¶ms->ShellInfo, (char *)info_size );
|
|
||||||
fix_unicode_string( ¶ms->RuntimeInfo, (char *)info_size );
|
|
||||||
|
|
||||||
/* environment needs to be a separate memory block */
|
|
||||||
env_size = info_size - params->Size;
|
|
||||||
if (!env_size) env_size = 1;
|
|
||||||
ptr = NULL;
|
|
||||||
if (NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &env_size,
|
|
||||||
MEM_COMMIT, PAGE_READWRITE ) != STATUS_SUCCESS)
|
|
||||||
return FALSE;
|
|
||||||
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;
|
|
||||||
|
|
||||||
RtlNormalizeProcessParams( params );
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* init_current_directory
|
* init_current_directory
|
||||||
*
|
*
|
||||||
|
@ -878,6 +774,7 @@ 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};
|
||||||
PEB *peb = NtCurrentTeb()->Peb;
|
PEB *peb = NtCurrentTeb()->Peb;
|
||||||
|
RTL_USER_PROCESS_PARAMETERS *params = peb->ProcessParameters;
|
||||||
|
|
||||||
PTHREAD_Init();
|
PTHREAD_Init();
|
||||||
|
|
||||||
|
@ -885,13 +782,11 @@ static BOOL process_init(void)
|
||||||
setbuf(stderr,NULL);
|
setbuf(stderr,NULL);
|
||||||
setlocale(LC_CTYPE,"");
|
setlocale(LC_CTYPE,"");
|
||||||
|
|
||||||
if (!init_user_process_params( peb->ProcessParameters )) return FALSE;
|
|
||||||
|
|
||||||
kernel32_handle = GetModuleHandleW(kernel32W);
|
kernel32_handle = GetModuleHandleW(kernel32W);
|
||||||
|
|
||||||
LOCALE_Init();
|
LOCALE_Init();
|
||||||
|
|
||||||
if (!peb->ProcessParameters->Environment)
|
if (!params->Environment)
|
||||||
{
|
{
|
||||||
/* 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;
|
||||||
|
@ -903,7 +798,26 @@ static BOOL process_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
init_windows_dirs();
|
init_windows_dirs();
|
||||||
init_current_directory( &peb->ProcessParameters->CurrentDirectory );
|
init_current_directory( ¶ms->CurrentDirectory );
|
||||||
|
|
||||||
|
/* convert value from server:
|
||||||
|
* + 0 => INVALID_HANDLE_VALUE
|
||||||
|
* + console handle needs to be mapped
|
||||||
|
*/
|
||||||
|
if (!params->hStdInput)
|
||||||
|
params->hStdInput = INVALID_HANDLE_VALUE;
|
||||||
|
else if (VerifyConsoleIoHandle(console_handle_map(params->hStdInput)))
|
||||||
|
params->hStdInput = console_handle_map(params->hStdInput);
|
||||||
|
|
||||||
|
if (!params->hStdOutput)
|
||||||
|
params->hStdOutput = INVALID_HANDLE_VALUE;
|
||||||
|
else if (VerifyConsoleIoHandle(console_handle_map(params->hStdOutput)))
|
||||||
|
params->hStdOutput = console_handle_map(params->hStdOutput);
|
||||||
|
|
||||||
|
if (!params->hStdError)
|
||||||
|
params->hStdError = INVALID_HANDLE_VALUE;
|
||||||
|
else if (VerifyConsoleIoHandle(console_handle_map(params->hStdError)))
|
||||||
|
params->hStdError = console_handle_map(params->hStdError);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1023,7 +937,7 @@ void __wine_kernel_init(void)
|
||||||
!get_builtin_path( exe_nameW, exeW, main_exe_name, MAX_PATH ))
|
!get_builtin_path( exe_nameW, exeW, main_exe_name, MAX_PATH ))
|
||||||
{
|
{
|
||||||
MESSAGE( "wine: cannot find '%s'\n", __wine_main_argv[0] );
|
MESSAGE( "wine: cannot find '%s'\n", __wine_main_argv[0] );
|
||||||
ExitProcess(1);
|
ExitProcess( GetLastError() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1031,8 +945,8 @@ void __wine_kernel_init(void)
|
||||||
p = strrchrW( main_exe_name, '.' );
|
p = strrchrW( main_exe_name, '.' );
|
||||||
if (!p || strchrW( p, '/' ) || strchrW( p, '\\' )) strcatW( main_exe_name, dotW );
|
if (!p || strchrW( p, '/' ) || strchrW( p, '\\' )) strcatW( main_exe_name, dotW );
|
||||||
|
|
||||||
TRACE( "starting process name=%s file=%p argv[0]=%s\n",
|
TRACE( "starting process name=%s argv[0]=%s\n",
|
||||||
debugstr_w(main_exe_name), main_exe_file, debugstr_a(__wine_main_argv[0]) );
|
debugstr_w(main_exe_name), debugstr_a(__wine_main_argv[0]) );
|
||||||
|
|
||||||
RtlInitUnicodeString( &NtCurrentTeb()->Peb->ProcessParameters->DllPath,
|
RtlInitUnicodeString( &NtCurrentTeb()->Peb->ProcessParameters->DllPath,
|
||||||
MODULE_get_dll_load_path(NULL) );
|
MODULE_get_dll_load_path(NULL) );
|
||||||
|
@ -1054,14 +968,12 @@ void __wine_kernel_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (main_exe_file) CloseHandle( main_exe_file );
|
|
||||||
|
|
||||||
if (!module)
|
if (!module)
|
||||||
{
|
{
|
||||||
char msg[1024];
|
char msg[1024];
|
||||||
FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, msg, sizeof(msg), NULL );
|
FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, msg, sizeof(msg), NULL );
|
||||||
MESSAGE( "wine: could not load %s: %s", debugstr_w(main_exe_name), msg );
|
MESSAGE( "wine: could not load %s: %s", debugstr_w(main_exe_name), msg );
|
||||||
ExitProcess(1);
|
ExitProcess( error );
|
||||||
}
|
}
|
||||||
|
|
||||||
peb->ImageBaseAddress = module;
|
peb->ImageBaseAddress = module;
|
||||||
|
|
|
@ -85,6 +85,7 @@ struct builtin_load_info
|
||||||
static struct builtin_load_info default_load_info;
|
static struct builtin_load_info default_load_info;
|
||||||
static struct builtin_load_info *builtin_load_info = &default_load_info;
|
static struct builtin_load_info *builtin_load_info = &default_load_info;
|
||||||
|
|
||||||
|
static HANDLE main_exe_file;
|
||||||
static UINT tls_module_count; /* number of modules with TLS directory */
|
static UINT tls_module_count; /* number of modules with TLS directory */
|
||||||
static UINT tls_total_size; /* total size of TLS storage */
|
static UINT tls_total_size; /* total size of TLS storage */
|
||||||
static const IMAGE_TLS_DIRECTORY **tls_dirs; /* array of TLS directories */
|
static const IMAGE_TLS_DIRECTORY **tls_dirs; /* array of TLS directories */
|
||||||
|
@ -2037,6 +2038,8 @@ void WINAPI LdrInitializeThunk( ULONG unknown1, ULONG unknown2, ULONG unknown3,
|
||||||
PEB *peb = NtCurrentTeb()->Peb;
|
PEB *peb = NtCurrentTeb()->Peb;
|
||||||
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
|
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
|
||||||
|
|
||||||
|
if (main_exe_file) NtClose( main_exe_file ); /* at this point the main module is created */
|
||||||
|
|
||||||
/* allocate the modref for the main exe (if not already done) */
|
/* allocate the modref for the main exe (if not already done) */
|
||||||
wm = get_modref( peb->ImageBaseAddress );
|
wm = get_modref( peb->ImageBaseAddress );
|
||||||
assert( wm );
|
assert( wm );
|
||||||
|
@ -2243,7 +2246,7 @@ void __wine_process_init( int argc, char *argv[] )
|
||||||
void (* DECLSPEC_NORETURN init_func)(void);
|
void (* DECLSPEC_NORETURN init_func)(void);
|
||||||
extern mode_t FILE_umask;
|
extern mode_t FILE_umask;
|
||||||
|
|
||||||
thread_init();
|
main_exe_file = thread_init();
|
||||||
|
|
||||||
/* retrieve current umask */
|
/* retrieve current umask */
|
||||||
FILE_umask = umask(0777);
|
FILE_umask = umask(0777);
|
||||||
|
|
|
@ -48,7 +48,7 @@ extern BOOL SIGNAL_Init(void);
|
||||||
extern size_t get_signal_stack_total_size(void);
|
extern size_t get_signal_stack_total_size(void);
|
||||||
extern void version_init( const WCHAR *appname );
|
extern void version_init( const WCHAR *appname );
|
||||||
extern void debug_init(void);
|
extern void debug_init(void);
|
||||||
extern void thread_init(void);
|
extern HANDLE thread_init(void);
|
||||||
|
|
||||||
/* server support */
|
/* server support */
|
||||||
extern time_t server_start_time;
|
extern time_t server_start_time;
|
||||||
|
|
|
@ -101,6 +101,94 @@ static inline void free_teb( TEB *teb )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* fix_unicode_string
|
||||||
|
*
|
||||||
|
* Make sure the unicode string doesn't point beyond the end pointer
|
||||||
|
*/
|
||||||
|
static inline void fix_unicode_string( UNICODE_STRING *str, char *end_ptr )
|
||||||
|
{
|
||||||
|
if ((char *)str->Buffer >= end_ptr)
|
||||||
|
{
|
||||||
|
str->Length = str->MaximumLength = 0;
|
||||||
|
str->Buffer = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((char *)str->Buffer + str->MaximumLength > end_ptr)
|
||||||
|
{
|
||||||
|
str->MaximumLength = (end_ptr - (char *)str->Buffer) & ~(sizeof(WCHAR) - 1);
|
||||||
|
}
|
||||||
|
if (str->Length >= str->MaximumLength)
|
||||||
|
{
|
||||||
|
if (str->MaximumLength >= sizeof(WCHAR))
|
||||||
|
str->Length = str->MaximumLength - sizeof(WCHAR);
|
||||||
|
else
|
||||||
|
str->Length = str->MaximumLength = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* init_user_process_params
|
||||||
|
*
|
||||||
|
* Fill the RTL_USER_PROCESS_PARAMETERS structure from the server.
|
||||||
|
*/
|
||||||
|
static NTSTATUS init_user_process_params( SIZE_T info_size, HANDLE *exe_file )
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
SIZE_T env_size;
|
||||||
|
NTSTATUS status;
|
||||||
|
RTL_USER_PROCESS_PARAMETERS *params = NULL;
|
||||||
|
|
||||||
|
status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)¶ms, 0, &info_size,
|
||||||
|
MEM_COMMIT, PAGE_READWRITE );
|
||||||
|
if (status != STATUS_SUCCESS) return status;
|
||||||
|
|
||||||
|
params->AllocationSize = info_size;
|
||||||
|
peb.ProcessParameters = params;
|
||||||
|
|
||||||
|
SERVER_START_REQ( get_startup_info )
|
||||||
|
{
|
||||||
|
wine_server_set_reply( req, params, info_size );
|
||||||
|
if (!(status = wine_server_call( req )))
|
||||||
|
{
|
||||||
|
info_size = wine_server_reply_size( reply );
|
||||||
|
*exe_file = reply->exe_file;
|
||||||
|
params->hStdInput = reply->hstdin;
|
||||||
|
params->hStdOutput = reply->hstdout;
|
||||||
|
params->hStdError = reply->hstderr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
if (status != STATUS_SUCCESS) return status;
|
||||||
|
|
||||||
|
if (params->Size > info_size) params->Size = info_size;
|
||||||
|
|
||||||
|
/* make sure the strings are valid */
|
||||||
|
fix_unicode_string( ¶ms->CurrentDirectory.DosPath, (char *)info_size );
|
||||||
|
fix_unicode_string( ¶ms->DllPath, (char *)info_size );
|
||||||
|
fix_unicode_string( ¶ms->ImagePathName, (char *)info_size );
|
||||||
|
fix_unicode_string( ¶ms->CommandLine, (char *)info_size );
|
||||||
|
fix_unicode_string( ¶ms->WindowTitle, (char *)info_size );
|
||||||
|
fix_unicode_string( ¶ms->Desktop, (char *)info_size );
|
||||||
|
fix_unicode_string( ¶ms->ShellInfo, (char *)info_size );
|
||||||
|
fix_unicode_string( ¶ms->RuntimeInfo, (char *)info_size );
|
||||||
|
|
||||||
|
/* environment needs to be a separate memory block */
|
||||||
|
env_size = info_size - params->Size;
|
||||||
|
if (!env_size) env_size = 1;
|
||||||
|
ptr = NULL;
|
||||||
|
status = NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &env_size,
|
||||||
|
MEM_COMMIT, PAGE_READWRITE );
|
||||||
|
if (status != STATUS_SUCCESS) return status;
|
||||||
|
memcpy( ptr, (char *)params + params->Size, info_size - params->Size );
|
||||||
|
params->Environment = ptr;
|
||||||
|
|
||||||
|
RtlNormalizeProcessParams( params );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* thread_init
|
* thread_init
|
||||||
*
|
*
|
||||||
|
@ -108,11 +196,12 @@ 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)
|
HANDLE thread_init(void)
|
||||||
{
|
{
|
||||||
TEB *teb;
|
TEB *teb;
|
||||||
void *addr;
|
void *addr;
|
||||||
SIZE_T info_size;
|
SIZE_T info_size;
|
||||||
|
HANDLE exe_file = 0;
|
||||||
struct ntdll_thread_data *thread_data;
|
struct ntdll_thread_data *thread_data;
|
||||||
struct ntdll_thread_regs *thread_regs;
|
struct ntdll_thread_regs *thread_regs;
|
||||||
struct wine_pthread_thread_info thread_info;
|
struct wine_pthread_thread_info thread_info;
|
||||||
|
@ -170,14 +259,7 @@ void thread_init(void)
|
||||||
/* allocate user parameters */
|
/* allocate user parameters */
|
||||||
if (info_size)
|
if (info_size)
|
||||||
{
|
{
|
||||||
RTL_USER_PROCESS_PARAMETERS *params = NULL;
|
init_user_process_params( info_size, &exe_file );
|
||||||
|
|
||||||
if (NtAllocateVirtualMemory( NtCurrentProcess(), (void **)¶ms, 0, &info_size,
|
|
||||||
MEM_COMMIT, PAGE_READWRITE ) == STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
params->AllocationSize = info_size;
|
|
||||||
NtCurrentTeb()->Peb->ProcessParameters = params;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -188,6 +270,7 @@ void thread_init(void)
|
||||||
wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, ¶ms.hStdOutput );
|
wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, ¶ms.hStdOutput );
|
||||||
wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, ¶ms.hStdError );
|
wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, OBJ_INHERIT, ¶ms.hStdError );
|
||||||
}
|
}
|
||||||
|
return exe_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue