https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c8681feee94bf0e31dfb3…
commit c8681feee94bf0e31dfb3f065fef432fa4eb39b6
Author: Colin Finck <colin(a)reactos.org>
AuthorDate: Wed Aug 28 22:42:52 2019 +0200
Commit: Colin Finck <colin(a)reactos.org>
CommitDate: Wed Aug 28 22:42:52 2019 +0200
Fix the ntstrsafe.h tests to make sense, actually succeed using ntstrsafe.h from Win10
(10.0.15063), and fix ReactOS' ntstrsafe.h to also pass these tests. (#1859)
---
modules/rostests/kmtests/rtl/RtlStrSafe.c | 262 +++++++++++++++---------------
sdk/include/ddk/ntstrsafe.h | 112 +++++--------
2 files changed, 171 insertions(+), 203 deletions(-)
diff --git a/modules/rostests/kmtests/rtl/RtlStrSafe.c
b/modules/rostests/kmtests/rtl/RtlStrSafe.c
index 807a036b2a7..82c2fe512cc 100644
--- a/modules/rostests/kmtests/rtl/RtlStrSafe.c
+++ b/modules/rostests/kmtests/rtl/RtlStrSafe.c
@@ -1,8 +1,9 @@
/*
* PROJECT: ReactOS kernel-mode tests
- * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Test for ntstrsafe.h functions
* COPYRIGHT: Copyright 2018 Hern�n Di Pietro <hernan.di.pietro(a)gmail.com>
+ * Copyright 2019 Colin Finck <colin(a)reactos.org>
*/
#define KMT_EMULATE_KERNEL
@@ -13,163 +14,168 @@
#define TESTAPI static void
+static const WCHAR FormatStringInts[] = L"%d %d %d";
+static const WCHAR FormatStringIntsResult[] = L"1 2 3";
+static const WCHAR FormatStringStrs[] = L"%s %s %s";
+
+
TESTAPI
Test_RtlUnicodeStringPrintf()
{
- WCHAR Buffer[1024];
- WCHAR OvrBuffer[1024];
- WCHAR BufferSmall[2];
- WCHAR BufferSmall2[7];
+ NTSTATUS Status;
+ PWSTR pBuffer = NULL;
+ size_t BufferSize;
+ size_t EqualBytes;
UNICODE_STRING UsString;
- const WCHAR FormatStringInts[] = L"%d %d %d";
- const WCHAR FormatStringStrs[] = L"%s %s %s";
- const WCHAR Result[] = L"1 2 3";
- UNICODE_STRING UsStringNull;
- /* No zeros (Don't assume UNICODE_STRINGS are NULL terminated) */
-
- RtlFillMemory(Buffer, sizeof(Buffer), 0xAA);
- RtlFillMemory(BufferSmall, sizeof(BufferSmall), 0xAA);
- RtlFillMemory(BufferSmall2, sizeof(BufferSmall2), 0xAA);
+ KmtStartSeh();
/* STATUS_SUCCESS test */
+ BufferSize = 6 * sizeof(WCHAR);
+ pBuffer = KmtAllocateGuarded(BufferSize);
+ if (!pBuffer)
+ goto Cleanup;
+
+ RtlFillMemory(pBuffer, BufferSize, 0xAA);
+ RtlInitEmptyUnicodeString(&UsString, pBuffer, BufferSize);
+
+ Status = RtlUnicodeStringPrintf(&UsString, FormatStringInts, 1, 2, 3);
+ EqualBytes = RtlCompareMemory(UsString.Buffer, FormatStringIntsResult,
sizeof(FormatStringIntsResult));
+ ok_eq_hex(Status, STATUS_SUCCESS);
+ ok_eq_size(EqualBytes, sizeof(FormatStringIntsResult));
+ ok_eq_uint(UsString.Length, sizeof(FormatStringIntsResult) - sizeof(WCHAR));
+ ok_eq_uint(UsString.MaximumLength, BufferSize);
+
+ KmtFreeGuarded(pBuffer);
+ pBuffer = NULL;
- UsString.Buffer = Buffer;
- UsString.Length = 0;
- UsString.MaximumLength = sizeof(Buffer);
-
- ok_eq_hex(RtlUnicodeStringPrintf(&UsString, FormatStringInts, 1, 2, 3),
STATUS_SUCCESS);
- ok_eq_uint(UsString.Length, sizeof(Result) - sizeof(WCHAR));
- ok_eq_uint(UsString.MaximumLength, sizeof(Buffer));
- ok_eq_wchar(UsString.Buffer[0], L'1');
- ok_eq_wchar(UsString.Buffer[1], L' ');
- ok_eq_wchar(UsString.Buffer[2], L'2');
- ok_eq_wchar(UsString.Buffer[3], L' ');
- ok_eq_wchar(UsString.Buffer[4], L'3');
- ok_eq_wchar(UsString.Buffer[5], (WCHAR) 0);
-
/* STATUS_BUFFER_OVERFLOW tests */
+ BufferSize = 2 * sizeof(WCHAR);
+ pBuffer = KmtAllocateGuarded(BufferSize);
+ if (!pBuffer)
+ goto Cleanup;
- UsString.Buffer = BufferSmall;
- UsString.Length = 0;
- UsString.MaximumLength = sizeof(BufferSmall);
-
- ok_eq_hex(RtlUnicodeStringPrintf(&UsString, FormatStringStrs, L"AAA",
L"BBB", L"CCC"), STATUS_BUFFER_OVERFLOW);
+ RtlInitEmptyUnicodeString(&UsString, pBuffer, BufferSize);
+
+ Status = RtlUnicodeStringPrintf(&UsString, FormatStringStrs, L"AAA",
L"BBB", L"CCC");
+ EqualBytes = RtlCompareMemory(UsString.Buffer, L"AA", BufferSize);
+ ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW);
+ ok_eq_size(EqualBytes, BufferSize);
ok_eq_uint(UsString.Length, UsString.MaximumLength);
- ok_eq_char(UsString.Buffer[0], L'A');
- ok_eq_char(UsString.Buffer[1], (WCHAR)0);
- UsString.Buffer = BufferSmall2;
- UsString.Length = 0;
- UsString.MaximumLength = sizeof(BufferSmall2);
+ KmtFreeGuarded(pBuffer);
+ pBuffer = NULL;
+
- ok_eq_hex(RtlUnicodeStringPrintf(&UsString, FormatStringStrs, L"0123",
L"4567", L"89AB"), STATUS_BUFFER_OVERFLOW);
+ BufferSize = 7 * sizeof(WCHAR);
+ pBuffer = KmtAllocateGuarded(BufferSize);
+ if (!pBuffer)
+ goto Cleanup;
+
+ RtlInitEmptyUnicodeString(&UsString, pBuffer, BufferSize);
+
+ Status = RtlUnicodeStringPrintf(&UsString, FormatStringStrs, L"0123",
L"4567", L"89AB");
+ EqualBytes = RtlCompareMemory(UsString.Buffer, L"0123 45", BufferSize);
+ ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW);
+ ok_eq_size(EqualBytes, BufferSize);
ok_eq_uint(UsString.Length, UsString.MaximumLength);
- ok_eq_char(UsString.Buffer[0], L'0');
- ok_eq_char(UsString.Buffer[1], L'1');
- ok_eq_char(UsString.Buffer[2], L'2');
- ok_eq_char(UsString.Buffer[3], L'3');
- ok_eq_char(UsString.Buffer[4], L' ');
- ok_eq_char(UsString.Buffer[5], L'4');
- ok_eq_char(UsString.Buffer[6], (WCHAR) 0);
-
- ///* STATUS_INVALID_PARAMETER tests */
-
- ok_eq_hex(RtlUnicodeStringPrintf(NULL, FormatStringStrs, L"AAA",
L"BBB", L"CCC"), STATUS_INVALID_PARAMETER);
- ok_eq_hex(RtlUnicodeStringPrintf(&UsString, NULL, L"AAA",
L"BBB", L"CCC"), STATUS_INVALID_PARAMETER);
-
- UsStringNull.Buffer = (PWCH)NULL;
- UsStringNull.Length = 0;
- UsStringNull.MaximumLength = 0;
- ok_eq_bool(RtlUnicodeStringPrintf(&UsStringNull, FormatStringStrs,
L"AAA", L"BBB", L"CCC"), STATUS_INVALID_PARAMETER);
-
- /* Test for buffer overruns */
-
- RtlFillMemory(Buffer, sizeof(Buffer), 0xAA);
- RtlFillMemory(OvrBuffer, sizeof(OvrBuffer), 0xAA);
- UsString.Buffer = Buffer;
- UsString.Length = 0;
- UsString.MaximumLength = 16 * sizeof(WCHAR);
-
- ok_eq_hex(RtlUnicodeStringPrintf(&UsString, FormatStringStrs, L"abc",
L"def", L"ghi"), STATUS_SUCCESS);
- ok_eq_uint(UsString.Length, sizeof(L"abc def ghi") -sizeof(WCHAR));
- ok_eq_char(UsString.Buffer[11], (WCHAR)0);
- ok_eq_uint(0, memcmp(OvrBuffer + 12, Buffer + 12, sizeof(Buffer) - (12 *
sizeof(WCHAR))));
+
+ KmtFreeGuarded(pBuffer);
+ pBuffer = NULL;
+
+ // Note: RtlUnicodeStringPrintf returns STATUS_BUFFER_OVERFLOW here while
RtlUnicodeStringPrintfEx returns STATUS_INVALID_PARAMETER!
+ // Documented on MSDN and verified with the Win10 version of ntstrsafe.h
+ RtlInitEmptyUnicodeString(&UsString, NULL, 0);
+ Status = RtlUnicodeStringPrintf(&UsString, FormatStringStrs, L"AAA",
L"BBB", L"CCC");
+ ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW);
+
+
+Cleanup:
+ if (pBuffer)
+ KmtFreeGuarded(pBuffer);
+
+ // None of these functions should have crashed.
+ KmtEndSeh(STATUS_SUCCESS);
}
TESTAPI
Test_RtlUnicodeStringPrintfEx()
{
- WCHAR Buffer[32];
- WCHAR BufferSmall[8] = { 0 };
- WCHAR OvrBuffer[1024];
- UNICODE_STRING UsString, RemString;
- const WCHAR FormatStringInts[] = L"%d %d %d";
- const WCHAR FormatStringStrs[] = L"%s %s %s";
- const WCHAR Result[] = L"1 2 3";
+ NTSTATUS Status;
+ PWSTR pBuffer = NULL;
+ size_t BufferSize;
+ size_t EqualBytes;
+ UNICODE_STRING RemString;
+ UNICODE_STRING UsString;
+ WCHAR FillResult[10];
- /* No zeros (Don't assume UNICODE_STRINGS are NULL terminated) */
+ RtlFillMemory(FillResult, sizeof(FillResult), 0xAA);
- RtlFillMemory(Buffer, sizeof(Buffer), 0xAA);
+ KmtStartSeh();
- UsString.Buffer = Buffer;
- UsString.Length = 0;
- UsString.MaximumLength = sizeof(Buffer);
+ /* STATUS_SUCCESS test, fill behind flag: low-byte as fill character */
+ BufferSize = sizeof(FormatStringIntsResult) - sizeof(UNICODE_NULL) +
sizeof(FillResult);
+ pBuffer = KmtAllocateGuarded(BufferSize);
+ if (!pBuffer)
+ goto Cleanup;
+
+ RtlInitEmptyUnicodeString(&UsString, pBuffer, BufferSize);
+ RtlInitEmptyUnicodeString(&RemString, NULL, 0);
+
+ Status = RtlUnicodeStringPrintfEx(&UsString, &RemString, STRSAFE_FILL_BEHIND
| 0xAA, FormatStringInts, 1, 2, 3);
+ EqualBytes = RtlCompareMemory(UsString.Buffer, FormatStringIntsResult,
sizeof(FormatStringIntsResult) - sizeof(WCHAR));
+ ok_eq_hex(Status, STATUS_SUCCESS);
+ ok_eq_size(EqualBytes, sizeof(FormatStringIntsResult) - sizeof(WCHAR));
+ ok_eq_uint(UsString.Length, sizeof(FormatStringIntsResult) - sizeof(WCHAR));
+ ok_eq_uint(UsString.MaximumLength, BufferSize);
+
+ ok_eq_pointer(RemString.Buffer, &UsString.Buffer[UsString.Length /
sizeof(WCHAR)]);
+ ok_eq_uint(RemString.Length, 0);
+ ok_eq_uint(RemString.MaximumLength, UsString.MaximumLength - UsString.Length);
- RemString.Buffer = (PWCH)NULL;
- RemString.Length = 0;
- RemString.MaximumLength = 0;
+ EqualBytes = RtlCompareMemory(RemString.Buffer, FillResult,
RemString.MaximumLength);
+ ok_eq_size(EqualBytes, sizeof(FillResult));
+
+ KmtFreeGuarded(pBuffer);
+ pBuffer = NULL;
- /* STATUS_SUCCESS test, fill behind flag: low-byte as fill character */
- ok_eq_hex(RtlUnicodeStringPrintfEx(&UsString, &RemString, STRSAFE_FILL_BEHIND
| 0xFF, FormatStringInts, 1, 2, 3), STATUS_SUCCESS);
-
- ok_eq_uint(UsString.Length, sizeof(Result) - sizeof(WCHAR));
- ok_eq_uint(UsString.MaximumLength, sizeof(Buffer));
- ok_eq_uint(memcmp(UsString.Buffer, Result, sizeof(Result) - sizeof(WCHAR)), 0);
+ /* STATUS_BUFFER_OVERFLOW test */
+ BufferSize = 8 * sizeof(WCHAR);
+ pBuffer = KmtAllocateGuarded(BufferSize);
+ if (!pBuffer)
+ goto Cleanup;
+
+ RtlInitEmptyUnicodeString(&UsString, pBuffer, BufferSize);
+ RtlInitEmptyUnicodeString(&RemString, NULL, 0);
+
+ Status = RtlUnicodeStringPrintfEx(&UsString, &RemString, 0, FormatStringStrs,
L"AAA", L"BBB", L"CCC");
+ EqualBytes = RtlCompareMemory(UsString.Buffer, L"AAA BBB ",
UsString.Length);
+ ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW);
+ ok_eq_size(EqualBytes, UsString.Length);
+ ok_eq_uint(UsString.Length, UsString.MaximumLength);
- ok_eq_pointer(RemString.Buffer, UsString.Buffer + (UsString.Length /
sizeof(WCHAR)));
+ ok_eq_pointer(RemString.Buffer, &UsString.Buffer[UsString.Length /
sizeof(WCHAR)]);
ok_eq_uint(RemString.Length, 0);
- ok_eq_uint(RemString.MaximumLength, UsString.MaximumLength - UsString.Length);
+ ok_eq_uint(RemString.MaximumLength, 0);
- /* STATUS_BUFFER_OVERFLOW test */
+ KmtFreeGuarded(pBuffer);
+ pBuffer = NULL;
- UsString.Buffer = BufferSmall;
- UsString.Length = 0;
- UsString.MaximumLength = sizeof(BufferSmall);
- RemString.Buffer = (PWCH)NULL;
- RemString.Length = 0;
- RemString.MaximumLength = 0;
-
- ok_eq_hex(RtlUnicodeStringPrintfEx(&UsString, &RemString, 0,
FormatStringStrs, L"AAA", L"BBB", L"CCC"),
STATUS_BUFFER_OVERFLOW);
- ok_eq_uint(UsString.Length, UsString.MaximumLength);
- ok_eq_char(UsString.Buffer[0], L'A');
- ok_eq_char(UsString.Buffer[1], L'A');
- ok_eq_char(UsString.Buffer[2], L'A');
- ok_eq_char(UsString.Buffer[3], L' ');
- ok_eq_char(UsString.Buffer[4], L'B');
- ok_eq_char(UsString.Buffer[5], L'B');
- ok_eq_char(UsString.Buffer[6], L'B');
- ok_eq_char(UsString.Buffer[7], (WCHAR)0);
-
- // Takes \0 into account
- ok_eq_pointer(RemString.Buffer, UsString.Buffer + (UsString.Length - 1) /
sizeof(WCHAR));
- ok_eq_uint(RemString.Length, 0);
- ok_eq_uint(RemString.MaximumLength, 2);
-
- /* Test for buffer overruns */
-
- RtlFillMemory(Buffer, sizeof(Buffer), 0xAA);
- RtlFillMemory(OvrBuffer, sizeof(OvrBuffer), 0xAA);
- UsString.Buffer = Buffer;
- UsString.Length = 0;
- UsString.MaximumLength = 16 * sizeof(WCHAR);
-
- ok_eq_hex(RtlUnicodeStringPrintfEx(&UsString, &RemString, 0,
FormatStringStrs, L"abc", L"def", L"ghi"), STATUS_SUCCESS);
- ok_eq_uint(UsString.Length, sizeof(L"abc def ghi") - sizeof(WCHAR));
- ok_eq_char(UsString.Buffer[11], (WCHAR)0);
- ok_eq_uint(0, memcmp(OvrBuffer + 12, Buffer + 12, sizeof(Buffer) - (12 *
sizeof(WCHAR))));
+ // Note: RtlUnicodeStringPrintf returns STATUS_BUFFER_OVERFLOW here while
RtlUnicodeStringPrintfEx returns STATUS_INVALID_PARAMETER!
+ // Documented on MSDN and verified with the Win10 version of ntstrsafe.h
+ RtlInitEmptyUnicodeString(&UsString, NULL, 0);
+ Status = RtlUnicodeStringPrintfEx(&UsString, NULL, 0, FormatStringStrs,
L"AAA", L"BBB", L"CCC");
+ ok_eq_hex(Status, STATUS_INVALID_PARAMETER);
+
+
+Cleanup:
+ if (pBuffer)
+ KmtFreeGuarded(pBuffer);
+
+ // None of these functions should have crashed.
+ KmtEndSeh(STATUS_SUCCESS);
}
START_TEST(RtlStrSafe)
diff --git a/sdk/include/ddk/ntstrsafe.h b/sdk/include/ddk/ntstrsafe.h
index fac1a46f723..2780efe76e7 100644
--- a/sdk/include/ddk/ntstrsafe.h
+++ b/sdk/include/ddk/ntstrsafe.h
@@ -15,20 +15,6 @@
#pragma warning(disable:28719) /* disable banned api usage warning */
#endif /* _MSC_VER */
-#ifndef C_ASSERT
-#ifdef _MSC_VER
-# define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
-#else
-# define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1])
-#endif
-#endif /* C_ASSERT */
-
-#ifdef __cplusplus
-#define _STRSAFE_EXTERN_C extern "C"
-#else
-#define _STRSAFE_EXTERN_C extern
-#endif
-
#define NTSTRSAFEAPI static __inline NTSTATUS NTAPI
#define NTSTRSAFEVAPI static __inline NTSTATUS __cdecl
#define NTSTRSAFE_INLINE_API static __inline NTSTATUS NTAPI
@@ -92,10 +78,8 @@ NTSTRSAFEAPI RtlStringCatNExWorkerA(STRSAFE_LPSTR pszDest, size_t
cchDest, size_
NTSTRSAFEAPI RtlStringCatNExWorkerW(STRSAFE_LPWSTR pszDest, size_t cchDest, size_t
cbDest, STRSAFE_LPCWSTR pszSrc, size_t cchToAppend, STRSAFE_LPWSTR *ppszDestEnd, size_t
*pcchRemaining, STRSAFE_DWORD dwFlags);
NTSTRSAFEAPI RtlStringVPrintfWorkerA(STRSAFE_LPSTR pszDest, size_t cchDest,
STRSAFE_LPCSTR pszFormat, va_list argList);
NTSTRSAFEAPI RtlStringVPrintfWorkerW(STRSAFE_LPWSTR pszDest, size_t cchDest,
STRSAFE_LPCWSTR pszFormat, va_list argList);
-NTSTRSAFEAPI RtlStringVPrintfWorkerLenW(STRSAFE_LPWSTR pszDest, size_t cchDest,
STRSAFE_LPCWSTR pszFormat, size_t* pcchDestNewLen, va_list argList);
NTSTRSAFEAPI RtlStringVPrintfExWorkerA(STRSAFE_LPSTR pszDest, size_t cchDest, size_t
cbDest, STRSAFE_LPSTR *ppszDestEnd, size_t *pcchRemaining, STRSAFE_DWORD dwFlags,
STRSAFE_LPCSTR pszFormat, va_list argList);
NTSTRSAFEAPI RtlStringVPrintfExWorkerW(STRSAFE_LPWSTR pszDest, size_t cchDest, size_t
cbDest, STRSAFE_LPWSTR *ppszDestEnd, size_t *pcchRemaining, STRSAFE_DWORD dwFlags,
STRSAFE_LPCWSTR pszFormat, va_list argList);
-NTSTRSAFEAPI RtlStringVPrintfExWorkerLenW(STRSAFE_LPWSTR pszDest, size_t cchDest, size_t
cbDest, STRSAFE_LPWSTR *ppszDestEnd, size_t *pcchRemaining, STRSAFE_DWORD dwFlags,
STRSAFE_LPCWSTR pszFormat, size_t* pcchDestNewLen, va_list argList);
NTSTRSAFEAPI RtlUnicodeStringValidate(PCUNICODE_STRING SourceString);
NTSTRSAFEAPI
@@ -1366,6 +1350,7 @@ RtlStringCbPrintfExW(
{
if (cchDest > 0)
*pszDest = L'\0';
+
return STATUS_INVALID_PARAMETER;
}
@@ -2842,6 +2827,29 @@ NTSTRSAFEAPI RtlStringVPrintfWorkerA(
return Status;
}
+NTSTRSAFEAPI RtlpArrayVPrintfWorkerW(
+ STRSAFE_LPWSTR pszDest,
+ size_t cchDest,
+ STRSAFE_LPCWSTR pszFormat,
+ size_t* pcchDestNewLen,
+ va_list argList)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ int iRet = _vsnwprintf(pszDest, cchDest, pszFormat, argList);
+
+ if ((iRet < 0) || (((size_t)iRet) > cchDest))
+ {
+ Status = STATUS_BUFFER_OVERFLOW;
+ *pcchDestNewLen = cchDest;
+ }
+ else
+ {
+ *pcchDestNewLen = iRet;
+ }
+
+ return Status;
+}
+
NTSTRSAFEAPI RtlpStringVPrintfWorkerW(
STRSAFE_LPWSTR pszDest,
size_t cchDest,
@@ -2883,19 +2891,6 @@ NTSTRSAFEAPI RtlStringVPrintfWorkerW(
return RtlpStringVPrintfWorkerW(pszDest, cchDest, pszFormat, NULL, argList);
}
-NTSTRSAFEAPI RtlStringVPrintfWorkerLenW(
- STRSAFE_LPWSTR pszDest,
- size_t cchDest,
- STRSAFE_LPCWSTR pszFormat,
- size_t* pcchDestNewLen,
- va_list argList)
-{
- if (cchDest == 0 || pcchDestNewLen == 0)
- return STATUS_INVALID_PARAMETER;
-
- return RtlpStringVPrintfWorkerW(pszDest, cchDest, pszFormat, pcchDestNewLen,
argList);
-}
-
NTSTRSAFEAPI RtlStringVPrintfExWorkerA(
STRSAFE_LPSTR pszDest,
size_t cchDest,
@@ -3068,35 +3063,19 @@ NTSTRSAFEAPI RtlpStringVPrintfExWorkerW(
}
else
{
- int iRet;
- size_t cchMax = cchDest - 1;
- iRet = _vsnwprintf(pszDest, cchMax, pszFormat, argList);
- if ((iRet < 0) || (((size_t)iRet) > cchMax))
- {
- pszDestEnd = pszDest + cchMax;
- cchRemaining = 1;
- *pszDestEnd = L'\0';
- Status = STATUS_BUFFER_OVERFLOW;
- }
- else if (((size_t)iRet) == cchMax)
- {
- pszDestEnd = pszDest + cchMax;
- cchRemaining = 1;
- *pszDestEnd = L'\0';
- }
- else if (((size_t)iRet) < cchMax)
- {
- pszDestEnd = pszDest + iRet;
- cchRemaining = cchDest - iRet;
+ size_t cchDestNewLen = 0;
- if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
- {
- memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags),
((cchRemaining - 1) * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
- }
+ Status = RtlpArrayVPrintfWorkerW(pszDest, cchDest, pszFormat,
&cchDestNewLen, argList);
+ pszDestEnd = pszDest + cchDestNewLen;
+ cchRemaining = cchDest - cchDestNewLen;
+
+ if (NT_SUCCESS(Status) && (dwFlags & STRSAFE_FILL_BEHIND)
&& cchRemaining)
+ {
+ memset(pszDestEnd, STRSAFE_GET_FILL_PATTERN(dwFlags), (cchRemaining *
sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)));
}
if (pcchDestNewLen)
- *pcchDestNewLen = iRet == -1 ? cchDest : iRet;
+ *pcchDestNewLen = cchDestNewLen;
}
}
}
@@ -3120,6 +3099,7 @@ NTSTRSAFEAPI RtlpStringVPrintfExWorkerW(
*pszDestEnd = L'\0';
}
}
+
if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
{
if (cchDest > 0)
@@ -3157,24 +3137,6 @@ NTSTRSAFEAPI RtlStringVPrintfExWorkerW(
return RtlpStringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd,
pcchRemaining, dwFlags, pszFormat, NULL, argList);
}
-NTSTRSAFEAPI RtlStringVPrintfExWorkerLenW(
- STRSAFE_LPWSTR pszDest,
- size_t cchDest,
- size_t cbDest,
- STRSAFE_LPWSTR *ppszDestEnd,
- size_t *pcchRemaining,
- STRSAFE_DWORD dwFlags,
- STRSAFE_LPCWSTR pszFormat,
- size_t* pcchDestNewLen,
- va_list argList)
-{
- if (pcchDestNewLen == 0)
- return STATUS_INVALID_PARAMETER;
-
- return RtlpStringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd,
pcchRemaining, dwFlags, pszFormat, pcchDestNewLen, argList);
-}
-
-
NTSTRSAFEAPI
RtlStringLengthWorkerA(
_In_reads_or_z_(cchMax) STRSAFE_LPCSTR psz,
@@ -3285,7 +3247,7 @@ RtlUnicodeStringPrintf(
size_t cchFinalLength;
va_list argList;
- if (DestinationString == NULL || pszFormat == NULL || DestinationString->Buffer ==
NULL)
+ if (DestinationString == NULL || pszFormat == NULL)
{
Status = STATUS_INVALID_PARAMETER;
}
@@ -3296,7 +3258,7 @@ RtlUnicodeStringPrintf(
{
va_start(argList, pszFormat);
- Status = RtlStringVPrintfWorkerLenW(DestinationString->Buffer,
+ Status = RtlpArrayVPrintfWorkerW(DestinationString->Buffer,
DestinationString->MaximumLength / sizeof(WCHAR),
pszFormat,
&cchFinalLength,
@@ -3328,7 +3290,7 @@ RtlUnicodeStringPrintfEx(
va_start(argList, pszFormat);
- Status = RtlStringVPrintfExWorkerLenW(DestinationString->Buffer,
+ Status = RtlpStringVPrintfExWorkerW(DestinationString->Buffer,
DestinationString->MaximumLength / sizeof(WCHAR),
DestinationString->MaximumLength,
&RemainingString->Buffer,