ntdll: Set the initial environment and command line in the process parameters on the Unix side.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0d3972ce8a
commit
528f9d3217
240
dlls/ntdll/env.c
240
dlls/ntdll/env.c
|
@ -360,52 +360,6 @@ static void set_wow64_environment( WCHAR **env )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* build_initial_environment
|
||||
*
|
||||
* Build the Win32 environment from the Unix environment
|
||||
*/
|
||||
static WCHAR *build_initial_environment( WCHAR **wargv[] )
|
||||
{
|
||||
SIZE_T size = 1024;
|
||||
WCHAR *ptr;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!(ptr = RtlAllocateHeap( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return NULL;
|
||||
if (!unix_funcs->get_initial_environment( wargv, ptr, &size )) break;
|
||||
RtlFreeHeap( GetProcessHeap(), 0, ptr );
|
||||
}
|
||||
first_prefix_start = set_registry_environment( &ptr, TRUE );
|
||||
set_additional_environment( &ptr );
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_current_directory
|
||||
*
|
||||
* Initialize the current directory from the Unix cwd.
|
||||
*/
|
||||
static void get_current_directory( UNICODE_STRING *dir )
|
||||
{
|
||||
unix_funcs->get_initial_directory( dir );
|
||||
|
||||
if (!dir->Length) /* still not initialized */
|
||||
{
|
||||
dir->Length = wcslen( windows_dir ) * sizeof(WCHAR);
|
||||
memcpy( dir->Buffer, windows_dir, dir->Length );
|
||||
}
|
||||
/* add trailing backslash */
|
||||
if (dir->Buffer[dir->Length / sizeof(WCHAR) - 1] != '\\')
|
||||
{
|
||||
dir->Buffer[dir->Length / sizeof(WCHAR)] = '\\';
|
||||
dir->Length += sizeof(WCHAR);
|
||||
}
|
||||
dir->Buffer[dir->Length / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* is_path_prefix
|
||||
*/
|
||||
|
@ -422,22 +376,22 @@ static inline BOOL is_path_prefix( const WCHAR *prefix, const WCHAR *path, const
|
|||
/***********************************************************************
|
||||
* get_image_path
|
||||
*/
|
||||
static void get_image_path( const WCHAR *name, UNICODE_STRING *path )
|
||||
static void get_image_path( const WCHAR *name, WCHAR *full_name, UINT size )
|
||||
{
|
||||
WCHAR *load_path, *file_part, full_name[MAX_PATH];
|
||||
WCHAR *load_path, *file_part;
|
||||
DWORD len;
|
||||
|
||||
if (RtlDetermineDosPathNameType_U( name ) != RELATIVE_PATH ||
|
||||
wcschr( name, '/' ) || wcschr( name, '\\' ))
|
||||
{
|
||||
len = RtlGetFullPathName_U( name, sizeof(full_name), full_name, &file_part );
|
||||
if (!len || len > sizeof(full_name)) goto failed;
|
||||
len = RtlGetFullPathName_U( name, size, full_name, &file_part );
|
||||
if (!len || len > size) goto failed;
|
||||
/* try first without extension */
|
||||
if (RtlDoesFileExists_U( full_name )) goto done;
|
||||
if (len < (MAX_PATH - 4) * sizeof(WCHAR) && !wcschr( file_part, '.' ))
|
||||
if (RtlDoesFileExists_U( full_name )) return;
|
||||
if (len < size - 4 * sizeof(WCHAR) && !wcschr( file_part, '.' ))
|
||||
{
|
||||
wcscat( file_part, L".exe" );
|
||||
if (RtlDoesFileExists_U( full_name )) goto done;
|
||||
if (RtlDoesFileExists_U( full_name )) return;
|
||||
}
|
||||
/* check for builtin path inside system directory */
|
||||
if (!is_path_prefix( system_dir, full_name, file_part ))
|
||||
|
@ -449,20 +403,18 @@ static void get_image_path( const WCHAR *name, UNICODE_STRING *path )
|
|||
else
|
||||
{
|
||||
RtlGetExePath( name, &load_path );
|
||||
len = RtlDosSearchPath_U( load_path, name, L".exe", sizeof(full_name), full_name, &file_part );
|
||||
len = RtlDosSearchPath_U( load_path, name, L".exe", size, full_name, &file_part );
|
||||
RtlReleasePath( load_path );
|
||||
if (!len || len > sizeof(full_name))
|
||||
if (!len || len > size)
|
||||
{
|
||||
/* build builtin path inside system directory */
|
||||
len = wcslen( system_dir );
|
||||
if (wcslen( name ) >= MAX_PATH - 4 - len) goto failed;
|
||||
if (wcslen( name ) >= size/sizeof(WCHAR) - 4 - len) goto failed;
|
||||
wcscpy( full_name, system_dir );
|
||||
wcscat( full_name, name );
|
||||
if (!wcschr( name, '.' )) wcscat( full_name, L".exe" );
|
||||
}
|
||||
}
|
||||
done:
|
||||
RtlCreateUnicodeString( path, full_name );
|
||||
return;
|
||||
|
||||
failed:
|
||||
|
@ -471,96 +423,6 @@ failed:
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* build_command_line
|
||||
*
|
||||
* Build the command line of a process from the argv array.
|
||||
*
|
||||
* Note that it does NOT necessarily include the file name.
|
||||
* Sometimes we don't even have any command line options at all.
|
||||
*
|
||||
* We must quote and escape characters so that the argv array can be rebuilt
|
||||
* from the command line:
|
||||
* - spaces and tabs must be quoted
|
||||
* 'a b' -> '"a b"'
|
||||
* - quotes must be escaped
|
||||
* '"' -> '\"'
|
||||
* - if '\'s are followed by a '"', they must be doubled and followed by '\"',
|
||||
* resulting in an odd number of '\' followed by a '"'
|
||||
* '\"' -> '\\\"'
|
||||
* '\\"' -> '\\\\\"'
|
||||
* - '\'s are followed by the closing '"' must be doubled,
|
||||
* resulting in an even number of '\' followed by a '"'
|
||||
* ' \' -> '" \\"'
|
||||
* ' \\' -> '" \\\\"'
|
||||
* - '\'s that are not followed by a '"' can be left as is
|
||||
* 'a\b' == 'a\b'
|
||||
* 'a\\b' == 'a\\b'
|
||||
*/
|
||||
static void build_command_line( WCHAR **argv, UNICODE_STRING *cmdline )
|
||||
{
|
||||
int len;
|
||||
WCHAR **arg;
|
||||
LPWSTR p;
|
||||
|
||||
len = 1;
|
||||
for (arg = argv; *arg; arg++) len += 3 + 2 * wcslen( *arg );
|
||||
if (!(cmdline->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return;
|
||||
|
||||
p = cmdline->Buffer;
|
||||
for (arg = argv; *arg; arg++)
|
||||
{
|
||||
BOOL has_space, has_quote;
|
||||
int i, bcount;
|
||||
WCHAR *a;
|
||||
|
||||
/* check for quotes and spaces in this argument */
|
||||
if (arg == argv || !**arg) has_space = TRUE;
|
||||
else has_space = wcschr( *arg, ' ' ) || wcschr( *arg, '\t' );
|
||||
has_quote = wcschr( *arg, '"' ) != NULL;
|
||||
|
||||
/* now transfer it to the command line */
|
||||
if (has_space) *p++ = '"';
|
||||
if (has_quote || has_space)
|
||||
{
|
||||
bcount = 0;
|
||||
for (a = *arg; *a; a++)
|
||||
{
|
||||
if (*a == '\\') bcount++;
|
||||
else
|
||||
{
|
||||
if (*a == '"') /* double all the '\\' preceding this '"', plus one */
|
||||
for (i = 0; i <= bcount; i++) *p++ = '\\';
|
||||
bcount = 0;
|
||||
}
|
||||
*p++ = *a;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscpy( p, *arg );
|
||||
p += wcslen( p );
|
||||
}
|
||||
if (has_space)
|
||||
{
|
||||
/* Double all the '\' preceding the closing quote */
|
||||
for (i = 0; i < bcount; i++) *p++ = '\\';
|
||||
*p++ = '"';
|
||||
}
|
||||
*p++ = ' ';
|
||||
}
|
||||
if (p > cmdline->Buffer) p--; /* remove last space */
|
||||
*p = 0;
|
||||
if (p - cmdline->Buffer >= 32767)
|
||||
{
|
||||
ERR( "command line too long (%u)\n", (DWORD)(p - cmdline->Buffer) );
|
||||
NtTerminateProcess( GetCurrentProcess(), 1 );
|
||||
}
|
||||
cmdline->Length = (p - cmdline->Buffer) * sizeof(WCHAR);
|
||||
cmdline->MaximumLength = cmdline->Length + sizeof(WCHAR);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* RtlCreateEnvironment [NTDLL.@]
|
||||
*/
|
||||
|
@ -1168,50 +1030,14 @@ wait:
|
|||
*/
|
||||
void init_user_process_params(void)
|
||||
{
|
||||
WCHAR *env, *load_path, *dummy;
|
||||
WCHAR *env, *load_path, *dummy, image[MAX_PATH];
|
||||
SIZE_T env_size;
|
||||
RTL_USER_PROCESS_PARAMETERS *new_params, *params = NtCurrentTeb()->Peb->ProcessParameters;
|
||||
UNICODE_STRING curdir, dllpath, cmdline;
|
||||
WCHAR **wargv;
|
||||
|
||||
if (!params->DllPath.MaximumLength) /* not inherited from parent process */
|
||||
{
|
||||
WCHAR curdir_buffer[MAX_PATH];
|
||||
|
||||
params->Environment = build_initial_environment( &wargv );
|
||||
curdir.Buffer = curdir_buffer;
|
||||
curdir.MaximumLength = sizeof(curdir_buffer);
|
||||
get_current_directory( &curdir );
|
||||
params->CurrentDirectory.DosPath = curdir;
|
||||
get_image_path( wargv[0], ¶ms->ImagePathName );
|
||||
wargv[0] = params->ImagePathName.Buffer;
|
||||
build_command_line( wargv, &cmdline );
|
||||
LdrGetDllPath( params->ImagePathName.Buffer, 0, &load_path, &dummy );
|
||||
RtlInitUnicodeString( &dllpath, load_path );
|
||||
|
||||
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;
|
||||
|
||||
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 */
|
||||
|
||||
run_wineboot( ¶ms->Environment );
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* environment needs to be a separate memory block */
|
||||
env_size = params->EnvironmentSize;
|
||||
env = params->Environment;
|
||||
if ((env = RtlAllocateHeap( GetProcessHeap(), 0, max( env_size, sizeof(WCHAR) ))))
|
||||
{
|
||||
if (env_size) memcpy( env, params->Environment, env_size );
|
||||
|
@ -1219,7 +1045,47 @@ void init_user_process_params(void)
|
|||
params->Environment = env;
|
||||
}
|
||||
|
||||
done:
|
||||
if (!params->DllPath.MaximumLength) /* not inherited from parent process */
|
||||
{
|
||||
first_prefix_start = set_registry_environment( ¶ms->Environment, TRUE );
|
||||
set_additional_environment( ¶ms->Environment );
|
||||
|
||||
get_image_path( params->ImagePathName.Buffer, image, sizeof(image) );
|
||||
RtlInitUnicodeString( ¶ms->ImagePathName, image );
|
||||
|
||||
cmdline.Length = params->ImagePathName.Length + params->CommandLine.MaximumLength + 3 * sizeof(WCHAR);
|
||||
cmdline.MaximumLength = cmdline.Length + sizeof(WCHAR);
|
||||
cmdline.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, cmdline.MaximumLength );
|
||||
swprintf( cmdline.Buffer, cmdline.MaximumLength / sizeof(WCHAR),
|
||||
L"\"%s\" %s", params->ImagePathName.Buffer, params->CommandLine.Buffer );
|
||||
|
||||
LdrGetDllPath( params->ImagePathName.Buffer, 0, &load_path, &dummy );
|
||||
RtlInitUnicodeString( &dllpath, load_path );
|
||||
|
||||
env = params->Environment;
|
||||
params->Environment = NULL; /* avoid copying it */
|
||||
if (RtlCreateProcessParametersEx( &new_params, ¶ms->ImagePathName, &dllpath,
|
||||
¶ms->CurrentDirectory.DosPath,
|
||||
&cmdline, NULL, ¶ms->ImagePathName, NULL, NULL, NULL,
|
||||
PROCESS_PARAMS_FLAG_NORMALIZED ))
|
||||
return;
|
||||
|
||||
new_params->Environment = env;
|
||||
new_params->hStdInput = params->hStdInput;
|
||||
new_params->hStdOutput = params->hStdOutput;
|
||||
new_params->hStdError = params->hStdError;
|
||||
new_params->ConsoleHandle = params->ConsoleHandle;
|
||||
new_params->dwXCountChars = params->dwXCountChars;
|
||||
new_params->dwYCountChars = params->dwYCountChars;
|
||||
new_params->wShowWindow = params->wShowWindow;
|
||||
NtCurrentTeb()->Peb->ProcessParameters = params = new_params;
|
||||
|
||||
RtlFreeUnicodeString( &cmdline );
|
||||
RtlReleasePath( load_path );
|
||||
|
||||
run_wineboot( ¶ms->Environment );
|
||||
}
|
||||
|
||||
if (RtlSetCurrentDirectory_U( ¶ms->CurrentDirectory.DosPath ))
|
||||
{
|
||||
MESSAGE("wine: could not open working directory %s, starting in the Windows directory.\n",
|
||||
|
|
|
@ -165,11 +165,11 @@ static NTSTATUS open_nls_data_file( ULONG type, ULONG id, HANDLE *file )
|
|||
if (!path) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
/* try to open file in system dir */
|
||||
ntdll_wcscpy( buffer, type == NLS_SECTION_SORTKEYS ? sortdirW : systemdirW );
|
||||
wcscpy( buffer, type == NLS_SECTION_SORTKEYS ? sortdirW : systemdirW );
|
||||
p = strrchr( path, '/' ) + 1;
|
||||
ascii_to_unicode( buffer + ntdll_wcslen(buffer), p, strlen(p) + 1 );
|
||||
ascii_to_unicode( buffer + wcslen(buffer), p, strlen(p) + 1 );
|
||||
valueW.Buffer = buffer;
|
||||
valueW.Length = ntdll_wcslen( buffer ) * sizeof(WCHAR);
|
||||
valueW.Length = wcslen( buffer ) * sizeof(WCHAR);
|
||||
valueW.MaximumLength = sizeof( buffer );
|
||||
InitializeObjectAttributes( &attr, &valueW, 0, 0, NULL );
|
||||
|
||||
|
@ -1080,12 +1080,22 @@ static const char overrides_help_message[] =
|
|||
*
|
||||
* Return the initial environment.
|
||||
*/
|
||||
NTSTATUS CDECL get_initial_environment( WCHAR **wargv[], WCHAR *env, SIZE_T *size )
|
||||
static WCHAR *get_initial_environment( SIZE_T *ret_size )
|
||||
{
|
||||
char **e;
|
||||
WCHAR *ptr = env, *end = env + *size;
|
||||
SIZE_T size = 1;
|
||||
WCHAR *env, *ptr, *end;
|
||||
|
||||
*wargv = main_wargv;
|
||||
/* estimate needed size */
|
||||
for (e = main_envp; *e; e++)
|
||||
{
|
||||
if (is_special_env_var( *e )) continue;
|
||||
size += strlen(*e) + 1;
|
||||
}
|
||||
|
||||
if (!(env = malloc( size * sizeof(WCHAR) ))) return NULL;
|
||||
ptr = env;
|
||||
end = env + size;
|
||||
for (e = main_envp; *e && ptr < end; e++)
|
||||
{
|
||||
char *str = *e;
|
||||
|
@ -1105,17 +1115,9 @@ NTSTATUS CDECL get_initial_environment( WCHAR **wargv[], WCHAR *env, SIZE_T *siz
|
|||
|
||||
ptr += ntdll_umbstowcs( str, strlen(str) + 1, ptr, end - ptr );
|
||||
}
|
||||
|
||||
if (ptr < end)
|
||||
{
|
||||
*ptr++ = 0;
|
||||
*size = ptr - env;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* estimate needed size */
|
||||
for (e = main_envp, *size = 1; *e; e++) if (!is_special_env_var( *e )) *size += strlen(*e) + 1;
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
*ptr++ = 0;
|
||||
*ret_size = (ptr - env) * sizeof(WCHAR);
|
||||
return env;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1220,7 +1222,7 @@ NTSTATUS CDECL get_dynamic_environment( WCHAR *env, SIZE_T *size )
|
|||
*
|
||||
* Return the initial console handles.
|
||||
*/
|
||||
void CDECL get_initial_console( RTL_USER_PROCESS_PARAMETERS *params )
|
||||
static void get_initial_console( RTL_USER_PROCESS_PARAMETERS *params )
|
||||
{
|
||||
int output_fd = -1;
|
||||
|
||||
|
@ -1264,12 +1266,13 @@ void CDECL get_initial_console( RTL_USER_PROCESS_PARAMETERS *params )
|
|||
*
|
||||
* Get the current directory at startup.
|
||||
*/
|
||||
void CDECL get_initial_directory( UNICODE_STRING *dir )
|
||||
static void get_initial_directory( UNICODE_STRING *dir )
|
||||
{
|
||||
const char *pwd;
|
||||
char *cwd;
|
||||
int size;
|
||||
|
||||
dir->MaximumLength = MAX_PATH * sizeof(WCHAR);
|
||||
dir->Length = 0;
|
||||
|
||||
/* try to get it from the Unix cwd */
|
||||
|
@ -1320,8 +1323,22 @@ void CDECL get_initial_directory( UNICODE_STRING *dir )
|
|||
}
|
||||
|
||||
if (!dir->Length) /* still not initialized */
|
||||
{
|
||||
static const WCHAR windows_dir[] = {'C',':','\\','w','i','n','d','o','w','s'};
|
||||
|
||||
MESSAGE("Warning: could not find DOS drive for current working directory '%s', "
|
||||
"starting in the Windows directory.\n", cwd ? cwd : "" );
|
||||
memcpy( dir->Buffer, windows_dir, sizeof(windows_dir) );
|
||||
dir->Length = sizeof(windows_dir);
|
||||
}
|
||||
|
||||
/* add trailing backslash */
|
||||
if (dir->Buffer[dir->Length / sizeof(WCHAR) - 1] != '\\')
|
||||
{
|
||||
dir->Buffer[dir->Length / sizeof(WCHAR)] = '\\';
|
||||
dir->Length += sizeof(WCHAR);
|
||||
}
|
||||
dir->Buffer[dir->Length / sizeof(WCHAR)] = 0;
|
||||
free( cwd );
|
||||
}
|
||||
|
||||
|
@ -1349,6 +1366,91 @@ void CDECL get_locales( WCHAR *sys, WCHAR *user )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* build_command_line
|
||||
*
|
||||
* Build the command line of a process from the argv array.
|
||||
*
|
||||
* We must quote and escape characters so that the argv array can be rebuilt
|
||||
* from the command line:
|
||||
* - spaces and tabs must be quoted
|
||||
* 'a b' -> '"a b"'
|
||||
* - quotes must be escaped
|
||||
* '"' -> '\"'
|
||||
* - if '\'s are followed by a '"', they must be doubled and followed by '\"',
|
||||
* resulting in an odd number of '\' followed by a '"'
|
||||
* '\"' -> '\\\"'
|
||||
* '\\"' -> '\\\\\"'
|
||||
* - '\'s are followed by the closing '"' must be doubled,
|
||||
* resulting in an even number of '\' followed by a '"'
|
||||
* ' \' -> '" \\"'
|
||||
* ' \\' -> '" \\\\"'
|
||||
* - '\'s that are not followed by a '"' can be left as is
|
||||
* 'a\b' == 'a\b'
|
||||
* 'a\\b' == 'a\\b'
|
||||
*/
|
||||
static WCHAR *build_command_line( WCHAR **wargv )
|
||||
{
|
||||
int len;
|
||||
WCHAR **arg, *ret;
|
||||
LPWSTR p;
|
||||
|
||||
len = 1;
|
||||
for (arg = wargv; *arg; arg++) len += 3 + 2 * wcslen( *arg );
|
||||
if (!(ret = malloc( len * sizeof(WCHAR) ))) return NULL;
|
||||
|
||||
p = ret;
|
||||
for (arg = wargv; *arg; arg++)
|
||||
{
|
||||
BOOL has_space, has_quote;
|
||||
int i, bcount;
|
||||
WCHAR *a;
|
||||
|
||||
/* check for quotes and spaces in this argument */
|
||||
has_space = !**arg || wcschr( *arg, ' ' ) || wcschr( *arg, '\t' );
|
||||
has_quote = wcschr( *arg, '"' ) != NULL;
|
||||
|
||||
/* now transfer it to the command line */
|
||||
if (has_space) *p++ = '"';
|
||||
if (has_quote || has_space)
|
||||
{
|
||||
bcount = 0;
|
||||
for (a = *arg; *a; a++)
|
||||
{
|
||||
if (*a == '\\') bcount++;
|
||||
else
|
||||
{
|
||||
if (*a == '"') /* double all the '\\' preceding this '"', plus one */
|
||||
for (i = 0; i <= bcount; i++) *p++ = '\\';
|
||||
bcount = 0;
|
||||
}
|
||||
*p++ = *a;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscpy( p, *arg );
|
||||
p += wcslen( p );
|
||||
}
|
||||
if (has_space)
|
||||
{
|
||||
/* Double all the '\' preceding the closing quote */
|
||||
for (i = 0; i < bcount; i++) *p++ = '\\';
|
||||
*p++ = '"';
|
||||
}
|
||||
*p++ = ' ';
|
||||
}
|
||||
if (p > ret) p--; /* remove last space */
|
||||
*p = 0;
|
||||
if (p - ret >= 32767)
|
||||
{
|
||||
ERR( "command line too long (%u)\n", (DWORD)(p - ret) );
|
||||
NtTerminateProcess( GetCurrentProcess(), 1 );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static inline void copy_unicode_string( WCHAR **src, WCHAR **dst, UNICODE_STRING *str, UINT len )
|
||||
{
|
||||
str->Buffer = *dst;
|
||||
|
@ -1360,6 +1462,11 @@ static inline void copy_unicode_string( WCHAR **src, WCHAR **dst, UNICODE_STRING
|
|||
*dst += len / sizeof(WCHAR) + 1;
|
||||
}
|
||||
|
||||
static inline void put_unicode_string( WCHAR *src, WCHAR **dst, UNICODE_STRING *str )
|
||||
{
|
||||
copy_unicode_string( &src, dst, str, wcslen(src) * sizeof(WCHAR) );
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* build_initial_params
|
||||
|
@ -1369,10 +1476,17 @@ static inline void copy_unicode_string( WCHAR **src, WCHAR **dst, UNICODE_STRING
|
|||
static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void)
|
||||
{
|
||||
RTL_USER_PROCESS_PARAMETERS *params = NULL;
|
||||
SIZE_T size;
|
||||
SIZE_T size, env_size;
|
||||
WCHAR *dst;
|
||||
WCHAR *cmdline = build_command_line( main_wargv + 1 );
|
||||
WCHAR *env = get_initial_environment( &env_size );
|
||||
NTSTATUS status;
|
||||
|
||||
size = sizeof(*params);
|
||||
size = (sizeof(*params)
|
||||
+ MAX_PATH * sizeof(WCHAR) /* curdir */
|
||||
+ (wcslen( cmdline ) + 1) * sizeof(WCHAR) /* command line */
|
||||
+ (wcslen( main_wargv[0] ) + 1) * sizeof(WCHAR) /* image path */
|
||||
+ env_size);
|
||||
|
||||
status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)¶ms, 0, &size,
|
||||
MEM_COMMIT, PAGE_READWRITE );
|
||||
|
@ -1382,6 +1496,22 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void)
|
|||
params->Size = size;
|
||||
params->Flags = PROCESS_PARAMS_FLAG_NORMALIZED;
|
||||
params->wShowWindow = 1; /* SW_SHOWNORMAL */
|
||||
|
||||
params->CurrentDirectory.DosPath.Buffer = (WCHAR *)(params + 1);
|
||||
get_initial_directory( ¶ms->CurrentDirectory.DosPath );
|
||||
dst = params->CurrentDirectory.DosPath.Buffer + MAX_PATH;
|
||||
|
||||
put_unicode_string( main_wargv[0], &dst, ¶ms->ImagePathName );
|
||||
put_unicode_string( cmdline, &dst, ¶ms->CommandLine );
|
||||
free( cmdline );
|
||||
|
||||
params->Environment = dst;
|
||||
params->EnvironmentSize = env_size;
|
||||
memcpy( dst, env, env_size );
|
||||
free( env );
|
||||
|
||||
get_initial_console( params );
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
@ -1487,7 +1617,7 @@ NTSTATUS WINAPI NtGetNlsSectionPtr( ULONG type, ULONG id, void *unknown, void **
|
|||
if ((status = get_nls_section_name( type, id, name ))) return status;
|
||||
|
||||
nameW.Buffer = name;
|
||||
nameW.Length = ntdll_wcslen(name) * sizeof(WCHAR);
|
||||
nameW.Length = wcslen(name) * sizeof(WCHAR);
|
||||
nameW.MaximumLength = sizeof(name);
|
||||
InitializeObjectAttributes( &attr, &nameW, 0, 0, NULL );
|
||||
if ((status = NtOpenSection( &handle, SECTION_MAP_READ, &attr )))
|
||||
|
|
|
@ -1607,10 +1607,7 @@ static struct unix_funcs unix_funcs =
|
|||
ntdll_sin,
|
||||
ntdll_sqrt,
|
||||
ntdll_tan,
|
||||
get_initial_environment,
|
||||
get_dynamic_environment,
|
||||
get_initial_console,
|
||||
get_initial_directory,
|
||||
get_unix_codepage_data,
|
||||
get_locales,
|
||||
virtual_release_address_space,
|
||||
|
|
|
@ -99,10 +99,7 @@ extern LONGLONG CDECL fast_RtlGetSystemTimePrecise(void) DECLSPEC_HIDDEN;
|
|||
extern NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value,
|
||||
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_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;
|
||||
extern USHORT * CDECL get_unix_codepage_data(void) DECLSPEC_HIDDEN;
|
||||
extern void CDECL get_locales( WCHAR *sys, WCHAR *user ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL virtual_release_address_space(void) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
struct _DISPATCHER_CONTEXT;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 109
|
||||
#define NTDLL_UNIXLIB_VERSION 110
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -71,10 +71,7 @@ struct unix_funcs
|
|||
double (CDECL *tan)( double d );
|
||||
|
||||
/* environment functions */
|
||||
NTSTATUS (CDECL *get_initial_environment)( WCHAR **wargv[], WCHAR *env, SIZE_T *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 );
|
||||
USHORT * (CDECL *get_unix_codepage_data)(void);
|
||||
void (CDECL *get_locales)( WCHAR *sys, WCHAR *user );
|
||||
|
||||
|
|
Loading…
Reference in New Issue