/* INCLUDES *****************************************************************/
#include "winlogon.h"
+#include <shlobj.h>
#include <wine/debug.h>
/* 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];
+ WCHAR szExpandedPath[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;
-
- TRACE("WL: CreateUserEnvironment called\n");
-
- /* Create environment block for the user */
- if (!CreateEnvironmentBlock(&lpEnviron,
- Session->UserToken,
- TRUE))
+ SIZE_T size;
+ WCHAR szEnvKey[MAX_PATH];
+ WCHAR szEnvValue[1024];
+ SIZE_T length;
+ LPWSTR eqptr, endptr;
+
+ /* Parse the environment variables and add them to the volatile environment key */
+ if (Session->Profile->dwType == WLX_PROFILE_TYPE_V2_0 &&
+ Session->Profile->pszEnvironment != NULL)
{
- 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;
+ 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)
+ /* Load shell32.dll and call SHGetFolderPathW to get the users appdata folder path */
+ 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)
+ {
+ /* FIXME: Expand %USERPROFILE% here. SHGetFolderPathW should do it for us. See Bug #5372.*/
+ TRACE("APPDATA path: %S\n", szPath);
+ ExpandEnvironmentStringsForUserW(Session->UserToken,
+ szPath,
+ szExpandedPath,
+ MAX_PATH);
+
+ /* Add the appdata folder path to the users volatile environment key */
+ TRACE("APPDATA expanded path: %S\n", szExpandedPath);
+ RegSetValueExW(hKey,
+ L"APPDATA",
+ 0,
+ REG_SZ,
+ (LPBYTE)szExpandedPath,
+ (wcslen(szExpandedPath) + 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);
&dwDisp);
if (lError == ERROR_SUCCESS)
{
+ BuildVolatileEnvironment(Session,
+ hKey);
+
RegCloseKey(hKey);
}
else
/* Revert the impersonation */
RevertToSelf();
- *lpEnvironment = lpEnviron;
- *lpFullEnv = lpFullEnviron;
-
TRACE("WL: CreateUserEnvironment done\n");
return TRUE;