2005-01-06 13:58:04 +00:00
|
|
|
/* $Id$
|
2000-02-18 00:51:03 +00:00
|
|
|
*
|
1998-12-04 18:28:13 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS system libraries
|
|
|
|
* FILE: lib/kernel32/misc/env.c
|
|
|
|
* PURPOSE: Environment functions
|
|
|
|
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
|
|
|
* UPDATE HISTORY:
|
|
|
|
* Created 01/11/98
|
|
|
|
*/
|
|
|
|
|
2003-01-15 21:24:36 +00:00
|
|
|
#include <k32.h>
|
1998-12-04 18:28:13 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
#define NDEBUG
|
2007-09-02 19:42:22 +00:00
|
|
|
#include <debug.h>
|
1999-04-14 00:52:19 +00:00
|
|
|
|
1998-12-04 18:28:13 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2000-02-18 00:51:03 +00:00
|
|
|
DWORD
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2000-02-18 00:51:03 +00:00
|
|
|
GetEnvironmentVariableA (
|
|
|
|
LPCSTR lpName,
|
|
|
|
LPSTR lpBuffer,
|
|
|
|
DWORD nSize
|
|
|
|
)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2000-02-18 00:51:03 +00:00
|
|
|
ANSI_STRING VarName;
|
|
|
|
ANSI_STRING VarValue;
|
|
|
|
UNICODE_STRING VarNameU;
|
|
|
|
UNICODE_STRING VarValueU;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* initialize unicode variable name string */
|
|
|
|
RtlInitAnsiString (&VarName,
|
|
|
|
(LPSTR)lpName);
|
|
|
|
RtlAnsiStringToUnicodeString (&VarNameU,
|
|
|
|
&VarName,
|
|
|
|
TRUE);
|
|
|
|
|
|
|
|
/* initialize ansi variable value string */
|
|
|
|
VarValue.Length = 0;
|
2007-01-26 07:22:19 +00:00
|
|
|
VarValue.MaximumLength = (USHORT)nSize;
|
2000-02-18 00:51:03 +00:00
|
|
|
VarValue.Buffer = lpBuffer;
|
|
|
|
|
|
|
|
/* initialize unicode variable value string and allocate buffer */
|
|
|
|
VarValueU.Length = 0;
|
2005-07-13 15:09:52 +00:00
|
|
|
if (nSize != 0)
|
2000-02-18 00:51:03 +00:00
|
|
|
{
|
2007-01-26 07:22:19 +00:00
|
|
|
VarValueU.MaximumLength = (USHORT)(nSize - 1) * sizeof(WCHAR);
|
2005-07-13 15:09:52 +00:00
|
|
|
VarValueU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
|
|
|
|
0,
|
|
|
|
nSize * sizeof(WCHAR));
|
|
|
|
if (VarValueU.Buffer != NULL)
|
|
|
|
{
|
|
|
|
/* NULL-terminate the buffer in any case! RtlQueryEnvironmentVariable_U
|
|
|
|
only terminates it if MaximumLength < Length! */
|
|
|
|
VarValueU.Buffer[nSize - 1] = L'\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
VarValueU.MaximumLength = 0;
|
|
|
|
VarValueU.Buffer = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VarValueU.Buffer != NULL || nSize == 0)
|
|
|
|
{
|
|
|
|
/* get unicode environment variable */
|
|
|
|
Status = RtlQueryEnvironmentVariable_U (NULL,
|
|
|
|
&VarNameU,
|
|
|
|
&VarValueU);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2000-02-18 00:51:03 +00:00
|
|
|
/* free unicode buffer */
|
|
|
|
RtlFreeHeap (RtlGetProcessHeap (),
|
|
|
|
0,
|
|
|
|
VarValueU.Buffer);
|
1998-12-04 18:28:13 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
/* free unicode variable name string */
|
|
|
|
RtlFreeUnicodeString (&VarNameU);
|
1998-12-04 18:28:13 +00:00
|
|
|
|
2000-07-01 17:07:02 +00:00
|
|
|
SetLastErrorByStatus (Status);
|
2002-03-17 17:56:57 +00:00
|
|
|
if (Status == STATUS_BUFFER_TOO_SMALL)
|
|
|
|
{
|
2005-07-13 15:09:52 +00:00
|
|
|
return (VarValueU.Length / sizeof(WCHAR)) + 1;
|
2002-03-17 17:56:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2005-07-13 15:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* convert unicode value string to ansi */
|
|
|
|
RtlUnicodeStringToAnsiString (&VarValue,
|
|
|
|
&VarValueU,
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
if (VarValueU.Buffer != NULL)
|
|
|
|
{
|
|
|
|
/* free unicode buffer */
|
|
|
|
RtlFreeHeap (RtlGetProcessHeap (),
|
|
|
|
0,
|
|
|
|
VarValueU.Buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* free unicode variable name string */
|
|
|
|
RtlFreeUnicodeString (&VarNameU);
|
|
|
|
|
|
|
|
return (VarValueU.Length / sizeof(WCHAR));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetLastError (ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return 0;
|
|
|
|
}
|
1999-01-16 02:11:45 +00:00
|
|
|
}
|
1998-12-04 18:28:13 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
1998-12-04 18:28:13 +00:00
|
|
|
DWORD
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2000-02-18 00:51:03 +00:00
|
|
|
GetEnvironmentVariableW (
|
|
|
|
LPCWSTR lpName,
|
|
|
|
LPWSTR lpBuffer,
|
|
|
|
DWORD nSize
|
|
|
|
)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2000-02-18 00:51:03 +00:00
|
|
|
UNICODE_STRING VarName;
|
|
|
|
UNICODE_STRING VarValue;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
RtlInitUnicodeString (&VarName,
|
|
|
|
lpName);
|
1998-12-04 18:28:13 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
VarValue.Length = 0;
|
2009-01-10 17:50:03 +00:00
|
|
|
VarValue.MaximumLength = (USHORT) (nSize ? nSize - 1 : 0) * sizeof(WCHAR);
|
2000-02-18 00:51:03 +00:00
|
|
|
VarValue.Buffer = lpBuffer;
|
|
|
|
|
|
|
|
Status = RtlQueryEnvironmentVariable_U (NULL,
|
|
|
|
&VarName,
|
|
|
|
&VarValue);
|
|
|
|
if (!NT_SUCCESS(Status))
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2002-03-17 17:56:57 +00:00
|
|
|
if (Status == STATUS_BUFFER_TOO_SMALL)
|
|
|
|
{
|
2005-07-13 15:09:52 +00:00
|
|
|
return (VarValue.Length / sizeof(WCHAR)) + 1;
|
2002-03-17 17:56:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-01-10 17:50:03 +00:00
|
|
|
SetLastErrorByStatus (Status);
|
2002-03-17 17:56:57 +00:00
|
|
|
return 0;
|
|
|
|
}
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
2005-07-13 15:09:52 +00:00
|
|
|
|
2005-07-13 16:36:24 +00:00
|
|
|
if (nSize != 0)
|
|
|
|
{
|
|
|
|
/* make sure the string is NULL-terminated! RtlQueryEnvironmentVariable_U
|
|
|
|
only terminates it if MaximumLength < Length */
|
2009-01-10 17:50:03 +00:00
|
|
|
lpBuffer[VarValue.Length / sizeof(WCHAR)] = L'\0';
|
2005-07-13 16:36:24 +00:00
|
|
|
}
|
1998-12-04 18:28:13 +00:00
|
|
|
|
2005-07-11 20:30:33 +00:00
|
|
|
return (VarValue.Length / sizeof(WCHAR));
|
2000-02-18 00:51:03 +00:00
|
|
|
}
|
1998-12-04 18:28:13 +00:00
|
|
|
|
1999-01-16 02:11:45 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2000-02-18 00:51:03 +00:00
|
|
|
SetEnvironmentVariableA (
|
|
|
|
LPCSTR lpName,
|
|
|
|
LPCSTR lpValue
|
|
|
|
)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2000-02-18 00:51:03 +00:00
|
|
|
ANSI_STRING VarName;
|
|
|
|
ANSI_STRING VarValue;
|
|
|
|
UNICODE_STRING VarNameU;
|
|
|
|
UNICODE_STRING VarValueU;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2002-03-17 17:56:57 +00:00
|
|
|
DPRINT("SetEnvironmentVariableA(Name '%s', Value '%s')\n", lpName, lpValue);
|
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
RtlInitAnsiString (&VarName,
|
|
|
|
(LPSTR)lpName);
|
|
|
|
RtlAnsiStringToUnicodeString (&VarNameU,
|
|
|
|
&VarName,
|
|
|
|
TRUE);
|
|
|
|
|
2008-08-26 15:28:29 +00:00
|
|
|
if (lpValue)
|
|
|
|
{
|
|
|
|
RtlInitAnsiString (&VarValue,
|
|
|
|
(LPSTR)lpValue);
|
|
|
|
RtlAnsiStringToUnicodeString (&VarValueU,
|
|
|
|
&VarValue,
|
|
|
|
TRUE);
|
2000-02-18 00:51:03 +00:00
|
|
|
|
2008-08-26 15:28:29 +00:00
|
|
|
Status = RtlSetEnvironmentVariable (NULL,
|
|
|
|
&VarNameU,
|
|
|
|
&VarValueU);
|
2000-02-18 00:51:03 +00:00
|
|
|
|
2008-08-26 15:28:29 +00:00
|
|
|
RtlFreeUnicodeString (&VarValueU);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Status = RtlSetEnvironmentVariable (NULL,
|
|
|
|
&VarNameU,
|
|
|
|
NULL);
|
|
|
|
}
|
2000-02-18 00:51:03 +00:00
|
|
|
RtlFreeUnicodeString (&VarNameU);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
1999-10-07 23:46:27 +00:00
|
|
|
{
|
2000-07-01 17:07:02 +00:00
|
|
|
SetLastErrorByStatus (Status);
|
2000-02-18 00:51:03 +00:00
|
|
|
return FALSE;
|
1999-10-07 23:46:27 +00:00
|
|
|
}
|
1999-01-16 02:11:45 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
return TRUE;
|
1999-01-16 02:11:45 +00:00
|
|
|
}
|
1998-12-04 18:28:13 +00:00
|
|
|
|
1999-10-07 23:46:27 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2000-02-18 00:51:03 +00:00
|
|
|
SetEnvironmentVariableW (
|
|
|
|
LPCWSTR lpName,
|
|
|
|
LPCWSTR lpValue
|
|
|
|
)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2000-02-18 00:51:03 +00:00
|
|
|
UNICODE_STRING VarName;
|
|
|
|
UNICODE_STRING VarValue;
|
|
|
|
NTSTATUS Status;
|
1998-12-04 18:28:13 +00:00
|
|
|
|
2002-03-17 17:56:57 +00:00
|
|
|
DPRINT("SetEnvironmentVariableW(Name '%S', Value '%S')\n", lpName, lpValue);
|
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
RtlInitUnicodeString (&VarName,
|
|
|
|
lpName);
|
|
|
|
|
2009-04-12 04:41:33 +00:00
|
|
|
RtlInitUnicodeString (&VarValue,
|
|
|
|
lpValue);
|
2008-08-26 15:28:29 +00:00
|
|
|
|
2009-04-12 04:41:33 +00:00
|
|
|
Status = RtlSetEnvironmentVariable (NULL,
|
|
|
|
&VarName,
|
|
|
|
&VarValue);
|
1999-01-16 02:11:45 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
1999-01-16 02:11:45 +00:00
|
|
|
{
|
2000-07-01 17:07:02 +00:00
|
|
|
SetLastErrorByStatus (Status);
|
2000-02-18 00:51:03 +00:00
|
|
|
return FALSE;
|
1999-01-16 02:11:45 +00:00
|
|
|
}
|
1998-12-04 18:28:13 +00:00
|
|
|
|
1999-10-07 23:46:27 +00:00
|
|
|
return TRUE;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
1999-10-07 23:46:27 +00:00
|
|
|
LPSTR
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2000-02-18 00:51:03 +00:00
|
|
|
GetEnvironmentStringsA (
|
|
|
|
VOID
|
|
|
|
)
|
1999-01-16 02:11:45 +00:00
|
|
|
{
|
2000-02-18 00:51:03 +00:00
|
|
|
UNICODE_STRING UnicodeString;
|
|
|
|
ANSI_STRING AnsiString;
|
|
|
|
PWCHAR EnvU;
|
|
|
|
PWCHAR PtrU;
|
|
|
|
ULONG Length;
|
|
|
|
PCHAR EnvPtr = NULL;
|
1999-01-16 02:11:45 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
EnvU = (PWCHAR)(NtCurrentPeb ()->ProcessParameters->Environment);
|
1999-01-16 02:11:45 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
if (EnvU == NULL)
|
|
|
|
return NULL;
|
1999-01-16 02:11:45 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
if (*EnvU == 0)
|
|
|
|
return NULL;
|
1999-01-16 02:11:45 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
/* get environment size */
|
|
|
|
PtrU = EnvU;
|
|
|
|
while (*PtrU)
|
|
|
|
{
|
|
|
|
while (*PtrU)
|
|
|
|
PtrU++;
|
|
|
|
PtrU++;
|
|
|
|
}
|
|
|
|
Length = (ULONG)(PtrU - EnvU);
|
|
|
|
DPRINT("Length %lu\n", Length);
|
1998-12-04 18:28:13 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
/* allocate environment buffer */
|
|
|
|
EnvPtr = RtlAllocateHeap (RtlGetProcessHeap (),
|
|
|
|
0,
|
|
|
|
Length + 1);
|
2005-12-11 21:12:22 +00:00
|
|
|
if (EnvPtr == NULL)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return NULL;
|
|
|
|
}
|
2000-02-18 00:51:03 +00:00
|
|
|
DPRINT("EnvPtr %p\n", EnvPtr);
|
1999-10-02 20:20:44 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
/* convert unicode environment to ansi */
|
2007-01-26 07:22:19 +00:00
|
|
|
UnicodeString.MaximumLength = (USHORT)Length * sizeof(WCHAR) + sizeof(WCHAR);
|
2000-02-18 00:51:03 +00:00
|
|
|
UnicodeString.Buffer = EnvU;
|
1999-10-02 20:20:44 +00:00
|
|
|
|
2007-01-26 07:22:19 +00:00
|
|
|
AnsiString.MaximumLength = (USHORT)Length + 1;
|
2000-02-18 00:51:03 +00:00
|
|
|
AnsiString.Length = 0;
|
|
|
|
AnsiString.Buffer = EnvPtr;
|
1999-10-02 20:20:44 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
DPRINT ("UnicodeString.Buffer \'%S\'\n", UnicodeString.Buffer);
|
1999-10-02 20:20:44 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
while (*(UnicodeString.Buffer))
|
|
|
|
{
|
|
|
|
UnicodeString.Length = wcslen (UnicodeString.Buffer) * sizeof(WCHAR);
|
2002-04-01 22:08:20 +00:00
|
|
|
UnicodeString.MaximumLength = UnicodeString.Length + sizeof(WCHAR);
|
2000-02-18 00:51:03 +00:00
|
|
|
if (UnicodeString.Length > 0)
|
|
|
|
{
|
2002-04-01 22:08:20 +00:00
|
|
|
AnsiString.Length = 0;
|
2007-01-26 07:22:19 +00:00
|
|
|
AnsiString.MaximumLength = (USHORT)Length + 1 - (AnsiString.Buffer - EnvPtr);
|
1999-10-02 20:20:44 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
RtlUnicodeStringToAnsiString (&AnsiString,
|
|
|
|
&UnicodeString,
|
|
|
|
FALSE);
|
1999-10-02 20:20:44 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
AnsiString.Buffer += (AnsiString.Length + 1);
|
|
|
|
UnicodeString.Buffer += ((UnicodeString.Length / sizeof(WCHAR)) + 1);
|
|
|
|
}
|
1999-10-02 20:20:44 +00:00
|
|
|
}
|
2000-02-18 00:51:03 +00:00
|
|
|
*(AnsiString.Buffer) = 0;
|
1999-10-02 20:20:44 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
return EnvPtr;
|
1999-10-02 20:20:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2000-02-18 00:51:03 +00:00
|
|
|
LPWSTR
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2000-02-18 00:51:03 +00:00
|
|
|
GetEnvironmentStringsW (
|
|
|
|
VOID
|
|
|
|
)
|
1999-10-02 20:20:44 +00:00
|
|
|
{
|
2000-02-18 00:51:03 +00:00
|
|
|
return (LPWSTR)(NtCurrentPeb ()->ProcessParameters->Environment);
|
1999-10-02 20:20:44 +00:00
|
|
|
}
|
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2000-02-18 00:51:03 +00:00
|
|
|
FreeEnvironmentStringsA (
|
|
|
|
LPSTR EnvironmentStrings
|
|
|
|
)
|
1999-10-02 20:20:44 +00:00
|
|
|
{
|
2000-02-18 00:51:03 +00:00
|
|
|
if (EnvironmentStrings == NULL)
|
|
|
|
return FALSE;
|
1999-10-02 20:20:44 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
RtlFreeHeap (RtlGetProcessHeap (),
|
|
|
|
0,
|
|
|
|
EnvironmentStrings);
|
1999-10-02 20:20:44 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
1999-10-02 20:20:44 +00:00
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-01-23 17:18:16 +00:00
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2000-02-18 00:51:03 +00:00
|
|
|
FreeEnvironmentStringsW (
|
|
|
|
LPWSTR EnvironmentStrings
|
|
|
|
)
|
|
|
|
{
|
2003-02-12 00:39:31 +00:00
|
|
|
return TRUE;
|
2000-02-18 00:51:03 +00:00
|
|
|
}
|
1999-10-02 20:20:44 +00:00
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2000-02-18 00:51:03 +00:00
|
|
|
DWORD
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2000-02-18 00:51:03 +00:00
|
|
|
ExpandEnvironmentStringsA (
|
|
|
|
LPCSTR lpSrc,
|
|
|
|
LPSTR lpDst,
|
|
|
|
DWORD nSize
|
|
|
|
)
|
|
|
|
{
|
|
|
|
ANSI_STRING Source;
|
|
|
|
ANSI_STRING Destination;
|
|
|
|
UNICODE_STRING SourceU;
|
|
|
|
UNICODE_STRING DestinationU;
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG Length = 0;
|
|
|
|
|
|
|
|
RtlInitAnsiString (&Source,
|
|
|
|
(LPSTR)lpSrc);
|
2005-12-11 21:12:22 +00:00
|
|
|
Status = RtlAnsiStringToUnicodeString (&SourceU,
|
|
|
|
&Source,
|
|
|
|
TRUE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastErrorByStatus (Status);
|
|
|
|
return 0;
|
|
|
|
}
|
2000-02-18 00:51:03 +00:00
|
|
|
|
2008-09-17 14:03:05 +00:00
|
|
|
/* make sure we don't overflow the maximum ANSI_STRING size */
|
|
|
|
if (nSize > 0x7fff)
|
|
|
|
nSize = 0x7fff;
|
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
Destination.Length = 0;
|
2007-01-26 07:22:19 +00:00
|
|
|
Destination.MaximumLength = (USHORT)nSize;
|
2004-12-27 16:40:14 +00:00
|
|
|
Destination.Buffer = lpDst;
|
2000-02-18 00:51:03 +00:00
|
|
|
|
|
|
|
DestinationU.Length = 0;
|
2007-01-26 07:22:19 +00:00
|
|
|
DestinationU.MaximumLength = (USHORT)nSize * sizeof(WCHAR);
|
2000-02-18 00:51:03 +00:00
|
|
|
DestinationU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
|
|
|
|
0,
|
|
|
|
DestinationU.MaximumLength);
|
2005-12-11 21:12:22 +00:00
|
|
|
if (DestinationU.Buffer == NULL)
|
|
|
|
{
|
|
|
|
RtlFreeUnicodeString(&SourceU);
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return 0;
|
|
|
|
}
|
2000-02-18 00:51:03 +00:00
|
|
|
|
|
|
|
Status = RtlExpandEnvironmentStrings_U (NULL,
|
|
|
|
&SourceU,
|
|
|
|
&DestinationU,
|
|
|
|
&Length);
|
|
|
|
|
|
|
|
RtlFreeUnicodeString (&SourceU);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2000-07-01 17:07:02 +00:00
|
|
|
SetLastErrorByStatus (Status);
|
2004-12-27 16:40:14 +00:00
|
|
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
|
|
{
|
|
|
|
RtlFreeHeap (RtlGetProcessHeap (),
|
|
|
|
0,
|
|
|
|
DestinationU.Buffer);
|
|
|
|
return 0;
|
|
|
|
}
|
1999-10-02 20:20:44 +00:00
|
|
|
}
|
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
RtlUnicodeStringToAnsiString (&Destination,
|
|
|
|
&DestinationU,
|
|
|
|
FALSE);
|
1999-10-02 20:20:44 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
RtlFreeHeap (RtlGetProcessHeap (),
|
|
|
|
0,
|
|
|
|
DestinationU.Buffer);
|
1999-10-02 20:20:44 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
return (Length / sizeof(WCHAR));
|
1999-10-02 20:20:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2000-02-18 00:51:03 +00:00
|
|
|
DWORD
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2000-02-18 00:51:03 +00:00
|
|
|
ExpandEnvironmentStringsW (
|
|
|
|
LPCWSTR lpSrc,
|
|
|
|
LPWSTR lpDst,
|
|
|
|
DWORD nSize
|
|
|
|
)
|
1999-10-02 20:20:44 +00:00
|
|
|
{
|
2000-02-18 00:51:03 +00:00
|
|
|
UNICODE_STRING Source;
|
|
|
|
UNICODE_STRING Destination;
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG Length = 0;
|
|
|
|
|
|
|
|
RtlInitUnicodeString (&Source,
|
|
|
|
(LPWSTR)lpSrc);
|
|
|
|
|
2008-09-17 14:03:05 +00:00
|
|
|
/* make sure we don't overflow the maximum UNICODE_STRING size */
|
|
|
|
if (nSize > 0x7fff)
|
|
|
|
nSize = 0x7fff;
|
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
Destination.Length = 0;
|
2007-01-26 07:22:19 +00:00
|
|
|
Destination.MaximumLength = (USHORT)nSize * sizeof(WCHAR);
|
2000-02-18 00:51:03 +00:00
|
|
|
Destination.Buffer = lpDst;
|
|
|
|
|
|
|
|
Status = RtlExpandEnvironmentStrings_U (NULL,
|
|
|
|
&Source,
|
|
|
|
&Destination,
|
|
|
|
&Length);
|
|
|
|
if (!NT_SUCCESS(Status))
|
1999-10-02 20:20:44 +00:00
|
|
|
{
|
2000-07-01 17:07:02 +00:00
|
|
|
SetLastErrorByStatus (Status);
|
2004-12-27 16:40:14 +00:00
|
|
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
|
|
return 0;
|
1999-10-02 20:20:44 +00:00
|
|
|
}
|
2000-02-18 00:51:03 +00:00
|
|
|
|
|
|
|
return (Length / sizeof(WCHAR));
|
1999-10-02 20:20:44 +00:00
|
|
|
}
|
|
|
|
|
2000-07-01 17:07:02 +00:00
|
|
|
/* EOF */
|