Alexandre Julliard : kernel32: Set the USERPROFILE and ALLUSERSPROFILE environment variables based on the ProfileList registry keys .

Alexandre Julliard julliard at winehq.org
Tue May 6 09:32:18 CDT 2008


Module: wine
Branch: master
Commit: 6477a1c1bfd7966ff75b6847156a765ec088b0b3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6477a1c1bfd7966ff75b6847156a765ec088b0b3

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue May  6 15:54:07 2008 +0200

kernel32: Set the USERPROFILE and ALLUSERSPROFILE environment variables based on the ProfileList registry keys.

---

 dlls/kernel32/process.c      |  117 +++++++++++++++++++++++++++++++++++++++--
 dlls/userenv/tests/userenv.c |    2 +-
 tools/wine.inf.in            |    1 -
 3 files changed, 112 insertions(+), 8 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index aeec13d..2118511 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -417,6 +417,50 @@ static BOOL set_registry_environment(void)
     return ret;
 }
 
+
+/***********************************************************************
+ *           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_additional_environment
  *
@@ -424,16 +468,73 @@ static BOOL set_registry_environment(void)
  */
 static void set_additional_environment(void)
 {
+    static const WCHAR profile_keyW[] = {'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',' ','N','T','\\',
+                                         'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+                                         'P','r','o','f','i','l','e','L','i','s','t',0};
+    static const WCHAR profiles_valueW[] = {'P','r','o','f','i','l','e','s','D','i','r','e','c','t','o','r','y',0};
+    static const WCHAR all_users_valueW[] = {'A','l','l','U','s','e','r','s','P','r','o','f','i','l','e','\0'};
     static const WCHAR usernameW[] = {'U','S','E','R','N','A','M','E',0};
+    static const WCHAR userprofileW[] = {'U','S','E','R','P','R','O','F','I','L','E',0};
+    static const WCHAR allusersW[] = {'A','L','L','U','S','E','R','S','P','R','O','F','I','L','E',0};
+    OBJECT_ATTRIBUTES attr;
+    UNICODE_STRING nameW;
+    WCHAR *user_name = NULL, *profile_dir = NULL, *all_users_dir = NULL;
+    HANDLE hkey;
     const char *name = wine_get_user_name();
-    DWORD len = MultiByteToWideChar( CP_UNIXCP, 0, name, -1, NULL, 0 );
+    DWORD len;
+
+    /* set the USERNAME variable */
+
+    len = MultiByteToWideChar( CP_UNIXCP, 0, name, -1, NULL, 0 );
     if (len)
     {
-        LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
-        MultiByteToWideChar( CP_UNIXCP, 0, name, -1, nameW, len );
-        SetEnvironmentVariableW( usernameW, nameW );
-        HeapFree( GetProcessHeap(), 0, nameW );
+        user_name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
+        MultiByteToWideChar( CP_UNIXCP, 0, name, -1, user_name, len );
+        SetEnvironmentVariableW( usernameW, user_name );
     }
+
+    /* set the USERPROFILE and ALLUSERSPROFILE variables */
+
+    attr.Length = sizeof(attr);
+    attr.RootDirectory = 0;
+    attr.ObjectName = &nameW;
+    attr.Attributes = 0;
+    attr.SecurityDescriptor = NULL;
+    attr.SecurityQualityOfService = NULL;
+    RtlInitUnicodeString( &nameW, profile_keyW );
+    if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ))
+    {
+        profile_dir = get_reg_value( hkey, profiles_valueW );
+        all_users_dir = get_reg_value( hkey, all_users_valueW );
+        NtClose( hkey );
+    }
+
+    if (profile_dir)
+    {
+        WCHAR *value, *p;
+
+        if (all_users_dir) len = max( len, strlenW(all_users_dir) + 1 );
+        len += strlenW(profile_dir) + 1;
+        value = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        strcpyW( value, profile_dir );
+        p = value + strlenW(value);
+        if (p > value && p[-1] != '\\') *p++ = '\\';
+        strcpyW( p, user_name );
+        SetEnvironmentVariableW( userprofileW, value );
+        if (all_users_dir)
+        {
+            strcpyW( p, all_users_dir );
+            SetEnvironmentVariableW( allusersW, value );
+        }
+        HeapFree( GetProcessHeap(), 0, value );
+    }
+
+    HeapFree( GetProcessHeap(), 0, all_users_dir );
+    HeapFree( GetProcessHeap(), 0, profile_dir );
+    HeapFree( GetProcessHeap(), 0, user_name );
 }
 
 /***********************************************************************
@@ -945,7 +1046,11 @@ 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();
+            set_additional_environment();
+        }
     }
 
     LdrInitializeThunk( 0, 0, 0, 0 );
diff --git a/dlls/userenv/tests/userenv.c b/dlls/userenv/tests/userenv.c
index eccb1f1..a8d5221 100644
--- a/dlls/userenv/tests/userenv.c
+++ b/dlls/userenv/tests/userenv.c
@@ -162,7 +162,7 @@ static void test_create_env(void)
     int i, j;
 
     static const struct profile_item common_vars[] = {
-        { "ALLUSERSPROFILE", { 1, 1, 1, 1 } },
+        { "ALLUSERSPROFILE", { 1, 1, 0, 0 } },
         { "CommonProgramFiles", { 1, 1, 1, 1 } },
         { "ComSpec", { 1, 1, 0, 0 } },
         { "COMPUTERNAME", { 1, 1, 1, 1 } },
diff --git a/tools/wine.inf.in b/tools/wine.inf.in
index f3750b3..bea392e 100644
--- a/tools/wine.inf.in
+++ b/tools/wine.inf.in
@@ -271,7 +271,6 @@ HKLM,System\CurrentControlSet\Control\Session Manager\Environment,"SystemDrive",
 HKLM,System\CurrentControlSet\Control\Session Manager\Environment,"SYSTEMROOT",,"%10%"
 HKLM,System\CurrentControlSet\Control\Session Manager\Environment,"TEMP",0x00020000,"%10%\temp"
 HKLM,System\CurrentControlSet\Control\Session Manager\Environment,"TMP",0x00020000,"%10%\temp"
-HKLM,System\CurrentControlSet\Control\Session Manager\Environment,"USERPROFILE",,"%53%"
 HKLM,System\CurrentControlSet\Control\Session Manager\Environment,"windir",0x00020000,"%10%"
 HKLM,System\CurrentControlSet\Control\Session Manager\Environment,"winsysdir",,"%11%"
 




More information about the wine-cvs mailing list