ReactOS 0.4.17-dev-116-ga4b6fe9
rtlstr.c
Go to the documentation of this file.
1/* Unit test suite for Rtl string functions
2 *
3 * Copyright 2002 Robert Shearman
4 * Copyright 2003 Thomas Mertes
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 *
20 * NOTES
21 * We use function pointers here as there is no import library for NTDLL on
22 * windows.
23 */
24
25#include <stdlib.h>
26#include <stdarg.h>
27
28#define INITGUID
29
30#include "ntstatus.h"
31#define WIN32_NO_STATUS
32#include "windef.h"
33#include "winbase.h"
34#include "winternl.h"
35#include "winnls.h"
36#include "guiddef.h"
37#include "wine/test.h"
38
39/* Function ptrs for ntdll calls */
40static HMODULE hntdll = 0;
41static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING, PCANSI_STRING, BOOLEAN);
42static NTSTATUS (WINAPI *pRtlAppendAsciizToString)(STRING *, LPCSTR);
43static NTSTATUS (WINAPI *pRtlAppendStringToString)(STRING *, const STRING *);
44static NTSTATUS (WINAPI *pRtlAppendUnicodeStringToString)(UNICODE_STRING *, const UNICODE_STRING *);
45static NTSTATUS (WINAPI *pRtlAppendUnicodeToString)(UNICODE_STRING *, LPCWSTR);
46static NTSTATUS (WINAPI *pRtlCharToInteger)(PCSZ, ULONG, int *);
47static LONG (WINAPI *pRtlCompareUnicodeString)(const UNICODE_STRING*, const UNICODE_STRING*, BOOLEAN);
48static LONG (WINAPI *pRtlCompareUnicodeStrings)(const WCHAR *,SIZE_T,const WCHAR *,SIZE_T,BOOLEAN);
49static VOID (WINAPI *pRtlCopyString)(STRING *, const STRING *);
50static BOOLEAN (WINAPI *pRtlCreateUnicodeString)(PUNICODE_STRING, LPCWSTR);
51static BOOLEAN (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
52static NTSTATUS (WINAPI *pRtlDowncaseUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
53static NTSTATUS (WINAPI *pRtlDuplicateUnicodeString)(int, UNICODE_STRING *, UNICODE_STRING *);
54static BOOLEAN (WINAPI *pRtlEqualUnicodeString)(const UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
55static NTSTATUS (WINAPI *pRtlFindCharInUnicodeString)(int, const UNICODE_STRING *, const UNICODE_STRING *, USHORT *);
56static VOID (WINAPI *pRtlFreeAnsiString)(PSTRING);
57static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
58static VOID (WINAPI *pRtlInitAnsiString)(PSTRING, LPCSTR);
59static VOID (WINAPI *pRtlInitString)(PSTRING, LPCSTR);
60static VOID (WINAPI *pRtlInitUnicodeString)(PUNICODE_STRING, LPCWSTR);
61static NTSTATUS (WINAPI *pRtlInitUnicodeStringEx)(PUNICODE_STRING, LPCWSTR);
62static NTSTATUS (WINAPI *pRtlIntegerToChar)(ULONG, ULONG, ULONG, PCHAR);
63static NTSTATUS (WINAPI *pRtlIntegerToUnicodeString)(ULONG, ULONG, UNICODE_STRING *);
64static NTSTATUS (WINAPI *pRtlMultiAppendUnicodeStringBuffer)(UNICODE_STRING *, LONG, UNICODE_STRING *);
65static NTSTATUS (WINAPI *pRtlUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN);
66static NTSTATUS (WINAPI *pRtlUnicodeStringToInteger)(const UNICODE_STRING *, int, int *);
67static WCHAR (WINAPI *pRtlUpcaseUnicodeChar)(WCHAR);
68static NTSTATUS (WINAPI *pRtlUpcaseUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
69static CHAR (WINAPI *pRtlUpperChar)(CHAR);
70static NTSTATUS (WINAPI *pRtlUpperString)(STRING *, const STRING *);
71static NTSTATUS (WINAPI *pRtlValidateUnicodeString)(LONG, UNICODE_STRING *);
72static NTSTATUS (WINAPI *pRtlGUIDFromString)(const UNICODE_STRING*,GUID*);
73static NTSTATUS (WINAPI *pRtlStringFromGUID)(const GUID*, UNICODE_STRING*);
74static BOOLEAN (WINAPI *pRtlIsTextUnicode)(LPVOID, INT, INT *);
75static NTSTATUS (WINAPI *pRtlHashUnicodeString)(PCUNICODE_STRING,BOOLEAN,ULONG,ULONG*);
76static NTSTATUS (WINAPI *pRtlUnicodeToUTF8N)(CHAR *, ULONG, ULONG *, const WCHAR *, ULONG);
77static NTSTATUS (WINAPI *pRtlUTF8ToUnicodeN)(WCHAR *, ULONG, ULONG *, const CHAR *, ULONG);
78static NTSTATUS (WINAPI *pRtlFormatMessage)(const WCHAR*,ULONG,BOOLEAN,BOOLEAN,BOOLEAN,va_list*,LPWSTR,ULONG,ULONG*);
79
80/*static VOID (WINAPI *pRtlFreeOemString)(PSTRING);*/
81/*static VOID (WINAPI *pRtlCopyUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *);*/
82/*static VOID (WINAPI *pRtlEraseUnicodeString)(UNICODE_STRING *);*/
83/*static LONG (WINAPI *pRtlCompareString)(const STRING *,const STRING *,BOOLEAN);*/
84/*static BOOLEAN (WINAPI *pRtlEqualString)(const STRING *,const STRING *,BOOLEAN);*/
85/*static BOOLEAN (WINAPI *pRtlPrefixString)(const STRING *, const STRING *, BOOLEAN);*/
86/*static BOOLEAN (WINAPI *pRtlPrefixUnicodeString)(const UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);*/
87/*static NTSTATUS (WINAPI *pRtlOemStringToUnicodeString)(PUNICODE_STRING, const STRING *, BOOLEAN);*/
88/*static NTSTATUS (WINAPI *pRtlUnicodeStringToOemString)(STRING *, const UNICODE_STRING *, BOOLEAN);*/
89/*static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)(LPWSTR, DWORD, LPDWORD, LPCSTR, DWORD);*/
90/*static NTSTATUS (WINAPI *pRtlOemToUnicodeN)(LPWSTR, DWORD, LPDWORD, LPCSTR, DWORD);*/
91/*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN);*/
92/*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeStringToOemString)(STRING *, const UNICODE_STRING *, BOOLEAN);*/
93/*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeToMultiByteN)(LPSTR, DWORD, LPDWORD, LPCWSTR, DWORD);*/
94/*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeToOemN)(LPSTR, DWORD, LPDWORD, LPCWSTR, DWORD);*/
95/*static UINT (WINAPI *pRtlOemToUnicodeSize)(const STRING *);*/
96/*static DWORD (WINAPI *pRtlAnsiStringToUnicodeSize)(const STRING *);*/
97
98
99static WCHAR* AtoW( const char* p )
100{
101 WCHAR* buffer;
102 DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
103 buffer = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR) );
105 return buffer;
106}
107
108
109static void InitFunctionPtrs(void)
110{
111 hntdll = LoadLibraryA("ntdll.dll");
112 ok(hntdll != 0, "LoadLibrary failed\n");
113 if (hntdll) {
114 pRtlAnsiStringToUnicodeString = (void *)GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString");
115 pRtlAppendAsciizToString = (void *)GetProcAddress(hntdll, "RtlAppendAsciizToString");
116 pRtlAppendStringToString = (void *)GetProcAddress(hntdll, "RtlAppendStringToString");
117 pRtlAppendUnicodeStringToString = (void *)GetProcAddress(hntdll, "RtlAppendUnicodeStringToString");
118 pRtlAppendUnicodeToString = (void *)GetProcAddress(hntdll, "RtlAppendUnicodeToString");
119 pRtlCharToInteger = (void *)GetProcAddress(hntdll, "RtlCharToInteger");
120 pRtlCompareUnicodeString = (void *)GetProcAddress(hntdll, "RtlCompareUnicodeString");
121 pRtlCompareUnicodeStrings = (void *)GetProcAddress(hntdll, "RtlCompareUnicodeStrings");
122 pRtlCopyString = (void *)GetProcAddress(hntdll, "RtlCopyString");
123 pRtlCreateUnicodeString = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeString");
124 pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
125 pRtlDowncaseUnicodeString = (void *)GetProcAddress(hntdll, "RtlDowncaseUnicodeString");
126 pRtlDuplicateUnicodeString = (void *)GetProcAddress(hntdll, "RtlDuplicateUnicodeString");
127 pRtlEqualUnicodeString = (void *)GetProcAddress(hntdll, "RtlEqualUnicodeString");
128 pRtlFindCharInUnicodeString = (void *)GetProcAddress(hntdll, "RtlFindCharInUnicodeString");
129 pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString");
130 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
131 pRtlInitAnsiString = (void *)GetProcAddress(hntdll, "RtlInitAnsiString");
132 pRtlInitString = (void *)GetProcAddress(hntdll, "RtlInitString");
133 pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
134 pRtlInitUnicodeStringEx = (void *)GetProcAddress(hntdll, "RtlInitUnicodeStringEx");
135 pRtlIntegerToChar = (void *)GetProcAddress(hntdll, "RtlIntegerToChar");
136 pRtlIntegerToUnicodeString = (void *)GetProcAddress(hntdll, "RtlIntegerToUnicodeString");
137 pRtlMultiAppendUnicodeStringBuffer = (void *)GetProcAddress(hntdll, "RtlMultiAppendUnicodeStringBuffer");
138 pRtlUnicodeStringToAnsiString = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToAnsiString");
139 pRtlUnicodeStringToInteger = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToInteger");
140 pRtlUpcaseUnicodeChar = (void *)GetProcAddress(hntdll, "RtlUpcaseUnicodeChar");
141 pRtlUpcaseUnicodeString = (void *)GetProcAddress(hntdll, "RtlUpcaseUnicodeString");
142 pRtlUpperChar = (void *)GetProcAddress(hntdll, "RtlUpperChar");
143 pRtlUpperString = (void *)GetProcAddress(hntdll, "RtlUpperString");
144 pRtlValidateUnicodeString = (void *)GetProcAddress(hntdll, "RtlValidateUnicodeString");
145 pRtlGUIDFromString = (void *)GetProcAddress(hntdll, "RtlGUIDFromString");
146 pRtlStringFromGUID = (void *)GetProcAddress(hntdll, "RtlStringFromGUID");
147 pRtlIsTextUnicode = (void *)GetProcAddress(hntdll, "RtlIsTextUnicode");
148 pRtlHashUnicodeString = (void*)GetProcAddress(hntdll, "RtlHashUnicodeString");
149 pRtlUnicodeToUTF8N = (void*)GetProcAddress(hntdll, "RtlUnicodeToUTF8N");
150 pRtlUTF8ToUnicodeN = (void*)GetProcAddress(hntdll, "RtlUTF8ToUnicodeN");
151 pRtlFormatMessage = (void*)GetProcAddress(hntdll, "RtlFormatMessage");
152 }
153}
154
155static void test_RtlInitString(void)
156{
157 static const char teststring[] = "Some Wild String";
158 STRING str;
159
160 str.Length = 0;
161 str.MaximumLength = 0;
162 str.Buffer = (void *)0xdeadbeef;
163 pRtlInitString(&str, teststring);
164 ok(str.Length == sizeof(teststring) - sizeof(char), "Length uninitialized\n");
165 ok(str.MaximumLength == sizeof(teststring), "MaximumLength uninitialized\n");
166 ok(str.Buffer == teststring, "Buffer not equal to teststring\n");
167 ok(strcmp(str.Buffer, "Some Wild String") == 0, "Buffer written to\n");
168 pRtlInitString(&str, NULL);
169 ok(str.Length == 0, "Length uninitialized\n");
170 ok(str.MaximumLength == 0, "MaximumLength uninitialized\n");
171 ok(str.Buffer == NULL, "Buffer not equal to NULL\n");
172/* pRtlInitString(NULL, teststring); */
173}
174
175
177{
178#define STRINGW {'S','o','m','e',' ','W','i','l','d',' ','S','t','r','i','n','g',0}
179 static const WCHAR teststring[] = STRINGW;
180 static const WCHAR originalstring[] = STRINGW;
181#undef STRINGW
182 UNICODE_STRING uni;
183
184 uni.Length = 0;
185 uni.MaximumLength = 0;
186 uni.Buffer = (void *)0xdeadbeef;
187 pRtlInitUnicodeString(&uni, teststring);
188 ok(uni.Length == sizeof(teststring) - sizeof(WCHAR), "Length uninitialized\n");
189 ok(uni.MaximumLength == sizeof(teststring), "MaximumLength uninitialized\n");
190 ok(uni.Buffer == teststring, "Buffer not equal to teststring\n");
191 ok(lstrcmpW(uni.Buffer, originalstring) == 0, "Buffer written to\n");
192 pRtlInitUnicodeString(&uni, NULL);
193 ok(uni.Length == 0, "Length uninitialized\n");
194 ok(uni.MaximumLength == 0, "MaximumLength uninitialized\n");
195 ok(uni.Buffer == NULL, "Buffer not equal to NULL\n");
196/* pRtlInitUnicodeString(NULL, teststring); */
197}
198
199
200#define TESTSTRING2_LEN 1000000
201/* #define TESTSTRING2_LEN 32766 */
202
203
205{
206 static const WCHAR teststring[] = {'S','o','m','e',' ','W','i','l','d',' ','S','t','r','i','n','g',0};
207 WCHAR *teststring2;
208 UNICODE_STRING uni;
210
211 if (!pRtlInitUnicodeStringEx)
212 {
213 win_skip("RtlInitUnicodeStringEx is not available\n");
214 return;
215 }
216
217 teststring2 = HeapAlloc(GetProcessHeap(), 0, (TESTSTRING2_LEN + 1) * sizeof(WCHAR));
218 memset(teststring2, 'X', TESTSTRING2_LEN * sizeof(WCHAR));
219 teststring2[TESTSTRING2_LEN] = '\0';
220
221 uni.Length = 12345;
222 uni.MaximumLength = 12345;
223 uni.Buffer = (void *) 0xdeadbeef;
224 result = pRtlInitUnicodeStringEx(&uni, teststring);
226 "pRtlInitUnicodeStringEx(&uni, 0) returns %lx, expected 0\n",
227 result);
228 ok(uni.Length == 32,
229 "pRtlInitUnicodeStringEx(&uni, 0) sets Length to %u, expected %u\n",
230 uni.Length, 32);
231 ok(uni.MaximumLength == 34,
232 "pRtlInitUnicodeStringEx(&uni, 0) sets MaximumLength to %u, expected %u\n",
233 uni.MaximumLength, 34);
234 ok(uni.Buffer == teststring,
235 "pRtlInitUnicodeStringEx(&uni, 0) sets Buffer to %p, expected %p\n",
236 uni.Buffer, teststring);
237
238 uni.Length = 12345;
239 uni.MaximumLength = 12345;
240 uni.Buffer = (void *) 0xdeadbeef;
241 pRtlInitUnicodeString(&uni, teststring);
242 ok(uni.Length == 32,
243 "pRtlInitUnicodeString(&uni, 0) sets Length to %u, expected %u\n",
244 uni.Length, 32);
245 ok(uni.MaximumLength == 34,
246 "pRtlInitUnicodeString(&uni, 0) sets MaximumLength to %u, expected %u\n",
247 uni.MaximumLength, 34);
248 ok(uni.Buffer == teststring,
249 "pRtlInitUnicodeString(&uni, 0) sets Buffer to %p, expected %p\n",
250 uni.Buffer, teststring);
251
252 uni.Length = 12345;
253 uni.MaximumLength = 12345;
254 uni.Buffer = (void *) 0xdeadbeef;
255 result = pRtlInitUnicodeStringEx(&uni, teststring2);
257 "pRtlInitUnicodeStringEx(&uni, 0) returns %lx, expected %lx\n",
259 ok(uni.Length == 12345 ||
260 uni.Length == 0, /* win2k3 */
261 "pRtlInitUnicodeStringEx(&uni, 0) sets Length to %u, expected 12345 or 0\n",
262 uni.Length);
263 ok(uni.MaximumLength == 12345 ||
264 uni.MaximumLength == 0, /* win2k3 */
265 "pRtlInitUnicodeStringEx(&uni, 0) sets MaximumLength to %u, expected 12345 or 0\n",
266 uni.MaximumLength);
267 ok(uni.Buffer == (void *) 0xdeadbeef ||
268 uni.Buffer == teststring2, /* win2k3 */
269 "pRtlInitUnicodeStringEx(&uni, 0) sets Buffer to %p, expected %x or %p\n",
270 uni.Buffer, 0xdeadbeef, teststring2);
271
272 uni.Length = 12345;
273 uni.MaximumLength = 12345;
274 uni.Buffer = (void *) 0xdeadbeef;
275 pRtlInitUnicodeString(&uni, teststring2);
276 ok(uni.Length == 33920 /* <= Win2000 */ || uni.Length == 65532 /* >= Win XP */,
277 "pRtlInitUnicodeString(&uni, 0) sets Length to %u, expected %u\n",
278 uni.Length, 65532);
279 ok(uni.MaximumLength == 33922 /* <= Win2000 */ || uni.MaximumLength == 65534 /* >= Win XP */,
280 "pRtlInitUnicodeString(&uni, 0) sets MaximumLength to %u, expected %u\n",
281 uni.MaximumLength, 65534);
282 ok(uni.Buffer == teststring2,
283 "pRtlInitUnicodeString(&uni, 0) sets Buffer to %p, expected %p\n",
284 uni.Buffer, teststring2);
285 ok(memcmp(uni.Buffer, teststring2, (TESTSTRING2_LEN + 1) * sizeof(WCHAR)) == 0,
286 "pRtlInitUnicodeString(&uni, 0) changes Buffer\n");
287
288 uni.Length = 12345;
289 uni.MaximumLength = 12345;
290 uni.Buffer = (void *) 0xdeadbeef;
291 result = pRtlInitUnicodeStringEx(&uni, 0);
293 "pRtlInitUnicodeStringEx(&uni, 0) returns %lx, expected 0\n",
294 result);
295 ok(uni.Length == 0,
296 "pRtlInitUnicodeStringEx(&uni, 0) sets Length to %u, expected %u\n",
297 uni.Length, 0);
298 ok(uni.MaximumLength == 0,
299 "pRtlInitUnicodeStringEx(&uni, 0) sets MaximumLength to %u, expected %u\n",
300 uni.MaximumLength, 0);
301 ok(uni.Buffer == NULL,
302 "pRtlInitUnicodeStringEx(&uni, 0) sets Buffer to %p, expected %p\n",
303 uni.Buffer, NULL);
304
305 uni.Length = 12345;
306 uni.MaximumLength = 12345;
307 uni.Buffer = (void *) 0xdeadbeef;
308 pRtlInitUnicodeString(&uni, 0);
309 ok(uni.Length == 0,
310 "pRtlInitUnicodeString(&uni, 0) sets Length to %u, expected %u\n",
311 uni.Length, 0);
312 ok(uni.MaximumLength == 0,
313 "pRtlInitUnicodeString(&uni, 0) sets MaximumLength to %u, expected %u\n",
314 uni.MaximumLength, 0);
315 ok(uni.Buffer == NULL,
316 "pRtlInitUnicodeString(&uni, 0) sets Buffer to %p, expected %p\n",
317 uni.Buffer, NULL);
318
319 HeapFree(GetProcessHeap(), 0, teststring2);
320}
321
322
323typedef struct {
328 const char *source_buf;
332 const char *dest_buf;
336 const char *res_buf;
339
340static const dupl_ustr_t dupl_ustr[] = {
341 { 0, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 32, 32, 32, "This is a string", STATUS_SUCCESS},
342 { 0, 32, 32, 32, "This is a string", 40, 42, 42, "--------------------", 32, 32, 32, "This is a string", STATUS_SUCCESS},
343 { 0, 32, 30, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
344 { 0, 32, 34, 34, "This is a string", 40, 42, 42, NULL, 32, 32, 32, "This is a string", STATUS_SUCCESS},
345 { 0, 32, 32, 32, "This is a string", 40, 42, 42, NULL, 32, 32, 32, "This is a string", STATUS_SUCCESS},
346 { 0, 32, 30, 34, "This is a string", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
347 { 1, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 32, 34, 34, "This is a string", STATUS_SUCCESS},
348 { 1, 32, 32, 32, "This is a string", 40, 42, 42, "--------------------", 32, 34, 34, "This is a string", STATUS_SUCCESS},
349 { 1, 32, 30, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
350 { 1, 32, 34, 34, "This is a string", 40, 42, 42, NULL, 32, 34, 34, "This is a string", STATUS_SUCCESS},
351 { 1, 32, 32, 32, "This is a string", 40, 42, 42, NULL, 32, 34, 34, "This is a string", STATUS_SUCCESS},
352 { 1, 32, 30, 34, "This is a string", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
353 { 2, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
354 { 2, 32, 32, 32, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
355 { 2, 32, 30, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
356 { 2, 32, 34, 34, "This is a string", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
357 { 2, 32, 32, 32, "This is a string", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
358 { 2, 32, 30, 34, "This is a string", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
359 { 3, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 32, 34, 34, "This is a string", STATUS_SUCCESS},
360 { 3, 32, 32, 32, "This is a string", 40, 42, 42, "--------------------", 32, 34, 34, "This is a string", STATUS_SUCCESS},
361 { 3, 32, 30, 32, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
362 { 3, 32, 34, 34, "This is a string", 40, 42, 42, NULL, 32, 34, 34, "This is a string", STATUS_SUCCESS},
363 { 3, 32, 32, 32, "This is a string", 40, 42, 42, NULL, 32, 34, 34, "This is a string", STATUS_SUCCESS},
364 { 3, 32, 30, 32, "This is a string", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
365 { 4, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
366 { 5, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
367 { 6, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
368 { 7, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
369 { 8, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
370 { 9, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
371 {10, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
372 {11, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
373 {12, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
374 {13, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
375 {14, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
376 {15, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
377 {16, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
378 {-1, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
379 {-5, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
380 {-9, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
381 { 0, 0, 2, 2, "", 40, 42, 42, "--------------------", 0, 0, 0, NULL, STATUS_SUCCESS},
382 { 0, 0, 0, 0, "", 40, 42, 42, "--------------------", 0, 0, 0, NULL, STATUS_SUCCESS},
383 { 0, 0, 2, 2, "", 40, 42, 42, NULL, 0, 0, 0, NULL, STATUS_SUCCESS},
384 { 0, 0, 0, 0, "", 40, 42, 42, NULL, 0, 0, 0, NULL, STATUS_SUCCESS},
385 { 0, 0, 2, 2, NULL, 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
386 { 0, 0, 0, 0, NULL, 40, 42, 42, "--------------------", 0, 0, 0, NULL, STATUS_SUCCESS},
387 { 0, 0, 2, 2, NULL, 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
388 { 0, 0, 0, 0, NULL, 40, 42, 42, NULL, 0, 0, 0, NULL, STATUS_SUCCESS},
389 { 1, 0, 2, 2, "", 40, 42, 42, "--------------------", 0, 0, 0, NULL, STATUS_SUCCESS},
390 { 1, 0, 0, 0, "", 40, 42, 42, "--------------------", 0, 0, 0, NULL, STATUS_SUCCESS},
391 { 1, 0, 2, 2, "", 40, 42, 42, NULL, 0, 0, 0, NULL, STATUS_SUCCESS},
392 { 1, 0, 0, 0, "", 40, 42, 42, NULL, 0, 0, 0, NULL, STATUS_SUCCESS},
393 { 1, 0, 2, 2, NULL, 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
394 { 1, 0, 0, 0, NULL, 40, 42, 42, "--------------------", 0, 0, 0, NULL, STATUS_SUCCESS},
395 { 1, 0, 2, 2, NULL, 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
396 { 1, 0, 0, 0, NULL, 40, 42, 42, NULL, 0, 0, 0, NULL, STATUS_SUCCESS},
397 { 2, 0, 2, 2, "", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
398 { 2, 0, 0, 0, "", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
399 { 2, 0, 2, 2, "", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
400 { 2, 0, 0, 0, "", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
401 { 2, 0, 2, 2, NULL, 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
402 { 2, 0, 0, 0, NULL, 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
403 { 2, 0, 2, 2, NULL, 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
404 { 2, 0, 0, 0, NULL, 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
405 { 3, 0, 2, 2, "", 40, 42, 42, "--------------------", 0, 2, 2, "", STATUS_SUCCESS},
406 { 3, 0, 0, 0, "", 40, 42, 42, "--------------------", 0, 2, 2, "", STATUS_SUCCESS},
407 { 3, 0, 2, 2, "", 40, 42, 42, NULL, 0, 2, 2, "", STATUS_SUCCESS},
408 { 3, 0, 0, 0, "", 40, 42, 42, NULL, 0, 2, 2, "", STATUS_SUCCESS},
409 { 3, 0, 2, 2, NULL, 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
410 { 3, 0, 0, 0, NULL, 40, 42, 42, "--------------------", 0, 2, 2, "", STATUS_SUCCESS},
411 { 3, 0, 2, 2, NULL, 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
412 { 3, 0, 0, 0, NULL, 40, 42, 42, NULL, 0, 2, 2, "", STATUS_SUCCESS},
413};
414
415
417{
418 size_t pos;
419 WCHAR source_buf[257];
420 WCHAR dest_buf[257];
421 WCHAR res_buf[257];
422 UNICODE_STRING source_str;
423 UNICODE_STRING dest_str;
424 UNICODE_STRING res_str;
425 CHAR dest_ansi_buf[257];
426 STRING dest_ansi_str;
428 unsigned int test_num;
429
430 if (!pRtlDuplicateUnicodeString)
431 {
432 win_skip("RtlDuplicateUnicodeString is not available\n");
433 return;
434 }
435
436 for (test_num = 0; test_num < ARRAY_SIZE(dupl_ustr); test_num++) {
437 source_str.Length = dupl_ustr[test_num].source_Length;
438 source_str.MaximumLength = dupl_ustr[test_num].source_MaximumLength;
439 if (dupl_ustr[test_num].source_buf != NULL) {
440 for (pos = 0; pos < dupl_ustr[test_num].source_buf_size/sizeof(WCHAR); pos++) {
441 source_buf[pos] = dupl_ustr[test_num].source_buf[pos];
442 }
443 source_str.Buffer = source_buf;
444 } else {
445 source_str.Buffer = NULL;
446 }
447 dest_str.Length = dupl_ustr[test_num].dest_Length;
448 dest_str.MaximumLength = dupl_ustr[test_num].dest_MaximumLength;
449 if (dupl_ustr[test_num].dest_buf != NULL) {
450 for (pos = 0; pos < dupl_ustr[test_num].dest_buf_size/sizeof(WCHAR); pos++) {
451 dest_buf[pos] = dupl_ustr[test_num].dest_buf[pos];
452 }
453 dest_str.Buffer = dest_buf;
454 } else {
455 dest_str.Buffer = NULL;
456 }
457 res_str.Length = dupl_ustr[test_num].res_Length;
458 res_str.MaximumLength = dupl_ustr[test_num].res_MaximumLength;
459 if (dupl_ustr[test_num].res_buf != NULL) {
460 for (pos = 0; pos < dupl_ustr[test_num].res_buf_size/sizeof(WCHAR); pos++) {
461 res_buf[pos] = dupl_ustr[test_num].res_buf[pos];
462 }
463 res_str.Buffer = res_buf;
464 } else {
465 res_str.Buffer = NULL;
466 }
467 result = pRtlDuplicateUnicodeString(dupl_ustr[test_num].add_nul, &source_str, &dest_str);
468 dest_ansi_str.Length = dest_str.Length / sizeof(WCHAR);
469 dest_ansi_str.MaximumLength = dest_ansi_str.Length + 1;
470 for (pos = 0; pos < dest_ansi_str.Length; pos++) {
471 dest_ansi_buf[pos] = (char)dest_buf[pos];
472 }
473 dest_ansi_buf[dest_ansi_str.Length] = '\0';
474 dest_ansi_str.Buffer = dest_ansi_buf;
475 ok(result == dupl_ustr[test_num].result,
476 "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has result %lx, expected %lx\n",
477 test_num, dupl_ustr[test_num].add_nul, result, dupl_ustr[test_num].result);
478 ok(dest_str.Length == dupl_ustr[test_num].res_Length,
479 "(test %d): RtlDuplicateUnicodeString(%d, source, dest) destination has Length %d, expected %d\n",
480 test_num, dupl_ustr[test_num].add_nul, dest_str.Length, dupl_ustr[test_num].res_Length);
481 ok(dest_str.MaximumLength == dupl_ustr[test_num].res_MaximumLength,
482 "(test %d): RtlDuplicateUnicodeString(%d, source, dest) destination has MaximumLength %d, expected %d\n",
483 test_num, dupl_ustr[test_num].add_nul, dest_str.MaximumLength, dupl_ustr[test_num].res_MaximumLength);
485 ok((dest_str.Buffer == NULL && res_str.Buffer == NULL) ||
486 dest_str.Buffer == dest_buf,
487 "(test %d): RtlDuplicateUnicodeString(%d, source, dest) destination buffer changed %p expected %p\n",
488 test_num, dupl_ustr[test_num].add_nul, dest_str.Buffer, dest_buf);
489 } else {
490 ok(dest_str.Buffer != dest_buf,
491 "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination buffer unchanged %p\n",
492 test_num, dupl_ustr[test_num].add_nul, dest_str.Buffer);
493 }
494 if (dest_str.Buffer != NULL && dupl_ustr[test_num].res_buf != NULL) {
495 ok(memcmp(dest_str.Buffer, res_str.Buffer, dupl_ustr[test_num].res_buf_size) == 0,
496 "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination \"%s\" expected \"%s\"\n",
497 test_num, dupl_ustr[test_num].add_nul, dest_ansi_str.Buffer, dupl_ustr[test_num].res_buf);
498 if(result == STATUS_SUCCESS) pRtlFreeUnicodeString(&dest_str);
499 } else {
500 ok(dest_str.Buffer == NULL && dupl_ustr[test_num].res_buf == NULL,
501 "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination %p expected %p\n",
502 test_num, dupl_ustr[test_num].add_nul, dest_str.Buffer, dupl_ustr[test_num].res_buf);
503 }
504 }
505}
506
507
508static void test_RtlCopyString(void)
509{
510 static const char teststring[] = "Some Wild String";
511 char deststring[] = " ";
512 STRING str;
513 STRING deststr;
514
515 pRtlInitString(&str, teststring);
516 pRtlInitString(&deststr, deststring);
517 pRtlCopyString(&deststr, &str);
518 ok(strncmp(str.Buffer, deststring, str.Length) == 0, "String not copied\n");
519}
520
521
522static void test_RtlUpperChar(void)
523{
524 int ch;
525 int upper_ch;
526 int expected_upper_ch;
527 int byte_ch;
528
529 for (ch = -1; ch <= 1024; ch++) {
530 upper_ch = pRtlUpperChar(ch);
531 byte_ch = ch & 0xff;
532 if (byte_ch >= 'a' && byte_ch <= 'z') {
533 expected_upper_ch = (CHAR) (byte_ch - 'a' + 'A');
534 } else {
535 expected_upper_ch = (CHAR) byte_ch;
536 }
537 ok(upper_ch == expected_upper_ch,
538 "RtlUpperChar('%c'[=0x%x]) has result '%c'[=0x%x], expected '%c'[=0x%x]\n",
539 ch, ch, upper_ch, upper_ch, expected_upper_ch, expected_upper_ch);
540 }
541}
542
543
544static void test_RtlUpperString(void)
545{
546 int i;
547 CHAR ch;
548 CHAR upper_ch;
549 char ascii_buf[257];
550 char result_buf[257];
551 char upper_buf[257];
552 STRING ascii_str;
553 STRING result_str;
554 STRING upper_str;
555
556 for (i = 0; i <= 255; i++) {
557 ch = (CHAR) i;
558 if (ch >= 'a' && ch <= 'z') {
559 upper_ch = ch - 'a' + 'A';
560 } else {
561 upper_ch = ch;
562 }
563 ascii_buf[i] = ch;
564 result_buf[i] = '\0';
565 upper_buf[i] = upper_ch;
566 }
567 ascii_buf[i] = '\0';
568 result_buf[i] = '\0';
569 upper_buf[i] = '\0';
570 ascii_str.Length = 256;
571 ascii_str.MaximumLength = 256;
572 ascii_str.Buffer = ascii_buf;
573 result_str.Length = 256;
574 result_str.MaximumLength = 256;
575 result_str.Buffer = result_buf;
576 upper_str.Length = 256;
577 upper_str.MaximumLength = 256;
578 upper_str.Buffer = upper_buf;
579
580 pRtlUpperString(&result_str, &ascii_str);
581 ok(memcmp(result_str.Buffer, upper_str.Buffer, 256) == 0,
582 "RtlUpperString does not work as expected\n");
583}
584
585
587{
588 int i;
589 WCHAR ch;
590 WCHAR upper_ch;
591 WCHAR expected_upper_ch;
592
593 for (i = 0; i <= 255; i++) {
594 ch = (WCHAR) i;
595 upper_ch = pRtlUpcaseUnicodeChar(ch);
596 if (ch >= 'a' && ch <= 'z') {
597 expected_upper_ch = ch - 'a' + 'A';
598 } else if (ch >= 0xe0 && ch <= 0xfe && ch != 0xf7) {
599 expected_upper_ch = ch - 0x20;
600 } else if (ch == 0xff) {
601 expected_upper_ch = 0x178;
602 } else {
603 expected_upper_ch = ch;
604 }
605 ok(upper_ch == expected_upper_ch,
606 "RtlUpcaseUnicodeChar('%c'[=0x%x]) has result '%c'[=0x%x], expected: '%c'[=0x%x]\n",
607 ch, ch, upper_ch, upper_ch, expected_upper_ch, expected_upper_ch);
608 }
609}
610
611
613{
614 int i, j;
615 WCHAR ch;
616 WCHAR upper_ch;
617 WCHAR ascii_buf[257];
618 WCHAR result_buf[257];
619 WCHAR upper_buf[257];
620 UNICODE_STRING ascii_str;
621 UNICODE_STRING result_str;
622 UNICODE_STRING upper_str;
623
624 for (i = 0; i <= 255; i++) {
625 ch = (WCHAR) i;
626 if (ch >= 'a' && ch <= 'z') {
627 upper_ch = ch - 'a' + 'A';
628 } else if (ch >= 0xe0 && ch <= 0xfe && ch != 0xf7) {
629 upper_ch = ch - 0x20;
630 } else if (ch == 0xff) {
631 upper_ch = 0x178;
632 } else {
633 upper_ch = ch;
634 }
635 ascii_buf[i] = ch;
636 result_buf[i] = '\0';
637 upper_buf[i] = upper_ch;
638 }
639 ascii_buf[i] = '\0';
640 result_buf[i] = '\0';
641 upper_buf[i] = '\0';
642 ascii_str.Length = 512;
643 ascii_str.MaximumLength = 512;
644 ascii_str.Buffer = ascii_buf;
645 result_str.Length = 512;
646 result_str.MaximumLength = 512;
647 result_str.Buffer = result_buf;
648 upper_str.Length = 512;
649 upper_str.MaximumLength = 512;
650 upper_str.Buffer = upper_buf;
651
652 pRtlUpcaseUnicodeString(&result_str, &ascii_str, 0);
653 for (i = 0; i <= 255; i++) {
654 ok(result_str.Buffer[i] == upper_str.Buffer[i],
655 "RtlUpcaseUnicodeString works wrong: '%c'[=0x%x] is converted to '%c'[=0x%x], expected: '%c'[=0x%x]\n",
656 ascii_str.Buffer[i], ascii_str.Buffer[i],
657 result_str.Buffer[i], result_str.Buffer[i],
658 upper_str.Buffer[i], upper_str.Buffer[i]);
659 }
660
661 /* test surrogates */
662 for (i = 0x100; i < 0x1100; i++)
663 {
664 WCHAR src[512], dst[512];
665 for (j = 0; j < 256; j++)
666 {
667 unsigned int ch = ((i << 8) + j) - 0x10000;
668 src[2 * j] = 0xd800 | (ch >> 10);
669 src[2 * j + 1] = 0xdc00 | (ch & 0x3ff);
670 }
671 upper_str.Length = upper_str.MaximumLength = 512 * sizeof(WCHAR);
672 upper_str.Buffer = src;
673 result_str.Length = result_str.MaximumLength = 512 * sizeof(WCHAR);
674 result_str.Buffer = dst;
675 pRtlUpcaseUnicodeString(&result_str, &upper_str, 0);
676 ok( !memcmp(src, dst, sizeof(dst)),
677 "string compare mismatch in %04x-%04x\n", i << 8, (i << 8) + 255 );
678 }
679}
680
681
683{
684 int i;
685 WCHAR ch;
686 WCHAR lower_ch;
687 WCHAR source_buf[1025];
688 WCHAR result_buf[1025];
689 WCHAR lower_buf[1025];
690 UNICODE_STRING source_str;
691 UNICODE_STRING result_str;
692 UNICODE_STRING lower_str;
693
694 for (i = 0; i < 1024; i++) {
695 ch = (WCHAR) i;
696 if (ch >= 'A' && ch <= 'Z') {
697 lower_ch = ch - 'A' + 'a';
698 } else if (ch >= 0xc0 && ch <= 0xde && ch != 0xd7) {
699 lower_ch = ch + 0x20;
700 } else if (ch >= 0x391 && ch <= 0x3ab && ch != 0x3a2) {
701 lower_ch = ch + 0x20;
702 } else {
703 switch (ch) {
704 case 0x178: lower_ch = 0xff; break;
705 case 0x181: lower_ch = 0x253; break;
706 case 0x186: lower_ch = 0x254; break;
707 case 0x189: lower_ch = 0x256; break;
708 case 0x18a: lower_ch = 0x257; break;
709 case 0x18e: lower_ch = 0x1dd; break;
710 case 0x18f: lower_ch = 0x259; break;
711 case 0x190: lower_ch = 0x25b; break;
712 case 0x193: lower_ch = 0x260; break;
713 case 0x194: lower_ch = 0x263; break;
714 case 0x196: lower_ch = 0x269; break;
715 case 0x197: lower_ch = 0x268; break;
716 case 0x19c: lower_ch = 0x26f; break;
717 case 0x19d: lower_ch = 0x272; break;
718 case 0x19f: lower_ch = 0x275; break;
719 case 0x1a9: lower_ch = 0x283; break;
720 case 0x1a6: lower_ch = 0x280; break;
721 case 0x1ae: lower_ch = 0x288; break;
722 case 0x1b1: lower_ch = 0x28a; break;
723 case 0x1b2: lower_ch = 0x28b; break;
724 case 0x1b7: lower_ch = 0x292; break;
725 case 0x1c4: lower_ch = 0x1c6; break;
726 case 0x1c7: lower_ch = 0x1c9; break;
727 case 0x1ca: lower_ch = 0x1cc; break;
728 case 0x1f1: lower_ch = 0x1f3; break;
729 case 0x1f6: lower_ch = 0x195; break;
730 case 0x1f7: lower_ch = 0x1bf; break;
731 case 0x220: lower_ch = 0x19e; break;
732 case 0x23a: lower_ch = 0x2c65; break;
733 case 0x23d: lower_ch = 0x19a; break;
734 case 0x23e: lower_ch = 0x2c66; break;
735 case 0x243: lower_ch = 0x180; break;
736 case 0x244: lower_ch = 0x289; break;
737 case 0x245: lower_ch = 0x28c; break;
738 case 0x37f: lower_ch = 0x3f3; break;
739 case 0x386: lower_ch = 0x3ac; break;
740 case 0x388: lower_ch = 0x3ad; break;
741 case 0x389: lower_ch = 0x3ae; break;
742 case 0x38a: lower_ch = 0x3af; break;
743 case 0x38c: lower_ch = 0x3cc; break;
744 case 0x38e: lower_ch = 0x3cd; break;
745 case 0x38f: lower_ch = 0x3ce; break;
746 case 0x3cf: lower_ch = 0x3d7; break;
747 case 0x3f9: lower_ch = 0x3f2; break;
748 case 0x3fd: lower_ch = 0x37b; break;
749 case 0x3fe: lower_ch = 0x37c; break;
750 case 0x3ff: lower_ch = 0x37d; break;
751 default: lower_ch = ch; break;
752 } /* switch */
753 }
754 source_buf[i] = ch;
755 result_buf[i] = '\0';
756 lower_buf[i] = lower_ch;
757 }
758 source_buf[i] = '\0';
759 result_buf[i] = '\0';
760 lower_buf[i] = '\0';
761 source_str.Length = 2048;
762 source_str.MaximumLength = 2048;
763 source_str.Buffer = source_buf;
764 result_str.Length = 2048;
765 result_str.MaximumLength = 2048;
766 result_str.Buffer = result_buf;
767 lower_str.Length = 2048;
768 lower_str.MaximumLength = 2048;
769 lower_str.Buffer = lower_buf;
770
771 pRtlDowncaseUnicodeString(&result_str, &source_str, 0);
772 for (i = 0; i <= 1024; i++) {
773 ok(result_str.Buffer[i] == lower_str.Buffer[i] || result_str.Buffer[i] == source_str.Buffer[i] + 1 ||
774 broken( result_str.Buffer[i] == source_str.Buffer[i] ),
775 "RtlDowncaseUnicodeString works wrong: '%c'[=0x%x] is converted to '%c'[=0x%x], expected: '%c'[=0x%x]\n",
776 source_str.Buffer[i], source_str.Buffer[i],
777 result_str.Buffer[i], result_str.Buffer[i],
778 lower_str.Buffer[i], lower_str.Buffer[i]);
779 }
780}
781
782
783typedef struct {
787 const char *ansi_buf;
791 const char *uni_buf;
796 const char *res_buf;
800
801static const ustr2astr_t ustr2astr[] = {
802 { 10, 12, 12, "------------", 0, 0, 0, "", TRUE, 0, 1, 1, "", STATUS_SUCCESS},
803 { 10, 12, 12, "------------", 12, 12, 12, "abcdef", TRUE, 6, 7, 7, "abcdef", STATUS_SUCCESS},
804 { 0, 2, 12, "------------", 12, 12, 12, "abcdef", TRUE, 6, 7, 7, "abcdef", STATUS_SUCCESS},
805 { 10, 12, 12, NULL, 12, 12, 12, "abcdef", TRUE, 6, 7, 7, "abcdef", STATUS_SUCCESS},
806 { 0, 0, 12, "------------", 12, 12, 12, "abcdef", FALSE, 6, 0, 0, "", STATUS_BUFFER_OVERFLOW, 1},
807 { 0, 1, 12, "------------", 12, 12, 12, "abcdef", FALSE, 0, 1, 1, "", STATUS_BUFFER_OVERFLOW},
808 { 0, 2, 12, "------------", 12, 12, 12, "abcdef", FALSE, 1, 2, 2, "a", STATUS_BUFFER_OVERFLOW},
809 { 0, 3, 12, "------------", 12, 12, 12, "abcdef", FALSE, 2, 3, 3, "ab", STATUS_BUFFER_OVERFLOW},
810 { 0, 5, 12, "------------", 12, 12, 12, "abcdef", FALSE, 4, 5, 5, "abcd", STATUS_BUFFER_OVERFLOW},
811 { 8, 5, 12, "------------", 12, 12, 12, "abcdef", FALSE, 4, 5, 5, "abcd", STATUS_BUFFER_OVERFLOW},
812 { 8, 6, 12, "------------", 12, 12, 12, "abcdef", FALSE, 5, 6, 6, "abcde", STATUS_BUFFER_OVERFLOW},
813 { 8, 7, 12, "------------", 12, 12, 12, "abcdef", FALSE, 6, 7, 7, "abcdef", STATUS_SUCCESS},
814 { 8, 7, 12, "------------", 0, 12, 12, NULL, FALSE, 0, 7, 0, "", STATUS_SUCCESS},
815#if 0
816 /* crashes on Japanese and Chinese XP */
817 { 0, 0, 12, NULL, 10, 10, 12, NULL, FALSE, 5, 0, 0, NULL, STATUS_BUFFER_OVERFLOW},
818#endif
819};
820
821
823{
824 size_t pos;
825 CHAR ansi_buf[257];
826 WCHAR uni_buf[257];
827 STRING ansi_str;
828 UNICODE_STRING uni_str;
830 unsigned int test_num;
831
832 for (test_num = 0; test_num < ARRAY_SIZE(ustr2astr); test_num++) {
833 ansi_str.Length = ustr2astr[test_num].ansi_Length;
834 ansi_str.MaximumLength = ustr2astr[test_num].ansi_MaximumLength;
835 if (ustr2astr[test_num].ansi_buf != NULL) {
836 memcpy(ansi_buf, ustr2astr[test_num].ansi_buf, ustr2astr[test_num].ansi_buf_size);
837 ansi_buf[ustr2astr[test_num].ansi_buf_size] = '\0';
838 ansi_str.Buffer = ansi_buf;
839 } else {
840 ansi_str.Buffer = NULL;
841 }
842 uni_str.Length = ustr2astr[test_num].uni_Length;
843 uni_str.MaximumLength = ustr2astr[test_num].uni_MaximumLength;
844 if (ustr2astr[test_num].uni_buf != NULL) {
845 for (pos = 0; pos < ustr2astr[test_num].uni_buf_size/sizeof(WCHAR); pos++) {
846 uni_buf[pos] = ustr2astr[test_num].uni_buf[pos];
847 }
848 uni_str.Buffer = uni_buf;
849 } else {
850 uni_str.Buffer = NULL;
851 }
852 result = pRtlUnicodeStringToAnsiString(&ansi_str, &uni_str, ustr2astr[test_num].doalloc);
853 ok(result == ustr2astr[test_num].result,
854 "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) has result %lx, expected %lx\n",
855 test_num, ustr2astr[test_num].doalloc, result, ustr2astr[test_num].result);
856 ok(ansi_str.Length == ustr2astr[test_num].res_Length ||
857 broken(ustr2astr[test_num].broken_len && !ansi_str.Length) /* win11 */,
858 "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) ansi has Length %d, expected %d\n",
859 test_num, ustr2astr[test_num].doalloc, ansi_str.Length, ustr2astr[test_num].res_Length);
860 ok(ansi_str.MaximumLength == ustr2astr[test_num].res_MaximumLength,
861 "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) ansi has MaximumLength %d, expected %d\n",
862 test_num, ustr2astr[test_num].doalloc, ansi_str.MaximumLength, ustr2astr[test_num].res_MaximumLength);
863 ok(memcmp(ansi_str.Buffer, ustr2astr[test_num].res_buf, ustr2astr[test_num].res_buf_size) == 0,
864 "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) has ansi \"%s\" expected \"%s\"\n",
865 test_num, ustr2astr[test_num].doalloc, ansi_str.Buffer, ustr2astr[test_num].res_buf);
866 if(result == STATUS_SUCCESS && ustr2astr[test_num].doalloc)
867 pRtlFreeAnsiString(&ansi_str);
868 }
869}
870
871
872typedef struct {
876 const char *dest_buf;
877 const char *src;
881 const char *res_buf;
884
885static const app_asc2str_t app_asc2str[] = {
886 { 5, 12, 15, "TestS01234abcde", "tring", 10, 12, 15, "TestStringabcde", STATUS_SUCCESS},
887 { 5, 11, 15, "TestS01234abcde", "tring", 10, 11, 15, "TestStringabcde", STATUS_SUCCESS},
888 { 5, 10, 15, "TestS01234abcde", "tring", 10, 10, 15, "TestStringabcde", STATUS_SUCCESS},
889 { 5, 9, 15, "TestS01234abcde", "tring", 5, 9, 15, "TestS01234abcde", STATUS_BUFFER_TOO_SMALL},
890 { 5, 0, 15, "TestS01234abcde", "tring", 5, 0, 15, "TestS01234abcde", STATUS_BUFFER_TOO_SMALL},
891 { 5, 14, 15, "TestS01234abcde", "tring", 10, 14, 15, "TestStringabcde", STATUS_SUCCESS},
892 { 5, 14, 15, "TestS01234abcde", NULL, 5, 14, 15, "TestS01234abcde", STATUS_SUCCESS},
893 { 5, 14, 15, NULL, NULL, 5, 14, 15, NULL, STATUS_SUCCESS},
894 { 5, 12, 15, "Tst\0S01234abcde", "tr\0i", 7, 12, 15, "Tst\0Str234abcde", STATUS_SUCCESS},
895};
896
897
899{
900 CHAR dest_buf[257];
901 STRING dest_str;
903 unsigned int test_num;
904
905 for (test_num = 0; test_num < ARRAY_SIZE(app_asc2str); test_num++) {
906 dest_str.Length = app_asc2str[test_num].dest_Length;
907 dest_str.MaximumLength = app_asc2str[test_num].dest_MaximumLength;
908 if (app_asc2str[test_num].dest_buf != NULL) {
909 memcpy(dest_buf, app_asc2str[test_num].dest_buf, app_asc2str[test_num].dest_buf_size);
910 dest_buf[app_asc2str[test_num].dest_buf_size] = '\0';
911 dest_str.Buffer = dest_buf;
912 } else {
913 dest_str.Buffer = NULL;
914 }
915 result = pRtlAppendAsciizToString(&dest_str, app_asc2str[test_num].src);
916 ok(result == app_asc2str[test_num].result,
917 "(test %d): RtlAppendAsciizToString(dest, src) has result %lx, expected %lx\n",
918 test_num, result, app_asc2str[test_num].result);
919 ok(dest_str.Length == app_asc2str[test_num].res_Length,
920 "(test %d): RtlAppendAsciizToString(dest, src) dest has Length %d, expected %d\n",
921 test_num, dest_str.Length, app_asc2str[test_num].res_Length);
922 ok(dest_str.MaximumLength == app_asc2str[test_num].res_MaximumLength,
923 "(test %d): RtlAppendAsciizToString(dest, src) dest has MaximumLength %d, expected %d\n",
924 test_num, dest_str.MaximumLength, app_asc2str[test_num].res_MaximumLength);
925 if (dest_str.Buffer == dest_buf) {
926 ok(memcmp(dest_buf, app_asc2str[test_num].res_buf, app_asc2str[test_num].res_buf_size) == 0,
927 "(test %d): RtlAppendAsciizToString(dest, src) has dest \"%s\" expected \"%s\"\n",
928 test_num, dest_buf, app_asc2str[test_num].res_buf);
929 } else {
930 ok(dest_str.Buffer == app_asc2str[test_num].res_buf,
931 "(test %d): RtlAppendAsciizToString(dest, src) dest has Buffer %p expected %p\n",
932 test_num, dest_str.Buffer, app_asc2str[test_num].res_buf);
933 }
934 }
935}
936
937
938typedef struct {
942 const char *dest_buf;
946 const char *src_buf;
950 const char *res_buf;
953
954static const app_str2str_t app_str2str[] = {
955 { 5, 12, 15, "TestS01234abcde", 5, 5, 7, "tringZY", 10, 12, 15, "TestStringabcde", STATUS_SUCCESS},
956 { 5, 11, 15, "TestS01234abcde", 5, 5, 7, "tringZY", 10, 11, 15, "TestStringabcde", STATUS_SUCCESS},
957 { 5, 10, 15, "TestS01234abcde", 5, 5, 7, "tringZY", 10, 10, 15, "TestStringabcde", STATUS_SUCCESS},
958 { 5, 9, 15, "TestS01234abcde", 5, 5, 7, "tringZY", 5, 9, 15, "TestS01234abcde", STATUS_BUFFER_TOO_SMALL},
959 { 5, 0, 15, "TestS01234abcde", 0, 0, 7, "tringZY", 5, 0, 15, "TestS01234abcde", STATUS_SUCCESS},
960 { 5, 14, 15, "TestS01234abcde", 0, 0, 7, "tringZY", 5, 14, 15, "TestS01234abcde", STATUS_SUCCESS},
961 { 5, 14, 15, "TestS01234abcde", 0, 0, 7, NULL, 5, 14, 15, "TestS01234abcde", STATUS_SUCCESS},
962 { 5, 14, 15, NULL, 0, 0, 7, NULL, 5, 14, 15, NULL, STATUS_SUCCESS},
963 { 5, 12, 15, "Tst\0S01234abcde", 4, 4, 7, "tr\0iZY", 9, 12, 15, "Tst\0Str\0i4abcde", STATUS_SUCCESS},
964};
965
966
968{
969 CHAR dest_buf[257];
970 CHAR src_buf[257];
971 STRING dest_str;
972 STRING src_str;
974 unsigned int test_num;
975
976 for (test_num = 0; test_num < ARRAY_SIZE(app_str2str); test_num++) {
977 dest_str.Length = app_str2str[test_num].dest_Length;
978 dest_str.MaximumLength = app_str2str[test_num].dest_MaximumLength;
979 if (app_str2str[test_num].dest_buf != NULL) {
980 memcpy(dest_buf, app_str2str[test_num].dest_buf, app_str2str[test_num].dest_buf_size);
981 dest_buf[app_str2str[test_num].dest_buf_size] = '\0';
982 dest_str.Buffer = dest_buf;
983 } else {
984 dest_str.Buffer = NULL;
985 }
986 src_str.Length = app_str2str[test_num].src_Length;
987 src_str.MaximumLength = app_str2str[test_num].src_MaximumLength;
988 if (app_str2str[test_num].src_buf != NULL) {
989 memcpy(src_buf, app_str2str[test_num].src_buf, app_str2str[test_num].src_buf_size);
990 src_buf[app_str2str[test_num].src_buf_size] = '\0';
991 src_str.Buffer = src_buf;
992 } else {
993 src_str.Buffer = NULL;
994 }
995 result = pRtlAppendStringToString(&dest_str, &src_str);
996 ok(result == app_str2str[test_num].result,
997 "(test %d): RtlAppendStringToString(dest, src) has result %lx, expected %lx\n",
998 test_num, result, app_str2str[test_num].result);
999 ok(dest_str.Length == app_str2str[test_num].res_Length,
1000 "(test %d): RtlAppendStringToString(dest, src) dest has Length %d, expected %d\n",
1001 test_num, dest_str.Length, app_str2str[test_num].res_Length);
1002 ok(dest_str.MaximumLength == app_str2str[test_num].res_MaximumLength,
1003 "(test %d): RtlAppendStringToString(dest, src) dest has MaximumLength %d, expected %d\n",
1004 test_num, dest_str.MaximumLength, app_str2str[test_num].res_MaximumLength);
1005 if (dest_str.Buffer == dest_buf) {
1006 ok(memcmp(dest_buf, app_str2str[test_num].res_buf, app_str2str[test_num].res_buf_size) == 0,
1007 "(test %d): RtlAppendStringToString(dest, src) has dest \"%s\" expected \"%s\"\n",
1008 test_num, dest_buf, app_str2str[test_num].res_buf);
1009 } else {
1010 ok(dest_str.Buffer == app_str2str[test_num].res_buf,
1011 "(test %d): RtlAppendStringToString(dest, src) dest has Buffer %p expected %p\n",
1012 test_num, dest_str.Buffer, app_str2str[test_num].res_buf);
1013 }
1014 }
1015}
1016
1017
1018typedef struct {
1022 const char *dest_buf;
1023 const char *src;
1027 const char *res_buf;
1030
1031static const app_uni2str_t app_uni2str[] = {
1032 { 4, 12, 14, "Fake0123abcdef", "Ustr\0", 8, 12, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS},
1033 { 4, 11, 14, "Fake0123abcdef", "Ustr\0", 8, 11, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS},
1034 { 4, 10, 14, "Fake0123abcdef", "Ustr\0", 8, 10, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS},
1035/* In the following test the native function writes beyond MaximumLength
1036 * { 4, 9, 14, "Fake0123abcdef", "Ustr\0", 8, 9, 14, "FakeUstrabcdef", STATUS_SUCCESS},
1037 */
1038 { 4, 8, 14, "Fake0123abcdef", "Ustr\0", 8, 8, 14, "FakeUstrabcdef", STATUS_SUCCESS},
1039 { 4, 7, 14, "Fake0123abcdef", "Ustr\0", 4, 7, 14, "Fake0123abcdef", STATUS_BUFFER_TOO_SMALL},
1040 { 4, 0, 14, "Fake0123abcdef", "Ustr\0", 4, 0, 14, "Fake0123abcdef", STATUS_BUFFER_TOO_SMALL},
1041 { 4, 14, 14, "Fake0123abcdef", "Ustr\0", 8, 14, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS},
1042 { 4, 14, 14, "Fake0123abcdef", NULL, 4, 14, 14, "Fake0123abcdef", STATUS_SUCCESS},
1043 { 4, 14, 14, NULL, NULL, 4, 14, 14, NULL, STATUS_SUCCESS},
1044 { 4, 14, 14, "Fake0123abcdef", "U\0stri\0", 10, 14, 14, "FakeU\0stri\0\0ef", STATUS_SUCCESS},
1045 { 6, 14, 16, "Te\0\0stabcdefghij", "St\0\0ri", 8, 14, 16, "Te\0\0stSt\0\0efghij", STATUS_SUCCESS},
1046};
1047
1048
1050{
1051 WCHAR dest_buf[257];
1052 UNICODE_STRING dest_str;
1054 unsigned int test_num;
1055
1056 for (test_num = 0; test_num < ARRAY_SIZE(app_uni2str); test_num++) {
1057 dest_str.Length = app_uni2str[test_num].dest_Length;
1058 dest_str.MaximumLength = app_uni2str[test_num].dest_MaximumLength;
1059 if (app_uni2str[test_num].dest_buf != NULL) {
1060 memcpy(dest_buf, app_uni2str[test_num].dest_buf, app_uni2str[test_num].dest_buf_size);
1061 dest_buf[app_uni2str[test_num].dest_buf_size/sizeof(WCHAR)] = '\0';
1062 dest_str.Buffer = dest_buf;
1063 } else {
1064 dest_str.Buffer = NULL;
1065 }
1066 result = pRtlAppendUnicodeToString(&dest_str, (LPCWSTR) app_uni2str[test_num].src);
1067 ok(result == app_uni2str[test_num].result,
1068 "(test %d): RtlAppendUnicodeToString(dest, src) has result %lx, expected %lx\n",
1069 test_num, result, app_uni2str[test_num].result);
1070 ok(dest_str.Length == app_uni2str[test_num].res_Length,
1071 "(test %d): RtlAppendUnicodeToString(dest, src) dest has Length %d, expected %d\n",
1072 test_num, dest_str.Length, app_uni2str[test_num].res_Length);
1073 ok(dest_str.MaximumLength == app_uni2str[test_num].res_MaximumLength,
1074 "(test %d): RtlAppendUnicodeToString(dest, src) dest has MaximumLength %d, expected %d\n",
1075 test_num, dest_str.MaximumLength, app_uni2str[test_num].res_MaximumLength);
1076 if (dest_str.Buffer == dest_buf) {
1077 ok(memcmp(dest_buf, app_uni2str[test_num].res_buf, app_uni2str[test_num].res_buf_size) == 0,
1078 "(test %d): RtlAppendUnicodeToString(dest, src) has dest \"%s\" expected \"%s\"\n",
1079 test_num, (char *) dest_buf, app_uni2str[test_num].res_buf);
1080 } else {
1081 ok(dest_str.Buffer == (WCHAR *) app_uni2str[test_num].res_buf,
1082 "(test %d): RtlAppendUnicodeToString(dest, src) dest has Buffer %p expected %p\n",
1083 test_num, dest_str.Buffer, app_uni2str[test_num].res_buf);
1084 }
1085 }
1086}
1087
1088
1089typedef struct {
1093 const char *dest_buf;
1097 const char *src_buf;
1101 const char *res_buf;
1104
1106 { 4, 12, 14, "Fake0123abcdef", 4, 6, 8, "UstrZYXW", 8, 12, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS},
1107 { 4, 11, 14, "Fake0123abcdef", 4, 6, 8, "UstrZYXW", 8, 11, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS},
1108 { 4, 10, 14, "Fake0123abcdef", 4, 6, 8, "UstrZYXW", 8, 10, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS},
1109/* In the following test the native function writes beyond MaximumLength
1110 * { 4, 9, 14, "Fake0123abcdef", 4, 6, 8, "UstrZYXW", 8, 9, 14, "FakeUstrabcdef", STATUS_SUCCESS},
1111 */
1112 { 4, 8, 14, "Fake0123abcdef", 4, 6, 8, "UstrZYXW", 8, 8, 14, "FakeUstrabcdef", STATUS_SUCCESS},
1113 { 4, 7, 14, "Fake0123abcdef", 4, 6, 8, "UstrZYXW", 4, 7, 14, "Fake0123abcdef", STATUS_BUFFER_TOO_SMALL},
1114 { 4, 0, 14, "Fake0123abcdef", 0, 0, 8, "UstrZYXW", 4, 0, 14, "Fake0123abcdef", STATUS_SUCCESS},
1115 { 4, 14, 14, "Fake0123abcdef", 0, 0, 8, "UstrZYXW", 4, 14, 14, "Fake0123abcdef", STATUS_SUCCESS},
1116 { 4, 14, 14, "Fake0123abcdef", 0, 0, 8, NULL, 4, 14, 14, "Fake0123abcdef", STATUS_SUCCESS},
1117 { 4, 14, 14, NULL, 0, 0, 8, NULL, 4, 14, 14, NULL, STATUS_SUCCESS},
1118 { 6, 14, 16, "Te\0\0stabcdefghij", 6, 8, 8, "St\0\0riZY", 12, 14, 16, "Te\0\0stSt\0\0ri\0\0ij", STATUS_SUCCESS},
1119};
1120
1121
1123{
1124 WCHAR dest_buf[257];
1125 WCHAR src_buf[257];
1126 UNICODE_STRING dest_str;
1127 UNICODE_STRING src_str;
1129 unsigned int test_num;
1130
1131 for (test_num = 0; test_num < ARRAY_SIZE(app_ustr2str); test_num++) {
1132 dest_str.Length = app_ustr2str[test_num].dest_Length;
1133 dest_str.MaximumLength = app_ustr2str[test_num].dest_MaximumLength;
1134 if (app_ustr2str[test_num].dest_buf != NULL) {
1135 memcpy(dest_buf, app_ustr2str[test_num].dest_buf, app_ustr2str[test_num].dest_buf_size);
1136 dest_buf[app_ustr2str[test_num].dest_buf_size/sizeof(WCHAR)] = '\0';
1137 dest_str.Buffer = dest_buf;
1138 } else {
1139 dest_str.Buffer = NULL;
1140 }
1141 src_str.Length = app_ustr2str[test_num].src_Length;
1142 src_str.MaximumLength = app_ustr2str[test_num].src_MaximumLength;
1143 if (app_ustr2str[test_num].src_buf != NULL) {
1144 memcpy(src_buf, app_ustr2str[test_num].src_buf, app_ustr2str[test_num].src_buf_size);
1145 src_buf[app_ustr2str[test_num].src_buf_size/sizeof(WCHAR)] = '\0';
1146 src_str.Buffer = src_buf;
1147 } else {
1148 src_str.Buffer = NULL;
1149 }
1150 result = pRtlAppendUnicodeStringToString(&dest_str, &src_str);
1151 ok(result == app_ustr2str[test_num].result,
1152 "(test %d): RtlAppendStringToString(dest, src) has result %lx, expected %lx\n",
1153 test_num, result, app_ustr2str[test_num].result);
1154 ok(dest_str.Length == app_ustr2str[test_num].res_Length,
1155 "(test %d): RtlAppendStringToString(dest, src) dest has Length %d, expected %d\n",
1156 test_num, dest_str.Length, app_ustr2str[test_num].res_Length);
1157 ok(dest_str.MaximumLength == app_ustr2str[test_num].res_MaximumLength,
1158 "(test %d): RtlAppendStringToString(dest, src) dest has MaximumLength %d, expected %d\n",
1159 test_num, dest_str.MaximumLength, app_ustr2str[test_num].res_MaximumLength);
1160 if (dest_str.Buffer == dest_buf) {
1161 ok(memcmp(dest_buf, app_ustr2str[test_num].res_buf, app_ustr2str[test_num].res_buf_size) == 0,
1162 "(test %d): RtlAppendStringToString(dest, src) has dest \"%s\" expected \"%s\"\n",
1163 test_num, (char *) dest_buf, app_ustr2str[test_num].res_buf);
1164 } else {
1165 ok(dest_str.Buffer == (WCHAR *) app_ustr2str[test_num].res_buf,
1166 "(test %d): RtlAppendStringToString(dest, src) dest has Buffer %p expected %p\n",
1167 test_num, dest_str.Buffer, app_ustr2str[test_num].res_buf);
1168 }
1169 }
1170}
1171
1172
1173typedef struct {
1175 const char *main_str;
1176 const char *search_chars;
1180
1182 { 0, "Some Wild String", "S", 2, STATUS_SUCCESS},
1183 { 0, "This is a String", "String", 6, STATUS_SUCCESS},
1184 { 1, "This is a String", "String", 30, STATUS_SUCCESS},
1185 { 2, "This is a String", "String", 2, STATUS_SUCCESS},
1186 { 3, "This is a String", "String", 18, STATUS_SUCCESS},
1187 { 0, "This is a String", "Wild", 6, STATUS_SUCCESS},
1188 { 1, "This is a String", "Wild", 26, STATUS_SUCCESS},
1189 { 2, "This is a String", "Wild", 2, STATUS_SUCCESS},
1190 { 3, "This is a String", "Wild", 30, STATUS_SUCCESS},
1191 { 0, "abcdefghijklmnopqrstuvwxyz", "", 0, STATUS_NOT_FOUND},
1192 { 0, "abcdefghijklmnopqrstuvwxyz", "123", 0, STATUS_NOT_FOUND},
1193 { 0, "abcdefghijklmnopqrstuvwxyz", "a", 2, STATUS_SUCCESS},
1194 { 0, "abcdefghijklmnopqrstuvwxyz", "12a34", 2, STATUS_SUCCESS},
1195 { 0, "abcdefghijklmnopqrstuvwxyz", "12b34", 4, STATUS_SUCCESS},
1196 { 0, "abcdefghijklmnopqrstuvwxyz", "12y34", 50, STATUS_SUCCESS},
1197 { 0, "abcdefghijklmnopqrstuvwxyz", "12z34", 52, STATUS_SUCCESS},
1198 { 0, "abcdefghijklmnopqrstuvwxyz", "rvz", 36, STATUS_SUCCESS},
1199 { 0, "abcdefghijklmmlkjihgfedcba", "egik", 10, STATUS_SUCCESS},
1200 { 1, "abcdefghijklmnopqrstuvwxyz", "", 0, STATUS_NOT_FOUND},
1201 { 1, "abcdefghijklmnopqrstuvwxyz", "rvz", 50, STATUS_SUCCESS},
1202 { 1, "abcdefghijklmnopqrstuvwxyz", "ravy", 48, STATUS_SUCCESS},
1203 { 1, "abcdefghijklmnopqrstuvwxyz", "raxv", 46, STATUS_SUCCESS},
1204 { 2, "abcdefghijklmnopqrstuvwxyz", "", 2, STATUS_SUCCESS},
1205 { 2, "abcdefghijklmnopqrstuvwxyz", "rvz", 2, STATUS_SUCCESS},
1206 { 2, "abcdefghijklmnopqrstuvwxyz", "vaz", 4, STATUS_SUCCESS},
1207 { 2, "abcdefghijklmnopqrstuvwxyz", "ravbz", 6, STATUS_SUCCESS},
1208 { 3, "abcdefghijklmnopqrstuvwxyz", "", 50, STATUS_SUCCESS},
1209 { 3, "abcdefghijklmnopqrstuvwxyz", "123", 50, STATUS_SUCCESS},
1210 { 3, "abcdefghijklmnopqrstuvwxyz", "ahp", 50, STATUS_SUCCESS},
1211 { 3, "abcdefghijklmnopqrstuvwxyz", "rvz", 48, STATUS_SUCCESS},
1212 { 0, NULL, "abc", 0, STATUS_NOT_FOUND},
1213 { 1, NULL, "abc", 0, STATUS_NOT_FOUND},
1214 { 2, NULL, "abc", 0, STATUS_NOT_FOUND},
1215 { 3, NULL, "abc", 0, STATUS_NOT_FOUND},
1216 { 0, "abcdefghijklmnopqrstuvwxyz", NULL, 0, STATUS_NOT_FOUND},
1217 { 1, "abcdefghijklmnopqrstuvwxyz", NULL, 0, STATUS_NOT_FOUND},
1218 { 2, "abcdefghijklmnopqrstuvwxyz", NULL, 2, STATUS_SUCCESS},
1219 { 3, "abcdefghijklmnopqrstuvwxyz", NULL, 50, STATUS_SUCCESS},
1220 { 0, NULL, NULL, 0, STATUS_NOT_FOUND},
1221 { 1, NULL, NULL, 0, STATUS_NOT_FOUND},
1222 { 2, NULL, NULL, 0, STATUS_NOT_FOUND},
1223 { 3, NULL, NULL, 0, STATUS_NOT_FOUND},
1224 { 0, "abcdabcdabcdabcdabcdabcd", "abcd", 2, STATUS_SUCCESS},
1225 { 1, "abcdabcdabcdabcdabcdabcd", "abcd", 46, STATUS_SUCCESS},
1226 { 2, "abcdabcdabcdabcdabcdabcd", "abcd", 0, STATUS_NOT_FOUND},
1227 { 3, "abcdabcdabcdabcdabcdabcd", "abcd", 0, STATUS_NOT_FOUND},
1228};
1229
1230
1232{
1233 WCHAR main_str_buf[257];
1234 WCHAR search_chars_buf[257];
1235 UNICODE_STRING main_str;
1236 UNICODE_STRING search_chars;
1237 USHORT pos;
1239 unsigned int idx;
1240 unsigned int test_num;
1241
1242 if (!pRtlFindCharInUnicodeString)
1243 {
1244 win_skip("RtlFindCharInUnicodeString is not available\n");
1245 return;
1246 }
1247
1248 for (test_num = 0; test_num < ARRAY_SIZE(find_ch_in_ustr); test_num++) {
1249 if (find_ch_in_ustr[test_num].main_str != NULL) {
1250 main_str.Length = strlen(find_ch_in_ustr[test_num].main_str) * sizeof(WCHAR);
1251 main_str.MaximumLength = main_str.Length + sizeof(WCHAR);
1252 for (idx = 0; idx < main_str.Length / sizeof(WCHAR); idx++) {
1253 main_str_buf[idx] = find_ch_in_ustr[test_num].main_str[idx];
1254 }
1255 main_str.Buffer = main_str_buf;
1256 } else {
1257 main_str.Length = 0;
1258 main_str.MaximumLength = 0;
1259 main_str.Buffer = NULL;
1260 }
1261 if (find_ch_in_ustr[test_num].search_chars != NULL) {
1262 search_chars.Length = strlen(find_ch_in_ustr[test_num].search_chars) * sizeof(WCHAR);
1263 search_chars.MaximumLength = search_chars.Length + sizeof(WCHAR);
1264 for (idx = 0; idx < search_chars.Length / sizeof(WCHAR); idx++) {
1265 search_chars_buf[idx] = find_ch_in_ustr[test_num].search_chars[idx];
1266 }
1267 search_chars.Buffer = search_chars_buf;
1268 } else {
1269 search_chars.Length = 0;
1270 search_chars.MaximumLength = 0;
1271 search_chars.Buffer = NULL;
1272 }
1273 pos = 12345;
1274 result = pRtlFindCharInUnicodeString(find_ch_in_ustr[test_num].flags, &main_str, &search_chars, &pos);
1275 ok(result == find_ch_in_ustr[test_num].result,
1276 "(test %d): RtlFindCharInUnicodeString(%d, %s, %s, [out]) has result %lx, expected %lx\n",
1277 test_num, find_ch_in_ustr[test_num].flags,
1278 find_ch_in_ustr[test_num].main_str, find_ch_in_ustr[test_num].search_chars,
1279 result, find_ch_in_ustr[test_num].result);
1280 ok(pos == find_ch_in_ustr[test_num].pos,
1281 "(test %d): RtlFindCharInUnicodeString(%d, %s, %s, [out]) assigns %d to pos, expected %d\n",
1282 test_num, find_ch_in_ustr[test_num].flags,
1283 find_ch_in_ustr[test_num].main_str, find_ch_in_ustr[test_num].search_chars,
1284 pos, find_ch_in_ustr[test_num].pos);
1285 }
1286}
1287
1288
1289typedef struct {
1290 int base;
1291 const char *str;
1294} str2int_t;
1295
1296static const str2int_t str2int[] = {
1297 { 0, "1011101100", 1011101100, STATUS_SUCCESS},
1298 { 0, "1234567", 1234567, STATUS_SUCCESS},
1299 { 0, "-214", -214, STATUS_SUCCESS},
1300 { 0, "+214", 214, STATUS_SUCCESS}, /* The + sign is allowed also */
1301 { 0, "--214", 0, STATUS_SUCCESS}, /* Do not accept more than one sign */
1302 { 0, "-+214", 0, STATUS_SUCCESS},
1303 { 0, "++214", 0, STATUS_SUCCESS},
1304 { 0, "+-214", 0, STATUS_SUCCESS},
1305 { 0, "\001\002\003\00411", 11, STATUS_SUCCESS}, /* whitespace char 1 to 4 */
1306 { 0, "\005\006\007\01012", 12, STATUS_SUCCESS}, /* whitespace char 5 to 8 */
1307 { 0, "\011\012\013\01413", 13, STATUS_SUCCESS}, /* whitespace char 9 to 12 */
1308 { 0, "\015\016\017\02014", 14, STATUS_SUCCESS}, /* whitespace char 13 to 16 */
1309 { 0, "\021\022\023\02415", 15, STATUS_SUCCESS}, /* whitespace char 17 to 20 */
1310 { 0, "\025\026\027\03016", 16, STATUS_SUCCESS}, /* whitespace char 21 to 24 */
1311 { 0, "\031\032\033\03417", 17, STATUS_SUCCESS}, /* whitespace char 25 to 28 */
1312 { 0, "\035\036\037\04018", 18, STATUS_SUCCESS}, /* whitespace char 29 to 32 */
1313 { 0, " \n \r \t214", 214, STATUS_SUCCESS},
1314 { 0, " \n \r \t+214", 214, STATUS_SUCCESS}, /* Signs can be used after whitespace */
1315 { 0, " \n \r \t-214", -214, STATUS_SUCCESS},
1316 { 0, "+214 0", 214, STATUS_SUCCESS}, /* Space terminates the number */
1317 { 0, " 214.01", 214, STATUS_SUCCESS}, /* Decimal point not accepted */
1318 { 0, " 214,01", 214, STATUS_SUCCESS}, /* Decimal comma not accepted */
1319 { 0, "f81", 0, STATUS_SUCCESS},
1320 { 0, "0x12345", 0x12345, STATUS_SUCCESS}, /* Hex */
1321 { 0, "00x12345", 0, STATUS_SUCCESS},
1322 { 0, "0xx12345", 0, STATUS_SUCCESS},
1323 { 0, "1x34", 1, STATUS_SUCCESS},
1324 { 0, "-9999999999", -1410065407, STATUS_SUCCESS}, /* Big negative integer */
1325 { 0, "-2147483649", 2147483647, STATUS_SUCCESS}, /* Too small to fit in 32 Bits */
1326 { 0, "-2147483648", 0x80000000L, STATUS_SUCCESS}, /* Smallest negative integer */
1327 { 0, "-2147483647", -2147483647, STATUS_SUCCESS},
1328 { 0, "-1", -1, STATUS_SUCCESS},
1329 { 0, "0", 0, STATUS_SUCCESS},
1330 { 0, "1", 1, STATUS_SUCCESS},
1331 { 0, "2147483646", 2147483646, STATUS_SUCCESS},
1332 { 0, "2147483647", 2147483647, STATUS_SUCCESS}, /* Largest signed positive integer */
1333 { 0, "2147483648", 0x80000000L, STATUS_SUCCESS}, /* Positive int equal to smallest negative int */
1334 { 0, "2147483649", -2147483647, STATUS_SUCCESS},
1335 { 0, "4294967294", -2, STATUS_SUCCESS},
1336 { 0, "4294967295", -1, STATUS_SUCCESS}, /* Largest unsigned integer */
1337 { 0, "4294967296", 0, STATUS_SUCCESS}, /* Too big to fit in 32 Bits */
1338 { 0, "9999999999", 1410065407, STATUS_SUCCESS}, /* Big positive integer */
1339 { 0, "056789", 56789, STATUS_SUCCESS}, /* Leading zero and still decimal */
1340 { 0, "b1011101100", 0, STATUS_SUCCESS}, /* Binary (b-notation) */
1341 { 0, "-b1011101100", 0, STATUS_SUCCESS}, /* Negative Binary (b-notation) */
1342 { 0, "b10123456789", 0, STATUS_SUCCESS}, /* Binary with nonbinary digits (2-9) */
1343 { 0, "0b1011101100", 748, STATUS_SUCCESS}, /* Binary (0b-notation) */
1344 { 0, "-0b1011101100", -748, STATUS_SUCCESS}, /* Negative binary (0b-notation) */
1345 { 0, "0b10123456789", 5, STATUS_SUCCESS}, /* Binary with nonbinary digits (2-9) */
1346 { 0, "-0b10123456789", -5, STATUS_SUCCESS}, /* Negative binary with nonbinary digits (2-9) */
1347 { 0, "0b1", 1, STATUS_SUCCESS}, /* one digit binary */
1348 { 0, "0b2", 0, STATUS_SUCCESS}, /* empty binary */
1349 { 0, "0b", 0, STATUS_SUCCESS}, /* empty binary */
1350 { 0, "o1234567", 0, STATUS_SUCCESS}, /* Octal (o-notation) */
1351 { 0, "-o1234567", 0, STATUS_SUCCESS}, /* Negative Octal (o-notation) */
1352 { 0, "o56789", 0, STATUS_SUCCESS}, /* Octal with nonoctal digits (8 and 9) */
1353 { 0, "0o1234567", 01234567, STATUS_SUCCESS}, /* Octal (0o-notation) */
1354 { 0, "-0o1234567", -01234567, STATUS_SUCCESS}, /* Negative octal (0o-notation) */
1355 { 0, "0o56789", 0567, STATUS_SUCCESS}, /* Octal with nonoctal digits (8 and 9) */
1356 { 0, "-0o56789", -0567, STATUS_SUCCESS}, /* Negative octal with nonoctal digits (8 and 9) */
1357 { 0, "0o7", 7, STATUS_SUCCESS}, /* one digit octal */
1358 { 0, "0o8", 0, STATUS_SUCCESS}, /* empty octal */
1359 { 0, "0o", 0, STATUS_SUCCESS}, /* empty octal */
1360 { 0, "0d1011101100", 0, STATUS_SUCCESS}, /* explicit decimal with 0d */
1361 { 0, "x89abcdef", 0, STATUS_SUCCESS}, /* Hex with lower case digits a-f (x-notation) */
1362 { 0, "xFEDCBA00", 0, STATUS_SUCCESS}, /* Hex with upper case digits A-F (x-notation) */
1363 { 0, "-xFEDCBA00", 0, STATUS_SUCCESS}, /* Negative Hexadecimal (x-notation) */
1364 { 0, "0x89abcdef", 0x89abcdef, STATUS_SUCCESS}, /* Hex with lower case digits a-f (0x-notation) */
1365 { 0, "0xFEDCBA00", 0xFEDCBA00, STATUS_SUCCESS}, /* Hex with upper case digits A-F (0x-notation) */
1366 { 0, "-0xFEDCBA00", 19088896, STATUS_SUCCESS}, /* Negative Hexadecimal (0x-notation) */
1367 { 0, "0xabcdefgh", 0xabcdef, STATUS_SUCCESS}, /* Hex with illegal lower case digits (g-z) */
1368 { 0, "0xABCDEFGH", 0xABCDEF, STATUS_SUCCESS}, /* Hex with illegal upper case digits (G-Z) */
1369 { 0, "0xF", 0xf, STATUS_SUCCESS}, /* one digit hexadecimal */
1370 { 0, "0xG", 0, STATUS_SUCCESS}, /* empty hexadecimal */
1371 { 0, "0x", 0, STATUS_SUCCESS}, /* empty hexadecimal */
1372 { 0, "", 0, STATUS_SUCCESS, STATUS_INVALID_PARAMETER}, /* empty string */
1373 { 2, "1011101100", 748, STATUS_SUCCESS},
1374 { 2, "-1011101100", -748, STATUS_SUCCESS},
1375 { 2, "2", 0, STATUS_SUCCESS},
1376 { 2, "0b1011101100", 0, STATUS_SUCCESS},
1377 { 2, "0o1011101100", 0, STATUS_SUCCESS},
1378 { 2, "0d1011101100", 0, STATUS_SUCCESS},
1379 { 2, "0x1011101100", 0, STATUS_SUCCESS},
1380 { 2, "", 0, STATUS_SUCCESS, STATUS_INVALID_PARAMETER}, /* empty string */
1381 { 8, "1011101100", 136610368, STATUS_SUCCESS},
1382 { 8, "-1011101100", -136610368, STATUS_SUCCESS},
1383 { 8, "8", 0, STATUS_SUCCESS},
1384 { 8, "0b1011101100", 0, STATUS_SUCCESS},
1385 { 8, "0o1011101100", 0, STATUS_SUCCESS},
1386 { 8, "0d1011101100", 0, STATUS_SUCCESS},
1387 { 8, "0x1011101100", 0, STATUS_SUCCESS},
1388 { 8, "", 0, STATUS_SUCCESS, STATUS_INVALID_PARAMETER}, /* empty string */
1389 {10, "1011101100", 1011101100, STATUS_SUCCESS},
1390 {10, "-1011101100", -1011101100, STATUS_SUCCESS},
1391 {10, "0b1011101100", 0, STATUS_SUCCESS},
1392 {10, "0o1011101100", 0, STATUS_SUCCESS},
1393 {10, "0d1011101100", 0, STATUS_SUCCESS},
1394 {10, "0x1011101100", 0, STATUS_SUCCESS},
1395 {10, "o12345", 0, STATUS_SUCCESS}, /* Octal although base is 10 */
1396 {10, "", 0, STATUS_SUCCESS, STATUS_INVALID_PARAMETER}, /* empty string */
1397 {16, "1011101100", 286265600, STATUS_SUCCESS},
1398 {16, "-1011101100", -286265600, STATUS_SUCCESS},
1399 {16, "G", 0, STATUS_SUCCESS},
1400 {16, "g", 0, STATUS_SUCCESS},
1401 {16, "0b1011101100", 286265600, STATUS_SUCCESS},
1402 {16, "0o1011101100", 0, STATUS_SUCCESS},
1403 {16, "0d1011101100", 286265600, STATUS_SUCCESS},
1404 {16, "0x1011101100", 0, STATUS_SUCCESS},
1405 {16, "", 0, STATUS_SUCCESS, STATUS_INVALID_PARAMETER}, /* empty string */
1406 {20, "0", 0, STATUS_INVALID_PARAMETER}, /* illegal base */
1407 {-8, "0", 0, STATUS_INVALID_PARAMETER}, /* Negative base */
1408/* { 0, NULL, 0, STATUS_SUCCESS}, */ /* NULL as string */
1409};
1410
1411
1413{
1414 unsigned int test_num;
1415 int value;
1417 WCHAR *wstr;
1418 UNICODE_STRING uni;
1419
1420 for (test_num = 0; test_num < ARRAY_SIZE(str2int); test_num++) {
1421 wstr = AtoW(str2int[test_num].str);
1422 value = 0xdeadbeef;
1423 pRtlInitUnicodeString(&uni, wstr);
1424 result = pRtlUnicodeStringToInteger(&uni, str2int[test_num].base, &value);
1425 ok(result == str2int[test_num].result ||
1426 (str2int[test_num].alternative && result == str2int[test_num].alternative),
1427 "(test %d): RtlUnicodeStringToInteger(\"%s\", %d, [out]) has result %lx, expected: %lx (%lx)\n",
1428 test_num, str2int[test_num].str, str2int[test_num].base, result,
1429 str2int[test_num].result, str2int[test_num].alternative);
1430 if (result == STATUS_SUCCESS)
1431 ok(value == str2int[test_num].value ||
1432 broken(str2int[test_num].str[0] == '\0' && str2int[test_num].base == 16), /* nt4 */
1433 "(test %d): RtlUnicodeStringToInteger(\"%s\", %d, [out]) assigns value %d, expected: %d\n",
1434 test_num, str2int[test_num].str, str2int[test_num].base, value, str2int[test_num].value);
1435 else
1436 ok(value == 0xdeadbeef || value == 0 /* vista */,
1437 "(test %d): RtlUnicodeStringToInteger(\"%s\", %d, [out]) assigns value %d, expected 0 or deadbeef\n",
1438 test_num, str2int[test_num].str, str2int[test_num].base, value);
1439 HeapFree(GetProcessHeap(), 0, wstr);
1440 }
1441
1442 wstr = AtoW(str2int[1].str);
1443 pRtlInitUnicodeString(&uni, wstr);
1444 result = pRtlUnicodeStringToInteger(&uni, str2int[1].base, NULL);
1446 "call failed: RtlUnicodeStringToInteger(\"%s\", %d, NULL) has result %lx\n",
1447 str2int[1].str, str2int[1].base, result);
1448 result = pRtlUnicodeStringToInteger(&uni, 20, NULL);
1450 "call failed: RtlUnicodeStringToInteger(\"%s\", 20, NULL) has result %lx\n",
1451 str2int[1].str, result);
1452
1453 uni.Length = 10; /* Make Length shorter (5 WCHARS instead of 7) */
1454 result = pRtlUnicodeStringToInteger(&uni, str2int[1].base, &value);
1456 "call failed: RtlUnicodeStringToInteger(\"12345\", %d, [out]) has result %lx\n",
1457 str2int[1].base, result);
1458 ok(value == 12345,
1459 "didn't return expected value (test a): expected: %d, got: %d\n",
1460 12345, value);
1461
1462 uni.Length = 5; /* Use odd Length (2.5 WCHARS) */
1463 result = pRtlUnicodeStringToInteger(&uni, str2int[1].base, &value);
1465 "call failed: RtlUnicodeStringToInteger(\"12\", %d, [out]) has result %lx\n",
1466 str2int[1].base, result);
1467 if (result == STATUS_SUCCESS)
1468 ok(value == 12, "didn't return expected value (test b): expected: %d, got: %d\n", 12, value);
1469
1470 uni.Length = 2;
1471 result = pRtlUnicodeStringToInteger(&uni, str2int[1].base, &value);
1473 "call failed: RtlUnicodeStringToInteger(\"1\", %d, [out]) has result %lx\n",
1474 str2int[1].base, result);
1475 ok(value == 1,
1476 "didn't return expected value (test c): expected: %d, got: %d\n",
1477 1, value);
1478 /* w2k: uni.Length = 0 returns value 11234567 instead of 0 */
1479 HeapFree(GetProcessHeap(), 0, wstr);
1480}
1481
1482
1483static void test_RtlCharToInteger(void)
1484{
1485 unsigned int test_num;
1486 int value;
1488
1489 for (test_num = 0; test_num < ARRAY_SIZE(str2int); test_num++) {
1490 /* w2k skips a leading '\0' and processes the string after */
1491 if (str2int[test_num].str[0] != '\0') {
1492 value = 0xdeadbeef;
1493 result = pRtlCharToInteger(str2int[test_num].str, str2int[test_num].base, &value);
1494 ok(result == str2int[test_num].result ||
1495 (str2int[test_num].alternative && result == str2int[test_num].alternative),
1496 "(test %d): call failed: RtlCharToInteger(\"%s\", %d, [out]) has result %lx, expected: %lx (%lx)\n",
1497 test_num, str2int[test_num].str, str2int[test_num].base, result,
1498 str2int[test_num].result, str2int[test_num].alternative);
1499 if (result == STATUS_SUCCESS)
1500 ok(value == str2int[test_num].value,
1501 "(test %d): call failed: RtlCharToInteger(\"%s\", %d, [out]) assigns value %d, expected: %d\n",
1502 test_num, str2int[test_num].str, str2int[test_num].base, value, str2int[test_num].value);
1503 else
1504 ok(value == 0 || value == 0xdeadbeef,
1505 "(test %d): call failed: RtlCharToInteger(\"%s\", %d, [out]) assigns value %d, expected 0 or deadbeef\n",
1506 test_num, str2int[test_num].str, str2int[test_num].base, value);
1507 }
1508 }
1509
1510 result = pRtlCharToInteger(str2int[1].str, str2int[1].base, NULL);
1512 "call failed: RtlCharToInteger(\"%s\", %d, NULL) has result %lx\n",
1513 str2int[1].str, str2int[1].base, result);
1514
1515 result = pRtlCharToInteger(str2int[1].str, 20, NULL);
1517 "call failed: RtlCharToInteger(\"%s\", 20, NULL) has result %lx\n",
1518 str2int[1].str, result);
1519}
1520
1521
1522#define STRI_BUFFER_LENGTH 35
1523
1524typedef struct {
1525 int base;
1529 const char *Buffer;
1532} int2str_t;
1533
1534static const int2str_t int2str[] = {
1535 {10, 123, 3, 11, "123\0-------------------------------", STATUS_SUCCESS},
1536
1537 { 0, 0x80000000U, 10, 11, "2147483648\0------------------------", STATUS_SUCCESS}, /* min signed int */
1538 { 0, -2147483647, 10, 11, "2147483649\0------------------------", STATUS_SUCCESS},
1539 { 0, -2, 10, 11, "4294967294\0------------------------", STATUS_SUCCESS},
1540 { 0, -1, 10, 11, "4294967295\0------------------------", STATUS_SUCCESS},
1541 { 0, 0, 1, 11, "0\0---------------------------------", STATUS_SUCCESS},
1542 { 0, 1, 1, 11, "1\0---------------------------------", STATUS_SUCCESS},
1543 { 0, 12, 2, 11, "12\0--------------------------------", STATUS_SUCCESS},
1544 { 0, 123, 3, 11, "123\0-------------------------------", STATUS_SUCCESS},
1545 { 0, 1234, 4, 11, "1234\0------------------------------", STATUS_SUCCESS},
1546 { 0, 12345, 5, 11, "12345\0-----------------------------", STATUS_SUCCESS},
1547 { 0, 123456, 6, 11, "123456\0----------------------------", STATUS_SUCCESS},
1548 { 0, 1234567, 7, 11, "1234567\0---------------------------", STATUS_SUCCESS},
1549 { 0, 12345678, 8, 11, "12345678\0--------------------------", STATUS_SUCCESS},
1550 { 0, 123456789, 9, 11, "123456789\0-------------------------", STATUS_SUCCESS},
1551 { 0, 2147483646, 10, 11, "2147483646\0------------------------", STATUS_SUCCESS},
1552 { 0, 2147483647, 10, 11, "2147483647\0------------------------", STATUS_SUCCESS}, /* max signed int */
1553 { 0, 2147483648U, 10, 11, "2147483648\0------------------------", STATUS_SUCCESS}, /* uint = -max int */
1554 { 0, 2147483649U, 10, 11, "2147483649\0------------------------", STATUS_SUCCESS},
1555 { 0, 4294967294U, 10, 11, "4294967294\0------------------------", STATUS_SUCCESS},
1556 { 0, 4294967295U, 10, 11, "4294967295\0------------------------", STATUS_SUCCESS}, /* max unsigned int */
1557
1558 { 2, 0x80000000U, 32, 33, "10000000000000000000000000000000\0--", STATUS_SUCCESS}, /* min signed int */
1559 { 2, -2147483647, 32, 33, "10000000000000000000000000000001\0--", STATUS_SUCCESS},
1560 { 2, -2, 32, 33, "11111111111111111111111111111110\0--", STATUS_SUCCESS},
1561 { 2, -1, 32, 33, "11111111111111111111111111111111\0--", STATUS_SUCCESS},
1562 { 2, 0, 1, 33, "0\0---------------------------------", STATUS_SUCCESS},
1563 { 2, 1, 1, 33, "1\0---------------------------------", STATUS_SUCCESS},
1564 { 2, 10, 4, 33, "1010\0------------------------------", STATUS_SUCCESS},
1565 { 2, 100, 7, 33, "1100100\0---------------------------", STATUS_SUCCESS},
1566 { 2, 1000, 10, 33, "1111101000\0------------------------", STATUS_SUCCESS},
1567 { 2, 10000, 14, 33, "10011100010000\0--------------------", STATUS_SUCCESS},
1568 { 2, 32767, 15, 33, "111111111111111\0-------------------", STATUS_SUCCESS},
1569/* { 2, 32768, 16, 33, "1000000000000000\0------------------", STATUS_SUCCESS}, broken on windows */
1570/* { 2, 65535, 16, 33, "1111111111111111\0------------------", STATUS_SUCCESS}, broken on windows */
1571 { 2, 65536, 17, 33, "10000000000000000\0-----------------", STATUS_SUCCESS},
1572 { 2, 100000, 17, 33, "11000011010100000\0-----------------", STATUS_SUCCESS},
1573 { 2, 1000000, 20, 33, "11110100001001000000\0--------------", STATUS_SUCCESS},
1574 { 2, 10000000, 24, 33, "100110001001011010000000\0----------", STATUS_SUCCESS},
1575 { 2, 100000000, 27, 33, "101111101011110000100000000\0-------", STATUS_SUCCESS},
1576 { 2, 1000000000, 30, 33, "111011100110101100101000000000\0----", STATUS_SUCCESS},
1577 { 2, 1073741823, 30, 33, "111111111111111111111111111111\0----", STATUS_SUCCESS},
1578 { 2, 2147483646, 31, 33, "1111111111111111111111111111110\0---", STATUS_SUCCESS},
1579 { 2, 2147483647, 31, 33, "1111111111111111111111111111111\0---", STATUS_SUCCESS}, /* max signed int */
1580 { 2, 2147483648U, 32, 33, "10000000000000000000000000000000\0--", STATUS_SUCCESS}, /* uint = -max int */
1581 { 2, 2147483649U, 32, 33, "10000000000000000000000000000001\0--", STATUS_SUCCESS},
1582 { 2, 4294967294U, 32, 33, "11111111111111111111111111111110\0--", STATUS_SUCCESS},
1583 { 2, 4294967295U, 32, 33, "11111111111111111111111111111111\0--", STATUS_SUCCESS}, /* max unsigned int */
1584
1585 { 8, 0x80000000U, 11, 12, "20000000000\0-----------------------", STATUS_SUCCESS}, /* min signed int */
1586 { 8, -2147483647, 11, 12, "20000000001\0-----------------------", STATUS_SUCCESS},
1587 { 8, -2, 11, 12, "37777777776\0-----------------------", STATUS_SUCCESS},
1588 { 8, -1, 11, 12, "37777777777\0-----------------------", STATUS_SUCCESS},
1589 { 8, 0, 1, 12, "0\0---------------------------------", STATUS_SUCCESS},
1590 { 8, 1, 1, 12, "1\0---------------------------------", STATUS_SUCCESS},
1591 { 8, 2147483646, 11, 12, "17777777776\0-----------------------", STATUS_SUCCESS},
1592 { 8, 2147483647, 11, 12, "17777777777\0-----------------------", STATUS_SUCCESS}, /* max signed int */
1593 { 8, 2147483648U, 11, 12, "20000000000\0-----------------------", STATUS_SUCCESS}, /* uint = -max int */
1594 { 8, 2147483649U, 11, 12, "20000000001\0-----------------------", STATUS_SUCCESS},
1595 { 8, 4294967294U, 11, 12, "37777777776\0-----------------------", STATUS_SUCCESS},
1596 { 8, 4294967295U, 11, 12, "37777777777\0-----------------------", STATUS_SUCCESS}, /* max unsigned int */
1597
1598 {10, 0x80000000U, 10, 11, "2147483648\0------------------------", STATUS_SUCCESS}, /* min signed int */
1599 {10, -2147483647, 10, 11, "2147483649\0------------------------", STATUS_SUCCESS},
1600 {10, -2, 10, 11, "4294967294\0------------------------", STATUS_SUCCESS},
1601 {10, -1, 10, 11, "4294967295\0------------------------", STATUS_SUCCESS},
1602 {10, 0, 1, 11, "0\0---------------------------------", STATUS_SUCCESS},
1603 {10, 1, 1, 11, "1\0---------------------------------", STATUS_SUCCESS},
1604 {10, 2147483646, 10, 11, "2147483646\0------------------------", STATUS_SUCCESS},
1605 {10, 2147483647, 10, 11, "2147483647\0------------------------", STATUS_SUCCESS}, /* max signed int */
1606 {10, 2147483648U, 10, 11, "2147483648\0------------------------", STATUS_SUCCESS}, /* uint = -max int */
1607 {10, 2147483649U, 10, 11, "2147483649\0------------------------", STATUS_SUCCESS},
1608 {10, 4294967294U, 10, 11, "4294967294\0------------------------", STATUS_SUCCESS},
1609 {10, 4294967295U, 10, 11, "4294967295\0------------------------", STATUS_SUCCESS}, /* max unsigned int */
1610
1611 {16, 0x80000000U, 8, 9, "80000000\0--------------------------", STATUS_SUCCESS}, /* min signed int */
1612 {16, -2147483647, 8, 9, "80000001\0--------------------------", STATUS_SUCCESS},
1613 {16, -2, 8, 9, "FFFFFFFE\0--------------------------", STATUS_SUCCESS},
1614 {16, -1, 8, 9, "FFFFFFFF\0--------------------------", STATUS_SUCCESS},
1615 {16, 0, 1, 9, "0\0---------------------------------", STATUS_SUCCESS},
1616 {16, 1, 1, 9, "1\0---------------------------------", STATUS_SUCCESS},
1617 {16, 2147483646, 8, 9, "7FFFFFFE\0--------------------------", STATUS_SUCCESS},
1618 {16, 2147483647, 8, 9, "7FFFFFFF\0--------------------------", STATUS_SUCCESS}, /* max signed int */
1619 {16, 2147483648U, 8, 9, "80000000\0--------------------------", STATUS_SUCCESS}, /* uint = -max int */
1620 {16, 2147483649U, 8, 9, "80000001\0--------------------------", STATUS_SUCCESS},
1621 {16, 4294967294U, 8, 9, "FFFFFFFE\0--------------------------", STATUS_SUCCESS},
1622 {16, 4294967295U, 8, 9, "FFFFFFFF\0--------------------------", STATUS_SUCCESS}, /* max unsigned int */
1623
1624/* { 2, 32768, 16, 17, "1000000000000000\0------------------", STATUS_SUCCESS}, broken on windows */
1625/* { 2, 32768, 16, 16, "1000000000000000-------------------", STATUS_SUCCESS}, broken on windows */
1626 { 2, 65536, 17, 18, "10000000000000000\0-----------------", STATUS_SUCCESS},
1627 { 2, 65536, 17, 17, "10000000000000000------------------", STATUS_SUCCESS},
1628 { 2, 131072, 18, 19, "100000000000000000\0----------------", STATUS_SUCCESS},
1629 { 2, 131072, 18, 18, "100000000000000000-----------------", STATUS_SUCCESS},
1630 {16, 0xffffffff, 8, 9, "FFFFFFFF\0--------------------------", STATUS_SUCCESS},
1631 {16, 0xffffffff, 8, 8, "FFFFFFFF---------------------------", STATUS_SUCCESS, 1}, /* No \0 term */
1632 {16, 0xffffffff, 8, 7, "-----------------------------------", STATUS_BUFFER_OVERFLOW, 1}, /* Too short */
1633 {16, 0xa, 1, 2, "A\0---------------------------------", STATUS_SUCCESS},
1634 {16, 0xa, 1, 1, "A----------------------------------", STATUS_SUCCESS, 1}, /* No \0 term */
1635 {16, 0, 1, 0, "-----------------------------------", STATUS_BUFFER_OVERFLOW, 1},
1636 {20, 0xdeadbeef, 0, 9, "-----------------------------------", STATUS_INVALID_PARAMETER}, /* ill. base */
1637 {-8, 07654321, 0, 12, "-----------------------------------", STATUS_INVALID_PARAMETER}, /* neg. base */
1638};
1639
1640
1642{
1643 int pos;
1644 WCHAR expected_str_Buffer[STRI_BUFFER_LENGTH + 1];
1645 UNICODE_STRING expected_unicode_string;
1646 STRING expected_ansi_str;
1647 WCHAR str_Buffer[STRI_BUFFER_LENGTH + 1];
1648 UNICODE_STRING unicode_string;
1649 STRING ansi_str;
1651
1652 for (pos = 0; pos < STRI_BUFFER_LENGTH; pos++) {
1653 expected_str_Buffer[pos] = int2str->Buffer[pos];
1654 }
1655 expected_unicode_string.Length = int2str->Length * sizeof(WCHAR);
1656 expected_unicode_string.MaximumLength = int2str->MaximumLength * sizeof(WCHAR);
1657 expected_unicode_string.Buffer = expected_str_Buffer;
1658 pRtlUnicodeStringToAnsiString(&expected_ansi_str, &expected_unicode_string, 1);
1659
1660 for (pos = 0; pos < STRI_BUFFER_LENGTH; pos++) {
1661 str_Buffer[pos] = '-';
1662 }
1663 unicode_string.Length = 0;
1664 unicode_string.MaximumLength = int2str->MaximumLength * sizeof(WCHAR);
1665 unicode_string.Buffer = str_Buffer;
1666
1667 result = pRtlIntegerToUnicodeString(int2str->value, int2str->base, &unicode_string);
1668 pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
1670 /* On BUFFER_OVERFLOW the string Buffer should be unchanged */
1671 for (pos = 0; pos < STRI_BUFFER_LENGTH; pos++) {
1672 expected_str_Buffer[pos] = '-';
1673 }
1674 /* w2k: The native function has two reasons for BUFFER_OVERFLOW: */
1675 /* If the value is too large to convert: The Length is unchanged */
1676 /* If str is too small to hold the string: Set str->Length to the length */
1677 /* the string would have (which can be larger than the MaximumLength). */
1678 /* To allow all this in the tests we do the following: */
1679 if (expected_unicode_string.Length > 32 && unicode_string.Length == 0) {
1680 /* The value is too large to convert only triggered when testing native */
1681 expected_unicode_string.Length = 0;
1682 }
1683 } else {
1684 ok(result == int2str->result,
1685 "(test %d): RtlIntegerToUnicodeString(%lu, %d, [out]) has result %lx, expected: %lx\n",
1686 test_num, int2str->value, int2str->base, result, int2str->result);
1687 if (result == STATUS_SUCCESS) {
1688 ok(unicode_string.Buffer[unicode_string.Length/sizeof(WCHAR)] == '\0',
1689 "(test %d): RtlIntegerToUnicodeString(%lu, %d, [out]) string \"%s\" is not NULL terminated\n",
1690 test_num, int2str->value, int2str->base, ansi_str.Buffer);
1691 }
1692 }
1693 ok(memcmp(unicode_string.Buffer, expected_unicode_string.Buffer, STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
1694 "(test %d): RtlIntegerToUnicodeString(%lu, %d, [out]) assigns string \"%s\", expected: \"%s\"\n",
1695 test_num, int2str->value, int2str->base, ansi_str.Buffer, expected_ansi_str.Buffer);
1696 ok(unicode_string.Length == expected_unicode_string.Length ||
1697 broken(int2str->broken_len && !unicode_string.Length) /* win11 */,
1698 "(test %d): RtlIntegerToUnicodeString(%lu, %d, [out]) string has Length %d, expected: %d\n",
1699 test_num, int2str->value, int2str->base, unicode_string.Length, expected_unicode_string.Length);
1700 ok(unicode_string.MaximumLength == expected_unicode_string.MaximumLength,
1701 "(test %d): RtlIntegerToUnicodeString(%lu, %d, [out]) string has MaximumLength %d, expected: %d\n",
1702 test_num, int2str->value, int2str->base, unicode_string.MaximumLength, expected_unicode_string.MaximumLength);
1703 pRtlFreeAnsiString(&expected_ansi_str);
1704 pRtlFreeAnsiString(&ansi_str);
1705}
1706
1707
1709{
1710 size_t test_num;
1711
1712 for (test_num = 0; test_num < ARRAY_SIZE(int2str); test_num++)
1713 one_RtlIntegerToUnicodeString_test(test_num, &int2str[test_num]);
1714}
1715
1716
1717static void one_RtlIntegerToChar_test(int test_num, const int2str_t *int2str)
1718{
1720 char dest_str[STRI_BUFFER_LENGTH + 1];
1721
1722 memset(dest_str, '-', STRI_BUFFER_LENGTH);
1723 dest_str[STRI_BUFFER_LENGTH] = '\0';
1724 result = pRtlIntegerToChar(int2str->value, int2str->base, int2str->MaximumLength, dest_str);
1725 ok(result == int2str->result,
1726 "(test %d): RtlIntegerToChar(%lu, %d, %d, [out]) has result %lx, expected: %lx\n",
1728 ok(memcmp(dest_str, int2str->Buffer, STRI_BUFFER_LENGTH) == 0,
1729 "(test %d): RtlIntegerToChar(%lu, %d, %d, [out]) assigns string \"%s\", expected: \"%s\"\n",
1730 test_num, int2str->value, int2str->base, int2str->MaximumLength, dest_str, int2str->Buffer);
1731}
1732
1733
1734static void test_RtlIntegerToChar(void)
1735{
1737 size_t test_num;
1738
1739 for (test_num = 0; test_num < ARRAY_SIZE(int2str); test_num++)
1740 one_RtlIntegerToChar_test(test_num, &int2str[test_num]);
1741
1742 result = pRtlIntegerToChar(int2str[0].value, 20, int2str[0].MaximumLength, NULL);
1744 "(test a): RtlIntegerToChar(%lu, %d, %d, NULL) has result %lx, expected: %lx\n",
1746
1747 result = pRtlIntegerToChar(int2str[0].value, 20, 0, NULL);
1749 "(test b): RtlIntegerToChar(%lu, %d, %d, NULL) has result %lx, expected: %lx\n",
1751
1752 result = pRtlIntegerToChar(int2str[0].value, int2str[0].base, 0, NULL);
1754 "(test c): RtlIntegerToChar(%lu, %d, %d, NULL) has result %lx, expected: %lx\n",
1756
1757 result = pRtlIntegerToChar(int2str[0].value, int2str[0].base, int2str[0].MaximumLength, NULL);
1759 "(test d): RtlIntegerToChar(%lu, %d, %d, NULL) has result %lx, expected: %lx\n",
1761}
1762
1763static void test_RtlIsTextUnicode(void)
1764{
1765 char ascii[] = "A simple string";
1766 char false_positive[] = {0x41, 0x0a, 0x0d, 0x1d};
1767 WCHAR false_negative = 0x0d0a;
1768 WCHAR unicode[] = {'A',' ','U','n','i','c','o','d','e',' ','s','t','r','i','n','g',0};
1769 WCHAR unicode_no_controls[] = {'A','U','n','i','c','o','d','e','s','t','r','i','n','g',0};
1770 /* String with both byte-reversed and standard Unicode control characters. */
1771 WCHAR mixed_controls[] = {'\t',0x9000,0x0d00,'\n',0};
1772 WCHAR *be_unicode;
1773 WCHAR *be_unicode_no_controls;
1774 BOOLEAN res;
1775 int flags;
1776 int i;
1777
1778 if (!pRtlIsTextUnicode)
1779 {
1780 win_skip("RtlIsTextUnicode is not available\n");
1781 return;
1782 }
1783
1784 ok(!pRtlIsTextUnicode(ascii, sizeof(ascii), NULL), "ASCII text detected as Unicode\n");
1785
1786 res = pRtlIsTextUnicode(unicode, sizeof(unicode), NULL);
1787 ok(res ||
1788 broken(res == FALSE), /* NT4 */
1789 "Text should be Unicode\n");
1790
1791 ok(!pRtlIsTextUnicode(unicode, sizeof(unicode) - 1, NULL), "Text should be Unicode\n");
1792
1794 ok(pRtlIsTextUnicode(unicode, sizeof(unicode), &flags), "Text should not pass a Unicode\n");
1796 "Expected flags 0x6, obtained %x\n", flags);
1797
1799 ok(!pRtlIsTextUnicode(unicode, sizeof(unicode), &flags), "Text should not pass reverse Unicode tests\n");
1800 ok(flags == 0, "Expected flags 0, obtained %x\n", flags);
1801
1803 ok(!pRtlIsTextUnicode(unicode, sizeof(unicode) - 1, &flags), "Odd length test should have passed\n");
1804 ok(flags == IS_TEXT_UNICODE_ODD_LENGTH, "Expected flags 0x200, obtained %x\n", flags);
1805
1806 be_unicode = HeapAlloc(GetProcessHeap(), 0, sizeof(unicode) + sizeof(WCHAR));
1807 be_unicode[0] = 0xfffe;
1808 for (i = 0; i < ARRAY_SIZE(unicode); i++)
1809 {
1810 be_unicode[i + 1] = (unicode[i] >> 8) | ((unicode[i] & 0xff) << 8);
1811 }
1812 ok(!pRtlIsTextUnicode(be_unicode, sizeof(unicode) + 2, NULL), "Reverse endian should not be Unicode\n");
1813 ok(!pRtlIsTextUnicode(&be_unicode[1], sizeof(unicode), NULL), "Reverse endian should not be Unicode\n");
1814
1816 ok(!pRtlIsTextUnicode(&be_unicode[1], sizeof(unicode), &flags), "Reverse endian should be Unicode\n");
1817 todo_wine
1819 "Expected flags 0x70, obtained %x\n", flags);
1820
1822 ok(!pRtlIsTextUnicode(be_unicode, sizeof(unicode) + 2, &flags), "Reverse endian should be Unicode\n");
1824 "Expected flags 0xc0, obtained %x\n", flags);
1825
1826 /* build byte reversed unicode string with no control chars */
1827 be_unicode_no_controls = HeapAlloc(GetProcessHeap(), 0, sizeof(unicode) + sizeof(WCHAR));
1828 ok(be_unicode_no_controls != NULL, "Expected HeapAlloc to succeed.\n");
1829 be_unicode_no_controls[0] = 0xfffe;
1830 for (i = 0; i < ARRAY_SIZE(unicode_no_controls); i++)
1831 be_unicode_no_controls[i + 1] = (unicode_no_controls[i] >> 8) | ((unicode_no_controls[i] & 0xff) << 8);
1832
1833
1834 /* The following tests verify that the tests for */
1835 /* IS_TEXT_UNICODE_CONTROLS and IS_TEXT_UNICODE_REVERSE_CONTROLS */
1836 /* are not mutually exclusive. Regardless of whether the strings */
1837 /* contain an indication of endianness, the tests are still */
1838 /* run if the flag is passed to (Rtl)IsTextUnicode. */
1839
1840 /* Test IS_TEXT_UNICODE_CONTROLS flag */
1842 ok(!pRtlIsTextUnicode(unicode_no_controls, sizeof(unicode_no_controls), &flags), "Test should not pass on Unicode string lacking control characters.\n");
1843 ok(flags == 0, "Expected flags 0x0, obtained %x\n", flags);
1844
1846 ok(!pRtlIsTextUnicode(be_unicode_no_controls, sizeof(unicode_no_controls), &flags), "Test should not pass on byte-reversed Unicode string lacking control characters.\n");
1847 ok(flags == 0, "Expected flags 0x0, obtained %x\n", flags);
1848
1850 ok(pRtlIsTextUnicode(unicode, sizeof(unicode), &flags), "Test should pass on Unicode string lacking control characters.\n");
1851 ok(flags == IS_TEXT_UNICODE_CONTROLS, "Expected flags 0x04, obtained %x\n", flags);
1852
1854 ok(!pRtlIsTextUnicode(be_unicode_no_controls, sizeof(unicode_no_controls) + 2, &flags),
1855 "Test should not pass with standard Unicode string.\n");
1856 ok(flags == 0, "Expected flags 0x0, obtained %x\n", flags);
1857
1859 ok(pRtlIsTextUnicode(mixed_controls, sizeof(mixed_controls), &flags), "Test should pass on a string containing control characters.\n");
1860 ok(flags == IS_TEXT_UNICODE_CONTROLS, "Expected flags 0x04, obtained %x\n", flags);
1861
1862 /* Test IS_TEXT_UNICODE_REVERSE_CONTROLS flag */
1864 ok(!pRtlIsTextUnicode(be_unicode_no_controls, sizeof(unicode_no_controls), &flags), "Test should not pass on Unicode string lacking control characters.\n");
1865 ok(flags == 0, "Expected flags 0x0, obtained %x\n", flags);
1866
1868 ok(!pRtlIsTextUnicode(unicode_no_controls, sizeof(unicode_no_controls), &flags), "Test should not pass on Unicode string lacking control characters.\n");
1869 ok(flags == 0, "Expected flags 0x0, obtained %x\n", flags);
1870
1872 ok(!pRtlIsTextUnicode(unicode, sizeof(unicode), &flags), "Test should not pass on Unicode string lacking control characters.\n");
1873 ok(flags == 0, "Expected flags 0x0, obtained %x\n", flags);
1874
1876 ok(!pRtlIsTextUnicode(be_unicode, sizeof(unicode) + 2, &flags),
1877 "Test should pass with byte-reversed Unicode string containing control characters.\n");
1878 ok(flags == IS_TEXT_UNICODE_REVERSE_CONTROLS, "Expected flags 0x40, obtained %x\n", flags);
1879
1881 ok(!pRtlIsTextUnicode(mixed_controls, sizeof(mixed_controls), &flags), "Test should pass on a string containing byte-reversed control characters.\n");
1882 ok(flags == IS_TEXT_UNICODE_REVERSE_CONTROLS, "Expected flags 0x40, obtained %x\n", flags);
1883
1884 /* Test with flags for both byte-reverse and standard Unicode characters */
1886 ok(!pRtlIsTextUnicode(mixed_controls, sizeof(mixed_controls), &flags), "Test should pass on string containing both byte-reversed and standard control characters.\n");
1887 ok(flags == (IS_TEXT_UNICODE_CONTROLS | IS_TEXT_UNICODE_REVERSE_CONTROLS), "Expected flags 0x44, obtained %x\n", flags);
1888
1890 todo_wine ok(pRtlIsTextUnicode(false_positive, sizeof(false_positive), &flags), "Test should pass on false positive.\n");
1891
1892 ok(!pRtlIsTextUnicode(&false_negative, sizeof(false_negative), NULL), "Test should fail on 0x0d0a (MALAYALAM LETTER UU).\n");
1893
1894 HeapFree(GetProcessHeap(), 0, be_unicode);
1895 HeapFree(GetProcessHeap(), 0, be_unicode_no_controls);
1896}
1897
1899{
1900 WCHAR ch1, ch2;
1902
1903 str1.Buffer = &ch1;
1904 str1.Length = str1.MaximumLength = sizeof(WCHAR);
1905 str2.Buffer = &ch2;
1906 str2.Length = str2.MaximumLength = sizeof(WCHAR);
1907 for (ch1 = 0; ch1 < 512; ch1++)
1908 {
1909 for (ch2 = 0; ch2 < 1024; ch2++)
1910 {
1911 LONG res = pRtlCompareUnicodeString( &str1, &str2, FALSE );
1912 ok( res == (ch1 - ch2), "wrong result %ld %04x %04x\n", res, ch1, ch2 );
1913 res = pRtlCompareUnicodeString( &str1, &str2, TRUE );
1914 ok( res == (pRtlUpcaseUnicodeChar(ch1) - pRtlUpcaseUnicodeChar(ch2)),
1915 "wrong result %ld %04x %04x\n", res, ch1, ch2 );
1916 if (pRtlCompareUnicodeStrings)
1917 {
1918 res = pRtlCompareUnicodeStrings( &ch1, 1, &ch2, 1, FALSE );
1919 ok( res == (ch1 - ch2), "wrong result %ld %04x %04x\n", res, ch1, ch2 );
1920 res = pRtlCompareUnicodeStrings( &ch1, 1, &ch2, 1, TRUE );
1921 ok( res == (pRtlUpcaseUnicodeChar(ch1) - pRtlUpcaseUnicodeChar(ch2)),
1922 "wrong result %ld %04x %04x\n", res, ch1, ch2 );
1923 }
1924 }
1925 }
1926}
1927
1928static const WCHAR szGuid[] = { '{','0','1','0','2','0','3','0','4','-',
1929 '0','5','0','6','-' ,'0','7','0','8','-','0','9','0','A','-',
1930 '0','B','0','C','0','D','0','E','0','F','0','A','}','\0' };
1931static const WCHAR szGuid2[] = { '{','0','1','0','2','0','3','0','4','-',
1932 '0','5','0','6','-' ,'0','7','0','8','-','0','9','0','A','-',
1933 '0','B','0','C','0','D','0','E','0','F','0','A',']','\0' };
1934DEFINE_GUID(IID_Endianness, 0x01020304, 0x0506, 0x0708, 0x09, 0x0A, 0x0B,
1935 0x0C, 0x0D, 0x0E, 0x0F, 0x0A);
1936
1937static void test_RtlGUIDFromString(void)
1938{
1939 GUID guid;
1941 NTSTATUS ret;
1942
1943 if (!pRtlGUIDFromString)
1944 {
1945 win_skip("RtlGUIDFromString is not available\n");
1946 return;
1947 }
1948
1949 str.Length = str.MaximumLength = sizeof(szGuid) - sizeof(WCHAR);
1950 str.Buffer = (LPWSTR)szGuid;
1951
1952 ret = pRtlGUIDFromString(&str, &guid);
1953 ok(ret == 0, "expected ret=0, got 0x%0lx\n", ret);
1954 ok(IsEqualGUID(&guid, &IID_Endianness), "Endianness broken\n");
1955
1956 str.Length = str.MaximumLength = sizeof(szGuid2) - sizeof(WCHAR);
1957 str.Buffer = (LPWSTR)szGuid2;
1958
1959 ret = pRtlGUIDFromString(&str, &guid);
1960 ok(ret, "expected ret!=0\n");
1961}
1962
1963static void test_RtlStringFromGUID(void)
1964{
1966 NTSTATUS ret;
1967
1968 if (!pRtlStringFromGUID)
1969 {
1970 win_skip("RtlStringFromGUID is not available\n");
1971 return;
1972 }
1973
1974 str.Length = str.MaximumLength = 0;
1975 str.Buffer = NULL;
1976
1977 ret = pRtlStringFromGUID(&IID_Endianness, &str);
1978 ok(ret == 0, "expected ret=0, got 0x%0lx\n", ret);
1979 ok(str.Buffer && !lstrcmpiW(str.Buffer, szGuid), "Endianness broken\n");
1980 pRtlFreeUnicodeString(&str);
1981}
1982
1987};
1988
1989static const struct hash_unicodestring_test hash_test[] = {
1990 { L"T", FALSE, 0x00000054 },
1991 { L"Test", FALSE, 0x766bb952 },
1992 { L"TeSt", FALSE, 0x764bb172 },
1993 { L"test", FALSE, 0x4745d132 },
1994 { L"test", TRUE, 0x6689c132 },
1995 { L"TEST", TRUE, 0x6689c132 },
1996 { L"TEST", FALSE, 0x6689c132 },
1997 { L"t\xe9st", FALSE, 0x8845cfb6 },
1998 { L"t\xe9st", TRUE, 0xa789bfb6 },
1999 { L"T\xc9ST", TRUE, 0xa789bfb6 },
2000 { L"T\xc9ST", FALSE, 0xa789bfb6 },
2001 { L"abcdef", FALSE, 0x971318c3 },
2002 { { 0 } }
2003};
2004
2006{
2007 static const WCHAR strW[] = {'T','e','s','t',0,'1',0};
2008 const struct hash_unicodestring_test *ptr;
2011 ULONG hash;
2012
2013 if (!pRtlHashUnicodeString)
2014 {
2015 win_skip("RtlHashUnicodeString is not available\n");
2016 return;
2017 }
2018
2019 status = pRtlHashUnicodeString(NULL, FALSE, HASH_STRING_ALGORITHM_X65599, &hash);
2020 ok(status == STATUS_INVALID_PARAMETER, "got status 0x%08lx\n", status);
2021
2022 pRtlInitUnicodeString(&str, strW);
2023 status = pRtlHashUnicodeString(&str, FALSE, HASH_STRING_ALGORITHM_X65599, NULL);
2024 ok(status == STATUS_INVALID_PARAMETER, "got status 0x%08lx\n", status);
2025
2026 status = pRtlHashUnicodeString(&str, FALSE, HASH_STRING_ALGORITHM_INVALID, &hash);
2027 ok(status == STATUS_INVALID_PARAMETER, "got status 0x%08lx\n", status);
2028
2029 /* embedded null */
2030 str.Buffer = (PWSTR)strW;
2031 str.Length = sizeof(strW) - sizeof(WCHAR);
2032 str.MaximumLength = sizeof(strW);
2033 status = pRtlHashUnicodeString(&str, FALSE, HASH_STRING_ALGORITHM_X65599, &hash);
2034 ok(status == STATUS_SUCCESS, "got status 0x%08lx\n", status);
2035 ok(hash == 0x32803083, "got 0x%08lx\n", hash);
2036
2037 ptr = hash_test;
2038 while (*ptr->str)
2039 {
2040 pRtlInitUnicodeString(&str, ptr->str);
2041 hash = 0;
2042 status = pRtlHashUnicodeString(&str, ptr->case_insensitive, HASH_STRING_ALGORITHM_X65599, &hash);
2043 ok(status == STATUS_SUCCESS, "got status 0x%08lx for %s\n", status, wine_dbgstr_w(ptr->str));
2044 ok(hash == ptr->hash, "got wrong hash 0x%08lx, expected 0x%08lx, for %s, mode %d\n", hash, ptr->hash,
2045 wine_dbgstr_w(ptr->str), ptr->case_insensitive);
2046
2047 ptr++;
2048 }
2049}
2050
2053 const char *expected;
2055};
2056
2057static const struct unicode_to_utf8_test unicode_to_utf8[] = {
2058 { { 0 }, "", STATUS_SUCCESS },
2059 { { '-',0 }, "-", STATUS_SUCCESS },
2060 { { 'h','e','l','l','o',0 }, "hello", STATUS_SUCCESS },
2061 { { '-',0x7f,'-',0x80,'-',0xff,'-',0x100,'-',0 }, "-\x7F-\xC2\x80-\xC3\xBF-\xC4\x80-", STATUS_SUCCESS },
2062 { { '-',0x7ff,'-',0x800,'-',0 }, "-\xDF\xBF-\xE0\xA0\x80-", STATUS_SUCCESS },
2063 { { '-',0xd7ff,'-',0xe000,'-',0 }, "-\xED\x9F\xBF-\xEE\x80\x80-", STATUS_SUCCESS },
2064 /* 0x10000 */
2065 { { '-',0xffff,'-',0xd800,0xdc00,'-',0 }, "-\xEF\xBF\xBF-\xF0\x90\x80\x80-", STATUS_SUCCESS },
2066 /* 0x103ff */ /* 0x10400 */
2067 { { '-',0xd800,0xdfff,'-',0xd801,0xdc00,'-',0 }, "-\xF0\x90\x8F\xBF-\xF0\x90\x90\x80-", STATUS_SUCCESS },
2068 /* 0x10ffff */
2069 { { '-',0xdbff,0xdfff,'-',0 }, "-\xF4\x8F\xBF\xBF-", STATUS_SUCCESS },
2070 /* standalone lead surrogates become 0xFFFD */
2071 { { '-',0xd800,'-',0xdbff,'-',0 }, "-\xEF\xBF\xBD-\xEF\xBF\xBD-", STATUS_SOME_NOT_MAPPED },
2072 /* standalone trail surrogates become 0xFFFD */
2073 { { '-',0xdc00,'-',0xdfff,'-',0 }, "-\xEF\xBF\xBD-\xEF\xBF\xBD-", STATUS_SOME_NOT_MAPPED },
2074 /* reverse surrogate pair */
2075 { { '-',0xdfff,0xdbff,'-',0 }, "-\xEF\xBF\xBD\xEF\xBF\xBD-", STATUS_SOME_NOT_MAPPED },
2076 /* byte order marks */
2077 { { '-',0xfeff,'-',0xfffe,'-',0 }, "-\xEF\xBB\xBF-\xEF\xBF\xBE-", STATUS_SUCCESS },
2078 { { 0xfeff,'-',0 }, "\xEF\xBB\xBF-", STATUS_SUCCESS },
2079 { { 0xfffe,'-',0 }, "\xEF\xBF\xBE-", STATUS_SUCCESS },
2080 /* invalid code points */
2081 { { 0xfffd, '-', 0xfffe, '-', 0xffff,'-',0 }, "\xEF\xBF\xBD-\xEF\xBF\xBE-\xEF\xBF\xBF-", STATUS_SUCCESS },
2082 /* canonically equivalent representations -- no normalization should happen */
2083 { { '-',0x1e09,'-',0 }, "-\xE1\xB8\x89-", STATUS_SUCCESS },
2084 { { '-',0x0107,0x0327,'-',0 }, "-\xC4\x87\xCC\xA7-", STATUS_SUCCESS },
2085 { { '-',0x00e7,0x0301,'-',0 }, "-\xC3\xA7\xCC\x81-", STATUS_SUCCESS },
2086 { { '-',0x0063,0x0327,0x0301,'-',0 }, "-\x63\xCC\xA7\xCC\x81-", STATUS_SUCCESS },
2087 { { '-',0x0063,0x0301,0x0327,'-',0 }, "-\x63\xCC\x81\xCC\xA7-", STATUS_SUCCESS },
2088};
2089
2090static void utf8_expect_(const unsigned char *out_string, ULONG buflen, ULONG out_bytes,
2091 const WCHAR *in_string, ULONG in_bytes,
2092 NTSTATUS expect_status, int line)
2093{
2095 ULONG bytes_out;
2096 char buffer[128];
2097 unsigned char *buf = (unsigned char *)buffer;
2098 unsigned int i;
2099
2100 if (buflen == (ULONG)-1)
2101 buflen = sizeof(buffer);
2102 bytes_out = 0x55555555;
2103 memset(buffer, 0x55, sizeof(buffer));
2104 status = pRtlUnicodeToUTF8N(
2105 out_string ? buffer : NULL, buflen, &bytes_out,
2106 in_string, in_bytes);
2107 ok_(__FILE__, line)(status == expect_status, "status 0x%lx, expected 0x%lx\n", status, expect_status);
2108 ok_(__FILE__, line)(bytes_out == out_bytes, "bytes_out = %lu, expected %lu\n", bytes_out, out_bytes);
2109 if (out_string)
2110 {
2111 for (i = 0; i < bytes_out; i++)
2112 ok_(__FILE__, line)(buf[i] == out_string[i],
2113 "buffer[%d] = 0x%x, expected 0x%x\n",
2114 i, buf[i], out_string[i]);
2115 for (; i < sizeof(buffer); i++)
2116 ok_(__FILE__, line)(buf[i] == 0x55,
2117 "buffer[%d] = 0x%x, expected 0x55\n",
2118 i, buf[i]);
2119 }
2120}
2121#define utf8_expect(out_string, buflen, out_bytes, in_string, in_bytes, expect_status) \
2122 utf8_expect_(out_string, buflen, out_bytes, in_string, in_bytes, expect_status, __LINE__)
2123
2124static void test_RtlUnicodeToUTF8N(void)
2125{
2127 ULONG bytes_out;
2128 ULONG bytes_out_array[2];
2129 void * const invalid_pointer = (void *)0x8;
2130 char buffer[128];
2131 const WCHAR empty_string[] = { 0 };
2132 const WCHAR test_string[] = { 'A',0,'a','b','c','d','e','f','g',0 };
2133 const WCHAR special_string[] = { 'X',0x80,0xd800,0 };
2134 const ULONG special_string_len[] = { 0, 1, 1, 3, 3, 3, 6, 7 };
2135 const unsigned char special_expected[] = { 'X',0xc2,0x80,0xef,0xbf,0xbd,0 };
2136 unsigned int input_len;
2137 const unsigned int test_count = ARRAY_SIZE(unicode_to_utf8);
2138 unsigned int i, ret;
2139
2140 if (!pRtlUnicodeToUTF8N)
2141 {
2142 win_skip("RtlUnicodeToUTF8N is not available\n");
2143 return;
2144 }
2145
2146 /* show that bytes_out is really ULONG */
2147 memset(bytes_out_array, 0x55, sizeof(bytes_out_array));
2148 status = pRtlUnicodeToUTF8N(NULL, 0, bytes_out_array, empty_string, 0);
2149 ok(status == STATUS_SUCCESS, "status = 0x%lx\n", status);
2150 ok(bytes_out_array[0] == 0x00000000, "Got 0x%lx\n", bytes_out_array[0]);
2151 ok(bytes_out_array[1] == 0x55555555, "Got 0x%lx\n", bytes_out_array[1]);
2152
2153 /* parameter checks */
2154 status = pRtlUnicodeToUTF8N(NULL, 0, NULL, NULL, 0);
2155 ok(status == STATUS_INVALID_PARAMETER_4, "status = 0x%lx\n", status);
2156
2157 status = pRtlUnicodeToUTF8N(NULL, 0, NULL, empty_string, 0);
2158 ok(status == STATUS_INVALID_PARAMETER, "status = 0x%lx\n", status);
2159
2160 bytes_out = 0x55555555;
2161 status = pRtlUnicodeToUTF8N(NULL, 0, &bytes_out, NULL, 0);
2162 ok(status == STATUS_INVALID_PARAMETER_4, "status = 0x%lx\n", status);
2163 ok(bytes_out == 0x55555555, "bytes_out = 0x%lx\n", bytes_out);
2164
2165 bytes_out = 0x55555555;
2166 status = pRtlUnicodeToUTF8N(NULL, 0, &bytes_out, invalid_pointer, 0);
2167 ok(status == STATUS_SUCCESS, "status = 0x%lx\n", status);
2168 ok(bytes_out == 0, "bytes_out = 0x%lx\n", bytes_out);
2169
2170 bytes_out = 0x55555555;
2171 status = pRtlUnicodeToUTF8N(NULL, 0, &bytes_out, empty_string, 0);
2172 ok(status == STATUS_SUCCESS, "status = 0x%lx\n", status);
2173 ok(bytes_out == 0, "bytes_out = 0x%lx\n", bytes_out);
2174
2175 bytes_out = 0x55555555;
2176 status = pRtlUnicodeToUTF8N(NULL, 0, &bytes_out, test_string, 0);
2177 ok(status == STATUS_SUCCESS, "status = 0x%lx\n", status);
2178 ok(bytes_out == 0, "bytes_out = 0x%lx\n", bytes_out);
2179
2180 bytes_out = 0x55555555;
2181 status = pRtlUnicodeToUTF8N(NULL, 0, &bytes_out, empty_string, 1);
2182 ok(status == STATUS_SUCCESS, "status = 0x%lx\n", status);
2183 ok(bytes_out == 0, "bytes_out = 0x%lx\n", bytes_out);
2184
2185 bytes_out = 0x55555555;
2186 status = pRtlUnicodeToUTF8N(invalid_pointer, 0, &bytes_out, empty_string, 1);
2187 ok(status == STATUS_INVALID_PARAMETER_5, "status = 0x%lx\n", status);
2188 ok(bytes_out == 0x55555555, "bytes_out = 0x%lx\n", bytes_out);
2189
2190 bytes_out = 0x55555555;
2191 status = pRtlUnicodeToUTF8N(invalid_pointer, 8, &bytes_out, empty_string, 1);
2192 ok(status == STATUS_INVALID_PARAMETER_5, "status = 0x%lx\n", status);
2193 ok(bytes_out == 0x55555555, "bytes_out = 0x%lx\n", bytes_out);
2194
2195 /* length output with special chars */
2196#define length_expect(in_chars, out_bytes, expect_status) \
2197 utf8_expect_(NULL, 0, out_bytes, \
2198 special_string, in_chars * sizeof(WCHAR), \
2199 expect_status, __LINE__)
2200
2206#undef length_expect
2207
2208 for (i = 0; i <= 6; i++)
2209 {
2210 memset(buffer, 0x55, sizeof(buffer));
2211 bytes_out = 0xdeadbeef;
2212 status = pRtlUnicodeToUTF8N(buffer, i, &bytes_out, special_string, sizeof(special_string));
2213 ok(status == STATUS_BUFFER_TOO_SMALL, "%d: status = 0x%lx\n", i, status);
2214 ok(bytes_out == special_string_len[i], "%d: expected %lu, got %lu\n", i, special_string_len[i], bytes_out);
2215 ok(memcmp(buffer, special_expected, special_string_len[i]) == 0, "%d: bad conversion\n", i);
2216 }
2217
2218 status = pRtlUnicodeToUTF8N(buffer, 7, &bytes_out, special_string, sizeof(special_string));
2219 ok(status == STATUS_SOME_NOT_MAPPED, "status = 0x%lx\n", status);
2220 ok(bytes_out == special_string_len[7], "expected %lu, got %lu\n", special_string_len[7], bytes_out);
2221 ok(memcmp(buffer, special_expected, 7) == 0, "bad conversion\n");
2222
2223 /* conversion behavior with varying input length */
2224 for (input_len = 0; input_len <= sizeof(test_string); input_len++) {
2225 /* no output buffer, just length */
2226 utf8_expect(NULL, 0, input_len / sizeof(WCHAR),
2227 test_string, input_len, STATUS_SUCCESS);
2228
2229 /* write output */
2230 bytes_out = 0x55555555;
2231 memset(buffer, 0x55, sizeof(buffer));
2232 status = pRtlUnicodeToUTF8N(
2233 buffer, sizeof(buffer), &bytes_out,
2234 test_string, input_len);
2235 if (input_len % sizeof(WCHAR) == 0) {
2237 "(len %u): status = 0x%lx\n", input_len, status);
2238 ok(bytes_out == input_len / sizeof(WCHAR),
2239 "(len %u): bytes_out = 0x%lx\n", input_len, bytes_out);
2240 for (i = 0; i < bytes_out; i++) {
2241 ok(buffer[i] == test_string[i],
2242 "(len %u): buffer[%d] = 0x%x, expected 0x%x\n",
2243 input_len, i, buffer[i], test_string[i]);
2244 }
2245 for (; i < sizeof(buffer); i++) {
2246 ok(buffer[i] == 0x55,
2247 "(len %u): buffer[%d] = 0x%x\n", input_len, i, buffer[i]);
2248 }
2249 } else {
2251 "(len %u): status = 0x%lx\n", input_len, status);
2252 ok(bytes_out == 0x55555555,
2253 "(len %u): bytes_out = 0x%lx\n", input_len, bytes_out);
2254 for (i = 0; i < sizeof(buffer); i++) {
2255 ok(buffer[i] == 0x55,
2256 "(len %u): buffer[%d] = 0x%x\n", input_len, i, buffer[i]);
2257 }
2258 }
2259 }
2260
2261 /* test cases for special characters */
2262 for (i = 0; i < test_count; i++) {
2263 bytes_out = 0x55555555;
2264 memset(buffer, 0x55, sizeof(buffer));
2265 status = pRtlUnicodeToUTF8N(
2266 buffer, sizeof(buffer), &bytes_out,
2269 "(test %d): status is 0x%lx, expected 0x%lx\n",
2271 ok(bytes_out == strlen(unicode_to_utf8[i].expected),
2272 "(test %d): bytes_out is %lu, expected %u\n",
2273 i, bytes_out, lstrlenA(unicode_to_utf8[i].expected));
2274 ok(!memcmp(buffer, unicode_to_utf8[i].expected, bytes_out),
2275 "(test %d): got \"%.*s\", expected \"%s\"\n",
2276 i, (int)bytes_out, buffer, unicode_to_utf8[i].expected);
2277 ok(buffer[bytes_out] == 0x55,
2278 "(test %d): behind string: 0x%x\n", i, buffer[bytes_out]);
2279 memset(buffer, 0x55, sizeof(buffer));
2281 buffer, sizeof(buffer), NULL, NULL );
2282 ok( ret == strlen(unicode_to_utf8[i].expected), "(test %d): wrong len %u\n", i, ret );
2284 "(test %d): got \"%.*s\", expected \"%s\"\n",
2286 ok(buffer[ret] == 0x55, "(test %d): behind string: 0x%x\n", i, buffer[ret]);
2287
2288 /* same test but include the null terminator */
2289 bytes_out = 0x55555555;
2290 memset(buffer, 0x55, sizeof(buffer));
2291 status = pRtlUnicodeToUTF8N(
2292 buffer, sizeof(buffer), &bytes_out,
2295 "(test %d): status is 0x%lx, expected 0x%lx\n",
2297 ok(bytes_out == strlen(unicode_to_utf8[i].expected) + 1,
2298 "(test %d): bytes_out is %lu, expected %u\n",
2299 i, bytes_out, lstrlenA(unicode_to_utf8[i].expected) + 1);
2300 ok(!memcmp(buffer, unicode_to_utf8[i].expected, bytes_out),
2301 "(test %d): got \"%.*s\", expected \"%s\"\n",
2302 i, (int)bytes_out, buffer, unicode_to_utf8[i].expected);
2303 ok(buffer[bytes_out] == 0x55,
2304 "(test %d): behind string: 0x%x\n", i, buffer[bytes_out]);
2305 memset(buffer, 0x55, sizeof(buffer));
2307 ok( ret == strlen(unicode_to_utf8[i].expected) + 1, "(test %d): wrong len %u\n", i, ret );
2309 "(test %d): got \"%.*s\", expected \"%s\"\n",
2311 ok(buffer[ret] == 0x55, "(test %d): behind string: 0x%x\n", i, buffer[ret]);
2312 SetLastError( 0xdeadbeef );
2313 memset(buffer, 0x55, sizeof(buffer));
2315 buffer, sizeof(buffer), NULL, NULL );
2317 {
2318 ok( ret == 0, "(test %d): wrong len %u\n", i, ret );
2319 ok( GetLastError() == ERROR_NO_UNICODE_TRANSLATION, "(test %d): wrong error %lu\n", i, GetLastError() );
2321 }
2322 else
2323 ok( ret == strlen(unicode_to_utf8[i].expected) + 1, "(test %d): wrong len %u\n", i, ret );
2324
2326 "(test %d): got \"%.*s\", expected \"%s\"\n",
2328 ok(buffer[ret] == 0x55, "(test %d): behind string: 0x%x\n", i, buffer[ret]);
2329 }
2330}
2331
2333 const char *utf8;
2336};
2337
2338static const struct utf8_to_unicode_test utf8_to_unicode[] = {
2339 { "", { 0 }, STATUS_SUCCESS },
2340 { "-", { '-',0 }, STATUS_SUCCESS },
2341 { "hello", { 'h','e','l','l','o',0 }, STATUS_SUCCESS },
2342 /* first and last of each range */
2343 { "-\x7F-\xC2\x80-\xC3\xBF-\xC4\x80-", { '-',0x7f,'-',0x80,'-',0xff,'-',0x100,'-',0 }, STATUS_SUCCESS },
2344 { "-\xDF\xBF-\xE0\xA0\x80-", { '-',0x7ff,'-',0x800,'-',0 }, STATUS_SUCCESS },
2345 { "-\xED\x9F\xBF-\xEE\x80\x80-", { '-',0xd7ff,'-',0xe000,'-',0 }, STATUS_SUCCESS },
2346 /* 0x10000 */
2347 { "-\xEF\xBF\xBF-\xF0\x90\x80\x80-", { '-',0xffff,'-',0xd800,0xdc00,'-',0 }, STATUS_SUCCESS },
2348 /* 0x103ff */ /* 0x10400 */
2349 { "-\xF0\x90\x8F\xBF-\xF0\x90\x90\x80-", { '-',0xd800,0xdfff,'-',0xd801,0xdc00,'-',0 }, STATUS_SUCCESS },
2350 /* 0x10ffff */
2351 { "-\xF4\x8F\xBF\xBF-", { '-',0xdbff,0xdfff,'-',0 }, STATUS_SUCCESS },
2352 /* standalone surrogate code points */
2353 /* 0xd800 */ /* 0xdbff */
2354 { "-\xED\xA0\x80-\xED\xAF\xBF-", { '-',0xfffd,0xfffd,'-',0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2355 /* 0xdc00 */ /* 0xdfff */
2356 { "-\xED\xB0\x80-\xED\xBF\xBF-", { '-',0xfffd,0xfffd,'-',0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2357 /* UTF-8 encoded surrogate pair */
2358 /* 0xdbff *//* 0xdfff */
2359 { "-\xED\xAF\xBF\xED\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2360 /* reverse surrogate pair */
2361 /* 0xdfff *//* 0xdbff */
2362 { "-\xED\xBF\xBF\xED\xAF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2363 /* code points outside the UTF-16 range */
2364 /* 0x110000 */
2365 { "-\xF4\x90\x80\x80-", { '-',0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2366 /* 0x1fffff */
2367 { "-\xF7\xBF\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2368 /* 0x200000 */
2369 { "-\xFA\x80\x80\x80\x80-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2370 /* 0x3ffffff */
2371 { "-\xFB\xBF\xBF\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2372 /* 0x4000000 */
2373 { "-\xFC\x84\x80\x80\x80\x80-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2374 /* 0x7fffffff */
2375 { "-\xFD\xBF\xBF\xBF\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2376 /* overlong encodings of each length for -, NUL, and the highest possible value */
2377 { "-\xC0\xAD-\xC0\x80-\xC1\xBF-", { '-',0xfffd,0xfffd,'-',0xfffd,0xfffd,'-',0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2378 { "-\xE0\x80\xAD-\xE0\x80\x80-\xE0\x9F\xBF-", { '-',0xfffd,0xfffd,'-',0xfffd,0xfffd,'-',0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2379 { "-\xF0\x80\x80\xAD-", { '-',0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2380 { "-\xF0\x80\x80\x80-", { '-',0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2381 { "-\xF0\x8F\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2382 { "-\xF8\x80\x80\x80\xAD-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2383 { "-\xF8\x80\x80\x80\x80-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2384 { "-\xF8\x87\xBF\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2385 { "-\xFC\x80\x80\x80\x80\xAD-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2386 { "-\xFC\x80\x80\x80\x80\x80-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2387 { "-\xFC\x83\xBF\xBF\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2388 /* invalid bytes */
2389 { "\xFE", { 0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
2390 { "\xFF", { 0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
2391 { "\xFE\xBF\xBF\xBF\xBF\xBF\xBF\xBF\xBF", { 0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
2392 { "\xFF\xBF\xBF\xBF\xBF\xBF\xBF\xBF\xBF", { 0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
2393 { "\xFF\x80\x80\x80\x80\x80\x80\x80\x80", { 0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
2394 { "\xFF\x40\x80\x80\x80\x80\x80\x80\x80", { 0xfffd,0x40,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
2395 /* lone continuation bytes */
2396 { "\x80", { 0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
2397 { "\x80\x80", { 0xfffd,0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
2398 { "\xBF", { 0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
2399 { "\xBF\xBF", { 0xfffd,0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
2400 /* incomplete sequences */
2401 { "\xC2-", { 0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2402 { "\xE0\xA0-", { 0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2403 { "\xF0\x90\x80-", { 0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2404 { "\xF4\x8F\xBF-", { 0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2405 { "\xFA\x80\x80\x80-", { 0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2406 { "\xFC\x84\x80\x80\x80-", { 0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2407 /* multibyte sequence followed by lone continuation byte */
2408 { "\xE0\xA0\x80\x80-", { 0x800,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
2409 /* byte order marks */
2410 { "-\xEF\xBB\xBF-\xEF\xBF\xBE-", { '-',0xfeff,'-',0xfffe,'-',0 }, STATUS_SUCCESS },
2411 { "\xEF\xBB\xBF-", { 0xfeff,'-',0 }, STATUS_SUCCESS },
2412 { "\xEF\xBF\xBE-", { 0xfffe,'-',0 }, STATUS_SUCCESS },
2413 /* invalid code points */
2414 { "\xEF\xBF\xBD-\xEF\xBF\xBE-\xEF\xBF\xBF-", { 0xfffd,'-',0xfffe,'-',0xffff,'-',0 }, STATUS_SUCCESS },
2415 /* canonically equivalent representations -- no normalization should happen */
2416 { "-\xE1\xB8\x89-", { '-',0x1e09,'-',0 }, STATUS_SUCCESS },
2417 { "-\xC4\x87\xCC\xA7-", { '-',0x0107,0x0327,'-',0 }, STATUS_SUCCESS },
2418 { "-\xC3\xA7\xCC\x81-", { '-',0x00e7,0x0301,'-',0 }, STATUS_SUCCESS },
2419 { "-\x63\xCC\xA7\xCC\x81-", { '-',0x0063,0x0327,0x0301,'-',0 }, STATUS_SUCCESS },
2420 { "-\x63\xCC\x81\xCC\xA7-", { '-',0x0063,0x0301,0x0327,'-',0 }, STATUS_SUCCESS },
2421};
2422
2423static void unicode_expect_(const WCHAR *out_string, ULONG buflen, ULONG out_chars,
2424 const char *in_string, ULONG in_chars,
2425 NTSTATUS expect_status, int line)
2426{
2428 ULONG bytes_out;
2429 WCHAR buffer[128];
2430 unsigned int i;
2431
2432 if (buflen == (ULONG)-1)
2433 buflen = sizeof(buffer);
2434 bytes_out = 0x55555555;
2435 memset(buffer, 0x55, sizeof(buffer));
2436 status = pRtlUTF8ToUnicodeN(
2437 out_string ? buffer : NULL, buflen, &bytes_out,
2438 in_string, in_chars);
2439 ok_(__FILE__, line)(status == expect_status, "status = 0x%lx\n", status);
2440 ok_(__FILE__, line)(bytes_out == out_chars * sizeof(WCHAR),
2441 "bytes_out = %lu, expected %lu\n", bytes_out, out_chars * (ULONG)sizeof(WCHAR));
2442 if (out_string)
2443 {
2444 for (i = 0; i < bytes_out / sizeof(WCHAR); i++)
2445 ok_(__FILE__, line)(buffer[i] == out_string[i],
2446 "buffer[%d] = 0x%x, expected 0x%x\n",
2447 i, buffer[i], out_string[i]);
2448 for (; i < ARRAY_SIZE(buffer); i++)
2449 ok_(__FILE__, line)(buffer[i] == 0x5555,
2450 "buffer[%d] = 0x%x, expected 0x5555\n",
2451 i, buffer[i]);
2452 }
2453}
2454#define unicode_expect(out_string, buflen, out_chars, in_string, in_chars, expect_status) \
2455 unicode_expect_(out_string, buflen, out_chars, in_string, in_chars, expect_status, __LINE__)
2456
2457static void test_RtlUTF8ToUnicodeN(void)
2458{
2460 ULONG bytes_out;
2461 ULONG bytes_out_array[2];
2462 void * const invalid_pointer = (void *)0x8;
2463 WCHAR buffer[128];
2464 const char empty_string[] = "";
2465 const char test_string[] = "A\0abcdefg";
2466 const WCHAR test_stringW[] = {'A',0,'a','b','c','d','e','f','g',0 };
2467 const char special_string[] = { 'X',0xc2,0x80,0xF0,0x90,0x80,0x80,0 };
2468 const WCHAR special_expected[] = { 'X',0x80,0xd800,0xdc00,0 };
2469 unsigned int input_len;
2470 const unsigned int test_count = ARRAY_SIZE(utf8_to_unicode);
2471 unsigned int i, ret;
2472
2473 if (!pRtlUTF8ToUnicodeN)
2474 {
2475 win_skip("RtlUTF8ToUnicodeN is not available\n");
2476 return;
2477 }
2478
2479 /* show that bytes_out is really ULONG */
2480 memset(bytes_out_array, 0x55, sizeof(bytes_out_array));
2481 status = pRtlUTF8ToUnicodeN(NULL, 0, bytes_out_array, empty_string, 0);
2482 ok(status == STATUS_SUCCESS, "status = 0x%lx\n", status);
2483 ok(bytes_out_array[0] == 0x00000000, "Got 0x%lx\n", bytes_out_array[0]);
2484 ok(bytes_out_array[1] == 0x55555555, "Got 0x%lx\n", bytes_out_array[1]);
2485
2486 /* parameter checks */
2487 status = pRtlUTF8ToUnicodeN(NULL, 0, NULL, NULL, 0);
2488 ok(status == STATUS_INVALID_PARAMETER_4, "status = 0x%lx\n", status);
2489
2490 status = pRtlUTF8ToUnicodeN(NULL, 0, NULL, empty_string, 0);
2491 ok(status == STATUS_INVALID_PARAMETER, "status = 0x%lx\n", status);
2492
2493 bytes_out = 0x55555555;
2494 status = pRtlUTF8ToUnicodeN(NULL, 0, &bytes_out, NULL, 0);
2495 ok(status == STATUS_INVALID_PARAMETER_4, "status = 0x%lx\n", status);
2496 ok(bytes_out == 0x55555555, "bytes_out = 0x%lx\n", bytes_out);
2497
2498 bytes_out = 0x55555555;
2499 status = pRtlUTF8ToUnicodeN(NULL, 0, &bytes_out, invalid_pointer, 0);
2500 ok(status == STATUS_SUCCESS, "status = 0x%lx\n", status);
2501 ok(bytes_out == 0, "bytes_out = 0x%lx\n", bytes_out);
2502
2503 bytes_out = 0x55555555;
2504 status = pRtlUTF8ToUnicodeN(NULL, 0, &bytes_out, empty_string, 0);
2505 ok(status == STATUS_SUCCESS, "status = 0x%lx\n", status);
2506 ok(bytes_out == 0, "bytes_out = 0x%lx\n", bytes_out);
2507
2508 bytes_out = 0x55555555;
2509 status = pRtlUTF8ToUnicodeN(NULL, 0, &bytes_out, test_string, 0);
2510 ok(status == STATUS_SUCCESS, "status = 0x%lx\n", status);
2511 ok(bytes_out == 0, "bytes_out = 0x%lx\n", bytes_out);
2512
2513 bytes_out = 0x55555555;
2514 status = pRtlUTF8ToUnicodeN(NULL, 0, &bytes_out, empty_string, 1);
2515 ok(status == STATUS_SUCCESS, "status = 0x%lx\n", status);
2516 ok(bytes_out == sizeof(WCHAR), "bytes_out = 0x%lx\n", bytes_out);
2517
2518 /* length output with special chars */
2519#define length_expect(in_chars, out_chars, expect_status) \
2520 unicode_expect_(NULL, 0, out_chars, special_string, in_chars, \
2521 expect_status, __LINE__)
2522
2532#undef length_expect
2533
2534 /* output truncation */
2535#define truncate_expect(buflen, out_chars, expect_status) \
2536 unicode_expect_(special_expected, buflen, out_chars, \
2537 special_string, sizeof(special_string), \
2538 expect_status, __LINE__)
2539
2551#undef truncate_expect
2552
2553 /* conversion behavior with varying input length */
2554 for (input_len = 0; input_len <= sizeof(test_string); input_len++) {
2555 /* no output buffer, just length */
2556 unicode_expect(NULL, 0, input_len,
2557 test_string, input_len, STATUS_SUCCESS);
2558
2559 /* write output */
2560 unicode_expect(test_stringW, -1, input_len,
2561 test_string, input_len, STATUS_SUCCESS);
2562 }
2563
2564 /* test cases for special characters */
2565 for (i = 0; i < test_count; i++) {
2566 bytes_out = 0x55555555;
2567 memset(buffer, 0x55, sizeof(buffer));
2568 status = pRtlUTF8ToUnicodeN(
2569 buffer, sizeof(buffer), &bytes_out,
2572 "(test %d): status is 0x%lx, expected 0x%lx\n",
2574 ok(bytes_out == lstrlenW(utf8_to_unicode[i].expected) * sizeof(WCHAR),
2575 "(test %d): bytes_out is %lu, expected %lu\n",
2576 i, bytes_out, lstrlenW(utf8_to_unicode[i].expected) * (ULONG)sizeof(WCHAR));
2577 ok(!memcmp(buffer, utf8_to_unicode[i].expected, bytes_out),
2578 "(test %d): got %s, expected %s\n",
2580 ok(buffer[bytes_out / sizeof(WCHAR)] == 0x5555,
2581 "(test %d): behind string: 0x%x\n", i, buffer[bytes_out / sizeof(WCHAR)]);
2582 memset(buffer, 0x55, sizeof(buffer));
2585 ok( ret == lstrlenW(utf8_to_unicode[i].expected), "(test %d): wrong len %u\n", i, ret );
2587 "(test %d): got %s, expected %s\n",
2589 ok(buffer[ret] == 0x5555,
2590 "(test %d): behind string: 0x%x\n", i, buffer[ret]);
2591
2592 /* same test but include the null terminator */
2593 bytes_out = 0x55555555;
2594 memset(buffer, 0x55, sizeof(buffer));
2595 status = pRtlUTF8ToUnicodeN(
2596 buffer, sizeof(buffer), &bytes_out,
2599 "(test %d): status is 0x%lx, expected 0x%lx\n",
2601 ok(bytes_out == (lstrlenW(utf8_to_unicode[i].expected) + 1) * sizeof(WCHAR),
2602 "(test %d): bytes_out is %lu, expected %lu\n",
2603 i, bytes_out, (lstrlenW(utf8_to_unicode[i].expected) + 1) * (ULONG)sizeof(WCHAR));
2604 ok(!memcmp(buffer, utf8_to_unicode[i].expected, bytes_out),
2605 "(test %d): got %s, expected %s\n",
2607 ok(buffer[bytes_out / sizeof(WCHAR)] == 0x5555,
2608 "(test %d): behind string: 0x%x\n", i, buffer[bytes_out / sizeof(WCHAR)]);
2609
2610 memset(buffer, 0x55, sizeof(buffer));
2612 ok( ret == lstrlenW(utf8_to_unicode[i].expected) + 1, "(test %d): wrong len %u\n", i, ret );
2614 "(test %d): got %s, expected %s\n",
2616 ok(buffer[ret] == 0x5555,
2617 "(test %d): behind string: 0x%x\n", i, buffer[ret]);
2618
2619 SetLastError( 0xdeadbeef );
2620 memset(buffer, 0x55, sizeof(buffer));
2624 {
2625 ok( ret == 0, "(test %d): wrong len %u\n", i, ret );
2626 ok( GetLastError() == ERROR_NO_UNICODE_TRANSLATION, "(test %d): wrong error %lu\n", i, GetLastError() );
2628 }
2629 else
2630 ok( ret == lstrlenW(utf8_to_unicode[i].expected) + 1, "(test %d): wrong len %u\n", i, ret );
2631
2633 "(test %d): got %s, expected %s\n",
2635 ok(buffer[ret] == 0x5555,
2636 "(test %d): behind string: 0x%x\n", i, buffer[ret]);
2637 }
2638}
2639
2640static NTSTATUS WINAPIV fmt( const WCHAR *src, ULONG width, BOOLEAN ignore_inserts, BOOLEAN ansi,
2641 WCHAR *buffer, ULONG size, ULONG *retsize, ... )
2642{
2643 va_list args;
2645
2646 *retsize = 0xdeadbeef;
2647 va_start( args, retsize );
2648 status = pRtlFormatMessage( src, width, ignore_inserts, ansi, FALSE, &args, buffer, size, retsize );
2649 va_end( args );
2650 return status;
2651}
2652
2653static void WINAPIV testfmt( const WCHAR *src, const WCHAR *expect, ULONG width, BOOL ansi, ... )
2654{
2655 va_list args;
2657 WCHAR buffer[128];
2658 ULONG size = 0xdeadbeef;
2659
2660 memset( buffer, 0xcc, sizeof(buffer) );
2661 va_start( args, ansi );
2662 status = pRtlFormatMessage( src, width, FALSE, ansi, FALSE, &args, buffer, sizeof(buffer), &size );
2663 va_end( args );
2664 ok( !status, "%s: failed %lx\n", debugstr_w(src), status );
2665 ok( !lstrcmpW( buffer, expect ), "%s: got %s expected %s\n", debugstr_w(src),
2667 ok( size == (lstrlenW(expect) + 1) * sizeof(WCHAR), "%s: wrong size %lu\n", debugstr_w(src), size );
2668}
2669
2670static void testfmt_arg_eaten( const WCHAR *src, ... )
2671{
2672 va_list args;
2674 WCHAR *arg, buffer[1];
2675 ULONG size = 0xdeadbeef;
2676
2677 buffer[0] = 0xcccc;
2678 va_start( args, src );
2679 status = pRtlFormatMessage( src, 0, FALSE, FALSE, FALSE, &args, buffer, ARRAY_SIZE(buffer), &size );
2680 ok( status == STATUS_BUFFER_OVERFLOW, "%s: failed %lx\n", debugstr_w(src), status );
2681 todo_wine
2682 ok( buffer[0] == 0xcccc, "%s: got %x\n", debugstr_w(src), buffer[0] );
2683 ok( size == 0xdeadbeef, "%s: wrong size %lu\n", debugstr_w(src), size );
2684 arg = va_arg( args, WCHAR * );
2685 ok( !wcscmp( L"unused", arg ), "%s: wrong arg %s\n", debugstr_w(src), debugstr_w(arg) );
2686 va_end( args );
2687}
2688
2689static void test_RtlFormatMessage(void)
2690{
2691 WCHAR buffer[128];
2693 ULONG i, size;
2694
2695#ifdef __REACTOS__
2696 if (is_reactos())
2697 {
2698 ok(FALSE, "RtlFormatMessage is unimplemented!\n");
2699 return;
2700 }
2701#endif
2702
2703 /* basic formats */
2704 testfmt( L"test", L"test", 0, FALSE );
2705 testfmt( L"", L"", 0, FALSE );
2706 testfmt( L"%1", L"test", 0, FALSE, L"test" );
2707 testfmt( L"%1!s!", L"test", 0, FALSE, L"test" );
2708 testfmt( L"%1!s!", L"foo", 0, TRUE, "foo" );
2709 testfmt( L"%1!S!", L"test", 0, FALSE, "test" );
2710 testfmt( L"%1!S!", L"foo", 0, TRUE, L"foo" );
2711 testfmt( L"%1!hs!%1!hS!", L"testtest", 0, FALSE, "test" );
2712 testfmt( L"%1!ls!%1!lS!%1!ws!%1!wS!", L"foofoofoofoo", 0, TRUE, L"foo" );
2713 testfmt( L"%1!c!", L"a", 0, FALSE, L'a' );
2714 testfmt( L"%1!c!", L"b", 0, TRUE, 'b' );
2715 testfmt( L"%1!C!", L"c", 0, FALSE, L'c' );
2716 testfmt( L"%1!C!", L"d", 0, TRUE, 'd' );
2717 testfmt( L"%1!hc!", L"e", 0, FALSE, L'e' );
2718 testfmt( L"%1!hC!", L"f", 0, FALSE, L'f' );
2719 testfmt( L"%1!lc!", L"g", 0, TRUE, 'g' );
2720 testfmt( L"%1!lC!", L"h", 0, TRUE, 'h' );
2721 testfmt( L"%1!wc!", L"i", 0, TRUE, 'i' );
2722 testfmt( L"%1!wC!", L"j", 0, TRUE, 'j' );
2723 testfmt( L"%1!04X!", L"BEEF", 0, FALSE, 0xbeef );
2724 testfmt( L"%1!Saa!", L"testaa", 0, FALSE, "test" );
2725 testfmt( L"%.%%%Z%n%t%r%!% ", L".%Z\r\n\t\r! ", 0, FALSE );
2726 testfmt( L"%1!*.*u!,%1!*.*u!", L" 001, 0002", 0, FALSE, 5, 3, 1, 4, 2 );
2727 testfmt( L"%1!*.*u!,%3!*.*u!", L" 001, 0002", 0, FALSE, 5, 3, 1, 6, 4, 2 );
2728 testfmt( L"%1", L"(null)", 0, FALSE, NULL );
2729 testfmt( L"%2", L"(null)", 0, TRUE, "abc", NULL );
2730 testfmt( L"ab%1!!cd", L"abcd", 0, FALSE, L"hello" );
2731 testfmt( L"abc%1!#.000000000000000000000000000x!", L"abc0x22", 0, FALSE, 34 );
2732 testfmt( L"a\r\nb\rc\r\rd\r\r\ne", L"a\r\nb\r\nc\r\n\r\nd\r\n\r\ne", 0, FALSE, NULL );
2733#ifdef _WIN64
2734 testfmt( L"%1!#I64x! %2!x!", L"0x1234 5678", 0, FALSE, (ULONG_PTR)0x1234, 0x5678, 0xbeef );
2735 testfmt( L"%1!x! %2!#I64x! %3!#I64x! %4!x!", L"dead 0x1111222233334444 0x5555666677778888 beef",
2736 0, FALSE, 0xdead, 0x1111222233334444ull, 0x5555666677778888ull, 0xbeef );
2737 testfmt( L"%3!#I64x! %4!#I64x! %3!x! %1!x!", L"0x3 0x4 3 1", 0, FALSE, 0xdead00000001ll, 2, 3ll, 4ll );
2738 testfmt( L"%2!x! %1!I64x!", L"5678 1234", 0, FALSE, (ULONG_PTR)0x1234, 0x5678, 0xbeef );
2739 testfmt( L"%2!*.*I64x! %1!u! %4!u! %2!u!", L" 00000000000000d 19 11 17", 0, FALSE,
2740 19ull, 17ull, 15ull, 13ull, 11ull, 9ull );
2741 { /* argument array works differently */
2742 ULONG_PTR args[] = { 19, 17, 15, 13, 11, 9, 7 };
2743 memset( buffer, 0xcc, sizeof(buffer) );
2744 status = pRtlFormatMessage( L"%2!*.*I64x! %1!u! %4!u! %2!u!", 0, FALSE, FALSE, TRUE,
2745 (va_list *)args, buffer, sizeof(buffer), &size );
2746 ok( !lstrcmpW( buffer, L" 00000000000000d 19 13 17" ), "got %s\n", wine_dbgstr_w(buffer) );
2747 memset( buffer, 0xcc, sizeof(buffer) );
2748 status = pRtlFormatMessage( L"%1!I64u! %2!u! %4!.*I64x! %5!I64u!", 0, FALSE, FALSE, TRUE,
2749 (va_list *)args, buffer, sizeof(buffer), &size );
2750 ok( !lstrcmpW( buffer, L"19 17 000000000000b 11" ), "got %s\n", wine_dbgstr_w(buffer) );
2751 }
2752#else
2753 fmt( L"%1!#I64x! %2!x!", 0, FALSE, FALSE, buffer, sizeof(buffer), &size, 0x1234, 0x5678, 0xbeef );
2754 if (lstrcmpW( buffer, L"0x567800001234 5678" ))
2755 {
2756 testfmt( L"%1!#I64x! %2!x!", L"0x567800001234 beef", 0, FALSE, 0x1234, 0x5678, 0xbeef );
2757 testfmt( L"%1!x! %2!#I64x! %3!#I64x! %4!x!", L"dead 0x1111222233334444 0x5555666677778888 beef",
2758 0, FALSE, 0xdead, 0x1111222233334444ull, 0x5555666677778888ull, 0xbeef );
2759 testfmt( L"%3!#I64x! %4!#I64x! %3!x! %1!x!", L"0x1111222233334444 0x5555666677778888 33334444 1",
2760 0, FALSE, 1, 2, 3, 4, 0x33334444, 0x11112222, 0x77778888, 0x55556666, 0xbeef, 0xbee2 );
2761 testfmt( L"%2!x! %1!I64x!", L"5678 1234", 0, FALSE, 0x1234, 0x5678, 0xbeef );
2762 testfmt( L"%2!*.*I64x! %1!u! %4!u! %2!u!", L" 000090000000b 19 7 15", 0, FALSE,
2763 19, 17, 15, 13, 11, 9, 7 );
2764 { /* argument array works differently */
2765 ULONG_PTR args[] = { 19, 17, 15, 13, 11, 9, 7 };
2766 memset( buffer, 0xcc, sizeof(buffer) );
2767 status = pRtlFormatMessage( L"%2!*.*I64x! %1!u! %4!u! %2!u!", 0, FALSE, FALSE, TRUE,
2768 (va_list *)args, buffer, sizeof(buffer), &size );
2769 ok( !lstrcmpW( buffer, L" d0000000f 19 13 17" ), "got %s\n", wine_dbgstr_w(buffer) );
2770 memset( buffer, 0xcc, sizeof(buffer) );
2771 status = pRtlFormatMessage( L"%1!I64u! %2!u! %4!.*I64x! %5!I64u!", 0, FALSE, FALSE, TRUE,
2772 (va_list *)args, buffer, sizeof(buffer), &size );
2773 ok( !lstrcmpW( buffer, L"19 17 0000b00000000 11" ), "got %s\n", wine_dbgstr_w(buffer) );
2774 }
2775 }
2776 else win_skip( "I64 support broken\n" );
2777#endif
2778 testfmt( L"%1!Ix! %2!QQ!", L"1234 QQ", 0, FALSE, (ULONG_PTR)0x1234 );
2779 testfmt( L"%1!#llx!%2!#x!%1!#hx!", L"0x1234560x789abc0x3456", 0, FALSE, 0x123456, 0x789abc );
2780 lstrcpyW( buffer, L"xxxxxxxxxx" );
2781 fmt( L"ab%0cd", 0, FALSE, FALSE, buffer, sizeof(buffer), &size );
2782 ok( !memcmp( buffer, L"ab\0xxxxxxx", 10 * sizeof(WCHAR) ), "got %s\n", wine_dbgstr_wn(buffer, 10) );
2783
2784 /* max width */
2785 testfmt( L"%1", L"testing\r\n", 3, FALSE, L"testing" );
2786 testfmt( L"%1%2%3", L"testing\r\nabcdef\r\nfoobar\r\n", 4, FALSE, L"testing", L"abcdef", L"foobar");
2787 testfmt( L"%1%2%3%4", L"test\r\nabcd\r\nabcdef\r\n", 4, FALSE, L"test", L"abcd", L"abc", L"def" );
2788 testfmt( L"%1a\nb%2", L"testing\r\na\r\nbfoo bar\r\n", 3, FALSE, L"testing", L"foo bar" );
2789 testfmt( L"a%tb%t%t%t%c%r%r%r%r%r%rdefg", L"a\r\nb\r\n\r\n\r\nc\r\r\r\r\r\rdef\r\ng", 3, FALSE );
2790 testfmt( L"test abcd ", L"test\r\n\r\nabcd\r\n ", 4, FALSE );
2791 testfmt( L"test abcdef %1 foobar", L"tes\r\nt\r\nabc\r\ndef\r\n\r\nhello\r\nfoo\r\nbar\r\n", 3, FALSE, L"hello" );
2792 testfmt( L"te st\nabc d\nfoo", L"te st\r\nabc d\r\nfoo", 6, FALSE );
2793 testfmt( L"te st ab d\nfoo", L"te st\r\n ab\r\n d foo", 7, FALSE );
2794 testfmt( L"te\tst\t\t\t\tab\t\t\td\nfoo", L"te\tst\t\t\r\n\t\tab\t\t\t\r\nd foo", 7, FALSE );
2795 testfmt( L"te st\n\n\r\n\nab d\nfoo ", L"te st\r\n ab\r\n d foo\r\n ", 7, FALSE );
2796 testfmt( L"te st\r\nabc d\n\nfoo\rbar", L"te st abc d foo bar", 0xff, FALSE );
2797 testfmt( L"te st%r%nabc d%nfoo%rbar", L"te st\r\r\nabc d\r\nfoo\rbar", 0xff, FALSE );
2798 testfmt( L"\01\02\03\04\a\a\a\a\b\b\b\b\t\t\t\t\v\v\v\v\f\f\f\f\r\r\r\r a",
2799 L"\01\02\r\n\03\04\r\n\a\a\r\n\a\a\r\n\b\b\r\n\b\b\r\n\t\t\r\n\t\t\r\n\v\v\r\n\v\v\r\n\f\f\r\n\f\f\r\n\r\n\r\n\r\n\r\na", 2, FALSE );
2800
2801 for (i = 1; i < 0xffff; i++)
2802 {
2803 WCHAR src[] = { i, ' ', i, i, i, i, i, ' ', i, 0 };
2804 WCHAR expect[16];
2805 switch (i)
2806 {
2807 case '\t':
2808 lstrcpyW( expect, L"\r\n\r\n\t" );
2809 break;
2810 case '\r':
2811 case '\n':
2812 case ' ':
2813 lstrcpyW( expect, L"\r\n\r\n " );
2814 break;
2815 case '%':
2816 lstrcpyW( expect, L" %% \r\nxxxx" );
2817 break;
2818 default:
2819 swprintf( expect, ARRAY_SIZE(expect), L"%c\r\n%c%c%c%c\r\n%c %c", i, i, i, i, i, i, i );
2820 break;
2821 }
2822 lstrcpyW( buffer, L"xxxxxxxxxx" );
2823 fmt( src, 4, FALSE, FALSE, buffer, sizeof(buffer), &size );
2824 ok( !lstrcmpW( buffer, expect ), "%04lx: got %s\n", i, debugstr_w(buffer) );
2825 }
2826
2827 /* args are not counted the same way with an argument array */
2828 {
2829 ULONG_PTR args[] = { 6, 4, 2, 5, 3, 1 };
2830 memset( buffer, 0xcc, sizeof(buffer) );
2831 status = pRtlFormatMessage( L"%1!*.*u!,%1!*.*u!", 0, FALSE, FALSE, TRUE, (va_list *)args,
2832 buffer, sizeof(buffer), &size );
2833 ok( !lstrcmpW( buffer, L" 0002, 00003" ), "got %s\n", wine_dbgstr_w(buffer) );
2834 memset( buffer, 0xcc, sizeof(buffer) );
2835 status = pRtlFormatMessage( L"%1!*.*u!,%4!*.*u!", 0, FALSE, FALSE, TRUE, (va_list *)args,
2836 buffer, sizeof(buffer), &size );
2837 ok( !lstrcmpW( buffer, L" 0002, 001" ), "got %s\n", wine_dbgstr_w(buffer) );
2838 }
2839
2840 /* buffer overflows */
2841 lstrcpyW( buffer, L"xxxxxxxxxx" );
2842 status = fmt( L"testing", 0, FALSE, FALSE, buffer, 8, &size );
2843 ok( status == STATUS_BUFFER_OVERFLOW, "failed %lx\n", status );
2844 ok( !lstrcmpW( buffer, L"testxxxxxx" ) || broken(!lstrcmpW( buffer, L"tesxxxxxxx" )), /* winxp */
2845 "got %s\n", wine_dbgstr_w(buffer) );
2846 ok( size == 0xdeadbeef, "wrong size %lu\n", size );
2847
2848 lstrcpyW( buffer, L"xxxxxxxxxx" );
2849 status = fmt( L"%1", 0, FALSE, FALSE, buffer, 8, &size, L"test" );
2850 ok( status == STATUS_BUFFER_OVERFLOW, "failed %lx\n", status );
2851 ok( !memcmp( buffer, L"tes\0xxxxxx", 10 * sizeof(WCHAR) ) || broken(!lstrcmpW( buffer, L"testxxxxxx" )), /* winxp */
2852 "got %s\n", wine_dbgstr_w(buffer) );
2853 ok( size == 0xdeadbeef, "wrong size %lu\n", size );
2854
2855 lstrcpyW( buffer, L"xxxxxxxxxx" );
2856 status = fmt( L"%1!x!", 0, FALSE, FALSE, buffer, 8, &size, 0x12345678 );
2857 ok( status == STATUS_BUFFER_OVERFLOW, "failed %lx\n", status );
2858 ok( !memcmp( buffer, L"123\0xxxxxx", 10 * sizeof(WCHAR) ) || broken(!lstrcmpW( buffer, L"1234xxxxxx" )), /* winxp */
2859 "got %s\n", wine_dbgstr_w(buffer) );
2860 ok( size == 0xdeadbeef, "wrong size %lu\n", size );
2861
2862 lstrcpyW( buffer, L"xxxxxxxxxx" );
2863 status = fmt( L"%1!*s!", 0, FALSE, FALSE, buffer, 10, &size, 5, L"abc" );
2864 ok( status == STATUS_BUFFER_OVERFLOW, "failed %lx\n", status );
2865 ok( !memcmp( buffer, L" ab\0xxxxx", 10 * sizeof(WCHAR) ) || broken(!lstrcmpW( buffer, L" abcxxxxx" )), /* winxp */
2866 "got %s\n", wine_dbgstr_w(buffer) );
2867 ok( size == 0xdeadbeef, "wrong size %lu\n", size );
2868
2869 lstrcpyW( buffer, L"xxxxxxxxxx" );
2870 status = fmt( L"ab%n", 0, FALSE, FALSE, buffer, 6, &size );
2871 ok( status == STATUS_BUFFER_OVERFLOW, "failed %lx\n", status );
2872 ok( !memcmp( buffer, L"abxxxxxxxx", 10 * sizeof(WCHAR) ), "got %s\n", wine_dbgstr_w(buffer) );
2873 ok( size == 0xdeadbeef, "wrong size %lu\n", size );
2874
2875 /* ignore inserts */
2876 lstrcpyW( buffer, L"xxxxxxxxxx" );
2877 status = fmt( L"%1!x!%r%%%n%t", 0, TRUE, FALSE, buffer, sizeof(buffer), &size );
2878 ok( !lstrcmpW( buffer, L"%1!x!\r%%\r\n\t" ), "got %s\n", wine_dbgstr_w(buffer) );
2879
2880 lstrcpyW( buffer, L"xxxxxxxxxx" );
2881 status = fmt( L"ab%0cd", 0, TRUE, FALSE, buffer, sizeof(buffer), &size );
2882 ok( !status, "failed %lx\n", status );
2883 ok( !memcmp( buffer, L"ab\0xxxxxxx", 10 * sizeof(WCHAR) ), "got %s\n", wine_dbgstr_wn(buffer, 10) );
2884
2885 /* invalid args */
2886 lstrcpyW( buffer, L"xxxxxxxxxx" );
2887 size = 0xdeadbeef;
2888 status = pRtlFormatMessage( L"abc%1", 0, FALSE, FALSE, FALSE, NULL, buffer, sizeof(buffer), &size );
2889 ok( status == STATUS_INVALID_PARAMETER, "failed %lx\n", status );
2890 ok( !lstrcmpW( buffer, L"abcxxxxxxx" ), "got %s\n", wine_dbgstr_w(buffer) );
2891 ok( size == 0xdeadbeef, "wrong size %lu\n", size );
2892
2893 lstrcpyW( buffer, L"xxxxxxxxxx" );
2894 status = pRtlFormatMessage( L"abc%1", 0, FALSE, FALSE, TRUE, NULL, buffer, sizeof(buffer), &size );
2895 ok( status == STATUS_INVALID_PARAMETER, "failed %lx\n", status );
2896 ok( !lstrcmpW( buffer, L"abcxxxxxxx" ), "got %s\n", wine_dbgstr_w(buffer) );
2897 ok( size == 0xdeadbeef, "wrong size %lu\n", size );
2898
2899 lstrcpyW( buffer, L"xxxxxxxxxx" );
2900 status = pRtlFormatMessage( L"abc%", 0, FALSE, FALSE, TRUE, NULL, buffer, sizeof(buffer), &size );
2901 ok( status == STATUS_INVALID_PARAMETER, "failed %lx\n", status );
2902 ok( !lstrcmpW( buffer, L"abcxxxxxxx" ), "got %s\n", wine_dbgstr_w(buffer) );
2903 ok( size == 0xdeadbeef, "wrong size %lu\n", size );
2904
2905 lstrcpyW( buffer, L"xxxxxxxxxx" );
2906 status = fmt( L"%1!u! %2!u", 0, FALSE, FALSE, buffer, sizeof(buffer), &size, 34 );
2907 ok( status == STATUS_INVALID_PARAMETER, "failed %lx\n", status );
2908 ok( !lstrcmpW( buffer, L"34 xxxxxxx" ), "got %s\n", wine_dbgstr_w(buffer) );
2909 ok( size == 0xdeadbeef, "wrong size %lu\n", size );
2910
2911 lstrcpyW( buffer, L"xxxxxxxxxx" );
2912 status = fmt( L"%1!**u!", 0, FALSE, FALSE, buffer, sizeof(buffer), &size, 34 );
2913 ok( status == STATUS_SUCCESS, "failed %lx\n", status );
2914 ok( !lstrcmpW( buffer, L"*u" ), "got %s\n", wine_dbgstr_w(buffer) );
2915
2916 lstrcpyW( buffer, L"xxxxxxxxxx" );
2917 status = fmt( L"%1!0.3+*u!", 0, FALSE, FALSE, buffer, sizeof(buffer), &size, 34 );
2918 ok( status == STATUS_SUCCESS, "failed %lx\n", status );
2919 ok( !lstrcmpW( buffer, L"+*u" ), "got %s\n", wine_dbgstr_w(buffer) );
2920
2921 lstrcpyW( buffer, L"xxxxxxxxxx" );
2922 status = fmt( L"aa%1!***u!", 0, FALSE, FALSE, buffer, sizeof(buffer), &size, 34 );
2923 ok( status == STATUS_INVALID_PARAMETER, "failed %lx\n", status );
2924 ok( !lstrcmpW( buffer, L"aaxxxxxxxx" ), "got %s\n", wine_dbgstr_w(buffer) );
2925 ok( size == 0xdeadbeef, "wrong size %lu\n", size );
2926
2927 lstrcpyW( buffer, L"xxxxxxxxxx" );
2928 status = fmt( L"abc%1!#.000000000000000000000000000x!", 0, FALSE, FALSE, buffer, sizeof(buffer), &size, 34 );
2929 ok( status == STATUS_SUCCESS, "failed %lx\n", status );
2930 ok( !lstrcmpW( buffer, L"abc0x22" ), "got %s\n", wine_dbgstr_w(buffer) );
2931
2932 lstrcpyW( buffer, L"xxxxxxxxxx" );
2933 status = fmt( L"abc%1!#.0000000000000000000000000000x!", 0, FALSE, FALSE, buffer, sizeof(buffer), &size, 34 );
2934 ok( status == STATUS_INVALID_PARAMETER, "failed %lx\n", status );
2935 ok( !lstrcmpW( buffer, L"abcxxxxxxx" ), "got %s\n", wine_dbgstr_w(buffer) );
2936 ok( size == 0xdeadbeef, "wrong size %lu\n", size );
2937
2938 lstrcpyW( buffer, L"xxxxxxxxxx" );
2939 status = fmt( L"abc%1!hsaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!", 0, FALSE, FALSE, buffer, sizeof(buffer), &size, "hello" );
2940 ok( status == STATUS_INVALID_PARAMETER, "failed %lx\n", status );
2941 ok( !lstrcmpW( buffer, L"abcxxxxxxx" ), "got %s\n", wine_dbgstr_w(buffer) );
2942 ok( size == 0xdeadbeef, "wrong size %lu\n", size );
2943
2944 /* va_arg is eaten even in case of buffer overflow */
2945 testfmt_arg_eaten( L"%1!s! %2!s!", L"eaten", L"unused" );
2946}
2947
2949{
2951 if (pRtlInitAnsiString) {
2966 }
2967
2982}
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
#define VOID
Definition: acefi.h:82
unsigned char BOOLEAN
Definition: actypes.h:127
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAY_SIZE(A)
Definition: main.h:20
#define CHAR(Char)
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
#define NTSTATUS
Definition: precomp.h:19
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrlenW
Definition: compat.h:750
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4152
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4171
GUID guid
Definition: version.c:147
unsigned char ch[4][2]
Definition: console.c:118
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1972
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
#define va_end(v)
Definition: stdarg.h:28
#define va_arg(v, l)
Definition: stdarg.h:27
#define va_start(v, l)
Definition: stdarg.h:26
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
_ACRTIMP int __cdecl strncmp(const char *, const char *, size_t)
Definition: string.c:3330
char * va_list
Definition: vadefs.h:50
unsigned char
Definition: typeof.h:29
#define swprintf
Definition: precomp.h:40
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
std::wstring STRING
Definition: fontsub.cpp:33
#define STATUS_ACCESS_VIOLATION
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define WC_ERR_INVALID_CHARS
Definition: unicode.h:47
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define win_skip
Definition: minitest.h:67
#define todo_wine
Definition: minitest.h:80
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
BOOL expected
Definition: store.c:2000
UINT test_count
Definition: shader.c:5671
static void test_RtlIntegerToUnicodeString(void)
Definition: rtlstr.c:1708
static HMODULE hntdll
Definition: rtlstr.c:40
static va_list ULONG *static WCHAR * AtoW(const char *p)
Definition: rtlstr.c:99
static void test_RtlIntegerToChar(void)
Definition: rtlstr.c:1734
#define truncate_expect(buflen, out_chars, expect_status)
static SIZE_T
Definition: rtlstr.c:48
static const ustr2astr_t ustr2astr[]
Definition: rtlstr.c:801
static void one_RtlIntegerToUnicodeString_test(int test_num, const int2str_t *int2str)
Definition: rtlstr.c:1641
#define TESTSTRING2_LEN
Definition: rtlstr.c:200
static const str2int_t str2int[]
Definition: rtlstr.c:1296
static void test_RtlDowncaseUnicodeString(void)
Definition: rtlstr.c:682
#define STRINGW
static void test_RtlUnicodeStringToAnsiString(void)
Definition: rtlstr.c:822
static void test_RtlUpcaseUnicodeString(void)
Definition: rtlstr.c:612
static void test_RtlCopyString(void)
Definition: rtlstr.c:508
static void utf8_expect_(const unsigned char *out_string, ULONG buflen, ULONG out_bytes, const WCHAR *in_string, ULONG in_bytes, NTSTATUS expect_status, int line)
Definition: rtlstr.c:2090
static void test_RtlUpcaseUnicodeChar(void)
Definition: rtlstr.c:586
static PCANSI_STRING
Definition: rtlstr.c:41
static void test_RtlHashUnicodeString(void)
Definition: rtlstr.c:2005
static void test_RtlAppendUnicodeStringToString(void)
Definition: rtlstr.c:1122
static void testfmt_arg_eaten(const WCHAR *src,...)
Definition: rtlstr.c:2670
static void test_RtlIsTextUnicode(void)
Definition: rtlstr.c:1763
static int
Definition: rtlstr.c:66
static const app_asc2str_t app_asc2str[]
Definition: rtlstr.c:885
static const struct hash_unicodestring_test hash_test[]
Definition: rtlstr.c:1989
static const struct unicode_to_utf8_test unicode_to_utf8[]
Definition: rtlstr.c:2057
static void test_RtlInitString(void)
Definition: rtlstr.c:155
static void test_RtlGUIDFromString(void)
Definition: rtlstr.c:1937
static void test_RtlAppendStringToString(void)
Definition: rtlstr.c:967
static void test_RtlUpperString(void)
Definition: rtlstr.c:544
static void test_RtlUnicodeStringToInteger(void)
Definition: rtlstr.c:1412
static void test_RtlDuplicateUnicodeString(void)
Definition: rtlstr.c:416
static const app_ustr2str_t app_ustr2str[]
Definition: rtlstr.c:1105
#define utf8_expect(out_string, buflen, out_bytes, in_string, in_bytes, expect_status)
Definition: rtlstr.c:2121
#define length_expect(in_chars, out_bytes, expect_status)
static const int2str_t int2str[]
Definition: rtlstr.c:1534
static const STRING *static UNICODE_STRING *static GUID *static UNICODE_STRING *static INT
Definition: rtlstr.c:74
static void test_RtlAppendAsciizToString(void)
Definition: rtlstr.c:898
static void test_RtlUnicodeToUTF8N(void)
Definition: rtlstr.c:2124
static void InitFunctionPtrs(void)
Definition: rtlstr.c:109
static const struct utf8_to_unicode_test utf8_to_unicode[]
Definition: rtlstr.c:2338
static void test_RtlAppendUnicodeToString(void)
Definition: rtlstr.c:1049
static void test_RtlInitUnicodeStringEx(void)
Definition: rtlstr.c:204
static const STRING *static const UNICODE_STRING *static LPCWSTR
Definition: rtlstr.c:45
#define STRI_BUFFER_LENGTH
Definition: rtlstr.c:1522
static PCHAR
Definition: rtlstr.c:62
static void test_RtlCompareUnicodeString(void)
Definition: rtlstr.c:1898
static void test_RtlStringFromGUID(void)
Definition: rtlstr.c:1963
static void unicode_expect_(const WCHAR *out_string, ULONG buflen, ULONG out_chars, const char *in_string, ULONG in_chars, NTSTATUS expect_status, int line)
Definition: rtlstr.c:2423
static void test_RtlUpperChar(void)
Definition: rtlstr.c:522
static void test_RtlFindCharInUnicodeString(void)
Definition: rtlstr.c:1231
static const WCHAR szGuid[]
Definition: rtlstr.c:1928
static void WINAPIV testfmt(const WCHAR *src, const WCHAR *expect, ULONG width, BOOL ansi,...)
Definition: rtlstr.c:2653
#define unicode_expect(out_string, buflen, out_chars, in_string, in_chars, expect_status)
Definition: rtlstr.c:2454
static void test_RtlInitUnicodeString(void)
Definition: rtlstr.c:176
static const app_str2str_t app_str2str[]
Definition: rtlstr.c:954
static va_list LPWSTR
Definition: rtlstr.c:78
static UNICODE_STRING *static LONG
Definition: rtlstr.c:64
static const WCHAR szGuid2[]
Definition: rtlstr.c:1931
static LPCSTR
Definition: rtlstr.c:42
static const app_uni2str_t app_uni2str[]
Definition: rtlstr.c:1031
static void one_RtlIntegerToChar_test(int test_num, const int2str_t *int2str)
Definition: rtlstr.c:1717
static void test_RtlCharToInteger(void)
Definition: rtlstr.c:1483
static void test_RtlUTF8ToUnicodeN(void)
Definition: rtlstr.c:2457
static BOOLEAN
Definition: rtlstr.c:41
static const dupl_ustr_t dupl_ustr[]
Definition: rtlstr.c:340
static ULONG
Definition: rtlstr.c:46
static const find_ch_in_ustr_t find_ch_in_ustr[]
Definition: rtlstr.c:1181
static void test_RtlFormatMessage(void)
Definition: rtlstr.c:2689
WCHAR strW[12]
Definition: clipboard.c:2216
#define LPVOID
Definition: nt_native.h:45
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:572
#define STATUS_SOME_NOT_MAPPED
Definition: ntstatus.h:139
#define STATUS_INVALID_PARAMETER_5
Definition: ntstatus.h:573
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:592
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
char CHAR
Definition: pedump.c:57
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: guiddef.h:68
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define wine_dbgstr_wn
Definition: testlist.c:2
const WCHAR * str
#define WINAPIV
Definition: sdbpapi.h:64
#define CP_UTF8
Definition: nls.h:20
XML_HIDDEN void xmlParserErrors const char const xmlChar const xmlChar * str2
Definition: parser.h:35
XML_HIDDEN void xmlParserErrors const char const xmlChar * str1
Definition: parser.h:35
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
USHORT MaximumLength
Definition: env_spec_w32.h:370
int dest_MaximumLength
Definition: rtlstr.c:874
const char * dest_buf
Definition: rtlstr.c:876
const char * src
Definition: rtlstr.c:877
int dest_Length
Definition: rtlstr.c:873
int res_buf_size
Definition: rtlstr.c:880
int res_Length
Definition: rtlstr.c:878
int dest_buf_size
Definition: rtlstr.c:875
const char * res_buf
Definition: rtlstr.c:881
NTSTATUS result
Definition: rtlstr.c:882
int res_MaximumLength
Definition: rtlstr.c:879
int dest_buf_size
Definition: rtlstr.c:941
const char * res_buf
Definition: rtlstr.c:950
const char * dest_buf
Definition: rtlstr.c:942
int src_MaximumLength
Definition: rtlstr.c:944
int src_Length
Definition: rtlstr.c:943
int res_buf_size
Definition: rtlstr.c:949
int src_buf_size
Definition: rtlstr.c:945
NTSTATUS result
Definition: rtlstr.c:951
const char * src_buf
Definition: rtlstr.c:946
int dest_MaximumLength
Definition: rtlstr.c:940
int res_Length
Definition: rtlstr.c:947
int res_MaximumLength
Definition: rtlstr.c:948
int dest_Length
Definition: rtlstr.c:939
const char * res_buf
Definition: rtlstr.c:1027
int dest_buf_size
Definition: rtlstr.c:1021
const char * dest_buf
Definition: rtlstr.c:1022
int res_MaximumLength
Definition: rtlstr.c:1025
int dest_MaximumLength
Definition: rtlstr.c:1020
int res_Length
Definition: rtlstr.c:1024
const char * src
Definition: rtlstr.c:1023
NTSTATUS result
Definition: rtlstr.c:1028
int res_buf_size
Definition: rtlstr.c:1026
int dest_Length
Definition: rtlstr.c:1019
int dest_MaximumLength
Definition: rtlstr.c:1091
int dest_Length
Definition: rtlstr.c:1090
const char * res_buf
Definition: rtlstr.c:1101
int res_Length
Definition: rtlstr.c:1098
int src_MaximumLength
Definition: rtlstr.c:1095
int res_MaximumLength
Definition: rtlstr.c:1099
NTSTATUS result
Definition: rtlstr.c:1102
int src_Length
Definition: rtlstr.c:1094
const char * src_buf
Definition: rtlstr.c:1097
const char * dest_buf
Definition: rtlstr.c:1093
int dest_buf_size
Definition: rtlstr.c:1092
int res_buf_size
Definition: rtlstr.c:1100
int src_buf_size
Definition: rtlstr.c:1096
Definition: match.c:390
const char * source_buf
Definition: rtlstr.c:328
int source_buf_size
Definition: rtlstr.c:327
const char * dest_buf
Definition: rtlstr.c:332
int dest_MaximumLength
Definition: rtlstr.c:330
int res_MaximumLength
Definition: rtlstr.c:334
int dest_Length
Definition: rtlstr.c:329
int res_Length
Definition: rtlstr.c:333
const char * res_buf
Definition: rtlstr.c:336
NTSTATUS result
Definition: rtlstr.c:337
int source_MaximumLength
Definition: rtlstr.c:326
int add_nul
Definition: rtlstr.c:324
int dest_buf_size
Definition: rtlstr.c:331
int source_Length
Definition: rtlstr.c:325
int res_buf_size
Definition: rtlstr.c:335
NTSTATUS result
Definition: rtlstr.c:1178
const char * search_chars
Definition: rtlstr.c:1176
const char * main_str
Definition: rtlstr.c:1175
Definition: dsound.c:943
BOOLEAN case_insensitive
Definition: rtlstr.c:1985
Definition: _hash_fun.h:40
USHORT MaximumLength
Definition: rtlstr.c:1528
const char * Buffer
Definition: rtlstr.c:1529
int broken_len
Definition: rtlstr.c:1531
ULONG value
Definition: rtlstr.c:1526
int base
Definition: rtlstr.c:1525
NTSTATUS result
Definition: rtlstr.c:1530
USHORT Length
Definition: rtlstr.c:1527
Definition: parser.c:49
Definition: ps.c:97
int base
Definition: rtlstr.c:1290
int value
Definition: rtlstr.c:1292
NTSTATUS alternative
Definition: rtlstr.c:1293
const char * str
Definition: rtlstr.c:1291
WCHAR unicode[128]
Definition: rtlstr.c:2052
const char * expected
Definition: rtlstr.c:2053
int ansi_MaximumLength
Definition: rtlstr.c:785
int res_MaximumLength
Definition: rtlstr.c:794
int res_Length
Definition: rtlstr.c:793
const char * ansi_buf
Definition: rtlstr.c:787
int uni_buf_size
Definition: rtlstr.c:790
int uni_Length
Definition: rtlstr.c:788
NTSTATUS result
Definition: rtlstr.c:797
int ansi_buf_size
Definition: rtlstr.c:786
const char * uni_buf
Definition: rtlstr.c:791
int res_buf_size
Definition: rtlstr.c:795
int ansi_Length
Definition: rtlstr.c:784
int broken_len
Definition: rtlstr.c:798
BOOLEAN doalloc
Definition: rtlstr.c:792
const char * res_buf
Definition: rtlstr.c:796
int uni_MaximumLength
Definition: rtlstr.c:789
WCHAR expected[128]
Definition: rtlstr.c:2334
const char * utf8
Definition: rtlstr.c:2333
void test_string()
Definition: test_string.cpp:38
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * LPCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
const UNICODE_STRING * PCUNICODE_STRING
Definition: typedefs.h:240
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct _STRING * PSTRING
CONST char * PCSZ
Definition: umtypes.h:125
Definition: pdh_main.c:96
_In_ WDFDMATRANSACTION _In_ size_t MaximumLength
static UINT WPARAM LPARAM BOOL ansi
Definition: misc.c:135
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define HASH_STRING_ALGORITHM_INVALID
Definition: winternl.h:4524
#define HASH_STRING_ALGORITHM_X65599
Definition: winternl.h:4523
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:973
#define IS_TEXT_UNICODE_UNICODE_MASK
Definition: winnt_old.h:958
#define IS_TEXT_UNICODE_REVERSE_ASCII16
Definition: winnt_old.h:947
#define IS_TEXT_UNICODE_REVERSE_CONTROLS
Definition: winnt_old.h:951
#define IS_TEXT_UNICODE_REVERSE_MASK
Definition: winnt_old.h:959
#define IS_TEXT_UNICODE_CONTROLS
Definition: winnt_old.h:950
#define IS_TEXT_UNICODE_ODD_LENGTH
Definition: winnt_old.h:955
#define IS_TEXT_UNICODE_REVERSE_SIGNATURE
Definition: winnt_old.h:953
#define IS_TEXT_UNICODE_STATISTICS
Definition: winnt_old.h:948
#define IS_TEXT_UNICODE_REVERSE_STATISTICS
Definition: winnt_old.h:949