Sync with trunk r47129
[reactos.git] / base / system / winlogon / environment.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winlogon
4 * FILE: base/system/winlogon/environment.c
5 * PURPOSE: User environment routines
6 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
7 * Hervé Poussineau (hpoussin@reactos.org)
8 * Eric Kohl
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include "winlogon.h"
14
15 #include <wine/debug.h>
16
17 WINE_DEFAULT_DEBUG_CHANNEL(winlogon);
18
19 /* GLOBALS ******************************************************************/
20
21
22 /* FUNCTIONS ****************************************************************/
23
24 BOOL
25 CreateUserEnvironment(IN PWLSESSION Session,
26 IN LPVOID *lpEnvironment,
27 IN LPWSTR *lpFullEnv)
28 {
29 LPCWSTR wstr;
30 SIZE_T EnvBlockSize = 0, ProfileSize = 0;
31 LPVOID lpEnviron = NULL;
32 LPWSTR lpFullEnviron = NULL;
33 HKEY hKey;
34 DWORD dwDisp;
35 LONG lError;
36 HKEY hKeyCurrentUser;
37
38 TRACE("WL: CreateUserEnvironment called\n");
39
40 /* Create environment block for the user */
41 if (!CreateEnvironmentBlock(&lpEnviron,
42 Session->UserToken,
43 TRUE))
44 {
45 WARN("WL: CreateEnvironmentBlock() failed\n");
46 return FALSE;
47 }
48
49 if (Session->Profile->dwType == WLX_PROFILE_TYPE_V2_0 && Session->Profile->pszEnvironment)
50 {
51 /* Count required size for full environment */
52 wstr = (LPCWSTR)lpEnviron;
53 while (*wstr != UNICODE_NULL)
54 {
55 SIZE_T size = wcslen(wstr) + 1;
56 wstr += size;
57 EnvBlockSize += size;
58 }
59
60 wstr = Session->Profile->pszEnvironment;
61 while (*wstr != UNICODE_NULL)
62 {
63 SIZE_T size = wcslen(wstr) + 1;
64 wstr += size;
65 ProfileSize += size;
66 }
67
68 /* Allocate enough memory */
69 lpFullEnviron = HeapAlloc(GetProcessHeap, 0, (EnvBlockSize + ProfileSize + 1) * sizeof(WCHAR));
70 if (!lpFullEnviron)
71 {
72 TRACE("HeapAlloc() failed\n");
73 return FALSE;
74 }
75
76 /* Fill user environment block */
77 CopyMemory(lpFullEnviron,
78 lpEnviron,
79 EnvBlockSize * sizeof(WCHAR));
80 CopyMemory(&lpFullEnviron[EnvBlockSize],
81 Session->Profile->pszEnvironment,
82 ProfileSize * sizeof(WCHAR));
83 lpFullEnviron[EnvBlockSize + ProfileSize] = UNICODE_NULL;
84 }
85 else
86 {
87 lpFullEnviron = (LPWSTR)lpEnviron;
88 }
89
90 /* Impersonate the new user */
91 ImpersonateLoggedOnUser(Session->UserToken);
92
93 /* Open the new users HKCU key */
94 lError = RegOpenCurrentUser(KEY_CREATE_SUB_KEY,
95 &hKeyCurrentUser);
96 if (lError == ERROR_SUCCESS)
97 {
98 /* Create the 'Volatile Environment' key */
99 lError = RegCreateKeyExW(hKeyCurrentUser,
100 L"Volatile Environment",
101 0,
102 NULL,
103 REG_OPTION_VOLATILE,
104 KEY_WRITE,
105 NULL,
106 &hKey,
107 &dwDisp);
108 if (lError == ERROR_SUCCESS)
109 {
110 RegCloseKey(hKey);
111 }
112 else
113 {
114 WARN("WL: RegCreateKeyExW() failed (Error: %ld)\n", lError);
115 }
116
117 RegCloseKey(hKeyCurrentUser);
118 }
119
120 /* Revert the impersonation */
121 RevertToSelf();
122
123 *lpEnvironment = lpEnviron;
124 *lpFullEnv = lpFullEnviron;
125
126 TRACE("WL: CreateUserEnvironment done\n");
127
128 return TRUE;
129 }