kernel32: Move initialization of the WoW64 environment to ntdll.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
461b5e56f9
commit
e5354008f4
|
@ -448,177 +448,6 @@ static BOOL find_exe_file( const WCHAR *name, WCHAR *buffer, int buflen, HANDLE
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_reg_value
|
||||
*/
|
||||
static WCHAR *get_reg_value( HKEY hkey, const WCHAR *name )
|
||||
{
|
||||
char buffer[1024 * sizeof(WCHAR) + sizeof(KEY_VALUE_PARTIAL_INFORMATION)];
|
||||
KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
|
||||
DWORD len, size = sizeof(buffer);
|
||||
WCHAR *ret = NULL;
|
||||
UNICODE_STRING nameW;
|
||||
|
||||
RtlInitUnicodeString( &nameW, name );
|
||||
if (NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, buffer, size, &size ))
|
||||
return NULL;
|
||||
|
||||
if (size <= FIELD_OFFSET( KEY_VALUE_PARTIAL_INFORMATION, Data )) return NULL;
|
||||
len = (size - FIELD_OFFSET( KEY_VALUE_PARTIAL_INFORMATION, Data )) / sizeof(WCHAR);
|
||||
|
||||
if (info->Type == REG_EXPAND_SZ)
|
||||
{
|
||||
UNICODE_STRING value, expanded;
|
||||
|
||||
value.MaximumLength = len * sizeof(WCHAR);
|
||||
value.Buffer = (WCHAR *)info->Data;
|
||||
if (!value.Buffer[len - 1]) len--; /* don't count terminating null if any */
|
||||
value.Length = len * sizeof(WCHAR);
|
||||
expanded.Length = expanded.MaximumLength = 1024 * sizeof(WCHAR);
|
||||
if (!(expanded.Buffer = HeapAlloc( GetProcessHeap(), 0, expanded.MaximumLength ))) return NULL;
|
||||
if (!RtlExpandEnvironmentStrings_U( NULL, &value, &expanded, NULL )) ret = expanded.Buffer;
|
||||
else RtlFreeUnicodeString( &expanded );
|
||||
}
|
||||
else if (info->Type == REG_SZ)
|
||||
{
|
||||
if ((ret = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
|
||||
{
|
||||
memcpy( ret, info->Data, len * sizeof(WCHAR) );
|
||||
ret[len] = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set an environment variable for one of the wine path variables */
|
||||
static void set_wine_path_variable( const WCHAR *name, const char *unix_path )
|
||||
{
|
||||
UNICODE_STRING nt_name, var_name;
|
||||
ANSI_STRING unix_name;
|
||||
|
||||
RtlInitUnicodeString( &var_name, name );
|
||||
if (unix_path)
|
||||
{
|
||||
RtlInitAnsiString( &unix_name, unix_path );
|
||||
if (wine_unix_to_nt_file_name( &unix_name, &nt_name )) return;
|
||||
RtlSetEnvironmentVariable( NULL, &var_name, &nt_name );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
}
|
||||
else RtlSetEnvironmentVariable( NULL, &var_name, NULL );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* set_wow64_environment
|
||||
*
|
||||
* Set the environment variables that change across 32/64/Wow64.
|
||||
*/
|
||||
static void set_wow64_environment(void)
|
||||
{
|
||||
static const WCHAR archW[] = {'P','R','O','C','E','S','S','O','R','_','A','R','C','H','I','T','E','C','T','U','R','E',0};
|
||||
static const WCHAR arch6432W[] = {'P','R','O','C','E','S','S','O','R','_','A','R','C','H','I','T','E','W','6','4','3','2',0};
|
||||
static const WCHAR x86W[] = {'x','8','6',0};
|
||||
static const WCHAR versionW[] = {'\\','R','e','g','i','s','t','r','y','\\',
|
||||
'M','a','c','h','i','n','e','\\',
|
||||
'S','o','f','t','w','a','r','e','\\',
|
||||
'M','i','c','r','o','s','o','f','t','\\',
|
||||
'W','i','n','d','o','w','s','\\',
|
||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n',0};
|
||||
static const WCHAR progdirW[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',0};
|
||||
static const WCHAR progdir86W[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',' ','(','x','8','6',')',0};
|
||||
static const WCHAR progfilesW[] = {'P','r','o','g','r','a','m','F','i','l','e','s',0};
|
||||
static const WCHAR progw6432W[] = {'P','r','o','g','r','a','m','W','6','4','3','2',0};
|
||||
static const WCHAR commondirW[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r',0};
|
||||
static const WCHAR commondir86W[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r',' ','(','x','8','6',')',0};
|
||||
static const WCHAR commonfilesW[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','F','i','l','e','s',0};
|
||||
static const WCHAR commonw6432W[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','W','6','4','3','2',0};
|
||||
static const WCHAR winedlldirW[] = {'W','I','N','E','D','L','L','D','I','R','%','u',0};
|
||||
static const WCHAR winehomedirW[] = {'W','I','N','E','H','O','M','E','D','I','R',0};
|
||||
static const WCHAR winedatadirW[] = {'W','I','N','E','D','A','T','A','D','I','R',0};
|
||||
static const WCHAR winebuilddirW[] = {'W','I','N','E','B','U','I','L','D','D','I','R',0};
|
||||
static const WCHAR wineconfigdirW[] = {'W','I','N','E','C','O','N','F','I','G','D','I','R',0};
|
||||
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
const char *path;
|
||||
WCHAR buf[64];
|
||||
WCHAR *value;
|
||||
HANDLE hkey;
|
||||
DWORD i;
|
||||
|
||||
/* set the Wine paths */
|
||||
|
||||
set_wine_path_variable( winedatadirW, wine_get_data_dir() );
|
||||
set_wine_path_variable( winehomedirW, getenv("HOME") );
|
||||
set_wine_path_variable( winebuilddirW, wine_get_build_dir() );
|
||||
set_wine_path_variable( wineconfigdirW, wine_get_config_dir() );
|
||||
for (i = 0; (path = wine_dll_enum_load_path( i )); i++)
|
||||
{
|
||||
sprintfW( buf, winedlldirW, i );
|
||||
set_wine_path_variable( buf, path );
|
||||
}
|
||||
sprintfW( buf, winedlldirW, i );
|
||||
set_wine_path_variable( buf, NULL );
|
||||
|
||||
/* set the PROCESSOR_ARCHITECTURE variable */
|
||||
|
||||
if (GetEnvironmentVariableW( arch6432W, buf, ARRAY_SIZE( buf )))
|
||||
{
|
||||
if (is_win64)
|
||||
{
|
||||
SetEnvironmentVariableW( archW, buf );
|
||||
SetEnvironmentVariableW( arch6432W, NULL );
|
||||
}
|
||||
}
|
||||
else if (GetEnvironmentVariableW( archW, buf, ARRAY_SIZE( buf )))
|
||||
{
|
||||
if (is_wow64)
|
||||
{
|
||||
SetEnvironmentVariableW( arch6432W, buf );
|
||||
SetEnvironmentVariableW( archW, x86W );
|
||||
}
|
||||
}
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.ObjectName = &nameW;
|
||||
attr.Attributes = 0;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
RtlInitUnicodeString( &nameW, versionW );
|
||||
if (NtOpenKey( &hkey, KEY_READ | KEY_WOW64_64KEY, &attr )) return;
|
||||
|
||||
/* set the ProgramFiles variables */
|
||||
|
||||
if ((value = get_reg_value( hkey, progdirW )))
|
||||
{
|
||||
if (is_win64 || is_wow64) SetEnvironmentVariableW( progw6432W, value );
|
||||
if (is_win64 || !is_wow64) SetEnvironmentVariableW( progfilesW, value );
|
||||
HeapFree( GetProcessHeap(), 0, value );
|
||||
}
|
||||
if (is_wow64 && (value = get_reg_value( hkey, progdir86W )))
|
||||
{
|
||||
SetEnvironmentVariableW( progfilesW, value );
|
||||
HeapFree( GetProcessHeap(), 0, value );
|
||||
}
|
||||
|
||||
/* set the CommonProgramFiles variables */
|
||||
|
||||
if ((value = get_reg_value( hkey, commondirW )))
|
||||
{
|
||||
if (is_win64 || is_wow64) SetEnvironmentVariableW( commonw6432W, value );
|
||||
if (is_win64 || !is_wow64) SetEnvironmentVariableW( commonfilesW, value );
|
||||
HeapFree( GetProcessHeap(), 0, value );
|
||||
}
|
||||
if (is_wow64 && (value = get_reg_value( hkey, commondir86W )))
|
||||
{
|
||||
SetEnvironmentVariableW( commonfilesW, value );
|
||||
HeapFree( GetProcessHeap(), 0, value );
|
||||
}
|
||||
|
||||
NtClose( hkey );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* set_library_argv
|
||||
*
|
||||
|
@ -777,7 +606,6 @@ void * CDECL __wine_kernel_init(void)
|
|||
TRACE( "starting process name=%s argv[0]=%s\n",
|
||||
debugstr_w(main_exe_name), debugstr_w(__wine_main_wargv[0]) );
|
||||
|
||||
set_wow64_environment();
|
||||
set_library_argv( __wine_main_wargv );
|
||||
|
||||
if (!(peb->ImageBaseAddress = LoadLibraryExW( main_exe_name, 0, DONT_RESOLVE_DLL_REFERENCES )))
|
||||
|
|
159
dlls/ntdll/env.c
159
dlls/ntdll/env.c
|
@ -86,6 +86,19 @@ static inline BOOL is_special_env_var( const char *var )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* set_env_var
|
||||
*/
|
||||
static void set_env_var( WCHAR **env, const WCHAR *name, const WCHAR *val )
|
||||
{
|
||||
UNICODE_STRING nameW, valW;
|
||||
|
||||
RtlInitUnicodeString( &nameW, name );
|
||||
RtlInitUnicodeString( &valW, val );
|
||||
RtlSetEnvironmentVariable( env, &nameW, &valW );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* set_registry_variables
|
||||
*
|
||||
|
@ -278,7 +291,7 @@ static void set_additional_environment( WCHAR **env )
|
|||
static const WCHAR programdataW[] = {'P','r','o','g','r','a','m','D','a','t','a',0};
|
||||
static const WCHAR publicW[] = {'P','U','B','L','I','C',0};
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW, valW;
|
||||
UNICODE_STRING nameW;
|
||||
WCHAR *val;
|
||||
HANDLE hkey;
|
||||
|
||||
|
@ -290,18 +303,13 @@ static void set_additional_environment( WCHAR **env )
|
|||
{
|
||||
if ((val = get_registry_value( *env, hkey, programdataW )))
|
||||
{
|
||||
RtlInitUnicodeString( &valW, val );
|
||||
RtlInitUnicodeString( &nameW, allusersW );
|
||||
RtlSetEnvironmentVariable( env, &nameW, &valW );
|
||||
RtlInitUnicodeString( &nameW, programdataW );
|
||||
RtlSetEnvironmentVariable( env, &nameW, &valW );
|
||||
set_env_var( env, allusersW, val );
|
||||
set_env_var( env, programdataW, val );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, val );
|
||||
}
|
||||
if ((val = get_registry_value( *env, hkey, public_valueW )))
|
||||
{
|
||||
RtlInitUnicodeString( &valW, val );
|
||||
RtlInitUnicodeString( &nameW, publicW );
|
||||
RtlSetEnvironmentVariable( env, &nameW, &valW );
|
||||
set_env_var( env, publicW, val );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, val );
|
||||
}
|
||||
NtClose( hkey );
|
||||
|
@ -314,9 +322,7 @@ static void set_additional_environment( WCHAR **env )
|
|||
{
|
||||
if ((val = get_registry_value( *env, hkey, computer_valueW )))
|
||||
{
|
||||
RtlInitUnicodeString( &valW, val );
|
||||
RtlInitUnicodeString( &nameW, computernameW );
|
||||
RtlSetEnvironmentVariable( env, &nameW, &valW );
|
||||
set_env_var( env, computernameW, val );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, val );
|
||||
}
|
||||
NtClose( hkey );
|
||||
|
@ -324,6 +330,134 @@ static void set_additional_environment( WCHAR **env )
|
|||
}
|
||||
|
||||
|
||||
/* set an environment variable for one of the wine path variables */
|
||||
static void set_wine_path_variable( WCHAR **env, const WCHAR *name, const char *unix_path )
|
||||
{
|
||||
UNICODE_STRING nt_name, var_name;
|
||||
ANSI_STRING unix_name;
|
||||
|
||||
RtlInitUnicodeString( &var_name, name );
|
||||
if (unix_path)
|
||||
{
|
||||
RtlInitAnsiString( &unix_name, unix_path );
|
||||
if (wine_unix_to_nt_file_name( &unix_name, &nt_name )) return;
|
||||
RtlSetEnvironmentVariable( env, &var_name, &nt_name );
|
||||
RtlFreeUnicodeString( &nt_name );
|
||||
}
|
||||
else RtlSetEnvironmentVariable( env, &var_name, NULL );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* set_wow64_environment
|
||||
*
|
||||
* Set the environment variables that change across 32/64/Wow64.
|
||||
*/
|
||||
static void set_wow64_environment( WCHAR **env )
|
||||
{
|
||||
static WCHAR archW[] = {'P','R','O','C','E','S','S','O','R','_','A','R','C','H','I','T','E','C','T','U','R','E',0};
|
||||
static WCHAR arch6432W[] = {'P','R','O','C','E','S','S','O','R','_','A','R','C','H','I','T','E','W','6','4','3','2',0};
|
||||
static const WCHAR x86W[] = {'x','8','6',0};
|
||||
static const WCHAR versionW[] = {'\\','R','e','g','i','s','t','r','y','\\',
|
||||
'M','a','c','h','i','n','e','\\',
|
||||
'S','o','f','t','w','a','r','e','\\',
|
||||
'M','i','c','r','o','s','o','f','t','\\',
|
||||
'W','i','n','d','o','w','s','\\',
|
||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n',0};
|
||||
static const WCHAR progdirW[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',0};
|
||||
static const WCHAR progdir86W[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',' ','(','x','8','6',')',0};
|
||||
static const WCHAR progfilesW[] = {'P','r','o','g','r','a','m','F','i','l','e','s',0};
|
||||
static const WCHAR progw6432W[] = {'P','r','o','g','r','a','m','W','6','4','3','2',0};
|
||||
static const WCHAR commondirW[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r',0};
|
||||
static const WCHAR commondir86W[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r',' ','(','x','8','6',')',0};
|
||||
static const WCHAR commonfilesW[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','F','i','l','e','s',0};
|
||||
static const WCHAR commonw6432W[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','W','6','4','3','2',0};
|
||||
static const WCHAR winedlldirW[] = {'W','I','N','E','D','L','L','D','I','R','%','u',0};
|
||||
static const WCHAR winehomedirW[] = {'W','I','N','E','H','O','M','E','D','I','R',0};
|
||||
static const WCHAR winedatadirW[] = {'W','I','N','E','D','A','T','A','D','I','R',0};
|
||||
static const WCHAR winebuilddirW[] = {'W','I','N','E','B','U','I','L','D','D','I','R',0};
|
||||
static const WCHAR wineconfigdirW[] = {'W','I','N','E','C','O','N','F','I','G','D','I','R',0};
|
||||
|
||||
WCHAR buf[64];
|
||||
UNICODE_STRING arch_strW = { sizeof(archW) - sizeof(WCHAR), sizeof(archW), archW };
|
||||
UNICODE_STRING arch6432_strW = { sizeof(arch6432W) - sizeof(WCHAR), sizeof(arch6432W), arch6432W };
|
||||
UNICODE_STRING valW = { 0, sizeof(buf), buf };
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
const char *path;
|
||||
WCHAR *val;
|
||||
HANDLE hkey;
|
||||
DWORD i;
|
||||
|
||||
/* set the Wine paths */
|
||||
|
||||
set_wine_path_variable( env, winedatadirW, wine_get_data_dir() );
|
||||
set_wine_path_variable( env, winehomedirW, getenv("HOME") );
|
||||
set_wine_path_variable( env, winebuilddirW, wine_get_build_dir() );
|
||||
set_wine_path_variable( env, wineconfigdirW, wine_get_config_dir() );
|
||||
for (i = 0; (path = wine_dll_enum_load_path( i )); i++)
|
||||
{
|
||||
sprintfW( buf, winedlldirW, i );
|
||||
set_wine_path_variable( env, buf, path );
|
||||
}
|
||||
sprintfW( buf, winedlldirW, i );
|
||||
set_wine_path_variable( env, buf, NULL );
|
||||
|
||||
/* set the PROCESSOR_ARCHITECTURE variable */
|
||||
|
||||
if (!RtlQueryEnvironmentVariable_U( *env, &arch6432_strW, &valW ))
|
||||
{
|
||||
if (is_win64)
|
||||
{
|
||||
RtlSetEnvironmentVariable( env, &arch_strW, &valW );
|
||||
RtlSetEnvironmentVariable( env, &arch6432_strW, NULL );
|
||||
}
|
||||
}
|
||||
else if (!RtlQueryEnvironmentVariable_U( *env, &arch_strW, &valW ))
|
||||
{
|
||||
if (is_wow64)
|
||||
{
|
||||
RtlSetEnvironmentVariable( env, &arch6432_strW, &valW );
|
||||
RtlInitUnicodeString( &nameW, x86W );
|
||||
RtlSetEnvironmentVariable( env, &arch_strW, &nameW );
|
||||
}
|
||||
}
|
||||
|
||||
InitializeObjectAttributes( &attr, &nameW, 0, 0, NULL );
|
||||
RtlInitUnicodeString( &nameW, versionW );
|
||||
if (NtOpenKey( &hkey, KEY_READ | KEY_WOW64_64KEY, &attr )) return;
|
||||
|
||||
/* set the ProgramFiles variables */
|
||||
|
||||
if ((val = get_registry_value( *env, hkey, progdirW )))
|
||||
{
|
||||
if (is_win64 || is_wow64) set_env_var( env, progw6432W, val );
|
||||
if (is_win64 || !is_wow64) set_env_var( env, progfilesW, val );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, val );
|
||||
}
|
||||
if (is_wow64 && (val = get_registry_value( *env, hkey, progdir86W )))
|
||||
{
|
||||
set_env_var( env, progfilesW, val );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, val );
|
||||
}
|
||||
|
||||
/* set the CommonProgramFiles variables */
|
||||
|
||||
if ((val = get_registry_value( *env, hkey, commondirW )))
|
||||
{
|
||||
if (is_win64 || is_wow64) set_env_var( env, commonw6432W, val );
|
||||
if (is_win64 || !is_wow64) set_env_var( env, commonfilesW, val );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, val );
|
||||
}
|
||||
if (is_wow64 && (val = get_registry_value( *env, hkey, commondir86W )))
|
||||
{
|
||||
set_env_var( env, commonfilesW, val );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, val );
|
||||
}
|
||||
NtClose( hkey );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* build_initial_environment
|
||||
*
|
||||
|
@ -1319,6 +1453,7 @@ done:
|
|||
RtlInitUnicodeString( &curdir, windows_dir );
|
||||
RtlSetCurrentDirectory_U( &curdir );
|
||||
}
|
||||
set_wow64_environment( ¶ms->Environment );
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue