[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.

svn path=/trunk/; revision=47198
This commit is contained in:
Eric Kohl 2010-05-14 17:08:20 +00:00
parent 0801068a35
commit 029c6e67a9
3 changed files with 101 additions and 68 deletions

View file

@ -11,6 +11,7 @@
/* INCLUDES *****************************************************************/
#include "winlogon.h"
#include <shlobj.h>
#include <wine/debug.h>
@ -18,18 +19,98 @@ 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;
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)
{
HKEY hKey;
DWORD dwDisp;
LONG lError;
@ -37,56 +118,6 @@ CreateUserEnvironment(IN PWLSESSION Session,
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 @@ 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;

View 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);

View 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