ntdll: Allocate the initial process parameters on the Unix side.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9ce326eea0
commit
0d3972ce8a
|
@ -1168,44 +1168,41 @@ wait:
|
|||
*/
|
||||
void init_user_process_params(void)
|
||||
{
|
||||
WCHAR *src, *load_path, *dummy;
|
||||
SIZE_T info_size, env_size, data_size = 0;
|
||||
startup_info_t *info = NULL;
|
||||
RTL_USER_PROCESS_PARAMETERS *params = NULL;
|
||||
UNICODE_STRING curdir, dllpath, imagepath, cmdline, title, desktop, shellinfo, runtime;
|
||||
WCHAR *env, *load_path, *dummy;
|
||||
SIZE_T env_size;
|
||||
RTL_USER_PROCESS_PARAMETERS *new_params, *params = NtCurrentTeb()->Peb->ProcessParameters;
|
||||
UNICODE_STRING curdir, dllpath, cmdline;
|
||||
WCHAR **wargv;
|
||||
|
||||
unix_funcs->get_startup_info( NULL, &data_size, &info_size );
|
||||
if (!data_size)
|
||||
if (!params->DllPath.MaximumLength) /* not inherited from parent process */
|
||||
{
|
||||
RTL_USER_PROCESS_PARAMETERS initial_params = {0};
|
||||
WCHAR *env, curdir_buffer[MAX_PATH];
|
||||
WCHAR curdir_buffer[MAX_PATH];
|
||||
|
||||
NtCurrentTeb()->Peb->ProcessParameters = &initial_params;
|
||||
initial_params.Environment = build_initial_environment( &wargv );
|
||||
params->Environment = build_initial_environment( &wargv );
|
||||
curdir.Buffer = curdir_buffer;
|
||||
curdir.MaximumLength = sizeof(curdir_buffer);
|
||||
get_current_directory( &curdir );
|
||||
initial_params.CurrentDirectory.DosPath = curdir;
|
||||
get_image_path( wargv[0], &initial_params.ImagePathName );
|
||||
wargv[0] = initial_params.ImagePathName.Buffer;
|
||||
params->CurrentDirectory.DosPath = curdir;
|
||||
get_image_path( wargv[0], ¶ms->ImagePathName );
|
||||
wargv[0] = params->ImagePathName.Buffer;
|
||||
build_command_line( wargv, &cmdline );
|
||||
LdrGetDllPath( initial_params.ImagePathName.Buffer, 0, &load_path, &dummy );
|
||||
LdrGetDllPath( params->ImagePathName.Buffer, 0, &load_path, &dummy );
|
||||
RtlInitUnicodeString( &dllpath, load_path );
|
||||
|
||||
env = initial_params.Environment;
|
||||
initial_params.Environment = NULL; /* avoid copying it */
|
||||
if (RtlCreateProcessParametersEx( ¶ms, &initial_params.ImagePathName, &dllpath, &curdir,
|
||||
&cmdline, NULL, &initial_params.ImagePathName, NULL, NULL, NULL,
|
||||
env = params->Environment;
|
||||
params->Environment = NULL; /* avoid copying it */
|
||||
if (RtlCreateProcessParametersEx( &new_params, ¶ms->ImagePathName, &dllpath, &curdir,
|
||||
&cmdline, NULL, ¶ms->ImagePathName, NULL, NULL, NULL,
|
||||
PROCESS_PARAMS_FLAG_NORMALIZED ))
|
||||
return;
|
||||
|
||||
params->Environment = env;
|
||||
NtCurrentTeb()->Peb->ProcessParameters = params;
|
||||
RtlFreeUnicodeString( &initial_params.ImagePathName );
|
||||
new_params->Environment = env;
|
||||
NtCurrentTeb()->Peb->ProcessParameters = new_params;
|
||||
RtlFreeUnicodeString( ¶ms->ImagePathName );
|
||||
RtlFreeUnicodeString( &cmdline );
|
||||
RtlReleasePath( load_path );
|
||||
|
||||
params = new_params;
|
||||
unix_funcs->get_initial_console( params );
|
||||
params->wShowWindow = 1; /* SW_SHOWNORMAL */
|
||||
|
||||
|
@ -1213,54 +1210,16 @@ void init_user_process_params(void)
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, data_size ))) return;
|
||||
|
||||
if (unix_funcs->get_startup_info( info, &data_size, &info_size )) goto done;
|
||||
|
||||
src = (WCHAR *)(info + 1);
|
||||
get_unicode_string( &curdir, &src, info->curdir_len );
|
||||
get_unicode_string( &dllpath, &src, info->dllpath_len );
|
||||
get_unicode_string( &imagepath, &src, info->imagepath_len );
|
||||
get_unicode_string( &cmdline, &src, info->cmdline_len );
|
||||
get_unicode_string( &title, &src, info->title_len );
|
||||
get_unicode_string( &desktop, &src, info->desktop_len );
|
||||
get_unicode_string( &shellinfo, &src, info->shellinfo_len );
|
||||
get_unicode_string( &runtime, &src, info->runtime_len );
|
||||
|
||||
runtime.MaximumLength = runtime.Length; /* runtime info isn't a real string */
|
||||
|
||||
if (RtlCreateProcessParametersEx( ¶ms, &imagepath, &dllpath, &curdir, &cmdline, NULL,
|
||||
&title, &desktop, &shellinfo, &runtime,
|
||||
PROCESS_PARAMS_FLAG_NORMALIZED ))
|
||||
goto done;
|
||||
|
||||
NtCurrentTeb()->Peb->ProcessParameters = params;
|
||||
params->DebugFlags = info->debug_flags;
|
||||
params->ConsoleHandle = wine_server_ptr_handle( info->console );
|
||||
params->ConsoleFlags = info->console_flags;
|
||||
params->hStdInput = wine_server_ptr_handle( info->hstdin );
|
||||
params->hStdOutput = wine_server_ptr_handle( info->hstdout );
|
||||
params->hStdError = wine_server_ptr_handle( info->hstderr );
|
||||
params->dwX = info->x;
|
||||
params->dwY = info->y;
|
||||
params->dwXSize = info->xsize;
|
||||
params->dwYSize = info->ysize;
|
||||
params->dwXCountChars = info->xchars;
|
||||
params->dwYCountChars = info->ychars;
|
||||
params->dwFillAttribute = info->attribute;
|
||||
params->dwFlags = info->flags;
|
||||
params->wShowWindow = info->show;
|
||||
|
||||
/* environment needs to be a separate memory block */
|
||||
env_size = data_size - info_size;
|
||||
if ((params->Environment = RtlAllocateHeap( GetProcessHeap(), 0, max( env_size, sizeof(WCHAR) ))))
|
||||
env_size = params->EnvironmentSize;
|
||||
if ((env = RtlAllocateHeap( GetProcessHeap(), 0, max( env_size, sizeof(WCHAR) ))))
|
||||
{
|
||||
if (env_size) memcpy( params->Environment, (char *)info + info_size, env_size );
|
||||
else params->Environment[0] = 0;
|
||||
if (env_size) memcpy( env, params->Environment, env_size );
|
||||
else env[0] = 0;
|
||||
params->Environment = env;
|
||||
}
|
||||
|
||||
done:
|
||||
RtlFreeHeap( GetProcessHeap(), 0, info );
|
||||
if (RtlSetCurrentDirectory_U( ¶ms->CurrentDirectory.DosPath ))
|
||||
{
|
||||
MESSAGE("wine: could not open working directory %s, starting in the Windows directory.\n",
|
||||
|
|
|
@ -1163,32 +1163,6 @@ static void add_path_var( WCHAR *env, SIZE_T *pos, const char *name, const char
|
|||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* get_startup_info
|
||||
*
|
||||
* Get the startup information from the server.
|
||||
*/
|
||||
NTSTATUS CDECL get_startup_info( startup_info_t *info, SIZE_T *total_size, SIZE_T *info_size )
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
if (*total_size < startup_info_size)
|
||||
{
|
||||
*total_size = startup_info_size;
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
SERVER_START_REQ( get_startup_info )
|
||||
{
|
||||
wine_server_set_reply( req, info, *total_size );
|
||||
status = wine_server_call( req );
|
||||
*total_size = wine_server_reply_size( reply );
|
||||
*info_size = reply->info_size;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* get_dynamic_environment
|
||||
*
|
||||
|
@ -1375,6 +1349,130 @@ void CDECL get_locales( WCHAR *sys, WCHAR *user )
|
|||
}
|
||||
|
||||
|
||||
static inline void copy_unicode_string( WCHAR **src, WCHAR **dst, UNICODE_STRING *str, UINT len )
|
||||
{
|
||||
str->Buffer = *dst;
|
||||
str->Length = len;
|
||||
str->MaximumLength = len + sizeof(WCHAR);
|
||||
memcpy( *dst, *src, len );
|
||||
(*dst)[len / sizeof(WCHAR)] = 0;
|
||||
*src += len / sizeof(WCHAR);
|
||||
*dst += len / sizeof(WCHAR) + 1;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* build_initial_params
|
||||
*
|
||||
* Build process parameters from scratch, for processes without a parent.
|
||||
*/
|
||||
static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void)
|
||||
{
|
||||
RTL_USER_PROCESS_PARAMETERS *params = NULL;
|
||||
SIZE_T size;
|
||||
NTSTATUS status;
|
||||
|
||||
size = sizeof(*params);
|
||||
|
||||
status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)¶ms, 0, &size,
|
||||
MEM_COMMIT, PAGE_READWRITE );
|
||||
assert( !status );
|
||||
|
||||
params->AllocationSize = size;
|
||||
params->Size = size;
|
||||
params->Flags = PROCESS_PARAMS_FLAG_NORMALIZED;
|
||||
params->wShowWindow = 1; /* SW_SHOWNORMAL */
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* init_startup_info
|
||||
*/
|
||||
void init_startup_info(void)
|
||||
{
|
||||
WCHAR *src, *dst;
|
||||
NTSTATUS status;
|
||||
SIZE_T size, info_size, env_size;
|
||||
RTL_USER_PROCESS_PARAMETERS *params = NULL;
|
||||
startup_info_t *info;
|
||||
|
||||
if (!startup_info_size)
|
||||
{
|
||||
NtCurrentTeb()->Peb->ProcessParameters = build_initial_params();
|
||||
return;
|
||||
}
|
||||
|
||||
info = malloc( startup_info_size );
|
||||
|
||||
SERVER_START_REQ( get_startup_info )
|
||||
{
|
||||
wine_server_set_reply( req, info, startup_info_size );
|
||||
status = wine_server_call( req );
|
||||
info_size = reply->info_size;
|
||||
env_size = wine_server_reply_size( reply ) - info_size;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
assert( !status );
|
||||
|
||||
size = (sizeof(*params)
|
||||
+ MAX_PATH * sizeof(WCHAR) /* curdir */
|
||||
+ info->dllpath_len + sizeof(WCHAR)
|
||||
+ info->imagepath_len + sizeof(WCHAR)
|
||||
+ info->cmdline_len + sizeof(WCHAR)
|
||||
+ info->title_len + sizeof(WCHAR)
|
||||
+ info->desktop_len + sizeof(WCHAR)
|
||||
+ info->shellinfo_len + sizeof(WCHAR)
|
||||
+ info->runtime_len + sizeof(WCHAR)
|
||||
+ env_size);
|
||||
|
||||
status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)¶ms, 0, &size,
|
||||
MEM_COMMIT, PAGE_READWRITE );
|
||||
assert( !status );
|
||||
|
||||
params->AllocationSize = size;
|
||||
params->Size = size;
|
||||
params->Flags = PROCESS_PARAMS_FLAG_NORMALIZED;
|
||||
params->EnvironmentSize = env_size;
|
||||
params->DebugFlags = info->debug_flags;
|
||||
params->ConsoleHandle = wine_server_ptr_handle( info->console );
|
||||
params->ConsoleFlags = info->console_flags;
|
||||
params->hStdInput = wine_server_ptr_handle( info->hstdin );
|
||||
params->hStdOutput = wine_server_ptr_handle( info->hstdout );
|
||||
params->hStdError = wine_server_ptr_handle( info->hstderr );
|
||||
params->dwX = info->x;
|
||||
params->dwY = info->y;
|
||||
params->dwXSize = info->xsize;
|
||||
params->dwYSize = info->ysize;
|
||||
params->dwXCountChars = info->xchars;
|
||||
params->dwYCountChars = info->ychars;
|
||||
params->dwFillAttribute = info->attribute;
|
||||
params->dwFlags = info->flags;
|
||||
params->wShowWindow = info->show;
|
||||
|
||||
src = (WCHAR *)(info + 1);
|
||||
dst = (WCHAR *)(params + 1);
|
||||
|
||||
/* curdir is special */
|
||||
copy_unicode_string( &src, &dst, ¶ms->CurrentDirectory.DosPath, info->curdir_len );
|
||||
params->CurrentDirectory.DosPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
|
||||
dst = params->CurrentDirectory.DosPath.Buffer + MAX_PATH;
|
||||
|
||||
copy_unicode_string( &src, &dst, ¶ms->DllPath, info->dllpath_len );
|
||||
copy_unicode_string( &src, &dst, ¶ms->ImagePathName, info->imagepath_len );
|
||||
copy_unicode_string( &src, &dst, ¶ms->CommandLine, info->cmdline_len );
|
||||
copy_unicode_string( &src, &dst, ¶ms->WindowTitle, info->title_len );
|
||||
copy_unicode_string( &src, &dst, ¶ms->Desktop, info->desktop_len );
|
||||
copy_unicode_string( &src, &dst, ¶ms->ShellInfo, info->shellinfo_len );
|
||||
copy_unicode_string( &src, &dst, ¶ms->RuntimeInfo, info->runtime_len );
|
||||
params->RuntimeInfo.MaximumLength = params->RuntimeInfo.Length; /* runtime info isn't a real string */
|
||||
params->Environment = dst;
|
||||
memcpy( dst, src, env_size );
|
||||
free( info );
|
||||
NtCurrentTeb()->Peb->ProcessParameters = params;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* NtGetNlsSectionPtr (NTDLL.@)
|
||||
*/
|
||||
|
|
|
@ -1608,7 +1608,6 @@ static struct unix_funcs unix_funcs =
|
|||
ntdll_sqrt,
|
||||
ntdll_tan,
|
||||
get_initial_environment,
|
||||
get_startup_info,
|
||||
get_dynamic_environment,
|
||||
get_initial_console,
|
||||
get_initial_directory,
|
||||
|
@ -1644,6 +1643,7 @@ static void start_main_thread(void)
|
|||
virtual_map_user_shared_data();
|
||||
init_cpu_info();
|
||||
init_files();
|
||||
init_startup_info();
|
||||
NtCreateKeyedEvent( &keyed_event, GENERIC_READ | GENERIC_WRITE, NULL, 0 );
|
||||
load_ntdll();
|
||||
load_libwine();
|
||||
|
|
|
@ -100,7 +100,6 @@ extern NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void
|
|||
const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern NTSTATUS CDECL get_initial_environment( WCHAR **wargv[], WCHAR *env, SIZE_T *size ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL get_startup_info( startup_info_t *info, SIZE_T *total_size, SIZE_T *info_size ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL get_dynamic_environment( WCHAR *env, SIZE_T *size ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL get_initial_directory( UNICODE_STRING *dir ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL get_initial_console( RTL_USER_PROCESS_PARAMETERS *params ) DECLSPEC_HIDDEN;
|
||||
|
@ -138,6 +137,7 @@ extern struct ldt_copy __wine_ldt_copy DECLSPEC_HIDDEN;
|
|||
#endif
|
||||
|
||||
extern void init_environment( int argc, char *argv[], char *envp[] ) DECLSPEC_HIDDEN;
|
||||
extern void init_startup_info(void) DECLSPEC_HIDDEN;
|
||||
extern DWORD ntdll_umbstowcs( const char *src, DWORD srclen, WCHAR *dst, DWORD dstlen ) DECLSPEC_HIDDEN;
|
||||
extern int ntdll_wcstoumbs( const WCHAR *src, DWORD srclen, char *dst, DWORD dstlen, BOOL strict ) DECLSPEC_HIDDEN;
|
||||
extern char **build_envp( const WCHAR *envW ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
struct _DISPATCHER_CONTEXT;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 108
|
||||
#define NTDLL_UNIXLIB_VERSION 109
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -72,7 +72,6 @@ struct unix_funcs
|
|||
|
||||
/* environment functions */
|
||||
NTSTATUS (CDECL *get_initial_environment)( WCHAR **wargv[], WCHAR *env, SIZE_T *size );
|
||||
NTSTATUS (CDECL *get_startup_info)( startup_info_t *info, SIZE_T *total_size, SIZE_T *info_size );
|
||||
NTSTATUS (CDECL *get_dynamic_environment)( WCHAR *env, SIZE_T *size );
|
||||
void (CDECL *get_initial_console)( RTL_USER_PROCESS_PARAMETERS *params );
|
||||
void (CDECL *get_initial_directory)( UNICODE_STRING *dir );
|
||||
|
|
Loading…
Reference in New Issue