Author: ekohl
Date: Fri May 14 19:08:20 2010
New Revision: 47198
URL: 
http://svn.reactos.org/svn/reactos?rev=47198&view=rev
Log:
[WINLOGON]
- 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.
Modified:
    trunk/reactos/base/system/winlogon/environment.c
    trunk/reactos/base/system/winlogon/sas.c
    trunk/reactos/base/system/winlogon/winlogon.h
Modified: trunk/reactos/base/system/winlogon/environment.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/winlogon/envir…
==============================================================================
--- trunk/reactos/base/system/winlogon/environment.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/winlogon/environment.c [iso-8859-1] Fri May 14 19:08:20 2010
@@ -11,6 +11,7 @@
 /* INCLUDES *****************************************************************/
 #include "winlogon.h"
+#include <shlobj.h>
 #include <wine/debug.h>
@@ -18,74 +19,104 @@
 /* GLOBALS ******************************************************************/
+typedef HRESULT (WINAPI *PFSHGETFOLDERPATHW)(HWND, int, HANDLE, DWORD, LPWSTR);
+
 /* FUNCTIONS ****************************************************************/
+static VOID
+BuildVolatileEnvironment(IN PWLSESSION Session,
+                         IN HKEY hKey)
+{
+    HINSTANCE hShell32 = NULL;
+    PFSHGETFOLDERPATHW pfSHGetFolderPathW = NULL;
+    WCHAR szPath[MAX_PATH + 1];
+    LPCWSTR wstr;
+    SIZE_T size;
+
+    WCHAR szEnvKey[MAX_PATH];
+    WCHAR szEnvValue[1024];
+
+    SIZE_T length;
+    LPWSTR eqptr, endptr;
+
+    if (Session->Profile->dwType == WLX_PROFILE_TYPE_V2_0 &&
+        Session->Profile->pszEnvironment != NULL)
+    {
+        wstr = Session->Profile->pszEnvironment;
+        while (*wstr != UNICODE_NULL)
+        {
+            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;
+        }
+    }
+
+
+    hShell32 = LoadLibraryW(L"shell32.dll");
+    if (hShell32 != NULL)
+    {
+        pfSHGetFolderPathW = (PFSHGETFOLDERPATHW)GetProcAddress(hShell32,
+
"SHGetFolderPathW");
+        if (pfSHGetFolderPathW != NULL)
+        {
+            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));
+            }
+        }
+
+        FreeLibrary(hShell32);
+    }
+}
+
+
 BOOL
-CreateUserEnvironment(IN PWLSESSION Session,
-                      IN LPVOID *lpEnvironment,
-                      IN LPWSTR *lpFullEnv)
+CreateUserEnvironment(IN PWLSESSION Session)
 {
-    LPCWSTR wstr;
-    SIZE_T EnvBlockSize = 0, ProfileSize = 0;
-    LPVOID lpEnviron = NULL;
-    LPWSTR lpFullEnviron = NULL;
     HKEY hKey;
     DWORD dwDisp;
     LONG lError;
     HKEY hKeyCurrentUser;
     TRACE("WL: CreateUserEnvironment called\n");
-
-    /* Create environment block for the user */
-    if (!CreateEnvironmentBlock(&lpEnviron,
-                                Session->UserToken,
-                                TRUE))
-    {
-        WARN("WL: CreateEnvironmentBlock() failed\n");
-        return FALSE;
-    }
-
-    if (Session->Profile->dwType == WLX_PROFILE_TYPE_V2_0 &&
Session->Profile->pszEnvironment)
-    {
-        /* 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;
-            wstr += size;
-            ProfileSize += size;
-        }
-
-        /* Allocate enough memory */
-        lpFullEnviron = HeapAlloc(GetProcessHeap(), 0, (EnvBlockSize + ProfileSize + 1) *
sizeof(WCHAR));
-        if (!lpFullEnviron)
-        {
-            TRACE("HeapAlloc() failed\n");
-            return FALSE;
-        }
-
-        /* 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;
-    }
     /* Impersonate the new user */
     ImpersonateLoggedOnUser(Session->UserToken);
@@ -107,6 +138,9 @@
                                  &dwDisp);
         if (lError == ERROR_SUCCESS)
         {
+            BuildVolatileEnvironment(Session,
+                                     hKey);
+
             RegCloseKey(hKey);
         }
         else
@@ -120,9 +154,6 @@
     /* Revert the impersonation */
     RevertToSelf();
-    *lpEnvironment = lpEnviron;
-    *lpFullEnv = lpFullEnviron;
-
     TRACE("WL: CreateUserEnvironment done\n");
     return TRUE;
Modified: trunk/reactos/base/system/winlogon/sas.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/winlogon/sas.c…
==============================================================================
--- trunk/reactos/base/system/winlogon/sas.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/winlogon/sas.c [iso-8859-1] Fri May 14 19:08:20 2010
@@ -170,7 +170,6 @@
 {
        PROFILEINFOW ProfileInfo;
        LPVOID lpEnvironment = NULL;
-       LPWSTR lpFullEnv = NULL;
        BOOLEAN Old;
        BOOL ret = FALSE;
@@ -208,9 +207,16 @@
        }
        /* 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;
        }
@@ -233,7 +239,7 @@
                Session->Gina.Context,
                L"Default",
                NULL, /* FIXME */
-               lpFullEnv))
+               lpEnvironment))
        {
                //WCHAR StatusMsg[256];
                WARN("WL: WlxActivateUserShell() failed\n");
@@ -260,8 +266,6 @@
        {
                UnloadUserProfile(WLSession->UserToken, ProfileInfo.hProfile);
        }
-       if (lpFullEnv != lpEnvironment)
-               HeapFree(GetProcessHeap(), 0, lpFullEnv);
        if (lpEnvironment)
                DestroyEnvironmentBlock(lpEnvironment);
        RemoveStatusMessage(Session);
Modified: trunk/reactos/base/system/winlogon/winlogon.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/winlogon/winlo…
==============================================================================
--- trunk/reactos/base/system/winlogon/winlogon.h [iso-8859-1] (original)
+++ trunk/reactos/base/system/winlogon/winlogon.h [iso-8859-1] Fri May 14 19:08:20 2010
@@ -182,9 +182,7 @@
 /* environment.c */
 BOOL
-CreateUserEnvironment(IN PWLSESSION Session,
-                      IN LPVOID *lpEnvironment,
-                      IN LPWSTR *lpFullEnv);
+CreateUserEnvironment(IN PWLSESSION Session);
 /* sas.c */
 BOOL