ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

environ.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.