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
313 sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion),
314 oviVerInfo.szCSDVersion
317 /* ANSI_STRING descriptor of the ANSI version string buffer */
318 ANSI_STRING strVerStr =
321 sizeof(((LPOSVERSIONINFOA)NULL)->szCSDVersion),
322 lpVersionInformation->szCSDVersion
325 switch(lpVersionInformation->dwOSVersionInfoSize)
327 case sizeof(OSVERSIONINFOEXA):
329 oviVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
333 case sizeof(OSVERSIONINFOA):
335 oviVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
341 /* unknown version information revision */
342 SetLastError(ERROR_INSUFFICIENT_BUFFER);
347 if(!GetVersionExW((LPOSVERSIONINFOW)&oviVerInfo))
350 /* null-terminate, just in case */
351 oviVerInfo.szCSDVersion
353 sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion) /
354 sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion[0]) -
357 wstrVerStr.Length = wcslen(wstrVerStr.Buffer) * sizeof(WCHAR);
359 /* convert the version string */
360 nErrCode = RtlUnicodeStringToAnsiString(&strVerStr, &wstrVerStr, FALSE);
362 if(!NT_SUCCESS(nErrCode))
365 SetLastErrorByStatus(nErrCode);
369 /* copy the fields */
370 lpVersionInformation->dwMajorVersion = oviVerInfo.dwMajorVersion;
371 lpVersionInformation->dwMinorVersion = oviVerInfo.dwMinorVersion;
372 lpVersionInformation->dwBuildNumber = oviVerInfo.dwBuildNumber;
373 lpVersionInformation->dwPlatformId = oviVerInfo.dwPlatformId;
375 if(lpVersionInformation->dwOSVersionInfoSize < sizeof(OSVERSIONINFOEXA))
379 /* copy the extended fields */
380 lpVersionInformationEx = (LPOSVERSIONINFOEXA)lpVersionInformation;
381 lpVersionInformationEx->wServicePackMajor = oviVerInfo.wServicePackMajor;
382 lpVersionInformationEx->wServicePackMinor = oviVerInfo.wServicePackMinor;
383 lpVersionInformationEx->wSuiteMask = oviVerInfo.wSuiteMask;
384 lpVersionInformationEx->wProductType = oviVerInfo.wProductType;
385 lpVersionInformationEx->wReserved = oviVerInfo.wReserved;
394 GetEnvironmentStringsA (
398 UNICODE_STRING UnicodeString;
399 ANSI_STRING AnsiString;
405 EnvU = (PWCHAR)(NtCurrentPeb ()->ProcessParameters->Environment);
413 /* get environment size */
421 Length = (ULONG)(PtrU - EnvU);
422 DPRINT("Length %lu\n", Length);
424 /* allocate environment buffer */
425 EnvPtr = RtlAllocateHeap (RtlGetProcessHeap (),
428 DPRINT("EnvPtr %p\n", EnvPtr);
430 /* convert unicode environment to ansi */
431 UnicodeString.MaximumLength = Length * sizeof(WCHAR) + sizeof(WCHAR);
432 UnicodeString.Buffer = EnvU;
434 AnsiString.MaximumLength = Length + 1;
435 AnsiString.Length = 0;
436 AnsiString.Buffer = EnvPtr;
438 DPRINT ("UnicodeString.Buffer \'%S\'\n", UnicodeString.Buffer);
440 while (*(UnicodeString.Buffer))
442 UnicodeString.Length = wcslen (UnicodeString.Buffer) * sizeof(WCHAR);
443 UnicodeString.MaximumLength = UnicodeString.Length + sizeof(WCHAR);
444 if (UnicodeString.Length > 0)
446 AnsiString.Length = 0;
447 AnsiString.MaximumLength = Length + 1 - (AnsiString.Buffer - EnvPtr);
449 RtlUnicodeStringToAnsiString (&AnsiString,
453 AnsiString.Buffer += (AnsiString.Length + 1);
454 UnicodeString.Buffer += ((UnicodeString.Length / sizeof(WCHAR)) + 1);
457 *(AnsiString.Buffer) = 0;
465 GetEnvironmentStringsW (
469 return (LPWSTR)(NtCurrentPeb ()->ProcessParameters->Environment);
475 FreeEnvironmentStringsA (
476 LPSTR EnvironmentStrings
479 if (EnvironmentStrings == NULL)
482 RtlFreeHeap (RtlGetProcessHeap (),
492 FreeEnvironmentStringsW (
493 LPWSTR EnvironmentStrings
496 (void)EnvironmentStrings;
503 ExpandEnvironmentStringsA (
510 ANSI_STRING Destination;
511 UNICODE_STRING SourceU;
512 UNICODE_STRING DestinationU;
516 RtlInitAnsiString (&Source,
518 RtlAnsiStringToUnicodeString (&SourceU,
522 Destination.Length = 0;
523 Destination.MaximumLength = nSize;
524 Destination.Buffer = lpDst,
526 DestinationU.Length = 0;
527 DestinationU.MaximumLength = nSize * sizeof(WCHAR);
528 DestinationU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
530 DestinationU.MaximumLength);
532 Status = RtlExpandEnvironmentStrings_U (NULL,
537 RtlFreeUnicodeString (&SourceU);
539 if (!NT_SUCCESS(Status))
541 RtlFreeHeap (RtlGetProcessHeap (),
543 DestinationU.Buffer);
544 SetLastErrorByStatus (Status);
548 RtlUnicodeStringToAnsiString (&Destination,
552 RtlFreeHeap (RtlGetProcessHeap (),
554 DestinationU.Buffer);
556 return (Length / sizeof(WCHAR));
562 ExpandEnvironmentStringsW (
568 UNICODE_STRING Source;
569 UNICODE_STRING Destination;
573 RtlInitUnicodeString (&Source,
576 Destination.Length = 0;
577 Destination.MaximumLength = nSize * sizeof(WCHAR);
578 Destination.Buffer = lpDst;
580 Status = RtlExpandEnvironmentStrings_U (NULL,
584 if (!NT_SUCCESS(Status))
586 SetLastErrorByStatus (Status);
590 return (Length / sizeof(WCHAR));