7a44fa5d4f7b7240a1e65315aa1f18801e243f1b
[reactos.git] / reactos / lib / userenv / environment.c
1 /* $Id: environment.c,v 1.5 2004/06/29 12:06:01 ekohl Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/userenv/environment.c
6 * PURPOSE: User environment functions
7 * PROGRAMMER: Eric Kohl
8 */
9
10 #define NTOS_MODE_USER
11 #include <ntos.h>
12 #include <windows.h>
13 #include <userenv.h>
14
15 #include "internal.h"
16
17
18 static BOOL
19 SetUserEnvironmentVariable (LPVOID *Environment,
20 LPWSTR lpName,
21 LPWSTR lpValue,
22 BOOL bExpand)
23 {
24 WCHAR ShortName[MAX_PATH];
25 UNICODE_STRING Name;
26 UNICODE_STRING SrcValue;
27 UNICODE_STRING DstValue;
28 ULONG Length;
29 NTSTATUS Status;
30
31 if (bExpand)
32 {
33 RtlInitUnicodeString(&SrcValue,
34 lpValue);
35
36 Length = 2 * MAX_PATH * sizeof(WCHAR);
37
38 DstValue.Length = 0;
39 DstValue.MaximumLength = Length;
40 DstValue.Buffer = LocalAlloc(LPTR,
41 Length);
42 if (DstValue.Buffer == NULL)
43 {
44 DPRINT1("LocalAlloc() failed\n");
45 return FALSE;
46 }
47
48 Status = RtlExpandEnvironmentStrings_U((PWSTR)*Environment,
49 &SrcValue,
50 &DstValue,
51 &Length);
52 if (!NT_SUCCESS(Status))
53 {
54 DPRINT1("RtlExpandEnvironmentStrings_U() failed (Status %lx)\n", Status);
55 DPRINT1("Length %lu\n", Length);
56 return FALSE;
57 }
58 }
59 else
60 {
61 RtlInitUnicodeString(&DstValue,
62 lpValue);
63 }
64
65 if (!_wcsicmp (lpName, L"temp") || !_wcsicmp (lpName, L"tmp"))
66 {
67 if (!GetShortPathNameW(DstValue.Buffer, ShortName, MAX_PATH))
68 {
69 DPRINT1("GetShortPathNameW() failed (Error %lu)\n", GetLastError());
70 return FALSE;
71 }
72
73 DPRINT("Buffer: %S\n", ShortName);
74 RtlInitUnicodeString(&DstValue,
75 ShortName);
76 }
77
78 RtlInitUnicodeString(&Name,
79 lpName);
80
81 DPRINT("Value: %wZ\n", &DstValue);
82
83 Status = RtlSetEnvironmentVariable((PWSTR*)Environment,
84 &Name,
85 &DstValue);
86
87 if (bExpand)
88 {
89 LocalFree(DstValue.Buffer);
90 }
91
92 if (!NT_SUCCESS(Status))
93 {
94 DPRINT1("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status);
95 return FALSE;
96 }
97
98 return TRUE;
99 }
100
101
102 static BOOL
103 AppendUserEnvironmentVariable (LPVOID *Environment,
104 LPWSTR lpName,
105 LPWSTR lpValue)
106 {
107 UNICODE_STRING Name;
108 UNICODE_STRING Value;
109 NTSTATUS Status;
110
111 RtlInitUnicodeString (&Name,
112 lpName);
113
114 Value.Length = 0;
115 Value.MaximumLength = 1024 * sizeof(WCHAR);
116 Value.Buffer = LocalAlloc (LPTR,
117 1024 * sizeof(WCHAR));
118 if (Value.Buffer == NULL)
119 {
120 return FALSE;
121 }
122 Value.Buffer[0] = UNICODE_NULL;
123
124 Status = RtlQueryEnvironmentVariable_U ((PWSTR)*Environment,
125 &Name,
126 &Value);
127 if (NT_SUCCESS(Status))
128 {
129 RtlAppendUnicodeToString (&Value,
130 L";");
131 }
132
133 RtlAppendUnicodeToString (&Value,
134 lpValue);
135
136 Status = RtlSetEnvironmentVariable ((PWSTR*)Environment,
137 &Name,
138 &Value);
139 LocalFree (Value.Buffer);
140 if (!NT_SUCCESS(Status))
141 {
142 DPRINT1 ("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status);
143 return FALSE;
144 }
145
146 return TRUE;
147 }
148
149
150 static HKEY
151 GetCurrentUserKey (HANDLE hToken)
152 {
153 UNICODE_STRING SidString;
154 HKEY hKey;
155
156 if (!GetUserSidFromToken (hToken,
157 &SidString))
158 {
159 DPRINT1 ("GetUserSidFromToken() failed\n");
160 return NULL;
161 }
162
163 if (RegOpenKeyExW (HKEY_USERS,
164 SidString.Buffer,
165 0,
166 KEY_ALL_ACCESS,
167 &hKey))
168 {
169 DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", GetLastError());
170 RtlFreeUnicodeString (&SidString);
171 return NULL;
172 }
173
174 RtlFreeUnicodeString (&SidString);
175
176 return hKey;
177 }
178
179
180 static BOOL
181 SetUserEnvironment (LPVOID *lpEnvironment,
182 HKEY hKey,
183 LPWSTR lpSubKeyName)
184 {
185 HKEY hEnvKey;
186 DWORD dwValues;
187 DWORD dwMaxValueNameLength;
188 DWORD dwMaxValueDataLength;
189 DWORD dwValueNameLength;
190 DWORD dwValueDataLength;
191 DWORD dwType;
192 DWORD i;
193 LPWSTR lpValueName;
194 LPWSTR lpValueData;
195
196 if (RegOpenKeyExW (hKey,
197 lpSubKeyName,
198 0,
199 KEY_ALL_ACCESS,
200 &hEnvKey))
201 {
202 DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", GetLastError());
203 return FALSE;
204 }
205
206 if (RegQueryInfoKey (hEnvKey,
207 NULL,
208 NULL,
209 NULL,
210 NULL,
211 NULL,
212 NULL,
213 &dwValues,
214 &dwMaxValueNameLength,
215 &dwMaxValueDataLength,
216 NULL,
217 NULL))
218 {
219 DPRINT1 ("RegQueryInforKey() failed (Error %ld)\n", GetLastError());
220 RegCloseKey (hEnvKey);
221 return FALSE;
222 }
223
224 if (dwValues == 0)
225 {
226 RegCloseKey (hEnvKey);
227 return TRUE;
228 }
229
230 /* Allocate buffers */
231 lpValueName = LocalAlloc (LPTR,
232 dwMaxValueNameLength * sizeof(WCHAR));
233 if (lpValueName == NULL)
234 {
235 RegCloseKey (hEnvKey);
236 return FALSE;
237 }
238
239 lpValueData = LocalAlloc (LPTR,
240 dwMaxValueDataLength);
241 if (lpValueData == NULL)
242 {
243 LocalFree (lpValueName);
244 RegCloseKey (hEnvKey);
245 return FALSE;
246 }
247
248 /* Enumerate values */
249 for (i = 0; i < dwValues; i++)
250 {
251 dwValueNameLength = dwMaxValueNameLength;
252 dwValueDataLength = dwMaxValueDataLength;
253 RegEnumValueW (hEnvKey,
254 i,
255 lpValueName,
256 &dwValueNameLength,
257 NULL,
258 &dwType,
259 (LPBYTE)lpValueData,
260 &dwValueDataLength);
261
262 if (!_wcsicmp (lpValueName, L"path"))
263 {
264 /* Append 'Path' environment variable */
265 AppendUserEnvironmentVariable (lpEnvironment,
266 lpValueName,
267 lpValueData);
268 }
269 else
270 {
271 /* Set environment variable */
272 SetUserEnvironmentVariable (lpEnvironment,
273 lpValueName,
274 lpValueData,
275 (dwType == REG_EXPAND_SZ));
276 }
277 }
278
279 LocalFree (lpValueData);
280 LocalFree (lpValueName);
281 RegCloseKey (hEnvKey);
282
283 return TRUE;
284 }
285
286
287 BOOL WINAPI
288 CreateEnvironmentBlock (LPVOID *lpEnvironment,
289 HANDLE hToken,
290 BOOL bInherit)
291 {
292 WCHAR Buffer[MAX_PATH];
293 DWORD Length;
294 HKEY hKeyUser;
295 NTSTATUS Status;
296
297 DPRINT1 ("CreateEnvironmentBlock() called\n");
298
299 if (lpEnvironment == NULL)
300 return FALSE;
301
302 Status = RtlCreateEnvironment ((BOOLEAN)bInherit,
303 (PWSTR*)lpEnvironment);
304 if (!NT_SUCCESS (Status))
305 {
306 DPRINT1 ("RtlCreateEnvironment() failed (Status %lx)\n", Status);
307 return FALSE;
308 }
309
310 /* Set 'COMPUTERNAME' variable */
311 Length = MAX_PATH;
312 if (GetComputerNameW (Buffer,
313 &Length))
314 {
315 SetUserEnvironmentVariable(lpEnvironment,
316 L"COMPUTERNAME",
317 Buffer,
318 FALSE);
319 }
320
321 if (hToken == NULL)
322 return TRUE;
323
324 hKeyUser = GetCurrentUserKey (hToken);
325 if (hKeyUser == NULL)
326 {
327 DPRINT1 ("GetCurrentUserKey() failed\n");
328 RtlDestroyEnvironment (*lpEnvironment);
329 return FALSE;
330 }
331
332 /* Set 'ALLUSERSPROFILE' variable */
333 Length = MAX_PATH;
334 if (GetAllUsersProfileDirectoryW (Buffer,
335 &Length))
336 {
337 SetUserEnvironmentVariable(lpEnvironment,
338 L"ALLUSERSPROFILE",
339 Buffer,
340 FALSE);
341 }
342
343 /* Set 'USERPROFILE' variable */
344 Length = MAX_PATH;
345 if (GetUserProfileDirectoryW (hToken,
346 Buffer,
347 &Length))
348 {
349 SetUserEnvironmentVariable(lpEnvironment,
350 L"USERPROFILE",
351 Buffer,
352 FALSE);
353 }
354
355 /* FIXME: Set 'USERDOMAIN' variable */
356
357 /* FIXME: Set 'USERNAME' variable */
358
359 /* Set user environment variables */
360 SetUserEnvironment (lpEnvironment,
361 hKeyUser,
362 L"Environment");
363
364 RegCloseKey (hKeyUser);
365
366 return TRUE;
367 }
368
369
370 BOOL WINAPI
371 DestroyEnvironmentBlock (LPVOID lpEnvironment)
372 {
373 DPRINT ("DestroyEnvironmentBlock() called\n");
374
375 if (lpEnvironment == NULL)
376 return FALSE;
377
378 RtlDestroyEnvironment (lpEnvironment);
379
380 return TRUE;
381 }
382
383 /* EOF */