From cd4cd7011fff87b9180b279cf699edf32b6e0666 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Wed, 30 Apr 2008 22:18:34 -0700 Subject: [PATCH 4/5] kernel32: implement __wine_kernel_init_environment. --- dlls/kernel32/kernel32.spec | 1 + dlls/kernel32/process.c | 57 +++++++++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 2f591c2..63532d4 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -1251,3 +1251,4 @@ # Init code @ cdecl __wine_kernel_init() +@ cdecl __wine_kernel_init_environment(ptr long) diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index 59fd1f5..08c32d8 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -267,7 +267,7 @@ static BOOL find_exe_file( const WCHAR *name, WCHAR *buffer, int buflen, HANDLE * * Build the Win32 environment from the Unix environment */ -static BOOL build_initial_environment( char **environ ) +static BOOL build_initial_environment( WCHAR ** env, char **environ ) { SIZE_T size = 1; char **e; @@ -288,7 +288,10 @@ static BOOL build_initial_environment( char **environ ) MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE) != STATUS_SUCCESS) return FALSE; - NtCurrentTeb()->Peb->ProcessParameters->Environment = p = ptr; + if (!env) + NtCurrentTeb()->Peb->ProcessParameters->Environment = p = ptr; + else + *env = p = ptr; endptr = p + size / sizeof(WCHAR); /* And fill it with the Unix environment */ @@ -319,7 +322,7 @@ static BOOL build_initial_environment( char **environ ) * helper for set_registry_environment(). * Note that Windows happily truncates the value if it's too big. */ -static void set_registry_variables( HANDLE hkey, ULONG type ) +static void set_registry_variables( WCHAR ** env, HANDLE hkey, ULONG type ) { UNICODE_STRING env_name, env_value; NTSTATUS status; @@ -350,11 +353,11 @@ static void set_registry_variables( HANDLE hkey, ULONG type ) env_expanded.Buffer=buf_expanded; status = RtlExpandEnvironmentStrings_U(NULL, &env_value, &env_expanded, NULL); if (status == STATUS_SUCCESS || status == STATUS_BUFFER_OVERFLOW) - RtlSetEnvironmentVariable( NULL, &env_name, &env_expanded ); + RtlSetEnvironmentVariable( env, &env_name, &env_expanded ); } else { - RtlSetEnvironmentVariable( NULL, &env_name, &env_value ); + RtlSetEnvironmentVariable( env, &env_name, &env_value ); } } } @@ -372,7 +375,7 @@ static void set_registry_variables( HANDLE hkey, ULONG type ) * %SystemRoot% which are predefined. But Wine defines these in the * registry, so we need two passes. */ -static BOOL set_registry_environment(void) +static BOOL set_registry_environment(WCHAR ** env, BOOL user) { static const WCHAR env_keyW[] = {'M','a','c','h','i','n','e','\\', 'S','y','s','t','e','m','\\', @@ -398,19 +401,21 @@ static BOOL set_registry_environment(void) RtlInitUnicodeString( &nameW, env_keyW ); if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) == STATUS_SUCCESS) { - set_registry_variables( hkey, REG_SZ ); - set_registry_variables( hkey, REG_EXPAND_SZ ); + set_registry_variables( env, hkey, REG_SZ ); + set_registry_variables( env, hkey, REG_EXPAND_SZ ); NtClose( hkey ); ret = TRUE; } + if (!user) return ret; + /* then the ones for the current user */ if (RtlOpenCurrentUser( KEY_ALL_ACCESS, &attr.RootDirectory ) != STATUS_SUCCESS) return ret; RtlInitUnicodeString( &nameW, envW ); if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) == STATUS_SUCCESS) { - set_registry_variables( hkey, REG_SZ ); - set_registry_variables( hkey, REG_EXPAND_SZ ); + set_registry_variables( env, hkey, REG_SZ ); + set_registry_variables( env, hkey, REG_EXPAND_SZ ); NtClose( hkey ); } NtClose( attr.RootDirectory ); @@ -422,16 +427,22 @@ static BOOL set_registry_environment(void) * * Set some additional environment variables not specified in the registry. */ -static void set_additional_environment(void) +static void set_additional_environment(WCHAR ** env) { static const WCHAR usernameW[] = {'U','S','E','R','N','A','M','E',0}; const char *name = wine_get_user_name(); DWORD len = MultiByteToWideChar( CP_UNIXCP, 0, name, -1, NULL, 0 ); if (len) { + UNICODE_STRING us_name; + UNICODE_STRING us_value; LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); MultiByteToWideChar( CP_UNIXCP, 0, name, -1, nameW, len ); - SetEnvironmentVariableW( usernameW, nameW ); + + RtlInitUnicodeString(&us_name, usernameW); + RtlInitUnicodeString(&us_value, nameW); + RtlSetEnvironmentVariable(env, &us_name, &us_value); + HeapFree( GetProcessHeap(), 0, nameW ); } } @@ -880,13 +891,13 @@ void __wine_kernel_init(void) if (!params->Environment) { /* Copy the parent environment */ - if (!build_initial_environment( __wine_main_environ )) exit(1); + if (!build_initial_environment( NULL, __wine_main_environ )) exit(1); /* convert old configuration to new format */ convert_old_config(); - got_environment = set_registry_environment(); - set_additional_environment(); + got_environment = set_registry_environment(NULL, TRUE); + set_additional_environment(NULL); } init_windows_dirs(); @@ -945,7 +956,7 @@ void __wine_kernel_init(void) if (WaitForSingleObject( boot_event, 30000 )) WARN( "boot event wait timed out\n" ); CloseHandle( boot_event ); /* if we didn't find environment section, try again now that wineboot has run */ - if (!got_environment) set_registry_environment(); + if (!got_environment) set_registry_environment(NULL, TRUE); } LdrInitializeThunk( 0, 0, 0, 0 ); @@ -2937,3 +2948,17 @@ HRESULT WINAPI RegisterApplicationRestart(PCWSTR pwzCommandLine, DWORD dwFlags) return S_OK; } + +/*********************************************************************** + * __wine_kernel_init_environment + * + * Initialize the environment. + */ +BOOL __wine_kernel_init_environment(WCHAR ** env, BOOL user) +{ + BOOL r = build_initial_environment(env, __wine_main_environ); + if (!r) return r; + set_registry_environment(env, user); + set_additional_environment(env); + return TRUE; +} -- 1.5.2.2