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 ******************************************************************/
25 GetEnvironmentVariableA (
33 UNICODE_STRING VarNameU;
34 UNICODE_STRING VarValueU;
37 /* initialize unicode variable name string */
38 RtlInitAnsiString (&VarName,
40 RtlAnsiStringToUnicodeString (&VarNameU,
44 /* initialize ansi variable value string */
46 VarValue.MaximumLength = nSize;
47 VarValue.Buffer = lpBuffer;
49 /* initialize unicode variable value string and allocate buffer */
51 VarValueU.MaximumLength = nSize * sizeof(WCHAR);
52 VarValueU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
54 VarValueU.MaximumLength);
56 /* get unicode environment variable */
57 Status = RtlQueryEnvironmentVariable_U (NULL,
60 if (!NT_SUCCESS(Status))
62 /* free unicode buffer */
63 RtlFreeHeap (RtlGetProcessHeap (),
67 /* free unicode variable name string */
68 RtlFreeUnicodeString (&VarNameU);
70 SetLastErrorByStatus (Status);
71 if (Status == STATUS_BUFFER_TOO_SMALL)
73 return VarValueU.Length / sizeof(WCHAR) + 1;
81 /* convert unicode value string to ansi */
82 RtlUnicodeStringToAnsiString (&VarValue,
86 /* free unicode buffer */
87 RtlFreeHeap (RtlGetProcessHeap (),
91 /* free unicode variable name string */
92 RtlFreeUnicodeString (&VarNameU);
94 return (VarValueU.Length / sizeof(WCHAR));
103 GetEnvironmentVariableW (
109 UNICODE_STRING VarName;
110 UNICODE_STRING VarValue;
113 RtlInitUnicodeString (&VarName,
117 VarValue.MaximumLength = nSize * sizeof(WCHAR);
118 VarValue.Buffer = lpBuffer;
120 Status = RtlQueryEnvironmentVariable_U (NULL,
123 if (!NT_SUCCESS(Status))
125 SetLastErrorByStatus (Status);
126 if (Status == STATUS_BUFFER_TOO_SMALL)
128 return (VarValue.Length / sizeof(WCHAR)) + 1;
136 return (VarValue.Length / sizeof(WCHAR));
145 SetEnvironmentVariableA (
151 ANSI_STRING VarValue;
152 UNICODE_STRING VarNameU;
153 UNICODE_STRING VarValueU;
156 DPRINT("SetEnvironmentVariableA(Name '%s', Value '%s')\n", lpName, lpValue);
158 RtlInitAnsiString (&VarName,
160 RtlAnsiStringToUnicodeString (&VarNameU,
164 RtlInitAnsiString (&VarValue,
166 RtlAnsiStringToUnicodeString (&VarValueU,
170 Status = RtlSetEnvironmentVariable (NULL,
174 RtlFreeUnicodeString (&VarNameU);
175 RtlFreeUnicodeString (&VarValueU);
177 if (!NT_SUCCESS(Status))
179 SetLastErrorByStatus (Status);
192 SetEnvironmentVariableW (
197 UNICODE_STRING VarName;
198 UNICODE_STRING VarValue;
201 DPRINT("SetEnvironmentVariableW(Name '%S', Value '%S')\n", lpName, lpValue);
203 RtlInitUnicodeString (&VarName,
206 RtlInitUnicodeString (&VarValue,
209 Status = RtlSetEnvironmentVariable (NULL,
212 if (!NT_SUCCESS(Status))
214 SetLastErrorByStatus (Status);
229 PPEB pPeb = NtCurrentPeb();
232 nVersion = MAKEWORD(pPeb->OSMajorVersion, pPeb->OSMinorVersion);
234 /* behave consistently when posing as another operating system */
236 if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_WINDOWS)
237 nVersion |= ((DWORD)(pPeb->OSBuildNumber)) << 16;
239 /* non-NT platform flag */
240 if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_NT)
241 nVersion |= 0x80000000;
253 LPOSVERSIONINFOW lpVersionInformation
256 PPEB pPeb = NtCurrentPeb();
258 /* TODO: move this into RtlGetVersion */
259 switch(lpVersionInformation->dwOSVersionInfoSize)
261 case sizeof(OSVERSIONINFOEXW):
263 LPOSVERSIONINFOEXW lpVersionInformationEx =
264 (LPOSVERSIONINFOEXW)lpVersionInformation;
266 lpVersionInformationEx->wServicePackMajor = pPeb->SPMajorVersion;
267 lpVersionInformationEx->wServicePackMinor = pPeb->SPMinorVersion;
268 /* TODO: read from the KUSER_SHARED_DATA */
269 lpVersionInformationEx->wSuiteMask = 0;
270 /* TODO: call RtlGetNtProductType */
271 lpVersionInformationEx->wProductType = 0;
273 lpVersionInformationEx->wReserved = 0;
277 case sizeof(OSVERSIONINFOW):
279 lpVersionInformation->dwMajorVersion = pPeb->OSMajorVersion;
280 lpVersionInformation->dwMinorVersion = pPeb->OSMinorVersion;
281 lpVersionInformation->dwBuildNumber = pPeb->OSBuildNumber;
282 lpVersionInformation->dwPlatformId = pPeb->OSPlatformId;
284 /* version string is "ReactOS x.y.z" */
287 lpVersionInformation->szCSDVersion,
288 L"ReactOS " KERNEL_VERSION_STR,
289 sizeof(lpVersionInformation->szCSDVersion) / sizeof(WCHAR)
292 /* null-terminate, just in case */
293 lpVersionInformation->szCSDVersion
295 sizeof(lpVersionInformation->szCSDVersion) / sizeof(WCHAR) - 1
303 /* unknown version information revision */
304 SetLastError(ERROR_INSUFFICIENT_BUFFER);
319 LPOSVERSIONINFOA lpVersionInformation
323 OSVERSIONINFOEXW oviVerInfo;
324 LPOSVERSIONINFOEXA lpVersionInformationEx;
326 /* UNICODE_STRING descriptor of the Unicode version string */
327 UNICODE_STRING wstrVerStr =
330 gives extra work to RtlUnicodeStringToAnsiString, but spares us an
331 RtlInitUnicodeString round
334 sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion),
335 oviVerInfo.szCSDVersion
338 /* ANSI_STRING descriptor of the ANSI version string buffer */
339 ANSI_STRING strVerStr =
342 sizeof(((LPOSVERSIONINFOA)NULL)->szCSDVersion),
343 lpVersionInformation->szCSDVersion
346 switch(lpVersionInformation->dwOSVersionInfoSize)
348 case sizeof(OSVERSIONINFOEXA):
350 oviVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
354 case sizeof(OSVERSIONINFOA):
356 oviVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
362 /* unknown version information revision */
363 SetLastError(ERROR_INSUFFICIENT_BUFFER);
368 if(!GetVersionExW((LPOSVERSIONINFOW)&oviVerInfo))
371 /* null-terminate, just in case */
372 oviVerInfo.szCSDVersion
374 sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion) /
375 sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion[0]) -
378 wstrVerStr.Length = wcslen(wstrVerStr.Buffer) * sizeof(WCHAR);
380 /* convert the version string */
381 nErrCode = RtlUnicodeStringToAnsiString(&strVerStr, &wstrVerStr, FALSE);
383 if(!NT_SUCCESS(nErrCode))
386 SetLastErrorByStatus(nErrCode);
390 /* copy the fields */
391 lpVersionInformation->dwMajorVersion = oviVerInfo.dwMajorVersion;
392 lpVersionInformation->dwMinorVersion = oviVerInfo.dwMinorVersion;
393 lpVersionInformation->dwBuildNumber = oviVerInfo.dwBuildNumber;
394 lpVersionInformation->dwPlatformId = oviVerInfo.dwPlatformId;
396 if(lpVersionInformation->dwOSVersionInfoSize < sizeof(OSVERSIONINFOEXA))
400 /* copy the extended fields */
401 lpVersionInformationEx = (LPOSVERSIONINFOEXA)lpVersionInformation;
402 lpVersionInformationEx->wServicePackMajor = oviVerInfo.wServicePackMajor;
403 lpVersionInformationEx->wServicePackMinor = oviVerInfo.wServicePackMinor;
404 lpVersionInformationEx->wSuiteMask = oviVerInfo.wSuiteMask;
405 lpVersionInformationEx->wProductType = oviVerInfo.wProductType;
406 lpVersionInformationEx->wReserved = oviVerInfo.wReserved;
418 GetEnvironmentStringsA (
422 UNICODE_STRING UnicodeString;
423 ANSI_STRING AnsiString;
429 EnvU = (PWCHAR)(NtCurrentPeb ()->ProcessParameters->Environment);
437 /* get environment size */
445 Length = (ULONG)(PtrU - EnvU);
446 DPRINT("Length %lu\n", Length);
448 /* allocate environment buffer */
449 EnvPtr = RtlAllocateHeap (RtlGetProcessHeap (),
452 DPRINT("EnvPtr %p\n", EnvPtr);
454 /* convert unicode environment to ansi */
455 UnicodeString.MaximumLength = Length * sizeof(WCHAR) + sizeof(WCHAR);
456 UnicodeString.Buffer = EnvU;
458 AnsiString.MaximumLength = Length + 1;
459 AnsiString.Length = 0;
460 AnsiString.Buffer = EnvPtr;
462 DPRINT ("UnicodeString.Buffer \'%S\'\n", UnicodeString.Buffer);
464 while (*(UnicodeString.Buffer))
466 UnicodeString.Length = wcslen (UnicodeString.Buffer) * sizeof(WCHAR);
467 UnicodeString.MaximumLength = UnicodeString.Length + sizeof(WCHAR);
468 if (UnicodeString.Length > 0)
470 AnsiString.Length = 0;
471 AnsiString.MaximumLength = Length + 1 - (AnsiString.Buffer - EnvPtr);
473 RtlUnicodeStringToAnsiString (&AnsiString,
477 AnsiString.Buffer += (AnsiString.Length + 1);
478 UnicodeString.Buffer += ((UnicodeString.Length / sizeof(WCHAR)) + 1);
481 *(AnsiString.Buffer) = 0;
492 GetEnvironmentStringsW (
496 return (LPWSTR)(NtCurrentPeb ()->ProcessParameters->Environment);
505 FreeEnvironmentStringsA (
506 LPSTR EnvironmentStrings
509 if (EnvironmentStrings == NULL)
512 RtlFreeHeap (RtlGetProcessHeap (),
525 FreeEnvironmentStringsW (
526 LPWSTR EnvironmentStrings
529 (void)EnvironmentStrings;
539 ExpandEnvironmentStringsA (
546 ANSI_STRING Destination;
547 UNICODE_STRING SourceU;
548 UNICODE_STRING DestinationU;
552 RtlInitAnsiString (&Source,
554 RtlAnsiStringToUnicodeString (&SourceU,
558 Destination.Length = 0;
559 Destination.MaximumLength = nSize;
560 Destination.Buffer = lpDst,
562 DestinationU.Length = 0;
563 DestinationU.MaximumLength = nSize * sizeof(WCHAR);
564 DestinationU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
566 DestinationU.MaximumLength);
568 Status = RtlExpandEnvironmentStrings_U (NULL,
573 RtlFreeUnicodeString (&SourceU);
575 if (!NT_SUCCESS(Status))
577 RtlFreeHeap (RtlGetProcessHeap (),
579 DestinationU.Buffer);
580 SetLastErrorByStatus (Status);
584 RtlUnicodeStringToAnsiString (&Destination,
588 RtlFreeHeap (RtlGetProcessHeap (),
590 DestinationU.Buffer);
592 return (Length / sizeof(WCHAR));
601 ExpandEnvironmentStringsW (
607 UNICODE_STRING Source;
608 UNICODE_STRING Destination;
612 RtlInitUnicodeString (&Source,
615 Destination.Length = 0;
616 Destination.MaximumLength = nSize * sizeof(WCHAR);
617 Destination.Buffer = lpDst;
619 Status = RtlExpandEnvironmentStrings_U (NULL,
623 if (!NT_SUCCESS(Status))
625 SetLastErrorByStatus (Status);
629 return (Length / sizeof(WCHAR));