ntdll: Set the Wow64 environment variables from the Unix side.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1b4b4a9bb5
commit
662730a1bf
100
dlls/ntdll/env.c
100
dlls/ntdll/env.c
|
@ -47,67 +47,6 @@ static inline SIZE_T get_env_length( const WCHAR *env )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* set_env_var
|
||||
*/
|
||||
static void set_env_var( WCHAR **env, const WCHAR *name, const WCHAR *val )
|
||||
{
|
||||
UNICODE_STRING nameW, valW;
|
||||
|
||||
RtlInitUnicodeString( &nameW, name );
|
||||
if (val)
|
||||
{
|
||||
RtlInitUnicodeString( &valW, val );
|
||||
RtlSetEnvironmentVariable( env, &nameW, &valW );
|
||||
}
|
||||
else RtlSetEnvironmentVariable( env, &nameW, NULL );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_registry_value
|
||||
*/
|
||||
static WCHAR *get_registry_value( WCHAR *env, 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 = RtlAllocateHeap( GetProcessHeap(), 0, expanded.MaximumLength )))
|
||||
return NULL;
|
||||
if (!RtlExpandEnvironmentStrings_U( env, &value, &expanded, NULL )) ret = expanded.Buffer;
|
||||
else RtlFreeUnicodeString( &expanded );
|
||||
}
|
||||
else if (info->Type == REG_SZ)
|
||||
{
|
||||
if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
|
||||
{
|
||||
memcpy( ret, info->Data, len * sizeof(WCHAR) );
|
||||
ret[len] = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* set_wow64_environment
|
||||
*
|
||||
|
@ -122,10 +61,7 @@ static void set_wow64_environment( WCHAR **env )
|
|||
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;
|
||||
HANDLE hkey;
|
||||
WCHAR *val;
|
||||
|
||||
/* set the PROCESSOR_ARCHITECTURE variable */
|
||||
|
||||
|
@ -147,40 +83,26 @@ static void set_wow64_environment( WCHAR **env )
|
|||
}
|
||||
}
|
||||
|
||||
InitializeObjectAttributes( &attr, &nameW, 0, 0, NULL );
|
||||
RtlInitUnicodeString( &nameW, L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion" );
|
||||
if (NtOpenKey( &hkey, KEY_READ | KEY_WOW64_64KEY, &attr )) return;
|
||||
|
||||
/* set the ProgramFiles variables */
|
||||
|
||||
if ((val = get_registry_value( *env, hkey, L"ProgramFilesDir" )))
|
||||
RtlInitUnicodeString( &nameW, is_win64 ? L"ProgramW6432" : L"ProgramFiles(x86)" );
|
||||
if (!RtlQueryEnvironmentVariable_U( *env, &nameW, &valW ))
|
||||
{
|
||||
if (is_win64 || is_wow64) set_env_var( env, L"ProgramW6432", val );
|
||||
if (is_win64 || !is_wow64) set_env_var( env, L"ProgramFiles", val );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, val );
|
||||
}
|
||||
if ((val = get_registry_value( *env, hkey, L"ProgramFilesDir (x86)" )))
|
||||
{
|
||||
if (is_win64 || is_wow64) set_env_var( env, L"ProgramFiles(x86)", val );
|
||||
if (is_wow64) set_env_var( env, L"ProgramFiles", val );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, val );
|
||||
RtlInitUnicodeString( &nameW, L"ProgramFiles" );
|
||||
RtlSetEnvironmentVariable( env, &nameW, &valW );
|
||||
}
|
||||
|
||||
/* set the CommonProgramFiles variables */
|
||||
|
||||
if ((val = get_registry_value( *env, hkey, L"CommonFilesDir" )))
|
||||
RtlInitUnicodeString( &nameW, is_win64 ? L"CommonProgramW6432" : L"CommonProgramFiles(x86)" );
|
||||
if (!RtlQueryEnvironmentVariable_U( *env, &nameW, &valW ))
|
||||
{
|
||||
if (is_win64 || is_wow64) set_env_var( env, L"CommonProgramW6432", val );
|
||||
if (is_win64 || !is_wow64) set_env_var( env, L"CommonProgramFiles", val );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, val );
|
||||
RtlInitUnicodeString( &nameW, L"CommonProgramFiles" );
|
||||
RtlSetEnvironmentVariable( env, &nameW, &valW );
|
||||
}
|
||||
if ((val = get_registry_value( *env, hkey, L"CommonFilesDir (x86)" )))
|
||||
{
|
||||
if (is_win64 || is_wow64) set_env_var( env, L"CommonProgramFiles(x86)", val );
|
||||
if (is_wow64) set_env_var( env, L"CommonProgramFiles", val );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, val );
|
||||
}
|
||||
NtClose( hkey );
|
||||
|
||||
RtlReAllocateHeap( GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, *env,
|
||||
get_env_length(*env) * sizeof(WCHAR) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1408,10 +1408,12 @@ static void add_registry_environment( WCHAR **env, SIZE_T *pos, SIZE_T *size )
|
|||
'\\','C','o','n','t','r','o','l',
|
||||
'\\','C','o','m','p','u','t','e','r','N','a','m','e',
|
||||
'\\','A','c','t','i','v','e','C','o','m','p','u','t','e','r','N','a','m','e',0};
|
||||
static const WCHAR progdataW[] = {'P','r','o','g','r','a','m','D','a','t','a',0};
|
||||
static const WCHAR allusersW[] = {'A','L','L','U','S','E','R','S','P','R','O','F','I','L','E',0};
|
||||
static const WCHAR publicW[] = {'P','U','B','L','I','C',0};
|
||||
static const WCHAR computernameW[] = {'C','O','M','P','U','T','E','R','N','A','M','E',0};
|
||||
static const WCHAR curversionW[] = {'\\','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};
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING nameW;
|
||||
WCHAR *value;
|
||||
|
@ -1439,6 +1441,9 @@ static void add_registry_environment( WCHAR **env, SIZE_T *pos, SIZE_T *size )
|
|||
init_unicode_string( &nameW, profileW );
|
||||
if (!NtOpenKey( &key, KEY_READ, &attr ))
|
||||
{
|
||||
static const WCHAR progdataW[] = {'P','r','o','g','r','a','m','D','a','t','a',0};
|
||||
static const WCHAR allusersW[] = {'A','L','L','U','S','E','R','S','P','R','O','F','I','L','E',0};
|
||||
static const WCHAR publicW[] = {'P','U','B','L','I','C',0};
|
||||
if ((value = get_registry_value( *env, *pos, key, progdataW )))
|
||||
{
|
||||
set_env_var( env, pos, size, allusersW, wcslen(allusersW), value );
|
||||
|
@ -1453,10 +1458,56 @@ static void add_registry_environment( WCHAR **env, SIZE_T *pos, SIZE_T *size )
|
|||
NtClose( key );
|
||||
}
|
||||
|
||||
/* set the ProgramFiles variables */
|
||||
init_unicode_string( &nameW, curversionW );
|
||||
if (!NtOpenKey( &key, KEY_READ | KEY_WOW64_64KEY, &attr ))
|
||||
{
|
||||
static const WCHAR progdirW[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',0};
|
||||
static const WCHAR progdirx86W[] = {'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 prog6432W[] = {'P','r','o','g','r','a','m','W','6','4','3','2',0};
|
||||
static const WCHAR progx86W[] = {'P','r','o','g','r','a','m','F','i','l','e','s','(','x','8','6',')',0};
|
||||
static const WCHAR commondirW[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r',0};
|
||||
static const WCHAR commondirx86W[] = {'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 common6432W[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','W','6','4','3','2',0};
|
||||
static const WCHAR commonx86W[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','F','i','l','e','s','(','x','8','6',')',0};
|
||||
|
||||
if ((value = get_registry_value( *env, *pos, key, progdirx86W )))
|
||||
{
|
||||
set_env_var( env, pos, size, progx86W, wcslen(progx86W), value );
|
||||
free( value );
|
||||
if ((value = get_registry_value( *env, *pos, key, progdirW )))
|
||||
set_env_var( env, pos, size, prog6432W, wcslen(prog6432W), value );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((value = get_registry_value( *env, *pos, key, progdirW )))
|
||||
set_env_var( env, pos, size, progfilesW, wcslen(progfilesW), value );
|
||||
}
|
||||
free( value );
|
||||
|
||||
if ((value = get_registry_value( *env, *pos, key, commondirx86W )))
|
||||
{
|
||||
set_env_var( env, pos, size, commonx86W, wcslen(commonx86W), value );
|
||||
free( value );
|
||||
if ((value = get_registry_value( *env, *pos, key, commondirW )))
|
||||
set_env_var( env, pos, size, common6432W, wcslen(common6432W), value );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((value = get_registry_value( *env, *pos, key, commondirW )))
|
||||
set_env_var( env, pos, size, commonfilesW, wcslen(commonfilesW), value );
|
||||
}
|
||||
free( value );
|
||||
NtClose( key );
|
||||
}
|
||||
|
||||
/* set the computer name */
|
||||
init_unicode_string( &nameW, computerW );
|
||||
if (!NtOpenKey( &key, KEY_READ, &attr ))
|
||||
{
|
||||
static const WCHAR computernameW[] = {'C','O','M','P','U','T','E','R','N','A','M','E',0};
|
||||
if ((value = get_registry_value( *env, *pos, key, computernameW )))
|
||||
{
|
||||
set_env_var( env, pos, size, computernameW, wcslen(computernameW), value );
|
||||
|
|
Loading…
Reference in New Issue