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.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS system libraries
23 * FILE: lib/userenv/environment.c
24 * PURPOSE: User environment functions
25 * PROGRAMMER: Eric Kohl
35 SetUserEnvironmentVariable (LPVOID
*Environment
,
40 WCHAR ShortName
[MAX_PATH
];
42 UNICODE_STRING SrcValue
;
43 UNICODE_STRING DstValue
;
50 RtlInitUnicodeString(&SrcValue
,
53 Length
= 2 * MAX_PATH
* sizeof(WCHAR
);
56 DstValue
.MaximumLength
= Length
;
57 DstValue
.Buffer
= Buffer
= LocalAlloc(LPTR
,
60 if (DstValue
.Buffer
== NULL
)
62 DPRINT1("LocalAlloc() failed\n");
66 Status
= RtlExpandEnvironmentStrings_U((PWSTR
)*Environment
,
70 if (!NT_SUCCESS(Status
))
72 DPRINT1("RtlExpandEnvironmentStrings_U() failed (Status %lx)\n", Status
);
73 DPRINT1("Length %lu\n", Length
);
74 if (Buffer
) LocalFree(Buffer
);
80 RtlInitUnicodeString(&DstValue
,
84 if (!_wcsicmp (lpName
, L
"temp") || !_wcsicmp (lpName
, L
"tmp"))
86 if (!GetShortPathNameW(DstValue
.Buffer
, ShortName
, MAX_PATH
))
88 DPRINT1("GetShortPathNameW() failed (Error %lu)\n", GetLastError());
89 if (Buffer
) LocalFree(Buffer
);
93 DPRINT("Buffer: %S\n", ShortName
);
94 RtlInitUnicodeString(&DstValue
,
98 RtlInitUnicodeString(&Name
,
101 DPRINT("Value: %wZ\n", &DstValue
);
103 Status
= RtlSetEnvironmentVariable((PWSTR
*)Environment
,
107 if (Buffer
) LocalFree(Buffer
);
109 if (!NT_SUCCESS(Status
))
111 DPRINT1("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status
);
120 AppendUserEnvironmentVariable (LPVOID
*Environment
,
125 UNICODE_STRING Value
;
128 RtlInitUnicodeString (&Name
,
132 Value
.MaximumLength
= 1024 * sizeof(WCHAR
);
133 Value
.Buffer
= LocalAlloc (LPTR
,
134 1024 * sizeof(WCHAR
));
135 if (Value
.Buffer
== NULL
)
139 Value
.Buffer
[0] = UNICODE_NULL
;
141 Status
= RtlQueryEnvironmentVariable_U ((PWSTR
)*Environment
,
144 if (NT_SUCCESS(Status
))
146 RtlAppendUnicodeToString (&Value
,
150 RtlAppendUnicodeToString (&Value
,
153 Status
= RtlSetEnvironmentVariable ((PWSTR
*)Environment
,
156 LocalFree (Value
.Buffer
);
157 if (!NT_SUCCESS(Status
))
159 DPRINT1 ("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status
);
168 GetCurrentUserKey (HANDLE hToken
)
170 UNICODE_STRING SidString
;
174 if (!GetUserSidFromToken (hToken
,
177 DPRINT1 ("GetUserSidFromToken() failed\n");
181 Error
= RegOpenKeyExW (HKEY_USERS
,
186 if (Error
!= ERROR_SUCCESS
)
188 DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", Error
);
189 RtlFreeUnicodeString (&SidString
);
190 SetLastError((DWORD
)Error
);
194 RtlFreeUnicodeString (&SidString
);
201 SetUserEnvironment (LPVOID
*lpEnvironment
,
207 DWORD dwMaxValueNameLength
;
208 DWORD dwMaxValueDataLength
;
209 DWORD dwValueNameLength
;
210 DWORD dwValueDataLength
;
217 Error
= RegOpenKeyExW (hKey
,
222 if (Error
!= ERROR_SUCCESS
)
224 DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", Error
);
225 SetLastError((DWORD
)Error
);
229 Error
= RegQueryInfoKey (hEnvKey
,
237 &dwMaxValueNameLength
,
238 &dwMaxValueDataLength
,
241 if (Error
!= ERROR_SUCCESS
)
243 DPRINT1 ("RegQueryInforKey() failed (Error %ld)\n", Error
);
244 RegCloseKey (hEnvKey
);
245 SetLastError((DWORD
)Error
);
251 RegCloseKey (hEnvKey
);
255 /* Allocate buffers */
256 lpValueName
= LocalAlloc (LPTR
,
257 dwMaxValueNameLength
* sizeof(WCHAR
));
258 if (lpValueName
== NULL
)
260 RegCloseKey (hEnvKey
);
264 lpValueData
= LocalAlloc (LPTR
,
265 dwMaxValueDataLength
);
266 if (lpValueData
== NULL
)
268 LocalFree (lpValueName
);
269 RegCloseKey (hEnvKey
);
273 /* Enumerate values */
274 for (i
= 0; i
< dwValues
; i
++)
276 dwValueNameLength
= dwMaxValueNameLength
;
277 dwValueDataLength
= dwMaxValueDataLength
;
278 RegEnumValueW (hEnvKey
,
287 if (!_wcsicmp (lpValueName
, L
"path"))
289 /* Append 'Path' environment variable */
290 AppendUserEnvironmentVariable (lpEnvironment
,
296 /* Set environment variable */
297 SetUserEnvironmentVariable (lpEnvironment
,
300 (dwType
== REG_EXPAND_SZ
));
304 LocalFree (lpValueData
);
305 LocalFree (lpValueName
);
306 RegCloseKey (hEnvKey
);
313 CreateEnvironmentBlock (LPVOID
*lpEnvironment
,
317 WCHAR Buffer
[MAX_PATH
];
322 DPRINT("CreateEnvironmentBlock() called\n");
324 if (lpEnvironment
== NULL
)
326 SetLastError(ERROR_INVALID_PARAMETER
);
330 Status
= RtlCreateEnvironment ((BOOLEAN
)bInherit
,
331 (PWSTR
*)lpEnvironment
);
332 if (!NT_SUCCESS (Status
))
334 DPRINT1 ("RtlCreateEnvironment() failed (Status %lx)\n", Status
);
335 SetLastError (RtlNtStatusToDosError (Status
));
339 /* Set 'COMPUTERNAME' variable */
341 if (GetComputerNameW (Buffer
,
344 SetUserEnvironmentVariable(lpEnvironment
,
353 hKeyUser
= GetCurrentUserKey (hToken
);
354 if (hKeyUser
== NULL
)
356 DPRINT1 ("GetCurrentUserKey() failed\n");
357 RtlDestroyEnvironment (*lpEnvironment
);
361 /* Set 'ALLUSERSPROFILE' variable */
363 if (GetAllUsersProfileDirectoryW (Buffer
,
366 SetUserEnvironmentVariable(lpEnvironment
,
372 /* Set 'USERPROFILE' variable */
374 if (GetUserProfileDirectoryW (hToken
,
378 SetUserEnvironmentVariable(lpEnvironment
,
383 wcscat(Buffer
, L
"\\Application Data");
384 SetUserEnvironmentVariable(lpEnvironment
, L
"APPDATA", Buffer
, FALSE
);
387 /* FIXME: Set 'USERDOMAIN' variable */
390 if (GetUserNameW(Buffer
,
393 SetUserEnvironmentVariable(lpEnvironment
,
401 /* Set user environment variables */
402 SetUserEnvironment (lpEnvironment
,
406 RegCloseKey (hKeyUser
);
413 DestroyEnvironmentBlock (LPVOID lpEnvironment
)
415 DPRINT ("DestroyEnvironmentBlock() called\n");
417 if (lpEnvironment
== NULL
)
419 SetLastError(ERROR_INVALID_PARAMETER
);
423 RtlDestroyEnvironment (lpEnvironment
);
430 ExpandEnvironmentStringsForUserW(IN HANDLE hToken
,
438 if (lpSrc
== NULL
|| lpDest
== NULL
|| dwSize
== 0)
440 SetLastError(ERROR_INVALID_PARAMETER
);
444 if (CreateEnvironmentBlock(&lpEnvironment
,
448 UNICODE_STRING SrcU
, DestU
;
451 /* initialize the strings */
452 RtlInitUnicodeString(&SrcU
,
455 DestU
.MaximumLength
= dwSize
* sizeof(WCHAR
);
456 DestU
.Buffer
= lpDest
;
458 /* expand the strings */
459 Status
= RtlExpandEnvironmentStrings_U((PWSTR
)lpEnvironment
,
464 DestroyEnvironmentBlock(lpEnvironment
);
466 if (NT_SUCCESS(Status
))
472 SetLastError(RtlNtStatusToDosError(Status
));
481 ExpandEnvironmentStringsForUserA(IN HANDLE hToken
,
487 LPWSTR lpSrcW
= NULL
, lpDestW
= NULL
;
490 if (lpSrc
== NULL
|| lpDest
== NULL
|| dwSize
== 0)
492 SetLastError(ERROR_INVALID_PARAMETER
);
496 dwSrcLen
= strlen(lpSrc
);
497 lpSrcW
= (LPWSTR
)GlobalAlloc(GMEM_FIXED
,
498 (dwSrcLen
+ 1) * sizeof(WCHAR
));
499 if (lpSrcW
== NULL
||
500 MultiByteToWideChar(CP_ACP
,
510 lpDestW
= (LPWSTR
)GlobalAlloc(GMEM_FIXED
,
511 dwSize
* sizeof(WCHAR
));
517 Ret
= ExpandEnvironmentStringsForUserW(hToken
,
523 if (WideCharToMultiByte(CP_ACP
,
539 GlobalFree((HGLOBAL
)lpSrcW
);
544 GlobalFree((HGLOBAL
)lpDestW
);