3 * Copyright (C) 2004 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS system libraries
22 * FILE: lib/userenv/environment.c
23 * PURPOSE: User environment functions
24 * PROGRAMMER: Eric Kohl
34 SetUserEnvironmentVariable(LPVOID
*Environment
,
39 WCHAR ShortName
[MAX_PATH
];
41 UNICODE_STRING SrcValue
;
42 UNICODE_STRING DstValue
;
49 RtlInitUnicodeString(&SrcValue
,
52 Length
= 2 * MAX_PATH
* sizeof(WCHAR
);
55 DstValue
.MaximumLength
= Length
;
56 DstValue
.Buffer
= Buffer
= LocalAlloc(LPTR
,
58 if (DstValue
.Buffer
== NULL
)
60 DPRINT1("LocalAlloc() failed\n");
64 Status
= RtlExpandEnvironmentStrings_U((PWSTR
)*Environment
,
68 if (!NT_SUCCESS(Status
))
70 DPRINT1("RtlExpandEnvironmentStrings_U() failed (Status %lx)\n", Status
);
71 DPRINT1("Length %lu\n", Length
);
79 RtlInitUnicodeString(&DstValue
,
83 if (!_wcsicmp(lpName
, L
"temp") || !_wcsicmp(lpName
, L
"tmp"))
85 if (!GetShortPathNameW(DstValue
.Buffer
, ShortName
, MAX_PATH
))
87 DPRINT1("GetShortPathNameW() failed for %S (Error %lu)\n", DstValue
.Buffer
, GetLastError());
93 DPRINT("Buffer: %S\n", ShortName
);
94 RtlInitUnicodeString(&DstValue
,
98 RtlInitUnicodeString(&Name
,
101 DPRINT("Value: %wZ\n", &DstValue
);
103 Status
= RtlSetEnvironmentVariable((PWSTR
*)Environment
,
110 if (!NT_SUCCESS(Status
))
112 DPRINT1("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status
);
121 AppendUserEnvironmentVariable(LPVOID
*Environment
,
126 UNICODE_STRING Value
;
129 RtlInitUnicodeString(&Name
,
133 Value
.MaximumLength
= 1024 * sizeof(WCHAR
);
134 Value
.Buffer
= LocalAlloc(LPTR
,
135 1024 * sizeof(WCHAR
));
136 if (Value
.Buffer
== NULL
)
140 Value
.Buffer
[0] = UNICODE_NULL
;
142 Status
= RtlQueryEnvironmentVariable_U((PWSTR
)*Environment
,
145 if (NT_SUCCESS(Status
))
147 RtlAppendUnicodeToString(&Value
,
151 RtlAppendUnicodeToString(&Value
,
154 Status
= RtlSetEnvironmentVariable((PWSTR
*)Environment
,
157 LocalFree(Value
.Buffer
);
158 if (!NT_SUCCESS(Status
))
160 DPRINT1("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status
);
169 GetCurrentUserKey(HANDLE hToken
)
171 UNICODE_STRING SidString
;
175 if (!GetUserSidFromToken(hToken
,
178 DPRINT1("GetUserSidFromToken() failed\n");
182 Error
= RegOpenKeyExW(HKEY_USERS
,
187 if (Error
!= ERROR_SUCCESS
)
189 DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error
);
190 RtlFreeUnicodeString(&SidString
);
191 SetLastError((DWORD
)Error
);
195 RtlFreeUnicodeString(&SidString
);
202 SetUserEnvironment(LPVOID
*lpEnvironment
,
208 DWORD dwMaxValueNameLength
;
209 DWORD dwMaxValueDataLength
;
210 DWORD dwValueNameLength
;
211 DWORD dwValueDataLength
;
218 Error
= RegOpenKeyExW(hKey
,
223 if (Error
!= ERROR_SUCCESS
)
225 DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error
);
226 SetLastError((DWORD
)Error
);
230 Error
= RegQueryInfoKey(hEnvKey
,
238 &dwMaxValueNameLength
,
239 &dwMaxValueDataLength
,
242 if (Error
!= ERROR_SUCCESS
)
244 DPRINT1("RegQueryInforKey() failed (Error %ld)\n", Error
);
245 RegCloseKey(hEnvKey
);
246 SetLastError((DWORD
)Error
);
252 RegCloseKey(hEnvKey
);
256 /* Allocate buffers */
257 lpValueName
= LocalAlloc(LPTR
,
258 dwMaxValueNameLength
* sizeof(WCHAR
));
259 if (lpValueName
== NULL
)
261 RegCloseKey(hEnvKey
);
265 lpValueData
= LocalAlloc(LPTR
,
266 dwMaxValueDataLength
);
267 if (lpValueData
== NULL
)
269 LocalFree(lpValueName
);
270 RegCloseKey(hEnvKey
);
274 /* Enumerate values */
275 for (i
= 0; i
< dwValues
; i
++)
277 dwValueNameLength
= dwMaxValueNameLength
;
278 dwValueDataLength
= dwMaxValueDataLength
;
279 RegEnumValueW(hEnvKey
,
288 if (!_wcsicmp (lpValueName
, L
"path"))
290 /* Append 'Path' environment variable */
291 AppendUserEnvironmentVariable(lpEnvironment
,
297 /* Set environment variable */
298 SetUserEnvironmentVariable(lpEnvironment
,
301 (dwType
== REG_EXPAND_SZ
));
305 LocalFree(lpValueData
);
306 LocalFree(lpValueName
);
307 RegCloseKey(hEnvKey
);
314 CreateEnvironmentBlock(LPVOID
*lpEnvironment
,
318 WCHAR Buffer
[MAX_PATH
];
327 DPRINT("CreateEnvironmentBlock() called\n");
329 if (lpEnvironment
== NULL
)
331 SetLastError(ERROR_INVALID_PARAMETER
);
335 Status
= RtlCreateEnvironment((BOOLEAN
)bInherit
,
336 (PWSTR
*)lpEnvironment
);
337 if (!NT_SUCCESS (Status
))
339 DPRINT1("RtlCreateEnvironment() failed (Status %lx)\n", Status
);
340 SetLastError(RtlNtStatusToDosError(Status
));
344 /* Set 'COMPUTERNAME' variable */
346 if (GetComputerNameW(Buffer
,
349 SetUserEnvironmentVariable(lpEnvironment
,
355 /* Set 'ALLUSERSPROFILE' variable */
357 if (GetAllUsersProfileDirectoryW(Buffer
,
360 SetUserEnvironmentVariable(lpEnvironment
,
366 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
367 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
371 if (lError
== ERROR_SUCCESS
)
373 Length
= 1024 * sizeof(WCHAR
);
374 lError
= RegQueryValueExW(hKey
,
380 if (lError
== ERROR_SUCCESS
)
382 SetUserEnvironmentVariable(lpEnvironment
,
388 Length
= 1024 * sizeof(WCHAR
);
389 lError
= RegQueryValueExW(hKey
,
395 if (lError
== ERROR_SUCCESS
)
397 SetUserEnvironmentVariable(lpEnvironment
,
398 L
"CommonProgramFiles",
409 hKeyUser
= GetCurrentUserKey(hToken
);
410 if (hKeyUser
== NULL
)
412 DPRINT1("GetCurrentUserKey() failed\n");
413 RtlDestroyEnvironment(*lpEnvironment
);
417 /* Set 'USERPROFILE' variable */
419 if (GetUserProfileDirectoryW(hToken
,
423 SetUserEnvironmentVariable(lpEnvironment
,
429 /* FIXME: Set 'USERDOMAIN' variable */
432 if (GetUserNameW(Buffer
,
435 SetUserEnvironmentVariable(lpEnvironment
,
441 /* Set user environment variables */
442 SetUserEnvironment(lpEnvironment
,
446 /* Set user volatile environment variables */
447 SetUserEnvironment(lpEnvironment
,
449 L
"Volatile Environment");
451 RegCloseKey(hKeyUser
);
458 DestroyEnvironmentBlock(LPVOID lpEnvironment
)
460 DPRINT("DestroyEnvironmentBlock() called\n");
462 if (lpEnvironment
== NULL
)
464 SetLastError(ERROR_INVALID_PARAMETER
);
468 RtlDestroyEnvironment(lpEnvironment
);
475 ExpandEnvironmentStringsForUserW(IN HANDLE hToken
,
483 if (lpSrc
== NULL
|| lpDest
== NULL
|| dwSize
== 0)
485 SetLastError(ERROR_INVALID_PARAMETER
);
489 if (CreateEnvironmentBlock(&lpEnvironment
,
493 UNICODE_STRING SrcU
, DestU
;
496 /* initialize the strings */
497 RtlInitUnicodeString(&SrcU
,
500 DestU
.MaximumLength
= dwSize
* sizeof(WCHAR
);
501 DestU
.Buffer
= lpDest
;
503 /* expand the strings */
504 Status
= RtlExpandEnvironmentStrings_U((PWSTR
)lpEnvironment
,
509 DestroyEnvironmentBlock(lpEnvironment
);
511 if (NT_SUCCESS(Status
))
517 SetLastError(RtlNtStatusToDosError(Status
));
526 ExpandEnvironmentStringsForUserA(IN HANDLE hToken
,
532 LPWSTR lpSrcW
= NULL
, lpDestW
= NULL
;
535 if (lpSrc
== NULL
|| lpDest
== NULL
|| dwSize
== 0)
537 SetLastError(ERROR_INVALID_PARAMETER
);
541 dwSrcLen
= strlen(lpSrc
);
542 lpSrcW
= (LPWSTR
)GlobalAlloc(GMEM_FIXED
,
543 (dwSrcLen
+ 1) * sizeof(WCHAR
));
544 if (lpSrcW
== NULL
||
545 MultiByteToWideChar(CP_ACP
,
555 lpDestW
= (LPWSTR
)GlobalAlloc(GMEM_FIXED
,
556 dwSize
* sizeof(WCHAR
));
562 Ret
= ExpandEnvironmentStringsForUserW(hToken
,
568 if (WideCharToMultiByte(CP_ACP
,
584 GlobalFree((HGLOBAL
)lpSrcW
);
589 GlobalFree((HGLOBAL
)lpDestW
);