ReactOS  0.4.14-dev-854-gb9426a3
RtlStrSafe.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS kernel-mode tests
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Test for ntstrsafe.h functions
5  * COPYRIGHT: Copyright 2018 Hernán Di Pietro <hernan.di.pietro@gmail.com>
6  * Copyright 2019 Colin Finck <colin@reactos.org>
7  */
8 
9 #define KMT_EMULATE_KERNEL
10 #include <kmt_test.h>
11 #include <ntstrsafe.h>
12 #include <ntdef.h>
13 #include <ndk/rtlfuncs.h>
14 
15 #define TESTAPI static void
16 
17 static const WCHAR FormatStringInts[] = L"%d %d %d";
18 static const WCHAR FormatStringIntsResult[] = L"1 2 3";
19 static const WCHAR FormatStringStrs[] = L"%s %s %s";
20 
21 
22 TESTAPI
24 {
26  PWSTR pBuffer = NULL;
28  size_t EqualBytes;
29  UNICODE_STRING UsString;
30 
31  KmtStartSeh();
32 
33  /* STATUS_SUCCESS test */
34  BufferSize = 6 * sizeof(WCHAR);
36  if (!pBuffer)
37  goto Cleanup;
38 
40  RtlInitEmptyUnicodeString(&UsString, pBuffer, BufferSize);
41 
42  Status = RtlUnicodeStringPrintf(&UsString, FormatStringInts, 1, 2, 3);
45  ok_eq_size(EqualBytes, sizeof(FormatStringIntsResult));
46  ok_eq_uint(UsString.Length, sizeof(FormatStringIntsResult) - sizeof(WCHAR));
48 
50  pBuffer = NULL;
51 
52  /* STATUS_BUFFER_OVERFLOW tests */
53  BufferSize = 2 * sizeof(WCHAR);
55  if (!pBuffer)
56  goto Cleanup;
57 
58  RtlInitEmptyUnicodeString(&UsString, pBuffer, BufferSize);
59 
60  Status = RtlUnicodeStringPrintf(&UsString, FormatStringStrs, L"AAA", L"BBB", L"CCC");
61  EqualBytes = RtlCompareMemory(UsString.Buffer, L"AA", BufferSize);
63  ok_eq_size(EqualBytes, BufferSize);
64  ok_eq_uint(UsString.Length, UsString.MaximumLength);
65 
67  pBuffer = NULL;
68 
69 
70  BufferSize = 7 * sizeof(WCHAR);
72  if (!pBuffer)
73  goto Cleanup;
74 
75  RtlInitEmptyUnicodeString(&UsString, pBuffer, BufferSize);
76 
77  Status = RtlUnicodeStringPrintf(&UsString, FormatStringStrs, L"0123", L"4567", L"89AB");
78  EqualBytes = RtlCompareMemory(UsString.Buffer, L"0123 45", BufferSize);
80  ok_eq_size(EqualBytes, BufferSize);
81  ok_eq_uint(UsString.Length, UsString.MaximumLength);
82 
84  pBuffer = NULL;
85 
86  // Note: RtlUnicodeStringPrintf returns STATUS_BUFFER_OVERFLOW here while RtlUnicodeStringPrintfEx returns STATUS_INVALID_PARAMETER!
87  // Documented on MSDN and verified with the Win10 version of ntstrsafe.h
88  RtlInitEmptyUnicodeString(&UsString, NULL, 0);
89  Status = RtlUnicodeStringPrintf(&UsString, FormatStringStrs, L"AAA", L"BBB", L"CCC");
91 
92 
93 Cleanup:
94  if (pBuffer)
96 
97  // None of these functions should have crashed.
99 }
100 
101 TESTAPI
103 {
105  PWSTR pBuffer = NULL;
107  size_t EqualBytes;
108  UNICODE_STRING RemString;
109  UNICODE_STRING UsString;
110  WCHAR FillResult[10];
111 
112  RtlFillMemory(FillResult, sizeof(FillResult), 0xAA);
113 
114  KmtStartSeh();
115 
116  /* STATUS_SUCCESS test, fill behind flag: low-byte as fill character */
117  BufferSize = sizeof(FormatStringIntsResult) - sizeof(UNICODE_NULL) + sizeof(FillResult);
119  if (!pBuffer)
120  goto Cleanup;
121 
122  RtlInitEmptyUnicodeString(&UsString, pBuffer, BufferSize);
123  RtlInitEmptyUnicodeString(&RemString, NULL, 0);
124 
125  Status = RtlUnicodeStringPrintfEx(&UsString, &RemString, STRSAFE_FILL_BEHIND | 0xAA, FormatStringInts, 1, 2, 3);
126  EqualBytes = RtlCompareMemory(UsString.Buffer, FormatStringIntsResult, sizeof(FormatStringIntsResult) - sizeof(WCHAR));
128  ok_eq_size(EqualBytes, sizeof(FormatStringIntsResult) - sizeof(WCHAR));
129  ok_eq_uint(UsString.Length, sizeof(FormatStringIntsResult) - sizeof(WCHAR));
131 
132  ok_eq_pointer(RemString.Buffer, &UsString.Buffer[UsString.Length / sizeof(WCHAR)]);
133  ok_eq_uint(RemString.Length, 0);
134  ok_eq_uint(RemString.MaximumLength, UsString.MaximumLength - UsString.Length);
135 
136  EqualBytes = RtlCompareMemory(RemString.Buffer, FillResult, RemString.MaximumLength);
137  ok_eq_size(EqualBytes, sizeof(FillResult));
138 
140  pBuffer = NULL;
141 
142 
143  /* STATUS_BUFFER_OVERFLOW test */
144  BufferSize = 8 * sizeof(WCHAR);
146  if (!pBuffer)
147  goto Cleanup;
148 
149  RtlInitEmptyUnicodeString(&UsString, pBuffer, BufferSize);
150  RtlInitEmptyUnicodeString(&RemString, NULL, 0);
151 
152  Status = RtlUnicodeStringPrintfEx(&UsString, &RemString, 0, FormatStringStrs, L"AAA", L"BBB", L"CCC");
153  EqualBytes = RtlCompareMemory(UsString.Buffer, L"AAA BBB ", UsString.Length);
155  ok_eq_size(EqualBytes, UsString.Length);
156  ok_eq_uint(UsString.Length, UsString.MaximumLength);
157 
158  ok_eq_pointer(RemString.Buffer, &UsString.Buffer[UsString.Length / sizeof(WCHAR)]);
159  ok_eq_uint(RemString.Length, 0);
160  ok_eq_uint(RemString.MaximumLength, 0);
161 
163  pBuffer = NULL;
164 
165 
166  // Note: RtlUnicodeStringPrintf returns STATUS_BUFFER_OVERFLOW here while RtlUnicodeStringPrintfEx returns STATUS_INVALID_PARAMETER!
167  // Documented on MSDN and verified with the Win10 version of ntstrsafe.h
168  RtlInitEmptyUnicodeString(&UsString, NULL, 0);
169  Status = RtlUnicodeStringPrintfEx(&UsString, NULL, 0, FormatStringStrs, L"AAA", L"BBB", L"CCC");
171 
172 
173 Cleanup:
174  if (pBuffer)
176 
177  // None of these functions should have crashed.
179 }
180 
181 START_TEST(RtlStrSafe)
182 {
185 }
static const WCHAR FormatStringStrs[]
Definition: RtlStrSafe.c:19
BOOLEAN BOOLEAN VOID VOID BOOLEAN BOOLEAN PVOID KmtAllocateGuarded(SIZE_T SizeRequested)
#define STRSAFE_FILL_BEHIND
Definition: ntstrsafe.h:48
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define ok_eq_size(value, expected)
Definition: kmt_test.h:247
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:54
#define ok_eq_pointer(value, expected)
LONG NTSTATUS
Definition: precomp.h:26
#define KmtEndSeh(ExpectedStatus)
Definition: kmt_test.h:283
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
PVOID pBuffer
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const WCHAR FormatStringIntsResult[]
Definition: RtlStrSafe.c:18
NTSTATUS RtlUnicodeStringPrintf(PUNICODE_STRING DestinationString, const WCHAR *pszFormat,...)
#define BufferSize
Definition: classpnp.h:419
TESTAPI Test_RtlUnicodeStringPrintf()
Definition: RtlStrSafe.c:23
static const WCHAR L[]
Definition: oid.c:1250
static const WCHAR Cleanup[]
Definition: register.c:80
#define KmtStartSeh()
Definition: kmt_test.h:277
Status
Definition: gdiplustypes.h:24
NTSTRSAFEVAPI RtlUnicodeStringPrintfEx(_In_opt_ PUNICODE_STRING DestinationString, _In_opt_ PUNICODE_STRING RemainingString, _In_ STRSAFE_DWORD dwFlags, _In_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:3280
START_TEST(RtlStrSafe)
Definition: RtlStrSafe.c:181
static const WCHAR FormatStringInts[]
Definition: RtlStrSafe.c:17
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
TESTAPI Test_RtlUnicodeStringPrintfEx()
Definition: RtlStrSafe.c:102
unsigned short USHORT
Definition: pedump.c:61
VOID KmtFreeGuarded(PVOID Pointer)
#define ok_eq_hex(value, expected)
#define ok_eq_uint(value, expected)
Definition: kmt_test.h:239
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
#define TESTAPI
Definition: RtlStrSafe.c:15
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465