sync with trunk r47227
[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 #include <shlobj.h>
15
16 #include <wine/debug.h>
17
18 WINE_DEFAULT_DEBUG_CHANNEL(winlogon);
19
20 /* GLOBALS ******************************************************************/
21
22 typedef HRESULT (WINAPI *PFSHGETFOLDERPATHW)(HWND, int, HANDLE, DWORD, LPWSTR);
23
24
25 /* FUNCTIONS ****************************************************************/
26
27 static VOID
28 BuildVolatileEnvironment(IN PWLSESSION Session,
29 IN HKEY hKey)
30 {
31 HINSTANCE hShell32 = NULL;
32 PFSHGETFOLDERPATHW pfSHGetFolderPathW = NULL;
33 WCHAR szPath[MAX_PATH + 1];
34 WCHAR szExpandedPath[MAX_PATH + 1];
35 LPCWSTR wstr;
36 SIZE_T size;
37 WCHAR szEnvKey[MAX_PATH];
38 WCHAR szEnvValue[1024];
39 SIZE_T length;
40 LPWSTR eqptr, endptr;
41
42 /* Parse the environment variables and add them to the volatile environment key */
43 if (Session->Profile->dwType == WLX_PROFILE_TYPE_V2_0 &&
44 Session->Profile->pszEnvironment != NULL)
45 {
46 wstr = Session->Profile->pszEnvironment;
47 while (*wstr != UNICODE_NULL)
48 {
49 size = wcslen(wstr) + 1;
50
51 eqptr = wcschr(wstr, L'=');
52
53 if (eqptr != NULL)
54 {
55 endptr = eqptr;
56
57 endptr--;
58 while (iswspace(*endptr))
59 endptr--;
60
61 length = (SIZE_T)(endptr - wstr + 1);
62
63 wcsncpy(szEnvKey, wstr, length);
64 szEnvKey[length] = 0;
65
66 eqptr++;
67 while (iswspace(*eqptr))
68 eqptr++;
69 wcscpy(szEnvValue, eqptr);
70
71 RegSetValueExW(hKey,
72 szEnvKey,
73 0,
74 REG_SZ,
75 (LPBYTE)szEnvValue,
76 (wcslen(szEnvValue) + 1) * sizeof(WCHAR));
77 }
78
79 wstr += size;
80 }
81 }
82
83 /* Load shell32.dll and call SHGetFolderPathW to get the users appdata folder path */
84 hShell32 = LoadLibraryW(L"shell32.dll");
85 if (hShell32 != NULL)
86 {
87 pfSHGetFolderPathW = (PFSHGETFOLDERPATHW)GetProcAddress(hShell32,
88 "SHGetFolderPathW");
89 if (pfSHGetFolderPathW != NULL)
90 {
91 if (pfSHGetFolderPathW(NULL,
92 CSIDL_APPDATA | CSIDL_FLAG_DONT_VERIFY,
93 Session->UserToken,
94 0,
95 szPath) == S_OK)
96 {
97 /* FIXME: Expand %USERPROFILE% here. SHGetFolderPathW should do it for us. See Bug #5372.*/
98 TRACE("APPDATA path: %S\n", szPath);
99 ExpandEnvironmentStringsForUserW(Session->UserToken,
100 szPath,
101 szExpandedPath,
102 MAX_PATH);
103
104 /* Add the appdata folder path to the users volatile environment key */
105 TRACE("APPDATA expanded path: %S\n", szExpandedPath);
106 RegSetValueExW(hKey,
107 L"APPDATA",
108 0,
109 REG_SZ,
110 (LPBYTE)szExpandedPath,
111 (wcslen(szExpandedPath) + 1) * sizeof(WCHAR));
112 }
113 }
114
115 FreeLibrary(hShell32);
116 }
117 }
118
119
120 BOOL
121 CreateUserEnvironment(IN PWLSESSION Session)
122 {
123 HKEY hKey;
124 DWORD dwDisp;
125 LONG lError;
126 HKEY hKeyCurrentUser;
127
128 TRACE("WL: CreateUserEnvironment called\n");
129
130 /* Impersonate the new user */
131 ImpersonateLoggedOnUser(Session->UserToken);
132
133 /* Open the new users HKCU key */
134 lError = RegOpenCurrentUser(KEY_CREATE_SUB_KEY,
135 &hKeyCurrentUser);
136 if (lError == ERROR_SUCCESS)
137 {
138 /* Create the 'Volatile Environment' key */
139 lError = RegCreateKeyExW(hKeyCurrentUser,
140 L"Volatile Environment",
141 0,
142 NULL,
143 REG_OPTION_VOLATILE,
144 KEY_WRITE,
145 NULL,
146 &hKey,
147 &dwDisp);
148 if (lError == ERROR_SUCCESS)
149 {
150 BuildVolatileEnvironment(Session,
151 hKey);
152
153 RegCloseKey(hKey);
154 }
155 else
156 {
157 WARN("WL: RegCreateKeyExW() failed (Error: %ld)\n", lError);
158 }
159
160 RegCloseKey(hKeyCurrentUser);
161 }
162
163 /* Revert the impersonation */
164 RevertToSelf();
165
166 TRACE("WL: CreateUserEnvironment done\n");
167
168 return TRUE;
169 }