[WINLOGON]
authorEric Kohl <eric.kohl@reactos.org>
Fri, 14 May 2010 17:08:20 +0000 (17:08 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Fri, 14 May 2010 17:08:20 +0000 (17:08 +0000)
- Store all environment variables that were passed from msgina.dll in the volatile environment key.
- Add the APPDATA environment variable to the volatile environment. Unfortunately SHGetFolderPath does not seem to expand the appdata path. Bug or Feature??
- Create the environment block for the shell process after the volatile environment key has been filled, so its variables are included.
- Yet another step to fixing bug #4102.

svn path=/trunk/; revision=47198

reactos/base/system/winlogon/environment.c
reactos/base/system/winlogon/sas.c
reactos/base/system/winlogon/winlogon.h

index 4d349fe..769767c 100644 (file)
@@ -11,6 +11,7 @@
 /* INCLUDES *****************************************************************/
 
 #include "winlogon.h"
+#include <shlobj.h>
 
 #include <wine/debug.h>
 
@@ -18,74 +19,104 @@ WINE_DEFAULT_DEBUG_CHANNEL(winlogon);
 
 /* GLOBALS ******************************************************************/
 
+typedef HRESULT (WINAPI *PFSHGETFOLDERPATHW)(HWND, int, HANDLE, DWORD, LPWSTR);
+
 
 /* FUNCTIONS ****************************************************************/
 
-BOOL
-CreateUserEnvironment(IN PWLSESSION Session,
-                      IN LPVOID *lpEnvironment,
-                      IN LPWSTR *lpFullEnv)
+static VOID
+BuildVolatileEnvironment(IN PWLSESSION Session,
+                         IN HKEY hKey)
 {
+    HINSTANCE hShell32 = NULL;
+    PFSHGETFOLDERPATHW pfSHGetFolderPathW = NULL;
+    WCHAR szPath[MAX_PATH + 1];
     LPCWSTR wstr;
-    SIZE_T EnvBlockSize = 0, ProfileSize = 0;
-    LPVOID lpEnviron = NULL;
-    LPWSTR lpFullEnviron = NULL;
-    HKEY hKey;
-    DWORD dwDisp;
-    LONG lError;
-    HKEY hKeyCurrentUser;
+    SIZE_T size;
 
-    TRACE("WL: CreateUserEnvironment called\n");
+    WCHAR szEnvKey[MAX_PATH];
+    WCHAR szEnvValue[1024];
 
-    /* Create environment block for the user */
-    if (!CreateEnvironmentBlock(&lpEnviron,
-                                Session->UserToken,
-                                TRUE))
-    {
-        WARN("WL: CreateEnvironmentBlock() failed\n");
-        return FALSE;
-    }
+    SIZE_T length;
+    LPWSTR eqptr, endptr;
 
-    if (Session->Profile->dwType == WLX_PROFILE_TYPE_V2_0 && Session->Profile->pszEnvironment)
+    if (Session->Profile->dwType == WLX_PROFILE_TYPE_V2_0 &&
+        Session->Profile->pszEnvironment != NULL)
     {
-        /* Count required size for full environment */
-        wstr = (LPCWSTR)lpEnviron;
-        while (*wstr != UNICODE_NULL)
-        {
-            SIZE_T size = wcslen(wstr) + 1;
-            wstr += size;
-            EnvBlockSize += size;
-        }
-
         wstr = Session->Profile->pszEnvironment;
         while (*wstr != UNICODE_NULL)
         {
-            SIZE_T size = wcslen(wstr) + 1;
+            size = wcslen(wstr) + 1;
+
+            eqptr = wcschr(wstr, L'=');
+
+            if (eqptr != NULL)
+            {
+                endptr = eqptr;
+
+                endptr--;
+                while (iswspace(*endptr))
+                    endptr--;
+
+                length = (SIZE_T)(endptr - wstr + 1);
+
+                wcsncpy(szEnvKey, wstr, length);
+                szEnvKey[length] = 0;
+
+                eqptr++;
+                while (iswspace(*eqptr))
+                    eqptr++;
+                wcscpy(szEnvValue, eqptr);
+
+                RegSetValueExW(hKey,
+                               szEnvKey,
+                               0,
+                               REG_SZ,
+                               (LPBYTE)szEnvValue,
+                               (wcslen(szEnvValue) + 1) * sizeof(WCHAR));
+            }
+
             wstr += size;
-            ProfileSize += size;
         }
+    }
 
-        /* Allocate enough memory */
-        lpFullEnviron = HeapAlloc(GetProcessHeap(), 0, (EnvBlockSize + ProfileSize + 1) * sizeof(WCHAR));
-        if (!lpFullEnviron)
+
+    hShell32 = LoadLibraryW(L"shell32.dll");
+    if (hShell32 != NULL)
+    {
+        pfSHGetFolderPathW = (PFSHGETFOLDERPATHW)GetProcAddress(hShell32,
+                                                                "SHGetFolderPathW");
+        if (pfSHGetFolderPathW != NULL)
         {
-            TRACE("HeapAlloc() failed\n");
-            return FALSE;
+            if (pfSHGetFolderPathW(NULL,
+                                   CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY,
+                                   Session->UserToken,
+                                   0,
+                                   szPath) == S_OK)
+            {
+                RegSetValueExW(hKey,
+                               L"APPDATA",
+                               0,
+                               REG_SZ,
+                               (LPBYTE)szPath,
+                               (wcslen(szPath) + 1) * sizeof(WCHAR));
+            }
         }
 
-        /* Fill user environment block */
-        CopyMemory(lpFullEnviron,
-                   lpEnviron,
-                   EnvBlockSize * sizeof(WCHAR));
-        CopyMemory(&lpFullEnviron[EnvBlockSize],
-                   Session->Profile->pszEnvironment,
-                   ProfileSize * sizeof(WCHAR));
-        lpFullEnviron[EnvBlockSize + ProfileSize] = UNICODE_NULL;
-    }
-    else
-    {
-        lpFullEnviron = (LPWSTR)lpEnviron;
+        FreeLibrary(hShell32);
     }
+}
+
+
+BOOL
+CreateUserEnvironment(IN PWLSESSION Session)
+{
+    HKEY hKey;
+    DWORD dwDisp;
+    LONG lError;
+    HKEY hKeyCurrentUser;
+
+    TRACE("WL: CreateUserEnvironment called\n");
 
     /* Impersonate the new user */
     ImpersonateLoggedOnUser(Session->UserToken);
@@ -107,6 +138,9 @@ CreateUserEnvironment(IN PWLSESSION Session,
                                  &dwDisp);
         if (lError == ERROR_SUCCESS)
         {
+            BuildVolatileEnvironment(Session,
+                                     hKey);
+
             RegCloseKey(hKey);
         }
         else
@@ -120,9 +154,6 @@ CreateUserEnvironment(IN PWLSESSION Session,
     /* Revert the impersonation */
     RevertToSelf();
 
-    *lpEnvironment = lpEnviron;
-    *lpFullEnv = lpFullEnviron;
-
     TRACE("WL: CreateUserEnvironment done\n");
 
     return TRUE;
index baecf98..d4dbad8 100644 (file)
@@ -170,7 +170,6 @@ HandleLogon(
 {
        PROFILEINFOW ProfileInfo;
        LPVOID lpEnvironment = NULL;
-       LPWSTR lpFullEnv = NULL;
        BOOLEAN Old;
        BOOL ret = FALSE;
 
@@ -208,12 +207,19 @@ HandleLogon(
        }
 
        /* Create environment block for the user */
-       if (!CreateUserEnvironment(Session, &lpEnvironment, &lpFullEnv))
+       if (!CreateUserEnvironment(Session))
        {
                WARN("WL: SetUserEnvironment() failed\n");
                goto cleanup;
        }
 
+       /* Create environment block for the user */
+       if (!CreateEnvironmentBlock(&lpEnvironment, Session->UserToken, TRUE))
+       {
+               WARN("WL: CreateEnvironmentBlock() failed\n");
+               goto cleanup;
+       }
+
        DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGYOURPERSONALSETTINGS);
        UpdatePerUserSystemParameters(0, TRUE);
 
@@ -233,7 +239,7 @@ HandleLogon(
                Session->Gina.Context,
                L"Default",
                NULL, /* FIXME */
-               lpFullEnv))
+               lpEnvironment))
        {
                //WCHAR StatusMsg[256];
                WARN("WL: WlxActivateUserShell() failed\n");
@@ -260,8 +266,6 @@ cleanup:
        {
                UnloadUserProfile(WLSession->UserToken, ProfileInfo.hProfile);
        }
-       if (lpFullEnv != lpEnvironment)
-               HeapFree(GetProcessHeap(), 0, lpFullEnv);
        if (lpEnvironment)
                DestroyEnvironmentBlock(lpEnvironment);
        RemoveStatusMessage(Session);
index c03bf69..45e7325 100644 (file)
@@ -182,9 +182,7 @@ UpdatePerUserSystemParameters(DWORD dwUnknown,
 
 /* environment.c */
 BOOL
-CreateUserEnvironment(IN PWLSESSION Session,
-                      IN LPVOID *lpEnvironment,
-                      IN LPWSTR *lpFullEnv);
+CreateUserEnvironment(IN PWLSESSION Session);
 
 /* sas.c */
 BOOL