Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenenvironment.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2004 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* $Id: environment.c 47194 2010-05-13 20:38:16Z ekohl $ 00020 * 00021 * COPYRIGHT: See COPYING in the top level directory 00022 * PROJECT: ReactOS system libraries 00023 * FILE: lib/userenv/environment.c 00024 * PURPOSE: User environment functions 00025 * PROGRAMMER: Eric Kohl 00026 */ 00027 00028 #include <precomp.h> 00029 00030 #define NDEBUG 00031 #include <debug.h> 00032 00033 00034 static BOOL 00035 SetUserEnvironmentVariable(LPVOID *Environment, 00036 LPWSTR lpName, 00037 LPWSTR lpValue, 00038 BOOL bExpand) 00039 { 00040 WCHAR ShortName[MAX_PATH]; 00041 UNICODE_STRING Name; 00042 UNICODE_STRING SrcValue; 00043 UNICODE_STRING DstValue; 00044 ULONG Length; 00045 NTSTATUS Status; 00046 PVOID Buffer = NULL; 00047 00048 if (bExpand) 00049 { 00050 RtlInitUnicodeString(&SrcValue, 00051 lpValue); 00052 00053 Length = 2 * MAX_PATH * sizeof(WCHAR); 00054 00055 DstValue.Length = 0; 00056 DstValue.MaximumLength = Length; 00057 DstValue.Buffer = Buffer = LocalAlloc(LPTR, 00058 Length); 00059 if (DstValue.Buffer == NULL) 00060 { 00061 DPRINT1("LocalAlloc() failed\n"); 00062 return FALSE; 00063 } 00064 00065 Status = RtlExpandEnvironmentStrings_U((PWSTR)*Environment, 00066 &SrcValue, 00067 &DstValue, 00068 &Length); 00069 if (!NT_SUCCESS(Status)) 00070 { 00071 DPRINT1("RtlExpandEnvironmentStrings_U() failed (Status %lx)\n", Status); 00072 DPRINT1("Length %lu\n", Length); 00073 if (Buffer) 00074 LocalFree(Buffer); 00075 return FALSE; 00076 } 00077 } 00078 else 00079 { 00080 RtlInitUnicodeString(&DstValue, 00081 lpValue); 00082 } 00083 00084 if (!_wcsicmp(lpName, L"temp") || !_wcsicmp(lpName, L"tmp")) 00085 { 00086 if (!GetShortPathNameW(DstValue.Buffer, ShortName, MAX_PATH)) 00087 { 00088 DPRINT1("GetShortPathNameW() failed for %S (Error %lu)\n", DstValue.Buffer, GetLastError()); 00089 if (Buffer) 00090 LocalFree(Buffer); 00091 return FALSE; 00092 } 00093 00094 DPRINT("Buffer: %S\n", ShortName); 00095 RtlInitUnicodeString(&DstValue, 00096 ShortName); 00097 } 00098 00099 RtlInitUnicodeString(&Name, 00100 lpName); 00101 00102 DPRINT("Value: %wZ\n", &DstValue); 00103 00104 Status = RtlSetEnvironmentVariable((PWSTR*)Environment, 00105 &Name, 00106 &DstValue); 00107 00108 if (Buffer) 00109 LocalFree(Buffer); 00110 00111 if (!NT_SUCCESS(Status)) 00112 { 00113 DPRINT1("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status); 00114 return FALSE; 00115 } 00116 00117 return TRUE; 00118 } 00119 00120 00121 static BOOL 00122 AppendUserEnvironmentVariable(LPVOID *Environment, 00123 LPWSTR lpName, 00124 LPWSTR lpValue) 00125 { 00126 UNICODE_STRING Name; 00127 UNICODE_STRING Value; 00128 NTSTATUS Status; 00129 00130 RtlInitUnicodeString(&Name, 00131 lpName); 00132 00133 Value.Length = 0; 00134 Value.MaximumLength = 1024 * sizeof(WCHAR); 00135 Value.Buffer = LocalAlloc(LPTR, 00136 1024 * sizeof(WCHAR)); 00137 if (Value.Buffer == NULL) 00138 { 00139 return FALSE; 00140 } 00141 Value.Buffer[0] = UNICODE_NULL; 00142 00143 Status = RtlQueryEnvironmentVariable_U((PWSTR)*Environment, 00144 &Name, 00145 &Value); 00146 if (NT_SUCCESS(Status)) 00147 { 00148 RtlAppendUnicodeToString(&Value, 00149 L";"); 00150 } 00151 00152 RtlAppendUnicodeToString(&Value, 00153 lpValue); 00154 00155 Status = RtlSetEnvironmentVariable((PWSTR*)Environment, 00156 &Name, 00157 &Value); 00158 LocalFree(Value.Buffer); 00159 if (!NT_SUCCESS(Status)) 00160 { 00161 DPRINT1("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status); 00162 return FALSE; 00163 } 00164 00165 return TRUE; 00166 } 00167 00168 00169 static HKEY 00170 GetCurrentUserKey(HANDLE hToken) 00171 { 00172 UNICODE_STRING SidString; 00173 HKEY hKey; 00174 LONG Error; 00175 00176 if (!GetUserSidFromToken(hToken, 00177 &SidString)) 00178 { 00179 DPRINT1("GetUserSidFromToken() failed\n"); 00180 return NULL; 00181 } 00182 00183 Error = RegOpenKeyExW(HKEY_USERS, 00184 SidString.Buffer, 00185 0, 00186 MAXIMUM_ALLOWED, 00187 &hKey); 00188 if (Error != ERROR_SUCCESS) 00189 { 00190 DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error); 00191 RtlFreeUnicodeString(&SidString); 00192 SetLastError((DWORD)Error); 00193 return NULL; 00194 } 00195 00196 RtlFreeUnicodeString(&SidString); 00197 00198 return hKey; 00199 } 00200 00201 00202 static BOOL 00203 SetUserEnvironment(LPVOID *lpEnvironment, 00204 HKEY hKey, 00205 LPWSTR lpSubKeyName) 00206 { 00207 HKEY hEnvKey; 00208 DWORD dwValues; 00209 DWORD dwMaxValueNameLength; 00210 DWORD dwMaxValueDataLength; 00211 DWORD dwValueNameLength; 00212 DWORD dwValueDataLength; 00213 DWORD dwType; 00214 DWORD i; 00215 LPWSTR lpValueName; 00216 LPWSTR lpValueData; 00217 LONG Error; 00218 00219 Error = RegOpenKeyExW(hKey, 00220 lpSubKeyName, 00221 0, 00222 KEY_QUERY_VALUE, 00223 &hEnvKey); 00224 if (Error != ERROR_SUCCESS) 00225 { 00226 DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error); 00227 SetLastError((DWORD)Error); 00228 return FALSE; 00229 } 00230 00231 Error = RegQueryInfoKey(hEnvKey, 00232 NULL, 00233 NULL, 00234 NULL, 00235 NULL, 00236 NULL, 00237 NULL, 00238 &dwValues, 00239 &dwMaxValueNameLength, 00240 &dwMaxValueDataLength, 00241 NULL, 00242 NULL); 00243 if (Error != ERROR_SUCCESS) 00244 { 00245 DPRINT1("RegQueryInforKey() failed (Error %ld)\n", Error); 00246 RegCloseKey(hEnvKey); 00247 SetLastError((DWORD)Error); 00248 return FALSE; 00249 } 00250 00251 if (dwValues == 0) 00252 { 00253 RegCloseKey(hEnvKey); 00254 return TRUE; 00255 } 00256 00257 /* Allocate buffers */ 00258 lpValueName = LocalAlloc(LPTR, 00259 dwMaxValueNameLength * sizeof(WCHAR)); 00260 if (lpValueName == NULL) 00261 { 00262 RegCloseKey(hEnvKey); 00263 return FALSE; 00264 } 00265 00266 lpValueData = LocalAlloc(LPTR, 00267 dwMaxValueDataLength); 00268 if (lpValueData == NULL) 00269 { 00270 LocalFree(lpValueName); 00271 RegCloseKey(hEnvKey); 00272 return FALSE; 00273 } 00274 00275 /* Enumerate values */ 00276 for (i = 0; i < dwValues; i++) 00277 { 00278 dwValueNameLength = dwMaxValueNameLength; 00279 dwValueDataLength = dwMaxValueDataLength; 00280 RegEnumValueW(hEnvKey, 00281 i, 00282 lpValueName, 00283 &dwValueNameLength, 00284 NULL, 00285 &dwType, 00286 (LPBYTE)lpValueData, 00287 &dwValueDataLength); 00288 00289 if (!_wcsicmp (lpValueName, L"path")) 00290 { 00291 /* Append 'Path' environment variable */ 00292 AppendUserEnvironmentVariable(lpEnvironment, 00293 lpValueName, 00294 lpValueData); 00295 } 00296 else 00297 { 00298 /* Set environment variable */ 00299 SetUserEnvironmentVariable(lpEnvironment, 00300 lpValueName, 00301 lpValueData, 00302 (dwType == REG_EXPAND_SZ)); 00303 } 00304 } 00305 00306 LocalFree(lpValueData); 00307 LocalFree(lpValueName); 00308 RegCloseKey(hEnvKey); 00309 00310 return TRUE; 00311 } 00312 00313 00314 BOOL WINAPI 00315 CreateEnvironmentBlock(LPVOID *lpEnvironment, 00316 HANDLE hToken, 00317 BOOL bInherit) 00318 { 00319 WCHAR Buffer[MAX_PATH]; 00320 WCHAR szValue[1024]; 00321 DWORD Length; 00322 DWORD dwType; 00323 HKEY hKey; 00324 HKEY hKeyUser; 00325 NTSTATUS Status; 00326 LONG lError; 00327 00328 DPRINT("CreateEnvironmentBlock() called\n"); 00329 00330 if (lpEnvironment == NULL) 00331 { 00332 SetLastError(ERROR_INVALID_PARAMETER); 00333 return FALSE; 00334 } 00335 00336 Status = RtlCreateEnvironment((BOOLEAN)bInherit, 00337 (PWSTR*)lpEnvironment); 00338 if (!NT_SUCCESS (Status)) 00339 { 00340 DPRINT1("RtlCreateEnvironment() failed (Status %lx)\n", Status); 00341 SetLastError(RtlNtStatusToDosError(Status)); 00342 return FALSE; 00343 } 00344 00345 /* Set 'COMPUTERNAME' variable */ 00346 Length = MAX_PATH; 00347 if (GetComputerNameW(Buffer, 00348 &Length)) 00349 { 00350 SetUserEnvironmentVariable(lpEnvironment, 00351 L"COMPUTERNAME", 00352 Buffer, 00353 FALSE); 00354 } 00355 00356 /* Set 'ALLUSERSPROFILE' variable */ 00357 Length = MAX_PATH; 00358 if (GetAllUsersProfileDirectoryW(Buffer, 00359 &Length)) 00360 { 00361 SetUserEnvironmentVariable(lpEnvironment, 00362 L"ALLUSERSPROFILE", 00363 Buffer, 00364 FALSE); 00365 } 00366 00367 lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 00368 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 00369 0, 00370 KEY_READ, 00371 &hKey); 00372 if (lError == ERROR_SUCCESS) 00373 { 00374 Length = 1024 * sizeof(WCHAR); 00375 lError = RegQueryValueExW(hKey, 00376 L"ProgramFilesDir", 00377 NULL, 00378 &dwType, 00379 (LPBYTE)szValue, 00380 &Length); 00381 if (lError == ERROR_SUCCESS) 00382 { 00383 SetUserEnvironmentVariable(lpEnvironment, 00384 L"ProgramFiles", 00385 szValue, 00386 FALSE); 00387 } 00388 00389 Length = 1024 * sizeof(WCHAR); 00390 lError = RegQueryValueExW(hKey, 00391 L"CommonFilesDir", 00392 NULL, 00393 &dwType, 00394 (LPBYTE)szValue, 00395 &Length); 00396 if (lError == ERROR_SUCCESS) 00397 { 00398 SetUserEnvironmentVariable(lpEnvironment, 00399 L"CommonProgramFiles", 00400 szValue, 00401 FALSE); 00402 } 00403 00404 RegCloseKey(hKey); 00405 } 00406 00407 if (hToken == NULL) 00408 return TRUE; 00409 00410 hKeyUser = GetCurrentUserKey(hToken); 00411 if (hKeyUser == NULL) 00412 { 00413 DPRINT1("GetCurrentUserKey() failed\n"); 00414 RtlDestroyEnvironment(*lpEnvironment); 00415 return FALSE; 00416 } 00417 00418 /* Set 'USERPROFILE' variable */ 00419 Length = MAX_PATH; 00420 if (GetUserProfileDirectoryW(hToken, 00421 Buffer, 00422 &Length)) 00423 { 00424 SetUserEnvironmentVariable(lpEnvironment, 00425 L"USERPROFILE", 00426 Buffer, 00427 FALSE); 00428 } 00429 00430 /* FIXME: Set 'USERDOMAIN' variable */ 00431 00432 Length = MAX_PATH; 00433 if (GetUserNameW(Buffer, 00434 &Length)) 00435 { 00436 SetUserEnvironmentVariable(lpEnvironment, 00437 L"USERNAME", 00438 Buffer, 00439 FALSE); 00440 } 00441 00442 /* Set user environment variables */ 00443 SetUserEnvironment(lpEnvironment, 00444 hKeyUser, 00445 L"Environment"); 00446 00447 /* Set user volatile environment variables */ 00448 SetUserEnvironment(lpEnvironment, 00449 hKeyUser, 00450 L"Volatile Environment"); 00451 00452 RegCloseKey(hKeyUser); 00453 00454 return TRUE; 00455 } 00456 00457 00458 BOOL WINAPI 00459 DestroyEnvironmentBlock(LPVOID lpEnvironment) 00460 { 00461 DPRINT("DestroyEnvironmentBlock() called\n"); 00462 00463 if (lpEnvironment == NULL) 00464 { 00465 SetLastError(ERROR_INVALID_PARAMETER); 00466 return FALSE; 00467 } 00468 00469 RtlDestroyEnvironment(lpEnvironment); 00470 00471 return TRUE; 00472 } 00473 00474 00475 BOOL WINAPI 00476 ExpandEnvironmentStringsForUserW(IN HANDLE hToken, 00477 IN LPCWSTR lpSrc, 00478 OUT LPWSTR lpDest, 00479 IN DWORD dwSize) 00480 { 00481 PVOID lpEnvironment; 00482 BOOL Ret = FALSE; 00483 00484 if (lpSrc == NULL || lpDest == NULL || dwSize == 0) 00485 { 00486 SetLastError(ERROR_INVALID_PARAMETER); 00487 return FALSE; 00488 } 00489 00490 if (CreateEnvironmentBlock(&lpEnvironment, 00491 hToken, 00492 FALSE)) 00493 { 00494 UNICODE_STRING SrcU, DestU; 00495 NTSTATUS Status; 00496 00497 /* initialize the strings */ 00498 RtlInitUnicodeString(&SrcU, 00499 lpSrc); 00500 DestU.Length = 0; 00501 DestU.MaximumLength = dwSize * sizeof(WCHAR); 00502 DestU.Buffer = lpDest; 00503 00504 /* expand the strings */ 00505 Status = RtlExpandEnvironmentStrings_U((PWSTR)lpEnvironment, 00506 &SrcU, 00507 &DestU, 00508 NULL); 00509 00510 DestroyEnvironmentBlock(lpEnvironment); 00511 00512 if (NT_SUCCESS(Status)) 00513 { 00514 Ret = TRUE; 00515 } 00516 else 00517 { 00518 SetLastError(RtlNtStatusToDosError(Status)); 00519 } 00520 } 00521 00522 return Ret; 00523 } 00524 00525 00526 BOOL WINAPI 00527 ExpandEnvironmentStringsForUserA(IN HANDLE hToken, 00528 IN LPCSTR lpSrc, 00529 OUT LPSTR lpDest, 00530 IN DWORD dwSize) 00531 { 00532 DWORD dwSrcLen; 00533 LPWSTR lpSrcW = NULL, lpDestW = NULL; 00534 BOOL Ret = FALSE; 00535 00536 if (lpSrc == NULL || lpDest == NULL || dwSize == 0) 00537 { 00538 SetLastError(ERROR_INVALID_PARAMETER); 00539 return FALSE; 00540 } 00541 00542 dwSrcLen = strlen(lpSrc); 00543 lpSrcW = (LPWSTR)GlobalAlloc(GMEM_FIXED, 00544 (dwSrcLen + 1) * sizeof(WCHAR)); 00545 if (lpSrcW == NULL || 00546 MultiByteToWideChar(CP_ACP, 00547 0, 00548 lpSrc, 00549 -1, 00550 lpSrcW, 00551 dwSrcLen + 1) == 0) 00552 { 00553 goto Cleanup; 00554 } 00555 00556 lpDestW = (LPWSTR)GlobalAlloc(GMEM_FIXED, 00557 dwSize * sizeof(WCHAR)); 00558 if (lpDestW == NULL) 00559 { 00560 goto Cleanup; 00561 } 00562 00563 Ret = ExpandEnvironmentStringsForUserW(hToken, 00564 lpSrcW, 00565 lpDestW, 00566 dwSize); 00567 if (Ret) 00568 { 00569 if (WideCharToMultiByte(CP_ACP, 00570 0, 00571 lpDestW, 00572 -1, 00573 lpDest, 00574 dwSize, 00575 NULL, 00576 NULL) == 0) 00577 { 00578 Ret = FALSE; 00579 } 00580 } 00581 00582 Cleanup: 00583 if (lpSrcW != NULL) 00584 { 00585 GlobalFree((HGLOBAL)lpSrcW); 00586 } 00587 00588 if (lpDestW != NULL) 00589 { 00590 GlobalFree((HGLOBAL)lpDestW); 00591 } 00592 00593 return Ret; 00594 } 00595 00596 /* EOF */ Generated on Sun May 27 2012 04:18:59 for ReactOS by
1.7.6.1
|