3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/misc/env.c
6 * PURPOSE: Environment functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
15 #include <kernel32/kernel32.h>
18 /* FUNCTIONS ******************************************************************/
22 GetEnvironmentVariableA (
30 UNICODE_STRING VarNameU;
31 UNICODE_STRING VarValueU;
34 /* initialize unicode variable name string */
35 RtlInitAnsiString (&VarName,
37 RtlAnsiStringToUnicodeString (&VarNameU,
41 /* initialize ansi variable value string */
43 VarValue.MaximumLength = nSize;
44 VarValue.Buffer = lpBuffer;
46 /* initialize unicode variable value string and allocate buffer */
48 VarValueU.MaximumLength = nSize * sizeof(WCHAR);
49 VarValueU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
51 VarValueU.MaximumLength);
53 /* get unicode environment variable */
54 Status = RtlQueryEnvironmentVariable_U (NULL,
57 if (!NT_SUCCESS(Status))
59 /* free unicode buffer */
60 RtlFreeHeap (RtlGetProcessHeap (),
64 /* free unicode variable name string */
65 RtlFreeUnicodeString (&VarNameU);
67 SetLastErrorByStatus (Status);
68 if (Status == STATUS_BUFFER_TOO_SMALL)
70 return VarValueU.Length / sizeof(WCHAR) + 1;
78 /* convert unicode value string to ansi */
79 RtlUnicodeStringToAnsiString (&VarValue,
83 /* free unicode buffer */
84 RtlFreeHeap (RtlGetProcessHeap (),
88 /* free unicode variable name string */
89 RtlFreeUnicodeString (&VarNameU);
91 return (VarValueU.Length / sizeof(WCHAR));
97 GetEnvironmentVariableW (
103 UNICODE_STRING VarName;
104 UNICODE_STRING VarValue;
107 RtlInitUnicodeString (&VarName,
111 VarValue.MaximumLength = nSize * sizeof(WCHAR);
112 VarValue.Buffer = lpBuffer;
114 Status = RtlQueryEnvironmentVariable_U (NULL,
117 if (!NT_SUCCESS(Status))
119 SetLastErrorByStatus (Status);
120 if (Status == STATUS_BUFFER_TOO_SMALL)
122 return (VarValue.Length / sizeof(WCHAR)) + 1;
130 return (VarValue.Length / sizeof(WCHAR));
136 SetEnvironmentVariableA (
142 ANSI_STRING VarValue;
143 UNICODE_STRING VarNameU;
144 UNICODE_STRING VarValueU;
147 DPRINT("SetEnvironmentVariableA(Name '%s', Value '%s')\n", lpName, lpValue);
149 RtlInitAnsiString (&VarName,
151 RtlAnsiStringToUnicodeString (&VarNameU,
155 RtlInitAnsiString (&VarValue,
157 RtlAnsiStringToUnicodeString (&VarValueU,
161 Status = RtlSetEnvironmentVariable (NULL,
165 RtlFreeUnicodeString (&VarNameU);
166 RtlFreeUnicodeString (&VarValueU);
168 if (!NT_SUCCESS(Status))
170 SetLastErrorByStatus (Status);
180 SetEnvironmentVariableW (
185 UNICODE_STRING VarName;
186 UNICODE_STRING VarValue;
189 DPRINT("SetEnvironmentVariableW(Name '%S', Value '%S')\n", lpName, lpValue);
191 RtlInitUnicodeString (&VarName,
194 RtlInitUnicodeString (&VarValue,
197 Status = RtlSetEnvironmentVariable (NULL,
200 if (!NT_SUCCESS(Status))
202 SetLastErrorByStatus (Status);
214 PPEB pPeb = NtCurrentPeb();
217 nVersion = MAKEWORD(pPeb->OSMajorVersion, pPeb->OSMinorVersion);
219 /* behave consistently when posing as another operating system */
221 if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_WINDOWS)
222 nVersion |= ((DWORD)(pPeb->OSBuildNumber)) << 16;
224 /* non-NT platform flag */
225 if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_NT)
226 nVersion |= 0x80000000;
235 LPOSVERSIONINFOW lpVersionInformation
238 PPEB pPeb = NtCurrentPeb();
240 /* TODO: move this into RtlGetVersion */
241 switch(lpVersionInformation->dwOSVersionInfoSize)
243 case sizeof(OSVERSIONINFOEXW):
245 LPOSVERSIONINFOEXW lpVersionInformationEx =
246 (LPOSVERSIONINFOEXW)lpVersionInformation;
248 lpVersionInformationEx->wServicePackMajor = pPeb->SPMajorVersion;
249 lpVersionInformationEx->wServicePackMinor = pPeb->SPMinorVersion;
250 /* TODO: read from the KUSER_SHARED_DATA */
251 lpVersionInformationEx->wSuiteMask = 0;
252 /* TODO: call RtlGetNtProductType */
253 lpVersionInformationEx->wProductType = 0;
255 lpVersionInformationEx->wReserved = 0;
259 case sizeof(OSVERSIONINFOW):
261 lpVersionInformation->dwMajorVersion = pPeb->OSMajorVersion;
262 lpVersionInformation->dwMinorVersion = pPeb->OSMinorVersion;
263 lpVersionInformation->dwBuildNumber = pPeb->OSBuildNumber;
264 lpVersionInformation->dwPlatformId = pPeb->OSPlatformId;
266 /* version string is "ReactOS x.y.z" */
269 lpVersionInformation->szCSDVersion,
270 L"ReactOS " KERNEL_VERSION_STR,
271 sizeof(lpVersionInformation->szCSDVersion) / sizeof(WCHAR)
274 /* null-terminate, just in case */
275 lpVersionInformation->szCSDVersion
277 sizeof(lpVersionInformation->szCSDVersion) / sizeof(WCHAR) - 1
285 /* unknown version information revision */
286 SetLastError(ERROR_INSUFFICIENT_BUFFER);
298 LPOSVERSIONINFOA lpVersionInformation
302 OSVERSIONINFOEXW oviVerInfo;
303 LPOSVERSIONINFOEXA lpVersionInformationEx;
305 /* UNICODE_STRING descriptor of the Unicode version string */
306 UNICODE_STRING wstrVerStr =
309 gives extra work to RtlUnicodeStringToAnsiString, but spares us an
310 RtlInitUnicodeString round
312 sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion) *
313 sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion[0]) -
315 sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion) *
316 sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion[0]),
317 oviVerInfo.szCSDVersion
320 /* ANSI_STRING descriptor of the ANSI version string buffer */
321 ANSI_STRING strVerStr =
324 sizeof(((LPOSVERSIONINFOA)NULL)->szCSDVersion) *
325 sizeof(((LPOSVERSIONINFOA)NULL)->szCSDVersion[0]) -
327 lpVersionInformation->szCSDVersion
330 switch(lpVersionInformation->dwOSVersionInfoSize)
332 case sizeof(OSVERSIONINFOEXA):
334 oviVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
338 case sizeof(OSVERSIONINFOA):
340 oviVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
346 /* unknown version information revision */
347 SetLastError(ERROR_INSUFFICIENT_BUFFER);
352 if(!GetVersionExW((LPOSVERSIONINFOW)&oviVerInfo))
355 /* null-terminate, just in case */
356 oviVerInfo.szCSDVersion
358 sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion) *
359 sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion[0]) -
363 /* convert the version string */
364 nErrCode = RtlUnicodeStringToAnsiString(&strVerStr, &wstrVerStr, FALSE);
366 if(!NT_SUCCESS(nErrCode))
369 SetLastErrorByStatus(nErrCode);
373 /* copy the fields */
374 lpVersionInformation->dwMajorVersion = oviVerInfo.dwMajorVersion;
375 lpVersionInformation->dwMinorVersion = oviVerInfo.dwMinorVersion;
376 lpVersionInformation->dwBuildNumber = oviVerInfo.dwBuildNumber;
377 lpVersionInformation->dwPlatformId = oviVerInfo.dwPlatformId;
379 if(lpVersionInformation->dwOSVersionInfoSize < sizeof(OSVERSIONINFOEXA))
383 /* copy the extended fields */
384 lpVersionInformationEx = (LPOSVERSIONINFOEXA)lpVersionInformation;
385 lpVersionInformationEx->wServicePackMajor = oviVerInfo.wServicePackMajor;
386 lpVersionInformationEx->wServicePackMinor = oviVerInfo.wServicePackMinor;
387 lpVersionInformationEx->wSuiteMask = oviVerInfo.wSuiteMask;
388 lpVersionInformationEx->wProductType = oviVerInfo.wProductType;
389 lpVersionInformationEx->wReserved = oviVerInfo.wReserved;
398 GetEnvironmentStringsA (
402 UNICODE_STRING UnicodeString;
403 ANSI_STRING AnsiString;
409 EnvU = (PWCHAR)(NtCurrentPeb ()->ProcessParameters->Environment);
417 /* get environment size */
425 Length = (ULONG)(PtrU - EnvU);
426 DPRINT("Length %lu\n", Length);
428 /* allocate environment buffer */
429 EnvPtr = RtlAllocateHeap (RtlGetProcessHeap (),
432 DPRINT("EnvPtr %p\n", EnvPtr);
434 /* convert unicode environment to ansi */
435 UnicodeString.MaximumLength = Length * sizeof(WCHAR) + sizeof(WCHAR);
436 UnicodeString.Buffer = EnvU;
438 AnsiString.MaximumLength = Length + 1;
439 AnsiString.Length = 0;
440 AnsiString.Buffer = EnvPtr;
442 DPRINT ("UnicodeString.Buffer \'%S\'\n", UnicodeString.Buffer);
444 while (*(UnicodeString.Buffer))
446 UnicodeString.Length = wcslen (UnicodeString.Buffer) * sizeof(WCHAR);
447 UnicodeString.MaximumLength = UnicodeString.Length + sizeof(WCHAR);
448 if (UnicodeString.Length > 0)
450 AnsiString.Length = 0;
451 AnsiString.MaximumLength = Length + 1 - (AnsiString.Buffer - EnvPtr);
453 RtlUnicodeStringToAnsiString (&AnsiString,
457 AnsiString.Buffer += (AnsiString.Length + 1);
458 UnicodeString.Buffer += ((UnicodeString.Length / sizeof(WCHAR)) + 1);
461 *(AnsiString.Buffer) = 0;
469 GetEnvironmentStringsW (
473 return (LPWSTR)(NtCurrentPeb ()->ProcessParameters->Environment);
479 FreeEnvironmentStringsA (
480 LPSTR EnvironmentStrings
483 if (EnvironmentStrings == NULL)
486 RtlFreeHeap (RtlGetProcessHeap (),
496 FreeEnvironmentStringsW (
497 LPWSTR EnvironmentStrings
500 (void)EnvironmentStrings;
507 ExpandEnvironmentStringsA (
514 ANSI_STRING Destination;
515 UNICODE_STRING SourceU;
516 UNICODE_STRING DestinationU;
520 RtlInitAnsiString (&Source,
522 RtlAnsiStringToUnicodeString (&SourceU,
526 Destination.Length = 0;
527 Destination.MaximumLength = nSize;
528 Destination.Buffer = lpDst,
530 DestinationU.Length = 0;
531 DestinationU.MaximumLength = nSize * sizeof(WCHAR);
532 DestinationU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
534 DestinationU.MaximumLength);
536 Status = RtlExpandEnvironmentStrings_U (NULL,
541 RtlFreeUnicodeString (&SourceU);
543 if (!NT_SUCCESS(Status))
545 RtlFreeHeap (RtlGetProcessHeap (),
547 DestinationU.Buffer);
548 SetLastErrorByStatus (Status);
552 RtlUnicodeStringToAnsiString (&Destination,
556 RtlFreeHeap (RtlGetProcessHeap (),
558 DestinationU.Buffer);
560 return (Length / sizeof(WCHAR));
566 ExpandEnvironmentStringsW (
572 UNICODE_STRING Source;
573 UNICODE_STRING Destination;
577 RtlInitUnicodeString (&Source,
580 Destination.Length = 0;
581 Destination.MaximumLength = nSize * sizeof(WCHAR);
582 Destination.Buffer = lpDst;
584 Status = RtlExpandEnvironmentStrings_U (NULL,
588 if (!NT_SUCCESS(Status))
590 SetLastErrorByStatus (Status);
594 return (Length / sizeof(WCHAR));