diff --git a/reactos/dll/win32/kernel32/client/environ.c b/reactos/dll/win32/kernel32/client/environ.c index 7564f7f9eef..6d15b7256e9 100644 --- a/reactos/dll/win32/kernel32/client/environ.c +++ b/reactos/dll/win32/kernel32/client/environ.c @@ -24,489 +24,506 @@ */ DWORD WINAPI -GetEnvironmentVariableA ( - LPCSTR lpName, - LPSTR lpBuffer, - DWORD nSize - ) +GetEnvironmentVariableA(IN LPCSTR lpName, + IN LPSTR lpBuffer, + IN DWORD nSize) { - ANSI_STRING VarName; - ANSI_STRING VarValue; - UNICODE_STRING VarNameU; - UNICODE_STRING VarValueU; - NTSTATUS Status; + ANSI_STRING VarName, VarValue; + UNICODE_STRING VarNameU, VarValueU; + PWSTR Buffer; + ULONG Result = 0, UniSize = 0; + NTSTATUS Status; - /* initialize unicode variable name string */ - RtlInitAnsiString (&VarName, - (LPSTR)lpName); - RtlAnsiStringToUnicodeString (&VarNameU, - &VarName, - TRUE); + /* Initialize all the strings */ + RtlInitAnsiString(&VarName, lpName); + RtlInitUnicodeString(&VarNameU, NULL); + RtlInitUnicodeString(&VarValueU, NULL); + Status = RtlAnsiStringToUnicodeString(&VarNameU, &VarName, TRUE); + if (!NT_SUCCESS(Status)) goto Quickie; - /* initialize ansi variable value string */ - VarValue.Length = 0; - VarValue.MaximumLength = (USHORT)nSize; - VarValue.Buffer = lpBuffer; + /* Check if the size is too big to fit */ + if (nSize <= UNICODE_STRING_MAX_BYTES) + { + /* Keep the given size, minus a NULL-char */ + if (nSize) UniSize = nSize * sizeof(WCHAR) - sizeof(UNICODE_NULL); + } + else + { + /* Set the maximum possible */ + UniSize = UNICODE_STRING_MAX_BYTES - sizeof(UNICODE_NULL); + } - /* initialize unicode variable value string and allocate buffer */ - VarValueU.Length = 0; - if (nSize != 0) - { - VarValueU.MaximumLength = (USHORT)(nSize - 1) * sizeof(WCHAR); - 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; - } + /* Allocate the value string buffer */ + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, UniSize); + if (!Buffer) + { + Status = STATUS_NO_MEMORY; + goto Quickie; + } - if (VarValueU.Buffer != NULL || nSize == 0) + /* And initialize its string */ + RtlInitEmptyUnicodeString(&VarValueU, Buffer, UniSize); + + /* Acquire the PEB lock since we'll be querying variables now */ + RtlAcquirePebLock(); + + /* Query the variable */ + Status = RtlQueryEnvironmentVariable_U(NULL, &VarNameU, &VarValueU); + if ((NT_SUCCESS(Status)) && !(nSize)) Status = STATUS_BUFFER_TOO_SMALL; + + /* Check if we didn't have enough space */ + if (Status == STATUS_BUFFER_TOO_SMALL) + { + /* Fixup the length that the API returned */ + VarValueU.MaximumLength = VarValueU.Length + 2; + + /* Free old Unicode buffer */ + RtlFreeHeap(RtlGetProcessHeap(), 0, VarValueU.Buffer); + + /* Allocate new one */ + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, VarValueU.MaximumLength); + if (Buffer) { - /* get unicode environment variable */ - Status = RtlQueryEnvironmentVariable_U (NULL, - &VarNameU, - &VarValueU); - if (!NT_SUCCESS(Status)) - { - /* free unicode buffer */ - RtlFreeHeap (RtlGetProcessHeap (), - 0, - VarValueU.Buffer); - - /* free unicode variable name string */ - RtlFreeUnicodeString (&VarNameU); - - BaseSetLastNTError (Status); - if (Status == STATUS_BUFFER_TOO_SMALL) - { - return (VarValueU.Length / sizeof(WCHAR)) + 1; - } - else - { - return 0; - } - } - - /* convert unicode value string to ansi */ - RtlUnicodeStringToAnsiString (&VarValue, - &VarValueU, - FALSE); - - if (VarValueU.Buffer != NULL) + /* Query the variable so we can know its size */ + VarValueU.Buffer = Buffer; + Status = RtlQueryEnvironmentVariable_U(NULL, &VarNameU, &VarValueU); + if (NT_SUCCESS(Status)) { - /* free unicode buffer */ - RtlFreeHeap (RtlGetProcessHeap (), - 0, - VarValueU.Buffer); + /* Get the ASCII length of the variable */ + Result = RtlUnicodeStringToAnsiSize(&VarValueU); } - - /* free unicode variable name string */ - RtlFreeUnicodeString (&VarNameU); - - return (VarValueU.Length / sizeof(WCHAR)); } else { - SetLastError (ERROR_NOT_ENOUGH_MEMORY); - return 0; + /* Set failure status */ + Status = STATUS_NO_MEMORY; + } + } + else + { + /* Check if the size is too big to fit */ + if (nSize <= MAXULONG) + { + /* Keep the given size, minus a NULL-char */ + if (nSize) nSize = nSize - sizeof(ANSI_NULL); + } + else + { + /* Set the maximum possible */ + nSize = MAXULONG - sizeof(ANSI_NULL); } -} + /* Check the size */ + Result = RtlUnicodeStringToAnsiSize(&VarValueU); + if (Result <= nSize) + { + /* Convert the string */ + RtlInitEmptyAnsiString(&VarValue, lpBuffer, nSize); + Status = RtlUnicodeStringToAnsiString(&VarValue, &VarValueU, FALSE); + if (NT_SUCCESS(Status)) + { + /* NULL-terminate and set the final length */ + lpBuffer[VarValue.Length] = ANSI_NULL; + Result = VarValue.Length; + } + } + } + + /* Release the lock */ + RtlReleasePebLock(); + +Quickie: + /* Free the strings */ + RtlFreeUnicodeString(&VarNameU); + if (VarValueU.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, VarValueU.Buffer); + + /* Check if we suceeded */ + if (!NT_SUCCESS(Status)) + { + /* We did not, clear the result and set the error code */ + BaseSetLastNTError(Status); + Result = 0; + } + + /* Return the result */ + return Result; +} /* * @implemented */ DWORD WINAPI -GetEnvironmentVariableW ( - LPCWSTR lpName, - LPWSTR lpBuffer, - DWORD nSize - ) +GetEnvironmentVariableW(IN LPCWSTR lpName, + IN LPWSTR lpBuffer, + IN DWORD nSize) { - UNICODE_STRING VarName; - UNICODE_STRING VarValue; - NTSTATUS Status; + UNICODE_STRING VarName, VarValue; + NTSTATUS Status; - RtlInitUnicodeString (&VarName, - lpName); + if (nSize <= UNICODE_STRING_MAX_BYTES) + { + if (nSize) nSize = nSize * sizeof(WCHAR) - sizeof(UNICODE_NULL); + } + else + { + nSize = UNICODE_STRING_MAX_BYTES - sizeof(UNICODE_NULL); + } - VarValue.Length = 0; - VarValue.MaximumLength = (USHORT) (nSize ? nSize - 1 : 0) * sizeof(WCHAR); - VarValue.Buffer = lpBuffer; + Status = RtlInitUnicodeStringEx(&VarName, lpName); + if (NT_SUCCESS(Status)) + { + RtlInitEmptyUnicodeString(&VarValue, lpBuffer, nSize); - Status = RtlQueryEnvironmentVariable_U (NULL, - &VarName, - &VarValue); - if (!NT_SUCCESS(Status)) - { - if (Status == STATUS_BUFFER_TOO_SMALL) - { - return (VarValue.Length / sizeof(WCHAR)) + 1; - } - else - { - BaseSetLastNTError (Status); - return 0; - } - } - - if (nSize != 0) + Status = RtlQueryEnvironmentVariable_U(NULL, &VarName, &VarValue); + if (!NT_SUCCESS(Status)) { - /* make sure the string is NULL-terminated! RtlQueryEnvironmentVariable_U - only terminates it if MaximumLength < Length */ - lpBuffer[VarValue.Length / sizeof(WCHAR)] = L'\0'; - } + if (Status == STATUS_BUFFER_TOO_SMALL) + { + return (VarValue.Length / sizeof(WCHAR)) + sizeof(ANSI_NULL); + } + BaseSetLastNTError (Status); + return 0; + } - return (VarValue.Length / sizeof(WCHAR)); + lpBuffer[VarValue.Length / sizeof(WCHAR)] = UNICODE_NULL; + } + + return (VarValue.Length / sizeof(WCHAR)); } - /* * @implemented */ BOOL WINAPI -SetEnvironmentVariableA ( - LPCSTR lpName, - LPCSTR lpValue - ) +SetEnvironmentVariableA(IN LPCSTR lpName, + IN LPCSTR lpValue) { - ANSI_STRING VarName; - ANSI_STRING VarValue; - UNICODE_STRING VarNameU; - UNICODE_STRING VarValueU; - NTSTATUS Status; + ANSI_STRING VarName, VarValue; + UNICODE_STRING VarNameU, VarValueU; + NTSTATUS Status; - DPRINT("SetEnvironmentVariableA(Name '%s', Value '%s')\n", lpName, lpValue); + RtlInitAnsiString(&VarName, (LPSTR)lpName); + Status = RtlAnsiStringToUnicodeString(&VarNameU, &VarName, TRUE); + if (NT_SUCCESS(Status)) + { + if (lpValue) + { + RtlInitAnsiString(&VarValue, (LPSTR)lpValue); + Status = RtlAnsiStringToUnicodeString(&VarValueU, &VarValue, TRUE); + if (NT_SUCCESS(Status)) + { + Status = RtlSetEnvironmentVariable(NULL, &VarNameU, &VarValueU); + RtlFreeUnicodeString(&VarValueU); + } + } + else + { + Status = RtlSetEnvironmentVariable(NULL, &VarNameU, NULL); + } - RtlInitAnsiString (&VarName, - (LPSTR)lpName); - RtlAnsiStringToUnicodeString (&VarNameU, - &VarName, - TRUE); + RtlFreeUnicodeString(&VarNameU); - if (lpValue) - { - RtlInitAnsiString (&VarValue, - (LPSTR)lpValue); - RtlAnsiStringToUnicodeString (&VarValueU, - &VarValue, - TRUE); + if (NT_SUCCESS(Status)) return TRUE; + } - Status = RtlSetEnvironmentVariable (NULL, - &VarNameU, - &VarValueU); - - RtlFreeUnicodeString (&VarValueU); - } - else - { - Status = RtlSetEnvironmentVariable (NULL, - &VarNameU, - NULL); - } - RtlFreeUnicodeString (&VarNameU); - - if (!NT_SUCCESS(Status)) - { - BaseSetLastNTError (Status); - return FALSE; - } - - return TRUE; + BaseSetLastNTError(Status); + return FALSE; } - /* * @implemented */ BOOL WINAPI -SetEnvironmentVariableW ( - LPCWSTR lpName, - LPCWSTR lpValue - ) +SetEnvironmentVariableW(IN LPCWSTR lpName, + IN LPCWSTR lpValue) { - UNICODE_STRING VarName; - UNICODE_STRING VarValue; - NTSTATUS Status; + UNICODE_STRING VarName, VarValue; + NTSTATUS Status; - DPRINT("SetEnvironmentVariableW(Name '%S', Value '%S')\n", lpName, lpValue); + Status = RtlInitUnicodeStringEx(&VarName, lpName); + if (NT_SUCCESS(Status)) + { + if (lpValue) + { + Status = RtlInitUnicodeStringEx(&VarValue, lpValue); + if (NT_SUCCESS(Status)) + { + Status = RtlSetEnvironmentVariable(NULL, &VarName, &VarValue); + } + } + else + { + Status = RtlSetEnvironmentVariable(NULL, &VarName, NULL); + } - RtlInitUnicodeString (&VarName, - lpName); + if (NT_SUCCESS(Status)) return TRUE; + } - RtlInitUnicodeString (&VarValue, - lpValue); - - Status = RtlSetEnvironmentVariable (NULL, - &VarName, - &VarValue); - - if (!NT_SUCCESS(Status)) - { - BaseSetLastNTError (Status); - return FALSE; - } - - return TRUE; + BaseSetLastNTError(Status); + return FALSE; } - /* * @implemented */ LPSTR WINAPI -GetEnvironmentStringsA ( - VOID - ) +GetEnvironmentStringsA(VOID) { - UNICODE_STRING UnicodeString; - ANSI_STRING AnsiString; - PWCHAR EnvU; - PWCHAR PtrU; - ULONG Length; - PCHAR EnvPtr = NULL; + ULONG Length, Size; + NTSTATUS Status; + PWCHAR Environment, p; + PCHAR Buffer = NULL; - EnvU = (PWCHAR)(NtCurrentPeb ()->ProcessParameters->Environment); + RtlAcquirePebLock(); + p = Environment = NtCurrentPeb()->ProcessParameters->Environment; - if (EnvU == NULL) - return NULL; + do + { + p += wcslen(Environment) + 1; + } while (*p); - if (*EnvU == 0) - return NULL; + Length = p - Environment + sizeof(UNICODE_NULL); - /* get environment size */ - PtrU = EnvU; - while (*PtrU) - { - while (*PtrU) - PtrU++; - PtrU++; - } - Length = (ULONG)(PtrU - EnvU); - DPRINT("Length %lu\n", Length); - - /* allocate environment buffer */ - EnvPtr = RtlAllocateHeap (RtlGetProcessHeap (), - 0, - Length + 1); - if (EnvPtr == NULL) + Status = RtlUnicodeToMultiByteSize(&Size, Environment, Length); + if (NT_SUCCESS(Status)) + { + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size); + if (Buffer) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; + Status = RtlUnicodeToOemN(Buffer, Size, 0, Environment, Length); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + Buffer = NULL; + + BaseSetLastNTError(Status); + } } - DPRINT("EnvPtr %p\n", EnvPtr); + else + { + BaseSetLastNTError(STATUS_NO_MEMORY); + } + } + else + { + BaseSetLastNTError(Status); + } - /* convert unicode environment to ansi */ - UnicodeString.MaximumLength = (USHORT)Length * sizeof(WCHAR) + sizeof(WCHAR); - UnicodeString.Buffer = EnvU; - - AnsiString.MaximumLength = (USHORT)Length + 1; - AnsiString.Length = 0; - AnsiString.Buffer = EnvPtr; - - DPRINT ("UnicodeString.Buffer \'%S\'\n", UnicodeString.Buffer); - - while (*(UnicodeString.Buffer)) - { - UnicodeString.Length = wcslen (UnicodeString.Buffer) * sizeof(WCHAR); - UnicodeString.MaximumLength = UnicodeString.Length + sizeof(WCHAR); - if (UnicodeString.Length > 0) - { - AnsiString.Length = 0; - AnsiString.MaximumLength = (USHORT)Length + 1 - (AnsiString.Buffer - EnvPtr); - - RtlUnicodeStringToAnsiString (&AnsiString, - &UnicodeString, - FALSE); - - AnsiString.Buffer += (AnsiString.Length + 1); - UnicodeString.Buffer += ((UnicodeString.Length / sizeof(WCHAR)) + 1); - } - } - *(AnsiString.Buffer) = 0; - - return EnvPtr; + RtlReleasePebLock(); + return Buffer; } - /* * @implemented */ LPWSTR WINAPI -GetEnvironmentStringsW ( - VOID - ) +GetEnvironmentStringsW(VOID) { - return (LPWSTR)(NtCurrentPeb ()->ProcessParameters->Environment); -} + PWCHAR Environment, p; + ULONG Length; + RtlAcquirePebLock(); + + p = Environment = NtCurrentPeb()->ProcessParameters->Environment; + + do + { + p += wcslen(Environment) + 1; + } while (*p); + + Length = p - Environment + sizeof(UNICODE_NULL); + + p = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length); + if (p) + { + RtlCopyMemory(p, Environment, Length); + } + else + { + BaseSetLastNTError(STATUS_NO_MEMORY); + } + + RtlReleasePebLock(); + return p; +} /* * @implemented */ BOOL WINAPI -FreeEnvironmentStringsA ( - LPSTR EnvironmentStrings - ) +FreeEnvironmentStringsA(IN LPSTR EnvironmentStrings) { - if (EnvironmentStrings == NULL) - return FALSE; - - RtlFreeHeap (RtlGetProcessHeap (), - 0, - EnvironmentStrings); - - return TRUE; + return (BOOL)RtlFreeHeap(RtlGetProcessHeap(), 0, EnvironmentStrings); } - /* * @implemented */ BOOL WINAPI -FreeEnvironmentStringsW ( - LPWSTR EnvironmentStrings - ) +FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings) { - return TRUE; + return (BOOL)RtlFreeHeap(RtlGetProcessHeap(), 0, EnvironmentStrings); } - /* * @implemented */ DWORD WINAPI -ExpandEnvironmentStringsA ( - LPCSTR lpSrc, - LPSTR lpDst, - DWORD nSize - ) +ExpandEnvironmentStringsA(IN LPCSTR lpSrc, + IN LPSTR lpDst, + IN DWORD nSize) { - ANSI_STRING Source; - ANSI_STRING Destination; - UNICODE_STRING SourceU; - UNICODE_STRING DestinationU; - NTSTATUS Status; - ULONG Length = 0; + ANSI_STRING Source, Dest; + UNICODE_STRING SourceU, DestU; + PWSTR Buffer; + ULONG Result = 0, UniSize = 0, Length; + NTSTATUS Status; - RtlInitAnsiString (&Source, - (LPSTR)lpSrc); - Status = RtlAnsiStringToUnicodeString (&SourceU, - &Source, - TRUE); - if (!NT_SUCCESS(Status)) + /* Initialize all the strings */ + RtlInitAnsiString(&Source, lpSrc); + RtlInitUnicodeString(&SourceU, NULL); + RtlInitUnicodeString(&DestU, NULL); + Status = RtlAnsiStringToUnicodeString(&SourceU, &Source, TRUE); + if (!NT_SUCCESS(Status)) goto Quickie; + + /* Check if the size is too big to fit */ + if (nSize <= UNICODE_STRING_MAX_BYTES) + { + /* Keep the given size, minus a NULL-char */ + if (nSize) UniSize = nSize * sizeof(WCHAR) - sizeof(UNICODE_NULL); + } + else + { + /* Set the maximum possible */ + UniSize = UNICODE_STRING_MAX_BYTES - sizeof(UNICODE_NULL); + } + + /* Allocate the value string buffer */ + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, UniSize); + if (!Buffer) + { + Status = STATUS_NO_MEMORY; + goto Quickie; + } + + /* And initialize its string */ + RtlInitEmptyUnicodeString(&DestU, Buffer, UniSize); + + /* Query the variable */ + Length = 0; + Status = RtlExpandEnvironmentStrings_U(NULL, &SourceU, &DestU, &Length); + + /* Check if we didn't have enough space */ + if (Status == STATUS_BUFFER_TOO_SMALL) + { + /* Fixup the length that the API returned */ + DestU.MaximumLength = Length; + + /* Free old Unicode buffer */ + RtlFreeHeap(RtlGetProcessHeap(), 0, DestU.Buffer); + + /* Allocate new one */ + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length); + if (Buffer) { - BaseSetLastNTError (Status); - return 0; + /* Query the variable so we can know its size */ + DestU.Buffer = Buffer; + Status = RtlExpandEnvironmentStrings_U(NULL, &SourceU, &DestU, &Length); + if (NT_SUCCESS(Status)) + { + /* Get the ASCII length of the variable */ + Result = RtlUnicodeStringToAnsiSize(&DestU); + } + } + else + { + /* Set failure status */ + Status = STATUS_NO_MEMORY; + } + } + else + { + /* Check if the size is too big to fit */ + if (nSize <= MAXULONG) + { + /* Keep the given size, minus a NULL-char */ + if (nSize) nSize = nSize - sizeof(ANSI_NULL); + } + else + { + /* Set the maximum possible */ + nSize = MAXULONG - sizeof(ANSI_NULL); } - /* make sure we don't overflow the maximum ANSI_STRING size */ - if (nSize > 0x7fff) - nSize = 0x7fff; - - Destination.Length = 0; - Destination.MaximumLength = (USHORT)nSize; - Destination.Buffer = lpDst; - - DestinationU.Length = 0; - DestinationU.MaximumLength = (USHORT)nSize * sizeof(WCHAR); - DestinationU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (), - 0, - DestinationU.MaximumLength); - if (DestinationU.Buffer == NULL) + /* Check the size */ + Result = RtlUnicodeStringToAnsiSize(&DestU); + if (Result <= nSize) { - RtlFreeUnicodeString(&SourceU); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return 0; + /* Convert the string */ + RtlInitEmptyAnsiString(&Dest, lpDst, nSize); + Status = RtlUnicodeStringToAnsiString(&Dest, &DestU, FALSE); + if (!NT_SUCCESS(Status)) + { + /* Clear the destination */ + *lpDst = ANSI_NULL; + } } + } +Quickie: + /* Free the strings */ + RtlFreeUnicodeString(&SourceU); + if (DestU.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, DestU.Buffer); - Status = RtlExpandEnvironmentStrings_U (NULL, - &SourceU, - &DestinationU, - &Length); + /* Check if we suceeded */ + if (!NT_SUCCESS(Status)) + { + /* We did not, clear the result and set the error code */ + BaseSetLastNTError(Status); + Result = 0; + } - RtlFreeUnicodeString (&SourceU); - - if (!NT_SUCCESS(Status)) - { - BaseSetLastNTError (Status); - if (Status != STATUS_BUFFER_TOO_SMALL) - { - RtlFreeHeap (RtlGetProcessHeap (), - 0, - DestinationU.Buffer); - return 0; - } - } - - RtlUnicodeStringToAnsiString (&Destination, - &DestinationU, - FALSE); - - RtlFreeHeap (RtlGetProcessHeap (), - 0, - DestinationU.Buffer); - - return (Length / sizeof(WCHAR)); + /* Return the result */ + return Result; } - /* * @implemented */ DWORD WINAPI -ExpandEnvironmentStringsW ( - LPCWSTR lpSrc, - LPWSTR lpDst, - DWORD nSize - ) +ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, + IN LPWSTR lpDst, + IN DWORD nSize) { - UNICODE_STRING Source; - UNICODE_STRING Destination; - NTSTATUS Status; - ULONG Length = 0; + UNICODE_STRING Source, Destination; + NTSTATUS Status;; - RtlInitUnicodeString (&Source, - (LPWSTR)lpSrc); + RtlInitUnicodeString(&Source, (LPWSTR)lpSrc); /* make sure we don't overflow the maximum UNICODE_STRING size */ - if (nSize > 0x7fff) - nSize = 0x7fff; + if (nSize > UNICODE_STRING_MAX_BYTES) nSize = UNICODE_STRING_MAX_BYTES; - Destination.Length = 0; - Destination.MaximumLength = (USHORT)nSize * sizeof(WCHAR); - Destination.Buffer = lpDst; + RtlInitEmptyUnicodeString(&Destination, lpDst, nSize * sizeof(WCHAR)); + Status = RtlExpandEnvironmentStrings_U(NULL, + &Source, + &Destination, + &nSize); + if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_TOO_SMALL)) + { + return nSize / sizeof(WCHAR); + } - Status = RtlExpandEnvironmentStrings_U (NULL, - &Source, - &Destination, - &Length); - if (!NT_SUCCESS(Status)) - { - BaseSetLastNTError (Status); - if (Status != STATUS_BUFFER_TOO_SMALL) - return 0; - } + BaseSetLastNTError (Status); + return 0; - return (Length / sizeof(WCHAR)); } /*