Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenenviron.c
Go to the documentation of this file.
00001 /* $Id: environ.c 54459 2011-11-20 17:00:39Z pschweitzer $ 00002 * 00003 * COPYRIGHT: See COPYING in the top level directory 00004 * PROJECT: ReactOS system libraries 00005 * FILE: lib/kernel32/misc/env.c 00006 * PURPOSE: Environment functions 00007 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) 00008 * Emanuele Aliberti 00009 * Thomas Weidenmueller 00010 * UPDATE HISTORY: 00011 * Created 01/11/98 00012 */ 00013 00014 /* INCLUDES *******************************************************************/ 00015 00016 #include <k32.h> 00017 00018 #define NDEBUG 00019 #include <debug.h> 00020 00021 /* FUNCTIONS ******************************************************************/ 00022 00023 /* 00024 * @implemented 00025 */ 00026 DWORD 00027 WINAPI 00028 GetEnvironmentVariableA(IN LPCSTR lpName, 00029 IN LPSTR lpBuffer, 00030 IN DWORD nSize) 00031 { 00032 ANSI_STRING VarName, VarValue; 00033 UNICODE_STRING VarNameU, VarValueU; 00034 PWSTR Buffer; 00035 ULONG Result = 0; 00036 USHORT UniSize; 00037 NTSTATUS Status; 00038 00039 /* Initialize all the strings */ 00040 RtlInitAnsiString(&VarName, lpName); 00041 RtlInitUnicodeString(&VarNameU, NULL); 00042 RtlInitUnicodeString(&VarValueU, NULL); 00043 Status = RtlAnsiStringToUnicodeString(&VarNameU, &VarName, TRUE); 00044 if (!NT_SUCCESS(Status)) goto Quickie; 00045 00046 /* Check if the size is too big to fit */ 00047 UniSize = UNICODE_STRING_MAX_CHARS - 2; 00048 if (nSize <= UniSize) 00049 { 00050 /* It fits, but was there a string at all? */ 00051 if (nSize) 00052 { 00053 /* Keep the given size, minus a NULL-char */ 00054 UniSize = nSize - 1; 00055 } 00056 else 00057 { 00058 /* No size */ 00059 UniSize = 0; 00060 } 00061 } 00062 else 00063 { 00064 /* String is too big, so we need to return a NULL char as well */ 00065 UniSize--; 00066 } 00067 00068 /* Allocate the value string buffer */ 00069 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, UniSize * sizeof(WCHAR)); 00070 if (!Buffer) 00071 { 00072 Status = STATUS_NO_MEMORY; 00073 goto Quickie; 00074 } 00075 00076 /* And initialize its string */ 00077 RtlInitEmptyUnicodeString(&VarValueU, Buffer, UniSize * sizeof(WCHAR)); 00078 00079 /* Acquire the PEB lock since we'll be querying variables now */ 00080 RtlAcquirePebLock(); 00081 00082 /* Query the variable */ 00083 Status = RtlQueryEnvironmentVariable_U(NULL, &VarNameU, &VarValueU); 00084 if ((NT_SUCCESS(Status)) && !(nSize)) Status = STATUS_BUFFER_TOO_SMALL; 00085 00086 /* Check if we didn't have enough space */ 00087 if (!(NT_SUCCESS(Status)) && (Status == STATUS_BUFFER_TOO_SMALL)) 00088 { 00089 /* Fixup the length that the API returned */ 00090 VarValueU.MaximumLength = VarValueU.Length + 2; 00091 00092 /* Free old Unicode buffer */ 00093 RtlFreeHeap(RtlGetProcessHeap(), 0, VarValueU.Buffer); 00094 00095 /* Allocate new one */ 00096 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, VarValueU.MaximumLength); 00097 if (Buffer) 00098 { 00099 /* Query the variable so we can know its size */ 00100 VarValueU.Buffer = Buffer; 00101 Status = RtlQueryEnvironmentVariable_U(NULL, &VarNameU, &VarValueU); 00102 if (NT_SUCCESS(Status)) 00103 { 00104 /* Get the ASCII length of the variable */ 00105 Result = RtlUnicodeStringToAnsiSize(&VarValueU); 00106 } 00107 } 00108 else 00109 { 00110 /* Set failure status */ 00111 Status = STATUS_NO_MEMORY; 00112 } 00113 } 00114 else if (NT_SUCCESS(Status)) 00115 { 00116 /* Check if the size is too big to fit */ 00117 UniSize = UNICODE_STRING_MAX_BYTES - 1; 00118 if (nSize <= UniSize) UniSize = nSize; 00119 00120 /* Check the size */ 00121 Result = RtlUnicodeStringToAnsiSize(&VarValueU); 00122 if (Result <= UniSize) 00123 { 00124 /* Convert the string */ 00125 RtlInitEmptyAnsiString(&VarValue, lpBuffer, UniSize); 00126 Status = RtlUnicodeStringToAnsiString(&VarValue, &VarValueU, FALSE); 00127 if (NT_SUCCESS(Status)) 00128 { 00129 /* NULL-terminate and set the final length */ 00130 lpBuffer[VarValue.Length] = ANSI_NULL; 00131 Result = VarValue.Length; 00132 } 00133 } 00134 } 00135 00136 /* Release the lock */ 00137 RtlReleasePebLock(); 00138 00139 Quickie: 00140 /* Free the strings */ 00141 RtlFreeUnicodeString(&VarNameU); 00142 if (VarValueU.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, VarValueU.Buffer); 00143 00144 /* Check if we suceeded */ 00145 if (!NT_SUCCESS(Status)) 00146 { 00147 /* We did not, clear the result and set the error code */ 00148 BaseSetLastNTError(Status); 00149 Result = 0; 00150 } 00151 00152 /* Return the result */ 00153 return Result; 00154 } 00155 00156 /* 00157 * @implemented 00158 */ 00159 DWORD 00160 WINAPI 00161 GetEnvironmentVariableW(IN LPCWSTR lpName, 00162 IN LPWSTR lpBuffer, 00163 IN DWORD nSize) 00164 { 00165 UNICODE_STRING VarName, VarValue; 00166 NTSTATUS Status; 00167 USHORT UniSize; 00168 00169 if (nSize <= (UNICODE_STRING_MAX_CHARS - 1)) 00170 { 00171 if (nSize) 00172 { 00173 UniSize = nSize * sizeof(WCHAR) - sizeof(UNICODE_NULL); 00174 } 00175 else 00176 { 00177 UniSize = 0; 00178 } 00179 } 00180 else 00181 { 00182 UniSize = UNICODE_STRING_MAX_BYTES - sizeof(UNICODE_NULL); 00183 } 00184 00185 Status = RtlInitUnicodeStringEx(&VarName, lpName); 00186 if (!NT_SUCCESS(Status)) 00187 { 00188 BaseSetLastNTError(Status); 00189 return 0; 00190 } 00191 00192 RtlInitEmptyUnicodeString(&VarValue, lpBuffer, UniSize); 00193 00194 Status = RtlQueryEnvironmentVariable_U(NULL, &VarName, &VarValue); 00195 if (!NT_SUCCESS(Status)) 00196 { 00197 if (Status == STATUS_BUFFER_TOO_SMALL) 00198 { 00199 return (VarValue.Length / sizeof(WCHAR)) + sizeof(ANSI_NULL); 00200 } 00201 BaseSetLastNTError (Status); 00202 return 0; 00203 } 00204 00205 lpBuffer[VarValue.Length / sizeof(WCHAR)] = UNICODE_NULL; 00206 00207 return (VarValue.Length / sizeof(WCHAR)); 00208 } 00209 00210 /* 00211 * @implemented 00212 */ 00213 BOOL 00214 WINAPI 00215 SetEnvironmentVariableA(IN LPCSTR lpName, 00216 IN LPCSTR lpValue) 00217 { 00218 ANSI_STRING VarName, VarValue; 00219 UNICODE_STRING VarNameU, VarValueU; 00220 NTSTATUS Status; 00221 00222 RtlInitAnsiString(&VarName, (LPSTR)lpName); 00223 Status = RtlAnsiStringToUnicodeString(&VarNameU, &VarName, TRUE); 00224 if (NT_SUCCESS(Status)) 00225 { 00226 if (lpValue) 00227 { 00228 RtlInitAnsiString(&VarValue, (LPSTR)lpValue); 00229 Status = RtlAnsiStringToUnicodeString(&VarValueU, &VarValue, TRUE); 00230 if (NT_SUCCESS(Status)) 00231 { 00232 Status = RtlSetEnvironmentVariable(NULL, &VarNameU, &VarValueU); 00233 RtlFreeUnicodeString(&VarValueU); 00234 } 00235 } 00236 else 00237 { 00238 Status = RtlSetEnvironmentVariable(NULL, &VarNameU, NULL); 00239 } 00240 00241 RtlFreeUnicodeString(&VarNameU); 00242 00243 if (NT_SUCCESS(Status)) return TRUE; 00244 } 00245 00246 BaseSetLastNTError(Status); 00247 return FALSE; 00248 } 00249 00250 /* 00251 * @implemented 00252 */ 00253 BOOL 00254 WINAPI 00255 SetEnvironmentVariableW(IN LPCWSTR lpName, 00256 IN LPCWSTR lpValue) 00257 { 00258 UNICODE_STRING VarName, VarValue; 00259 NTSTATUS Status; 00260 00261 Status = RtlInitUnicodeStringEx(&VarName, lpName); 00262 if (NT_SUCCESS(Status)) 00263 { 00264 if (lpValue) 00265 { 00266 Status = RtlInitUnicodeStringEx(&VarValue, lpValue); 00267 if (NT_SUCCESS(Status)) 00268 { 00269 Status = RtlSetEnvironmentVariable(NULL, &VarName, &VarValue); 00270 } 00271 } 00272 else 00273 { 00274 Status = RtlSetEnvironmentVariable(NULL, &VarName, NULL); 00275 } 00276 00277 if (NT_SUCCESS(Status)) return TRUE; 00278 } 00279 00280 BaseSetLastNTError(Status); 00281 return FALSE; 00282 } 00283 00284 /* 00285 * @implemented 00286 */ 00287 LPSTR 00288 WINAPI 00289 GetEnvironmentStringsA(VOID) 00290 { 00291 ULONG Length, Size; 00292 NTSTATUS Status; 00293 PWCHAR Environment, p; 00294 PCHAR Buffer = NULL; 00295 00296 RtlAcquirePebLock(); 00297 p = Environment = NtCurrentPeb()->ProcessParameters->Environment; 00298 00299 do 00300 { 00301 p += wcslen(p) + 1; 00302 } while (*p); 00303 00304 Length = p - Environment + 1; 00305 00306 Status = RtlUnicodeToMultiByteSize(&Size, Environment, Length * sizeof(WCHAR)); 00307 if (NT_SUCCESS(Status)) 00308 { 00309 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size); 00310 if (Buffer) 00311 { 00312 Status = RtlUnicodeToOemN(Buffer, Size, 0, Environment, Length * sizeof(WCHAR)); 00313 if (!NT_SUCCESS(Status)) 00314 { 00315 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); 00316 Buffer = NULL; 00317 00318 BaseSetLastNTError(Status); 00319 } 00320 } 00321 else 00322 { 00323 BaseSetLastNTError(STATUS_NO_MEMORY); 00324 } 00325 } 00326 else 00327 { 00328 BaseSetLastNTError(Status); 00329 } 00330 00331 RtlReleasePebLock(); 00332 return Buffer; 00333 } 00334 00335 /* 00336 * @implemented 00337 */ 00338 LPWSTR 00339 WINAPI 00340 GetEnvironmentStringsW(VOID) 00341 { 00342 PWCHAR Environment, p; 00343 ULONG Length; 00344 00345 RtlAcquirePebLock(); 00346 00347 p = Environment = NtCurrentPeb()->ProcessParameters->Environment; 00348 00349 do 00350 { 00351 p += wcslen(p) + 1; 00352 } while (*p); 00353 00354 Length = p - Environment + 1; 00355 00356 p = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR)); 00357 if (p) 00358 { 00359 RtlCopyMemory(p, Environment, Length * sizeof(WCHAR)); 00360 } 00361 else 00362 { 00363 BaseSetLastNTError(STATUS_NO_MEMORY); 00364 } 00365 00366 RtlReleasePebLock(); 00367 return p; 00368 } 00369 00370 /* 00371 * @implemented 00372 */ 00373 BOOL 00374 WINAPI 00375 FreeEnvironmentStringsA(IN LPSTR EnvironmentStrings) 00376 { 00377 return (BOOL)RtlFreeHeap(RtlGetProcessHeap(), 0, EnvironmentStrings); 00378 } 00379 00380 /* 00381 * @implemented 00382 */ 00383 BOOL 00384 WINAPI 00385 FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings) 00386 { 00387 return (BOOL)RtlFreeHeap(RtlGetProcessHeap(), 0, EnvironmentStrings); 00388 } 00389 00390 /* 00391 * @implemented 00392 */ 00393 DWORD 00394 WINAPI 00395 ExpandEnvironmentStringsA(IN LPCSTR lpSrc, 00396 IN LPSTR lpDst, 00397 IN DWORD nSize) 00398 { 00399 ANSI_STRING Source, Dest; 00400 UNICODE_STRING SourceU, DestU; 00401 PWSTR Buffer; 00402 ULONG Result = 0, Length; 00403 USHORT UniSize; 00404 NTSTATUS Status; 00405 00406 /* Check if the size is too big to fit */ 00407 UniSize = UNICODE_STRING_MAX_CHARS - 2; 00408 if (nSize <= UniSize) UniSize = nSize; 00409 00410 /* Clear the input buffer */ 00411 if (lpDst) *lpDst = ANSI_NULL; 00412 00413 /* Initialize all the strings */ 00414 RtlInitAnsiString(&Source, lpSrc); 00415 RtlInitUnicodeString(&SourceU, NULL); 00416 RtlInitUnicodeString(&DestU, NULL); 00417 Status = RtlAnsiStringToUnicodeString(&SourceU, &Source, TRUE); 00418 if (!NT_SUCCESS(Status)) goto Quickie; 00419 00420 /* If the string fit in, make space for a NULL char */ 00421 if (UniSize) 00422 { 00423 UniSize--; 00424 } 00425 else 00426 { 00427 /* No input size, so no string size */ 00428 UniSize = 0; 00429 } 00430 00431 /* Allocate the value string buffer */ 00432 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, UniSize * sizeof(WCHAR)); 00433 if (!Buffer) 00434 { 00435 Status = STATUS_NO_MEMORY; 00436 goto Quickie; 00437 } 00438 00439 /* And initialize its string */ 00440 RtlInitEmptyUnicodeString(&DestU, Buffer, UniSize * sizeof(WCHAR)); 00441 00442 /* Query the variable */ 00443 Length = 0; 00444 Status = RtlExpandEnvironmentStrings_U(NULL, &SourceU, &DestU, &Length); 00445 00446 /* Check if we didn't have enough space */ 00447 if (!(NT_SUCCESS(Status)) && (Status == STATUS_BUFFER_TOO_SMALL)) 00448 { 00449 /* Fixup the length that the API returned */ 00450 DestU.MaximumLength = Length; 00451 00452 /* Free old Unicode buffer */ 00453 RtlFreeHeap(RtlGetProcessHeap(), 0, DestU.Buffer); 00454 00455 /* Allocate new one */ 00456 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length); 00457 if (Buffer) 00458 { 00459 /* Query the variable so we can know its size */ 00460 DestU.Buffer = Buffer; 00461 Status = RtlExpandEnvironmentStrings_U(NULL, &SourceU, &DestU, &Length); 00462 if (NT_SUCCESS(Status)) 00463 { 00464 /* Get the ASCII length of the variable, add a byte for NULL */ 00465 Result = RtlUnicodeStringToAnsiSize(&DestU) + sizeof(ANSI_NULL); 00466 } 00467 } 00468 else 00469 { 00470 /* Set failure status */ 00471 Status = STATUS_NO_MEMORY; 00472 } 00473 } 00474 else if (NT_SUCCESS(Status)) 00475 { 00476 /* Check if the size is too big to fit */ 00477 UniSize = UNICODE_STRING_MAX_BYTES - 1; 00478 if (nSize <= UniSize) UniSize = nSize; 00479 00480 /* Check the size */ 00481 Result = RtlUnicodeStringToAnsiSize(&DestU); 00482 if (Result <= UniSize) 00483 { 00484 /* Convert the string */ 00485 RtlInitEmptyAnsiString(&Dest, lpDst, UniSize); 00486 Status = RtlUnicodeStringToAnsiString(&Dest, &DestU, FALSE); 00487 00488 /* Write a NULL-char in case of failure only */ 00489 if (!NT_SUCCESS(Status)) *lpDst = ANSI_NULL; 00490 } 00491 } 00492 Quickie: 00493 /* Free the strings */ 00494 RtlFreeUnicodeString(&SourceU); 00495 if (DestU.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, DestU.Buffer); 00496 00497 /* Check if we suceeded */ 00498 if (!NT_SUCCESS(Status)) 00499 { 00500 /* We did not, clear the result and set the error code */ 00501 BaseSetLastNTError(Status); 00502 Result = 0; 00503 } 00504 00505 /* Return the result */ 00506 return Result; 00507 } 00508 00509 /* 00510 * @implemented 00511 */ 00512 DWORD 00513 WINAPI 00514 ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, 00515 IN LPWSTR lpDst, 00516 IN DWORD nSize) 00517 { 00518 UNICODE_STRING Source, Destination; 00519 NTSTATUS Status; 00520 USHORT UniSize; 00521 00522 UniSize = UNICODE_STRING_MAX_CHARS - 2; 00523 if (nSize <= UniSize) UniSize = nSize; 00524 00525 RtlInitUnicodeString(&Source, (LPWSTR)lpSrc); 00526 RtlInitEmptyUnicodeString(&Destination, lpDst, UniSize * sizeof(WCHAR)); 00527 00528 Status = RtlExpandEnvironmentStrings_U(NULL, 00529 &Source, 00530 &Destination, 00531 &nSize); 00532 if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_TOO_SMALL)) 00533 { 00534 return nSize / sizeof(WCHAR); 00535 } 00536 00537 BaseSetLastNTError(Status); 00538 return 0; 00539 } 00540 00541 /* 00542 * @implemented 00543 */ 00544 BOOL 00545 WINAPI 00546 SetEnvironmentStringsA(IN LPCH NewEnvironment) 00547 { 00548 STUB; 00549 return FALSE; 00550 } 00551 00552 /* 00553 * @implemented 00554 */ 00555 BOOL 00556 WINAPI 00557 SetEnvironmentStringsW(IN LPWCH NewEnvironment) 00558 { 00559 STUB; 00560 return FALSE; 00561 } 00562 00563 /* EOF */ Generated on Sat May 26 2012 04:22:56 for ReactOS by
1.7.6.1
|