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: dll/win32/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
);
122 AppendUserEnvironmentVariable(LPVOID
*Environment
,
127 UNICODE_STRING Value
;
130 RtlInitUnicodeString(&Name
,
134 Value
.MaximumLength
= 1024 * sizeof(WCHAR
);
135 Value
.Buffer
= LocalAlloc(LPTR
,
136 1024 * sizeof(WCHAR
));
137 if (Value
.Buffer
== NULL
)
141 Value
.Buffer
[0] = UNICODE_NULL
;
143 Status
= RtlQueryEnvironmentVariable_U((PWSTR
)*Environment
,
146 if (NT_SUCCESS(Status
))
148 RtlAppendUnicodeToString(&Value
,
152 RtlAppendUnicodeToString(&Value
,
155 Status
= RtlSetEnvironmentVariable((PWSTR
*)Environment
,
158 LocalFree(Value
.Buffer
);
159 if (!NT_SUCCESS(Status
))
161 DPRINT1("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status
);
171 GetCurrentUserKey(HANDLE hToken
)
173 UNICODE_STRING SidString
;
177 if (!GetUserSidStringFromToken(hToken
,
180 DPRINT1("GetUserSidFromToken() failed\n");
184 Error
= RegOpenKeyExW(HKEY_USERS
,
189 if (Error
!= ERROR_SUCCESS
)
191 DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error
);
192 RtlFreeUnicodeString(&SidString
);
193 SetLastError((DWORD
)Error
);
197 RtlFreeUnicodeString(&SidString
);
205 GetUserAndDomainName(IN HANDLE hToken
,
206 OUT LPWSTR
*UserName
,
207 OUT LPWSTR
*DomainName
)
210 LPWSTR lpUserName
= NULL
;
211 LPWSTR lpDomainName
= NULL
;
212 DWORD cbUserName
= 0;
213 DWORD cbDomainName
= 0;
214 SID_NAME_USE SidNameUse
;
217 if (!GetUserSidFromToken(hToken
,
220 DPRINT1("GetUserSidFromToken() failed\n");
224 if (!LookupAccountSidW(NULL
,
232 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
239 lpUserName
= LocalAlloc(LPTR
,
240 cbUserName
* sizeof(WCHAR
));
241 if (lpUserName
== NULL
)
247 lpDomainName
= LocalAlloc(LPTR
,
248 cbDomainName
* sizeof(WCHAR
));
249 if (lpDomainName
== NULL
)
255 if (!LookupAccountSidW(NULL
,
267 *UserName
= lpUserName
;
268 *DomainName
= lpDomainName
;
273 if (lpUserName
!= NULL
)
274 LocalFree(lpUserName
);
276 if (lpDomainName
!= NULL
)
277 LocalFree(lpDomainName
);
288 SetUserEnvironment(LPVOID
*lpEnvironment
,
294 DWORD dwMaxValueNameLength
;
295 DWORD dwMaxValueDataLength
;
296 DWORD dwValueNameLength
;
297 DWORD dwValueDataLength
;
304 Error
= RegOpenKeyExW(hKey
,
309 if (Error
!= ERROR_SUCCESS
)
311 DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error
);
312 SetLastError((DWORD
)Error
);
316 Error
= RegQueryInfoKey(hEnvKey
,
324 &dwMaxValueNameLength
,
325 &dwMaxValueDataLength
,
328 if (Error
!= ERROR_SUCCESS
)
330 DPRINT1("RegQueryInforKey() failed (Error %ld)\n", Error
);
331 RegCloseKey(hEnvKey
);
332 SetLastError((DWORD
)Error
);
338 RegCloseKey(hEnvKey
);
342 /* Allocate buffers */
343 dwMaxValueNameLength
++;
344 lpValueName
= LocalAlloc(LPTR
,
345 dwMaxValueNameLength
* sizeof(WCHAR
));
346 if (lpValueName
== NULL
)
348 RegCloseKey(hEnvKey
);
352 lpValueData
= LocalAlloc(LPTR
,
353 dwMaxValueDataLength
);
354 if (lpValueData
== NULL
)
356 LocalFree(lpValueName
);
357 RegCloseKey(hEnvKey
);
361 /* Enumerate values */
362 for (i
= 0; i
< dwValues
; i
++)
364 dwValueNameLength
= dwMaxValueNameLength
;
365 dwValueDataLength
= dwMaxValueDataLength
;
366 RegEnumValueW(hEnvKey
,
375 if (!_wcsicmp (lpValueName
, L
"path"))
377 /* Append 'Path' environment variable */
378 AppendUserEnvironmentVariable(lpEnvironment
,
384 /* Set environment variable */
385 SetUserEnvironmentVariable(lpEnvironment
,
388 (dwType
== REG_EXPAND_SZ
));
392 LocalFree(lpValueData
);
393 LocalFree(lpValueName
);
394 RegCloseKey(hEnvKey
);
402 CreateEnvironmentBlock(LPVOID
*lpEnvironment
,
406 WCHAR Buffer
[MAX_PATH
];
412 LPWSTR lpUserName
= NULL
;
413 LPWSTR lpDomainName
= NULL
;
417 DPRINT("CreateEnvironmentBlock() called\n");
419 if (lpEnvironment
== NULL
)
421 SetLastError(ERROR_INVALID_PARAMETER
);
425 Status
= RtlCreateEnvironment((BOOLEAN
)bInherit
,
426 (PWSTR
*)lpEnvironment
);
427 if (!NT_SUCCESS (Status
))
429 DPRINT1("RtlCreateEnvironment() failed (Status %lx)\n", Status
);
430 SetLastError(RtlNtStatusToDosError(Status
));
434 /* Set 'COMPUTERNAME' variable */
436 if (GetComputerNameW(Buffer
,
439 SetUserEnvironmentVariable(lpEnvironment
,
445 /* Set 'ALLUSERSPROFILE' variable */
447 if (GetAllUsersProfileDirectoryW(Buffer
,
450 SetUserEnvironmentVariable(lpEnvironment
,
456 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
457 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
461 if (lError
== ERROR_SUCCESS
)
463 Length
= 1024 * sizeof(WCHAR
);
464 lError
= RegQueryValueExW(hKey
,
470 if (lError
== ERROR_SUCCESS
)
472 SetUserEnvironmentVariable(lpEnvironment
,
478 Length
= 1024 * sizeof(WCHAR
);
479 lError
= RegQueryValueExW(hKey
,
485 if (lError
== ERROR_SUCCESS
)
487 SetUserEnvironmentVariable(lpEnvironment
,
488 L
"CommonProgramFiles",
499 hKeyUser
= GetCurrentUserKey(hToken
);
500 if (hKeyUser
== NULL
)
502 DPRINT1("GetCurrentUserKey() failed\n");
503 RtlDestroyEnvironment(*lpEnvironment
);
507 /* Set 'USERPROFILE' variable */
509 if (GetUserProfileDirectoryW(hToken
,
513 SetUserEnvironmentVariable(lpEnvironment
,
519 if (GetUserAndDomainName(hToken
,
523 /* Set 'USERDOMAIN' variable */
524 SetUserEnvironmentVariable(lpEnvironment
,
529 /* Set 'USERNAME' variable */
530 SetUserEnvironmentVariable(lpEnvironment
,
536 /* Set user environment variables */
537 SetUserEnvironment(lpEnvironment
,
541 /* Set user volatile environment variables */
542 SetUserEnvironment(lpEnvironment
,
544 L
"Volatile Environment");
546 RegCloseKey(hKeyUser
);
548 if (lpUserName
!= NULL
)
549 LocalFree(lpUserName
);
551 if (lpDomainName
!= NULL
)
552 LocalFree(lpDomainName
);
560 DestroyEnvironmentBlock(LPVOID lpEnvironment
)
562 DPRINT("DestroyEnvironmentBlock() called\n");
564 if (lpEnvironment
== NULL
)
566 SetLastError(ERROR_INVALID_PARAMETER
);
570 RtlDestroyEnvironment(lpEnvironment
);
578 ExpandEnvironmentStringsForUserW(IN HANDLE hToken
,
586 if (lpSrc
== NULL
|| lpDest
== NULL
|| dwSize
== 0)
588 SetLastError(ERROR_INVALID_PARAMETER
);
592 if (CreateEnvironmentBlock(&lpEnvironment
,
596 UNICODE_STRING SrcU
, DestU
;
599 /* initialize the strings */
600 RtlInitUnicodeString(&SrcU
,
603 DestU
.MaximumLength
= dwSize
* sizeof(WCHAR
);
604 DestU
.Buffer
= lpDest
;
606 /* expand the strings */
607 Status
= RtlExpandEnvironmentStrings_U((PWSTR
)lpEnvironment
,
612 DestroyEnvironmentBlock(lpEnvironment
);
614 if (NT_SUCCESS(Status
))
620 SetLastError(RtlNtStatusToDosError(Status
));
630 ExpandEnvironmentStringsForUserA(IN HANDLE hToken
,
636 LPWSTR lpSrcW
= NULL
, lpDestW
= NULL
;
639 if (lpSrc
== NULL
|| lpDest
== NULL
|| dwSize
== 0)
641 SetLastError(ERROR_INVALID_PARAMETER
);
645 dwSrcLen
= strlen(lpSrc
);
646 lpSrcW
= (LPWSTR
)GlobalAlloc(GMEM_FIXED
,
647 (dwSrcLen
+ 1) * sizeof(WCHAR
));
648 if (lpSrcW
== NULL
||
649 MultiByteToWideChar(CP_ACP
,
659 lpDestW
= (LPWSTR
)GlobalAlloc(GMEM_FIXED
,
660 dwSize
* sizeof(WCHAR
));
666 Ret
= ExpandEnvironmentStringsForUserW(hToken
,
672 if (WideCharToMultiByte(CP_ACP
,
688 GlobalFree((HGLOBAL
)lpSrcW
);
693 GlobalFree((HGLOBAL
)lpDestW
);