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/enviro... ============================================================================== --- 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/winlog... ============================================================================== --- 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