urlmon: Don't create stgmed_obj for binding to object.
[wine] / dlls / ntdll / tests / rtlstr.c
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
27 #define INITGUID
28
29 #include "ntdll_test.h"
30 #include "winnls.h"
31 #include "guiddef.h"
32
33 /* Function ptrs for ntdll calls */
34 static HMODULE hntdll = 0;
35 static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING, PCANSI_STRING, BOOLEAN);
36 static NTSTATUS (WINAPI *pRtlAppendAsciizToString)(STRING *, LPCSTR);
37 static NTSTATUS (WINAPI *pRtlAppendStringToString)(STRING *, const STRING *);
38 static NTSTATUS (WINAPI *pRtlAppendUnicodeStringToString)(UNICODE_STRING *, const UNICODE_STRING *);
39 static NTSTATUS (WINAPI *pRtlAppendUnicodeToString)(UNICODE_STRING *, LPCWSTR);
40 static NTSTATUS (WINAPI *pRtlCharToInteger)(PCSZ, ULONG, int *);
41 static VOID     (WINAPI *pRtlCopyString)(STRING *, const STRING *);
42 static BOOLEAN  (WINAPI *pRtlCreateUnicodeString)(PUNICODE_STRING, LPCWSTR);
43 static BOOLEAN  (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
44 static NTSTATUS (WINAPI *pRtlDowncaseUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
45 static NTSTATUS (WINAPI *pRtlDuplicateUnicodeString)(long, UNICODE_STRING *, UNICODE_STRING *);
46 static BOOLEAN  (WINAPI *pRtlEqualUnicodeString)(const UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
47 static NTSTATUS (WINAPI *pRtlFindCharInUnicodeString)(int, const UNICODE_STRING *, const UNICODE_STRING *, USHORT *);
48 static VOID     (WINAPI *pRtlFreeAnsiString)(PSTRING);
49 static VOID     (WINAPI *pRtlInitAnsiString)(PSTRING, LPCSTR);
50 static VOID     (WINAPI *pRtlInitString)(PSTRING, LPCSTR);
51 static VOID     (WINAPI *pRtlInitUnicodeString)(PUNICODE_STRING, LPCWSTR);
52 static NTSTATUS (WINAPI *pRtlInitUnicodeStringEx)(PUNICODE_STRING, LPCWSTR);
53 static NTSTATUS (WINAPI *pRtlIntegerToChar)(ULONG, ULONG, ULONG, PCHAR);
54 static NTSTATUS (WINAPI *pRtlIntegerToUnicodeString)(ULONG, ULONG, UNICODE_STRING *);
55 static NTSTATUS (WINAPI *pRtlMultiAppendUnicodeStringBuffer)(UNICODE_STRING *, long, UNICODE_STRING *);
56 static NTSTATUS (WINAPI *pRtlUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN);
57 static NTSTATUS (WINAPI *pRtlUnicodeStringToInteger)(const UNICODE_STRING *, int, int *);
58 static WCHAR    (WINAPI *pRtlUpcaseUnicodeChar)(WCHAR);
59 static NTSTATUS (WINAPI *pRtlUpcaseUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
60 static CHAR     (WINAPI *pRtlUpperChar)(CHAR);
61 static NTSTATUS (WINAPI *pRtlUpperString)(STRING *, const STRING *);
62 static NTSTATUS (WINAPI *pRtlValidateUnicodeString)(long, UNICODE_STRING *);
63 static NTSTATUS (WINAPI *pRtlGUIDFromString)(const UNICODE_STRING*,GUID*);
64 static NTSTATUS (WINAPI *pRtlStringFromGUID)(const GUID*, UNICODE_STRING*);
65 static BOOLEAN (WINAPI *pRtlIsTextUnicode)(LPVOID, INT, INT *);
66
67 /*static VOID (WINAPI *pRtlFreeOemString)(PSTRING);*/
68 /*static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);*/
69 /*static VOID (WINAPI *pRtlCopyUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *);*/
70 /*static VOID (WINAPI *pRtlEraseUnicodeString)(UNICODE_STRING *);*/
71 /*static LONG (WINAPI *pRtlCompareString)(const STRING *,const STRING *,BOOLEAN);*/
72 /*static LONG (WINAPI *pRtlCompareUnicodeString)(const UNICODE_STRING *,const UNICODE_STRING *,BOOLEAN);*/
73 /*static BOOLEAN (WINAPI *pRtlEqualString)(const STRING *,const STRING *,BOOLEAN);*/
74 /*static BOOLEAN (WINAPI *pRtlPrefixString)(const STRING *, const STRING *, BOOLEAN);*/
75 /*static BOOLEAN (WINAPI *pRtlPrefixUnicodeString)(const UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);*/
76 /*static NTSTATUS (WINAPI *pRtlOemStringToUnicodeString)(PUNICODE_STRING, const STRING *, BOOLEAN);*/
77 /*static NTSTATUS (WINAPI *pRtlUnicodeStringToOemString)(STRING *, const UNICODE_STRING *, BOOLEAN);*/
78 /*static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)(LPWSTR, DWORD, LPDWORD, LPCSTR, DWORD);*/
79 /*static NTSTATUS (WINAPI *pRtlOemToUnicodeN)(LPWSTR, DWORD, LPDWORD, LPCSTR, DWORD);*/
80 /*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN);*/
81 /*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeStringToOemString)(STRING *, const UNICODE_STRING *, BOOLEAN);*/
82 /*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeToMultiByteN)(LPSTR, DWORD, LPDWORD, LPCWSTR, DWORD);*/
83 /*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeToOemN)(LPSTR, DWORD, LPDWORD, LPCWSTR, DWORD);*/
84 /*static UINT (WINAPI *pRtlOemToUnicodeSize)(const STRING *);*/
85 /*static DWORD (WINAPI *pRtlAnsiStringToUnicodeSize)(const STRING *);*/
86
87
88 static WCHAR* AtoW( const char* p )
89 {
90     WCHAR* buffer;
91     DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
92     buffer = malloc( len * sizeof(WCHAR) );
93     MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
94     return buffer;
95 }
96
97
98 static void InitFunctionPtrs(void)
99 {
100     hntdll = LoadLibraryA("ntdll.dll");
101     ok(hntdll != 0, "LoadLibrary failed\n");
102     if (hntdll) {
103         pRtlAnsiStringToUnicodeString = (void *)GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString");
104         pRtlAppendAsciizToString = (void *)GetProcAddress(hntdll, "RtlAppendAsciizToString");
105         pRtlAppendStringToString = (void *)GetProcAddress(hntdll, "RtlAppendStringToString");
106         pRtlAppendUnicodeStringToString = (void *)GetProcAddress(hntdll, "RtlAppendUnicodeStringToString");
107         pRtlAppendUnicodeToString = (void *)GetProcAddress(hntdll, "RtlAppendUnicodeToString");
108         pRtlCharToInteger = (void *)GetProcAddress(hntdll, "RtlCharToInteger");
109         pRtlCopyString = (void *)GetProcAddress(hntdll, "RtlCopyString");
110         pRtlCreateUnicodeString = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeString");
111         pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
112         pRtlDowncaseUnicodeString = (void *)GetProcAddress(hntdll, "RtlDowncaseUnicodeString");
113         pRtlDuplicateUnicodeString = (void *)GetProcAddress(hntdll, "RtlDuplicateUnicodeString");
114         pRtlEqualUnicodeString = (void *)GetProcAddress(hntdll, "RtlEqualUnicodeString");
115         pRtlFindCharInUnicodeString = (void *)GetProcAddress(hntdll, "RtlFindCharInUnicodeString");
116         pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString");
117         pRtlInitAnsiString = (void *)GetProcAddress(hntdll, "RtlInitAnsiString");
118         pRtlInitString = (void *)GetProcAddress(hntdll, "RtlInitString");
119         pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
120         pRtlInitUnicodeStringEx = (void *)GetProcAddress(hntdll, "RtlInitUnicodeStringEx");
121         pRtlIntegerToChar = (void *)GetProcAddress(hntdll, "RtlIntegerToChar");
122         pRtlIntegerToUnicodeString = (void *)GetProcAddress(hntdll, "RtlIntegerToUnicodeString");
123         pRtlMultiAppendUnicodeStringBuffer = (void *)GetProcAddress(hntdll, "RtlMultiAppendUnicodeStringBuffer");
124         pRtlUnicodeStringToAnsiString = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToAnsiString");
125         pRtlUnicodeStringToInteger = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToInteger");
126         pRtlUpcaseUnicodeChar = (void *)GetProcAddress(hntdll, "RtlUpcaseUnicodeChar");
127         pRtlUpcaseUnicodeString = (void *)GetProcAddress(hntdll, "RtlUpcaseUnicodeString");
128         pRtlUpperChar = (void *)GetProcAddress(hntdll, "RtlUpperChar");
129         pRtlUpperString = (void *)GetProcAddress(hntdll, "RtlUpperString");
130         pRtlValidateUnicodeString = (void *)GetProcAddress(hntdll, "RtlValidateUnicodeString");
131         pRtlGUIDFromString = (void *)GetProcAddress(hntdll, "RtlGUIDFromString");
132         pRtlStringFromGUID = (void *)GetProcAddress(hntdll, "RtlStringFromGUID");
133         pRtlIsTextUnicode = (void *)GetProcAddress(hntdll, "RtlIsTextUnicode");
134     }
135 }
136
137
138 static void test_RtlInitString(void)
139 {
140     static const char teststring[] = "Some Wild String";
141     STRING str;
142
143     str.Length = 0;
144     str.MaximumLength = 0;
145     str.Buffer = (void *)0xdeadbeef;
146     pRtlInitString(&str, teststring);
147     ok(str.Length == sizeof(teststring) - sizeof(char), "Length uninitialized\n");
148     ok(str.MaximumLength == sizeof(teststring), "MaximumLength uninitialized\n");
149     ok(str.Buffer == teststring, "Buffer not equal to teststring\n");
150     ok(strcmp(str.Buffer, "Some Wild String") == 0, "Buffer written to\n");
151     pRtlInitString(&str, NULL);
152     ok(str.Length == 0, "Length uninitialized\n");
153     ok(str.MaximumLength == 0, "MaximumLength uninitialized\n");
154     ok(str.Buffer == NULL, "Buffer not equal to NULL\n");
155 /*  pRtlInitString(NULL, teststring); */
156 }
157
158
159 static void test_RtlInitUnicodeString(void)
160 {
161 #define STRINGW {'S','o','m','e',' ','W','i','l','d',' ','S','t','r','i','n','g',0}
162     static const WCHAR teststring[] = STRINGW;
163     static const WCHAR originalstring[] = STRINGW;
164 #undef STRINGW
165     UNICODE_STRING uni;
166
167     uni.Length = 0;
168     uni.MaximumLength = 0;
169     uni.Buffer = (void *)0xdeadbeef;
170     pRtlInitUnicodeString(&uni, teststring);
171     ok(uni.Length == sizeof(teststring) - sizeof(WCHAR), "Length uninitialized\n");
172     ok(uni.MaximumLength == sizeof(teststring), "MaximumLength uninitialized\n");
173     ok(uni.Buffer == teststring, "Buffer not equal to teststring\n");
174     ok(lstrcmpW(uni.Buffer, originalstring) == 0, "Buffer written to\n");
175     pRtlInitUnicodeString(&uni, NULL);
176     ok(uni.Length == 0, "Length uninitialized\n");
177     ok(uni.MaximumLength == 0, "MaximumLength uninitialized\n");
178     ok(uni.Buffer == NULL, "Buffer not equal to NULL\n");
179 /*  pRtlInitUnicodeString(NULL, teststring); */
180 }
181
182
183 #define TESTSTRING2_LEN 1000000
184 /* #define TESTSTRING2_LEN 32766 */
185
186
187 static void test_RtlInitUnicodeStringEx(void)
188 {
189     static const WCHAR teststring[] = {'S','o','m','e',' ','W','i','l','d',' ','S','t','r','i','n','g',0};
190     WCHAR *teststring2;
191     UNICODE_STRING uni;
192     NTSTATUS result;
193
194     teststring2 = (WCHAR *) malloc((TESTSTRING2_LEN + 1) * sizeof(WCHAR));
195     memset(teststring2, 'X', TESTSTRING2_LEN * sizeof(WCHAR));
196     teststring2[TESTSTRING2_LEN] = '\0';
197
198     uni.Length = 12345;
199     uni.MaximumLength = 12345;
200     uni.Buffer = (void *) 0xdeadbeef;
201     result = pRtlInitUnicodeStringEx(&uni, teststring);
202     ok(result == STATUS_SUCCESS,
203        "pRtlInitUnicodeStringEx(&uni, 0) returns %x, expected 0\n",
204        result);
205     ok(uni.Length == 32,
206        "pRtlInitUnicodeStringEx(&uni, 0) sets Length to %u, expected %u\n",
207        uni.Length, 32);
208     ok(uni.MaximumLength == 34,
209        "pRtlInitUnicodeStringEx(&uni, 0) sets MaximumLength to %u, expected %u\n",
210        uni.MaximumLength, 34);
211     ok(uni.Buffer == teststring,
212        "pRtlInitUnicodeStringEx(&uni, 0) sets Buffer to %p, expected %p\n",
213        uni.Buffer, teststring);
214
215     uni.Length = 12345;
216     uni.MaximumLength = 12345;
217     uni.Buffer = (void *) 0xdeadbeef;
218     pRtlInitUnicodeString(&uni, teststring);
219     ok(uni.Length == 32,
220        "pRtlInitUnicodeString(&uni, 0) sets Length to %u, expected %u\n",
221        uni.Length, 32);
222     ok(uni.MaximumLength == 34,
223        "pRtlInitUnicodeString(&uni, 0) sets MaximumLength to %u, expected %u\n",
224        uni.MaximumLength, 34);
225     ok(uni.Buffer == teststring,
226        "pRtlInitUnicodeString(&uni, 0) sets Buffer to %p, expected %p\n",
227        uni.Buffer, teststring);
228
229     uni.Length = 12345;
230     uni.MaximumLength = 12345;
231     uni.Buffer = (void *) 0xdeadbeef;
232     result = pRtlInitUnicodeStringEx(&uni, teststring2);
233     ok(result == STATUS_NAME_TOO_LONG,
234        "pRtlInitUnicodeStringEx(&uni, 0) returns %x, expected %x\n",
235        result, STATUS_NAME_TOO_LONG);
236     ok(uni.Length == 12345,
237        "pRtlInitUnicodeStringEx(&uni, 0) sets Length to %u, expected %u\n",
238        uni.Length, 12345);
239     ok(uni.MaximumLength == 12345,
240        "pRtlInitUnicodeStringEx(&uni, 0) sets MaximumLength to %u, expected %u\n",
241        uni.MaximumLength, 12345);
242     ok(uni.Buffer == (void *) 0xdeadbeef,
243        "pRtlInitUnicodeStringEx(&uni, 0) sets Buffer to %p, expected %x\n",
244        uni.Buffer, 0xdeadbeef);
245
246     uni.Length = 12345;
247     uni.MaximumLength = 12345;
248     uni.Buffer = (void *) 0xdeadbeef;
249     pRtlInitUnicodeString(&uni, teststring2);
250     ok(uni.Length == 33920 /* <= Win2000 */ || uni.Length == 65532 /* >= Win XP */,
251        "pRtlInitUnicodeString(&uni, 0) sets Length to %u, expected %u\n",
252        uni.Length, 65532);
253     ok(uni.MaximumLength == 33922 /* <= Win2000 */ || uni.MaximumLength == 65534 /* >= Win XP */,
254        "pRtlInitUnicodeString(&uni, 0) sets MaximumLength to %u, expected %u\n",
255        uni.MaximumLength, 65534);
256     ok(uni.Buffer == teststring2,
257        "pRtlInitUnicodeString(&uni, 0) sets Buffer to %p, expected %p\n",
258        uni.Buffer, teststring2);
259     ok(memcmp(uni.Buffer, teststring2, (TESTSTRING2_LEN + 1) * sizeof(WCHAR)) == 0,
260        "pRtlInitUnicodeString(&uni, 0) changes Buffer\n");
261
262     uni.Length = 12345;
263     uni.MaximumLength = 12345;
264     uni.Buffer = (void *) 0xdeadbeef;
265     result = pRtlInitUnicodeStringEx(&uni, 0);
266     ok(result == STATUS_SUCCESS,
267        "pRtlInitUnicodeStringEx(&uni, 0) returns %x, expected 0\n",
268        result);
269     ok(uni.Length == 0,
270        "pRtlInitUnicodeStringEx(&uni, 0) sets Length to %u, expected %u\n",
271        uni.Length, 0);
272     ok(uni.MaximumLength == 0,
273        "pRtlInitUnicodeStringEx(&uni, 0) sets MaximumLength to %u, expected %u\n",
274        uni.MaximumLength, 0);
275     ok(uni.Buffer == NULL,
276        "pRtlInitUnicodeStringEx(&uni, 0) sets Buffer to %p, expected %p\n",
277        uni.Buffer, NULL);
278
279     uni.Length = 12345;
280     uni.MaximumLength = 12345;
281     uni.Buffer = (void *) 0xdeadbeef;
282     pRtlInitUnicodeString(&uni, 0);
283     ok(uni.Length == 0,
284        "pRtlInitUnicodeString(&uni, 0) sets Length to %u, expected %u\n",
285        uni.Length, 0);
286     ok(uni.MaximumLength == 0,
287        "pRtlInitUnicodeString(&uni, 0) sets MaximumLength to %u, expected %u\n",
288        uni.MaximumLength, 0);
289     ok(uni.Buffer == NULL,
290        "pRtlInitUnicodeString(&uni, 0) sets Buffer to %p, expected %p\n",
291        uni.Buffer, NULL);
292
293     free(teststring2);
294 }
295
296
297 typedef struct {
298     int add_nul;
299     int source_Length;
300     int source_MaximumLength;
301     int source_buf_size;
302     const char *source_buf;
303     int dest_Length;
304     int dest_MaximumLength;
305     int dest_buf_size;
306     const char *dest_buf;
307     int res_Length;
308     int res_MaximumLength;
309     int res_buf_size;
310     const char *res_buf;
311     NTSTATUS result;
312 } dupl_ustr_t;
313
314 static const dupl_ustr_t dupl_ustr[] = {
315     { 0, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 32, 32, 32, "This is a string",     STATUS_SUCCESS},
316     { 0, 32, 32, 32, "This is a string", 40, 42, 42, "--------------------", 32, 32, 32, "This is a string",     STATUS_SUCCESS},
317     { 0, 32, 30, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
318     { 0, 32, 34, 34, "This is a string", 40, 42, 42, NULL,                   32, 32, 32, "This is a string",     STATUS_SUCCESS},
319     { 0, 32, 32, 32, "This is a string", 40, 42, 42, NULL,                   32, 32, 32, "This is a string",     STATUS_SUCCESS},
320     { 0, 32, 30, 34, "This is a string", 40, 42, 42, NULL,                   40, 42,  0, NULL,                   STATUS_INVALID_PARAMETER},
321     { 1, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 32, 34, 34, "This is a string",     STATUS_SUCCESS},
322     { 1, 32, 32, 32, "This is a string", 40, 42, 42, "--------------------", 32, 34, 34, "This is a string",     STATUS_SUCCESS},
323     { 1, 32, 30, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
324     { 1, 32, 34, 34, "This is a string", 40, 42, 42, NULL,                   32, 34, 34, "This is a string",     STATUS_SUCCESS},
325     { 1, 32, 32, 32, "This is a string", 40, 42, 42, NULL,                   32, 34, 34, "This is a string",     STATUS_SUCCESS},
326     { 1, 32, 30, 34, "This is a string", 40, 42, 42, NULL,                   40, 42,  0, NULL,                   STATUS_INVALID_PARAMETER},
327     { 2, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
328     { 2, 32, 32, 32, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
329     { 2, 32, 30, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
330     { 2, 32, 34, 34, "This is a string", 40, 42, 42, NULL,                   40, 42,  0, NULL,                   STATUS_INVALID_PARAMETER},
331     { 2, 32, 32, 32, "This is a string", 40, 42, 42, NULL,                   40, 42,  0, NULL,                   STATUS_INVALID_PARAMETER},
332     { 2, 32, 30, 34, "This is a string", 40, 42, 42, NULL,                   40, 42,  0, NULL,                   STATUS_INVALID_PARAMETER},
333     { 3, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 32, 34, 34, "This is a string",     STATUS_SUCCESS},
334     { 3, 32, 32, 32, "This is a string", 40, 42, 42, "--------------------", 32, 34, 34, "This is a string",     STATUS_SUCCESS},
335     { 3, 32, 30, 32, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
336     { 3, 32, 34, 34, "This is a string", 40, 42, 42, NULL,                   32, 34, 34, "This is a string",     STATUS_SUCCESS},
337     { 3, 32, 32, 32, "This is a string", 40, 42, 42, NULL,                   32, 34, 34, "This is a string",     STATUS_SUCCESS},
338     { 3, 32, 30, 32, "This is a string", 40, 42, 42, NULL,                   40, 42,  0, NULL,                   STATUS_INVALID_PARAMETER},
339     { 4, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
340     { 5, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
341     { 6, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
342     { 7, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
343     { 8, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
344     { 9, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
345     {10, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
346     {11, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
347     {12, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
348     {13, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
349     {14, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
350     {15, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
351     {16, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
352     {-1, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
353     {-5, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
354     {-9, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
355     { 0,  0,  2,  2, "",                 40, 42, 42, "--------------------",  0,  0,  0, NULL,                   STATUS_SUCCESS},
356     { 0,  0,  0,  0, "",                 40, 42, 42, "--------------------",  0,  0,  0, NULL,                   STATUS_SUCCESS},
357     { 0,  0,  2,  2, "",                 40, 42, 42, NULL,                    0,  0,  0, NULL,                   STATUS_SUCCESS},
358     { 0,  0,  0,  0, "",                 40, 42, 42, NULL,                    0,  0,  0, NULL,                   STATUS_SUCCESS},
359     { 0,  0,  2,  2, NULL,               40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
360     { 0,  0,  0,  0, NULL,               40, 42, 42, "--------------------",  0,  0,  0, NULL,                   STATUS_SUCCESS},
361     { 0,  0,  2,  2, NULL,               40, 42, 42, NULL,                   40, 42,  0, NULL,                   STATUS_INVALID_PARAMETER},
362     { 0,  0,  0,  0, NULL,               40, 42, 42, NULL,                    0,  0,  0, NULL,                   STATUS_SUCCESS},
363     { 1,  0,  2,  2, "",                 40, 42, 42, "--------------------",  0,  0,  0, NULL,                   STATUS_SUCCESS},
364     { 1,  0,  0,  0, "",                 40, 42, 42, "--------------------",  0,  0,  0, NULL,                   STATUS_SUCCESS},
365     { 1,  0,  2,  2, "",                 40, 42, 42, NULL,                    0,  0,  0, NULL,                   STATUS_SUCCESS},
366     { 1,  0,  0,  0, "",                 40, 42, 42, NULL,                    0,  0,  0, NULL,                   STATUS_SUCCESS},
367     { 1,  0,  2,  2, NULL,               40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
368     { 1,  0,  0,  0, NULL,               40, 42, 42, "--------------------",  0,  0,  0, NULL,                   STATUS_SUCCESS},
369     { 1,  0,  2,  2, NULL,               40, 42, 42, NULL,                   40, 42,  0, NULL,                   STATUS_INVALID_PARAMETER},
370     { 1,  0,  0,  0, NULL,               40, 42, 42, NULL,                    0,  0,  0, NULL,                   STATUS_SUCCESS},
371     { 2,  0,  2,  2, "",                 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
372     { 2,  0,  0,  0, "",                 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
373     { 2,  0,  2,  2, "",                 40, 42, 42, NULL,                   40, 42,  0, NULL,                   STATUS_INVALID_PARAMETER},
374     { 2,  0,  0,  0, "",                 40, 42, 42, NULL,                   40, 42,  0, NULL,                   STATUS_INVALID_PARAMETER},
375     { 2,  0,  2,  2, NULL,               40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
376     { 2,  0,  0,  0, NULL,               40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
377     { 2,  0,  2,  2, NULL,               40, 42, 42, NULL,                   40, 42,  0, NULL,                   STATUS_INVALID_PARAMETER},
378     { 2,  0,  0,  0, NULL,               40, 42, 42, NULL,                   40, 42,  0, NULL,                   STATUS_INVALID_PARAMETER},
379     { 3,  0,  2,  2, "",                 40, 42, 42, "--------------------",  0,  2,  2, "",                     STATUS_SUCCESS},
380     { 3,  0,  0,  0, "",                 40, 42, 42, "--------------------",  0,  2,  2, "",                     STATUS_SUCCESS},
381     { 3,  0,  2,  2, "",                 40, 42, 42, NULL,                    0,  2,  2, "",                     STATUS_SUCCESS},
382     { 3,  0,  0,  0, "",                 40, 42, 42, NULL,                    0,  2,  2, "",                     STATUS_SUCCESS},
383     { 3,  0,  2,  2, NULL,               40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER},
384     { 3,  0,  0,  0, NULL,               40, 42, 42, "--------------------",  0,  2,  2, "",                     STATUS_SUCCESS},
385     { 3,  0,  2,  2, NULL,               40, 42, 42, NULL,                   40, 42,  0, NULL,                   STATUS_INVALID_PARAMETER},
386     { 3,  0,  0,  0, NULL,               40, 42, 42, NULL,                    0,  2,  2, "",                     STATUS_SUCCESS},
387 };
388 #define NB_DUPL_USTR (sizeof(dupl_ustr)/sizeof(*dupl_ustr))
389
390
391 static void test_RtlDuplicateUnicodeString(void)
392 {
393     size_t pos;
394     WCHAR source_buf[257];
395     WCHAR dest_buf[257];
396     WCHAR res_buf[257];
397     UNICODE_STRING source_str;
398     UNICODE_STRING dest_str;
399     UNICODE_STRING res_str;
400     CHAR dest_ansi_buf[257];
401     STRING dest_ansi_str;
402     NTSTATUS result;
403     unsigned int test_num;
404
405     for (test_num = 0; test_num < NB_DUPL_USTR; test_num++) {
406         source_str.Length        = dupl_ustr[test_num].source_Length;
407         source_str.MaximumLength = dupl_ustr[test_num].source_MaximumLength;
408         if (dupl_ustr[test_num].source_buf != NULL) {
409             for (pos = 0; pos < dupl_ustr[test_num].source_buf_size/sizeof(WCHAR); pos++) {
410                 source_buf[pos] = dupl_ustr[test_num].source_buf[pos];
411             }
412             source_str.Buffer = source_buf;
413         } else {
414             source_str.Buffer = NULL;
415         }
416         dest_str.Length        = dupl_ustr[test_num].dest_Length;
417         dest_str.MaximumLength = dupl_ustr[test_num].dest_MaximumLength;
418         if (dupl_ustr[test_num].dest_buf != NULL) {
419             for (pos = 0; pos < dupl_ustr[test_num].dest_buf_size/sizeof(WCHAR); pos++) {
420                 dest_buf[pos] = dupl_ustr[test_num].dest_buf[pos];
421             }
422             dest_str.Buffer = dest_buf;
423         } else {
424             dest_str.Buffer = NULL;
425         }
426         res_str.Length        = dupl_ustr[test_num].res_Length;
427         res_str.MaximumLength = dupl_ustr[test_num].res_MaximumLength;
428         if (dupl_ustr[test_num].res_buf != NULL) {
429             for (pos = 0; pos < dupl_ustr[test_num].res_buf_size/sizeof(WCHAR); pos++) {
430                 res_buf[pos] = dupl_ustr[test_num].res_buf[pos];
431             }
432             res_str.Buffer = res_buf;
433         } else {
434             res_str.Buffer = NULL;
435         }
436         result = pRtlDuplicateUnicodeString(dupl_ustr[test_num].add_nul, &source_str, &dest_str);
437         dest_ansi_str.Length = dest_str.Length / sizeof(WCHAR);
438         dest_ansi_str.MaximumLength = dest_ansi_str.Length + 1;
439         for (pos = 0; pos < dest_ansi_str.Length; pos++) {
440             dest_ansi_buf[pos] = (char)dest_buf[pos];
441         }
442         dest_ansi_buf[dest_ansi_str.Length] = '\0';
443         dest_ansi_str.Buffer = dest_ansi_buf;
444         ok(result == dupl_ustr[test_num].result,
445            "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has result %x, expected %x\n",
446            test_num, dupl_ustr[test_num].add_nul, result, dupl_ustr[test_num].result);
447         ok(dest_str.Length == dupl_ustr[test_num].res_Length,
448            "(test %d): RtlDuplicateUnicodeString(%d, source, dest) destination has Length %d, expected %d\n",
449            test_num, dupl_ustr[test_num].add_nul, dest_str.Length, dupl_ustr[test_num].res_Length);
450         ok(dest_str.MaximumLength == dupl_ustr[test_num].res_MaximumLength,
451            "(test %d): RtlDuplicateUnicodeString(%d, source, dest) destination has MaximumLength %d, expected %d\n",
452            test_num, dupl_ustr[test_num].add_nul, dest_str.MaximumLength, dupl_ustr[test_num].res_MaximumLength);
453         if (result == STATUS_INVALID_PARAMETER) {
454             ok((dest_str.Buffer == NULL && res_str.Buffer == NULL) ||
455                dest_str.Buffer == dest_buf,
456                "(test %d): RtlDuplicateUnicodeString(%d, source, dest) destination buffer changed %p expected %p\n",
457                test_num, dupl_ustr[test_num].add_nul, dest_str.Buffer, dest_buf);
458         } else {
459             ok(dest_str.Buffer != dest_buf,
460                "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination buffer unchanged %p\n",
461                test_num, dupl_ustr[test_num].add_nul, dest_str.Buffer);
462         }
463         if (dest_str.Buffer != NULL && dupl_ustr[test_num].res_buf != NULL) {
464             ok(memcmp(dest_str.Buffer, res_str.Buffer, dupl_ustr[test_num].res_buf_size) == 0,
465                "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination \"%s\" expected \"%s\"\n",
466                test_num, dupl_ustr[test_num].add_nul, dest_ansi_str.Buffer, dupl_ustr[test_num].res_buf);
467         } else {
468             ok(dest_str.Buffer == NULL && dupl_ustr[test_num].res_buf == NULL,
469                "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination %p expected %p\n",
470                test_num, dupl_ustr[test_num].add_nul, dest_str.Buffer, dupl_ustr[test_num].res_buf);
471         }
472     }
473 }
474
475
476 static void test_RtlCopyString(void)
477 {
478     static const char teststring[] = "Some Wild String";
479     char deststring[] = "                    ";
480     STRING str;
481     STRING deststr;
482
483     pRtlInitString(&str, teststring);
484     pRtlInitString(&deststr, deststring);
485     pRtlCopyString(&deststr, &str);
486     ok(strncmp(str.Buffer, deststring, str.Length) == 0, "String not copied\n");
487 }
488
489
490 static void test_RtlUpperChar(void)
491 {
492     int ch;
493     int upper_ch;
494     int expected_upper_ch;
495     int byte_ch;
496
497     for (ch = -1; ch <= 1024; ch++) {
498         upper_ch = pRtlUpperChar(ch);
499         byte_ch = ch & 0xff;
500         if (byte_ch >= 'a' && byte_ch <= 'z') {
501             expected_upper_ch = (CHAR) (byte_ch - 'a' + 'A');
502         } else {
503             expected_upper_ch = (CHAR) byte_ch;
504         }
505         ok(upper_ch == expected_upper_ch,
506            "RtlUpperChar('%c'[=0x%x]) has result '%c'[=0x%x], expected '%c'[=0x%x]\n",
507            ch, ch, upper_ch, upper_ch, expected_upper_ch, expected_upper_ch);
508     }
509 }
510
511
512 static void test_RtlUpperString(void)
513 {
514     int i;
515     CHAR ch;
516     CHAR upper_ch;
517     char ascii_buf[257];
518     char result_buf[257];
519     char upper_buf[257];
520     STRING ascii_str;
521     STRING result_str;
522     STRING upper_str;
523
524     for (i = 0; i <= 255; i++) {
525         ch = (CHAR) i;
526         if (ch >= 'a' && ch <= 'z') {
527             upper_ch = ch - 'a' + 'A';
528         } else {
529             upper_ch = ch;
530         }
531         ascii_buf[i] = ch;
532         result_buf[i] = '\0';
533         upper_buf[i] = upper_ch;
534     }
535     ascii_buf[i] = '\0';
536     result_buf[i] = '\0';
537     upper_buf[i] = '\0';
538     ascii_str.Length = 256;
539     ascii_str.MaximumLength = 256;
540     ascii_str.Buffer = ascii_buf;
541     result_str.Length = 256;
542     result_str.MaximumLength = 256;
543     result_str.Buffer = result_buf;
544     upper_str.Length = 256;
545     upper_str.MaximumLength = 256;
546     upper_str.Buffer = upper_buf;
547
548     pRtlUpperString(&result_str, &ascii_str);
549     ok(memcmp(result_str.Buffer, upper_str.Buffer, 256) == 0,
550        "RtlUpperString does not work as expected\n");
551 }
552
553
554 static void test_RtlUpcaseUnicodeChar(void)
555 {
556     int i;
557     WCHAR ch;
558     WCHAR upper_ch;
559     WCHAR expected_upper_ch;
560
561     for (i = 0; i <= 255; i++) {
562         ch = (WCHAR) i;
563         upper_ch = pRtlUpcaseUnicodeChar(ch);
564         if (ch >= 'a' && ch <= 'z') {
565             expected_upper_ch = ch - 'a' + 'A';
566         } else if (ch >= 0xe0 && ch <= 0xfe && ch != 0xf7) {
567             expected_upper_ch = ch - 0x20;
568         } else if (ch == 0xff) {
569             expected_upper_ch = 0x178;
570         } else {
571             expected_upper_ch = ch;
572         }
573         ok(upper_ch == expected_upper_ch,
574            "RtlUpcaseUnicodeChar('%c'[=0x%x]) has result '%c'[=0x%x], expected: '%c'[=0x%x]\n",
575            ch, ch, upper_ch, upper_ch, expected_upper_ch, expected_upper_ch);
576     }
577 }
578
579
580 static void test_RtlUpcaseUnicodeString(void)
581 {
582     int i;
583     WCHAR ch;
584     WCHAR upper_ch;
585     WCHAR ascii_buf[257];
586     WCHAR result_buf[257];
587     WCHAR upper_buf[257];
588     UNICODE_STRING ascii_str;
589     UNICODE_STRING result_str;
590     UNICODE_STRING upper_str;
591
592     for (i = 0; i <= 255; i++) {
593         ch = (WCHAR) i;
594         if (ch >= 'a' && ch <= 'z') {
595             upper_ch = ch - 'a' + 'A';
596         } else if (ch >= 0xe0 && ch <= 0xfe && ch != 0xf7) {
597             upper_ch = ch - 0x20;
598         } else if (ch == 0xff) {
599             upper_ch = 0x178;
600         } else {
601             upper_ch = ch;
602         }
603         ascii_buf[i] = ch;
604         result_buf[i] = '\0';
605         upper_buf[i] = upper_ch;
606     }
607     ascii_buf[i] = '\0';
608     result_buf[i] = '\0';
609     upper_buf[i] = '\0';
610     ascii_str.Length = 512;
611     ascii_str.MaximumLength = 512;
612     ascii_str.Buffer = ascii_buf;
613     result_str.Length = 512;
614     result_str.MaximumLength = 512;
615     result_str.Buffer = result_buf;
616     upper_str.Length = 512;
617     upper_str.MaximumLength = 512;
618     upper_str.Buffer = upper_buf;
619
620     pRtlUpcaseUnicodeString(&result_str, &ascii_str, 0);
621     for (i = 0; i <= 255; i++) {
622         ok(result_str.Buffer[i] == upper_str.Buffer[i],
623            "RtlUpcaseUnicodeString works wrong: '%c'[=0x%x] is converted to '%c'[=0x%x], expected: '%c'[=0x%x]\n",
624            ascii_str.Buffer[i], ascii_str.Buffer[i],
625            result_str.Buffer[i], result_str.Buffer[i],
626            upper_str.Buffer[i], upper_str.Buffer[i]);
627     }
628 }
629
630
631 static void test_RtlDowncaseUnicodeString(void)
632 {
633     int i;
634     WCHAR ch;
635     WCHAR lower_ch;
636     WCHAR source_buf[1025];
637     WCHAR result_buf[1025];
638     WCHAR lower_buf[1025];
639     UNICODE_STRING source_str;
640     UNICODE_STRING result_str;
641     UNICODE_STRING lower_str;
642
643     for (i = 0; i < 1024; i++) {
644         ch = (WCHAR) i;
645         if (ch >= 'A' && ch <= 'Z') {
646             lower_ch = ch - 'A' + 'a';
647         } else if (ch >= 0xc0 && ch <= 0xde && ch != 0xd7) {
648             lower_ch = ch + 0x20;
649         } else if (ch >= 0x391 && ch <= 0x3ab && ch != 0x3a2) {
650             lower_ch = ch + 0x20;
651         } else {
652             switch (ch) {
653                 case 0x178: lower_ch = 0xff; break;
654                 case 0x181: lower_ch = 0x253; break;
655                 case 0x186: lower_ch = 0x254; break;
656                 case 0x189: lower_ch = 0x256; break;
657                 case 0x18a: lower_ch = 0x257; break;
658                 case 0x18e: lower_ch = 0x1dd; break;
659                 case 0x18f: lower_ch = 0x259; break;
660                 case 0x190: lower_ch = 0x25b; break;
661                 case 0x193: lower_ch = 0x260; break;
662                 case 0x194: lower_ch = 0x263; break;
663                 case 0x196: lower_ch = 0x269; break;
664                 case 0x197: lower_ch = 0x268; break;
665                 case 0x19c: lower_ch = 0x26f; break;
666                 case 0x19d: lower_ch = 0x272; break;
667                 case 0x19f: lower_ch = 0x275; break;
668                 case 0x1a9: lower_ch = 0x283; break;
669                 case 0x1ae: lower_ch = 0x288; break;
670                 case 0x1b1: lower_ch = 0x28a; break;
671                 case 0x1b2: lower_ch = 0x28b; break;
672                 case 0x1b7: lower_ch = 0x292; break;
673                 case 0x1c4: lower_ch = 0x1c6; break;
674                 case 0x1c7: lower_ch = 0x1c9; break;
675                 case 0x1ca: lower_ch = 0x1cc; break;
676                 case 0x1f1: lower_ch = 0x1f3; break;
677                 case 0x386: lower_ch = 0x3ac; break;
678                 case 0x388: lower_ch = 0x3ad; break;
679                 case 0x389: lower_ch = 0x3ae; break;
680                 case 0x38a: lower_ch = 0x3af; break;
681                 case 0x38c: lower_ch = 0x3cc; break;
682                 case 0x38e: lower_ch = 0x3cd; break;
683                 case 0x38f: lower_ch = 0x3ce; break;
684                 default: lower_ch = ch; break;
685             } /* switch */
686         }
687         source_buf[i] = ch;
688         result_buf[i] = '\0';
689         lower_buf[i] = lower_ch;
690     }
691     source_buf[i] = '\0';
692     result_buf[i] = '\0';
693     lower_buf[i] = '\0';
694     source_str.Length = 2048;
695     source_str.MaximumLength = 2048;
696     source_str.Buffer = source_buf;
697     result_str.Length = 2048;
698     result_str.MaximumLength = 2048;
699     result_str.Buffer = result_buf;
700     lower_str.Length = 2048;
701     lower_str.MaximumLength = 2048;
702     lower_str.Buffer = lower_buf;
703
704     pRtlDowncaseUnicodeString(&result_str, &source_str, 0);
705     for (i = 0; i <= 1024; i++) {
706         ok(result_str.Buffer[i] == lower_str.Buffer[i] || result_str.Buffer[i] == source_str.Buffer[i] + 1,
707            "RtlDowncaseUnicodeString works wrong: '%c'[=0x%x] is converted to '%c'[=0x%x], expected: '%c'[=0x%x]\n",
708            source_str.Buffer[i], source_str.Buffer[i],
709            result_str.Buffer[i], result_str.Buffer[i],
710            lower_str.Buffer[i], lower_str.Buffer[i]);
711     }
712 }
713
714
715 typedef struct {
716     int ansi_Length;
717     int ansi_MaximumLength;
718     int ansi_buf_size;
719     const char *ansi_buf;
720     int uni_Length;
721     int uni_MaximumLength;
722     int uni_buf_size;
723     const char *uni_buf;
724     BOOLEAN doalloc;
725     int res_Length;
726     int res_MaximumLength;
727     int res_buf_size;
728     const char *res_buf;
729     NTSTATUS result;
730 } ustr2astr_t;
731
732 static const ustr2astr_t ustr2astr[] = {
733     { 10, 12, 12, "------------",  0,  0,  0, "",       TRUE,  0, 1, 1, "",       STATUS_SUCCESS},
734     { 10, 12, 12, "------------", 12, 12, 12, "abcdef", TRUE,  6, 7, 7, "abcdef", STATUS_SUCCESS},
735     {  0,  2, 12, "------------", 12, 12, 12, "abcdef", TRUE,  6, 7, 7, "abcdef", STATUS_SUCCESS},
736     { 10, 12, 12, NULL,           12, 12, 12, "abcdef", TRUE,  6, 7, 7, "abcdef", STATUS_SUCCESS},
737     {  0,  0, 12, "------------", 12, 12, 12, "abcdef", FALSE, 6, 0, 0, "",       STATUS_BUFFER_OVERFLOW},
738     {  0,  1, 12, "------------", 12, 12, 12, "abcdef", FALSE, 0, 1, 1, "",       STATUS_BUFFER_OVERFLOW},
739     {  0,  2, 12, "------------", 12, 12, 12, "abcdef", FALSE, 1, 2, 2, "a",      STATUS_BUFFER_OVERFLOW},
740     {  0,  3, 12, "------------", 12, 12, 12, "abcdef", FALSE, 2, 3, 3, "ab",     STATUS_BUFFER_OVERFLOW},
741     {  0,  5, 12, "------------", 12, 12, 12, "abcdef", FALSE, 4, 5, 5, "abcd",   STATUS_BUFFER_OVERFLOW},
742     {  8,  5, 12, "------------", 12, 12, 12, "abcdef", FALSE, 4, 5, 5, "abcd",   STATUS_BUFFER_OVERFLOW},
743     {  8,  6, 12, "------------", 12, 12, 12, "abcdef", FALSE, 5, 6, 6, "abcde",  STATUS_BUFFER_OVERFLOW},
744     {  8,  7, 12, "------------", 12, 12, 12, "abcdef", FALSE, 6, 7, 7, "abcdef", STATUS_SUCCESS},
745     {  8,  7, 12, "------------",  0, 12, 12,  NULL,    FALSE, 0, 7, 0, "",       STATUS_SUCCESS},
746     {  0,  0, 12, NULL,           10, 10, 12,  NULL,    FALSE, 5, 0, 0, NULL,     STATUS_BUFFER_OVERFLOW},
747 };
748 #define NB_USTR2ASTR (sizeof(ustr2astr)/sizeof(*ustr2astr))
749
750
751 static void test_RtlUnicodeStringToAnsiString(void)
752 {
753     size_t pos;
754     CHAR ansi_buf[257];
755     WCHAR uni_buf[257];
756     STRING ansi_str;
757     UNICODE_STRING uni_str;
758     NTSTATUS result;
759     unsigned int test_num;
760
761     for (test_num = 0; test_num < NB_USTR2ASTR; test_num++) {
762         ansi_str.Length        = ustr2astr[test_num].ansi_Length;
763         ansi_str.MaximumLength = ustr2astr[test_num].ansi_MaximumLength;
764         if (ustr2astr[test_num].ansi_buf != NULL) {
765             memcpy(ansi_buf, ustr2astr[test_num].ansi_buf, ustr2astr[test_num].ansi_buf_size);
766             ansi_buf[ustr2astr[test_num].ansi_buf_size] = '\0';
767             ansi_str.Buffer = ansi_buf;
768         } else {
769             ansi_str.Buffer = NULL;
770         }
771         uni_str.Length        = ustr2astr[test_num].uni_Length;
772         uni_str.MaximumLength = ustr2astr[test_num].uni_MaximumLength;
773         if (ustr2astr[test_num].uni_buf != NULL) {
774             for (pos = 0; pos < ustr2astr[test_num].uni_buf_size/sizeof(WCHAR); pos++) {
775                 uni_buf[pos] = ustr2astr[test_num].uni_buf[pos];
776             }
777             uni_str.Buffer = uni_buf;
778         } else {
779             uni_str.Buffer = NULL;
780         }
781         result = pRtlUnicodeStringToAnsiString(&ansi_str, &uni_str, ustr2astr[test_num].doalloc);
782         ok(result == ustr2astr[test_num].result,
783            "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) has result %x, expected %x\n",
784            test_num, ustr2astr[test_num].doalloc, result, ustr2astr[test_num].result);
785         ok(ansi_str.Length == ustr2astr[test_num].res_Length,
786            "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) ansi has Length %d, expected %d\n",
787            test_num, ustr2astr[test_num].doalloc, ansi_str.Length, ustr2astr[test_num].res_Length);
788         ok(ansi_str.MaximumLength == ustr2astr[test_num].res_MaximumLength,
789            "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) ansi has MaximumLength %d, expected %d\n",
790            test_num, ustr2astr[test_num].doalloc, ansi_str.MaximumLength, ustr2astr[test_num].res_MaximumLength);
791         ok(memcmp(ansi_str.Buffer, ustr2astr[test_num].res_buf, ustr2astr[test_num].res_buf_size) == 0,
792            "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) has ansi \"%s\" expected \"%s\"\n",
793            test_num, ustr2astr[test_num].doalloc, ansi_str.Buffer, ustr2astr[test_num].res_buf);
794     }
795 }
796
797
798 typedef struct {
799     int dest_Length;
800     int dest_MaximumLength;
801     int dest_buf_size;
802     const char *dest_buf;
803     const char *src;
804     int res_Length;
805     int res_MaximumLength;
806     int res_buf_size;
807     const char *res_buf;
808     NTSTATUS result;
809 } app_asc2str_t;
810
811 static const app_asc2str_t app_asc2str[] = {
812     { 5, 12, 15,  "TestS01234abcde", "tring", 10, 12, 15,  "TestStringabcde", STATUS_SUCCESS},
813     { 5, 11, 15,  "TestS01234abcde", "tring", 10, 11, 15,  "TestStringabcde", STATUS_SUCCESS},
814     { 5, 10, 15,  "TestS01234abcde", "tring", 10, 10, 15,  "TestStringabcde", STATUS_SUCCESS},
815     { 5,  9, 15,  "TestS01234abcde", "tring",  5,  9, 15,  "TestS01234abcde", STATUS_BUFFER_TOO_SMALL},
816     { 5,  0, 15,  "TestS01234abcde", "tring",  5,  0, 15,  "TestS01234abcde", STATUS_BUFFER_TOO_SMALL},
817     { 5, 14, 15,  "TestS01234abcde", "tring", 10, 14, 15,  "TestStringabcde", STATUS_SUCCESS},
818     { 5, 14, 15,  "TestS01234abcde",    NULL,  5, 14, 15,  "TestS01234abcde", STATUS_SUCCESS},
819     { 5, 14, 15,               NULL,    NULL,  5, 14, 15,               NULL, STATUS_SUCCESS},
820     { 5, 12, 15, "Tst\0S01234abcde", "tr\0i",  7, 12, 15, "Tst\0Str234abcde", STATUS_SUCCESS},
821 };
822 #define NB_APP_ASC2STR (sizeof(app_asc2str)/sizeof(*app_asc2str))
823
824
825 static void test_RtlAppendAsciizToString(void)
826 {
827     CHAR dest_buf[257];
828     STRING dest_str;
829     NTSTATUS result;
830     unsigned int test_num;
831
832     for (test_num = 0; test_num < NB_APP_ASC2STR; test_num++) {
833         dest_str.Length        = app_asc2str[test_num].dest_Length;
834         dest_str.MaximumLength = app_asc2str[test_num].dest_MaximumLength;
835         if (app_asc2str[test_num].dest_buf != NULL) {
836             memcpy(dest_buf, app_asc2str[test_num].dest_buf, app_asc2str[test_num].dest_buf_size);
837             dest_buf[app_asc2str[test_num].dest_buf_size] = '\0';
838             dest_str.Buffer = dest_buf;
839         } else {
840             dest_str.Buffer = NULL;
841         }
842         result = pRtlAppendAsciizToString(&dest_str, app_asc2str[test_num].src);
843         ok(result == app_asc2str[test_num].result,
844            "(test %d): RtlAppendAsciizToString(dest, src) has result %x, expected %x\n",
845            test_num, result, app_asc2str[test_num].result);
846         ok(dest_str.Length == app_asc2str[test_num].res_Length,
847            "(test %d): RtlAppendAsciizToString(dest, src) dest has Length %d, expected %d\n",
848            test_num, dest_str.Length, app_asc2str[test_num].res_Length);
849         ok(dest_str.MaximumLength == app_asc2str[test_num].res_MaximumLength,
850            "(test %d): RtlAppendAsciizToString(dest, src) dest has MaximumLength %d, expected %d\n",
851            test_num, dest_str.MaximumLength, app_asc2str[test_num].res_MaximumLength);
852         if (dest_str.Buffer == dest_buf) {
853             ok(memcmp(dest_buf, app_asc2str[test_num].res_buf, app_asc2str[test_num].res_buf_size) == 0,
854                "(test %d): RtlAppendAsciizToString(dest, src) has dest \"%s\" expected \"%s\"\n",
855                test_num, dest_buf, app_asc2str[test_num].res_buf);
856         } else {
857             ok(dest_str.Buffer == app_asc2str[test_num].res_buf,
858                "(test %d): RtlAppendAsciizToString(dest, src) dest has Buffer %p expected %p\n",
859                test_num, dest_str.Buffer, app_asc2str[test_num].res_buf);
860         }
861     }
862 }
863
864
865 typedef struct {
866     int dest_Length;
867     int dest_MaximumLength;
868     int dest_buf_size;
869     const char *dest_buf;
870     int src_Length;
871     int src_MaximumLength;
872     int src_buf_size;
873     const char *src_buf;
874     int res_Length;
875     int res_MaximumLength;
876     int res_buf_size;
877     const char *res_buf;
878     NTSTATUS result;
879 } app_str2str_t;
880
881 static const app_str2str_t app_str2str[] = {
882     { 5, 12, 15,  "TestS01234abcde", 5, 5, 7, "tringZY", 10, 12, 15,   "TestStringabcde", STATUS_SUCCESS},
883     { 5, 11, 15,  "TestS01234abcde", 5, 5, 7, "tringZY", 10, 11, 15,   "TestStringabcde", STATUS_SUCCESS},
884     { 5, 10, 15,  "TestS01234abcde", 5, 5, 7, "tringZY", 10, 10, 15,   "TestStringabcde", STATUS_SUCCESS},
885     { 5,  9, 15,  "TestS01234abcde", 5, 5, 7, "tringZY",  5,  9, 15,   "TestS01234abcde", STATUS_BUFFER_TOO_SMALL},
886     { 5,  0, 15,  "TestS01234abcde", 0, 0, 7, "tringZY",  5,  0, 15,   "TestS01234abcde", STATUS_SUCCESS},
887     { 5, 14, 15,  "TestS01234abcde", 0, 0, 7, "tringZY",  5, 14, 15,   "TestS01234abcde", STATUS_SUCCESS},
888     { 5, 14, 15,  "TestS01234abcde", 0, 0, 7,      NULL,  5, 14, 15,   "TestS01234abcde", STATUS_SUCCESS},
889     { 5, 14, 15,               NULL, 0, 0, 7,      NULL,  5, 14, 15,                NULL, STATUS_SUCCESS},
890     { 5, 12, 15, "Tst\0S01234abcde", 4, 4, 7, "tr\0iZY",  9, 12, 15, "Tst\0Str\0i4abcde", STATUS_SUCCESS},
891 };
892 #define NB_APP_STR2STR (sizeof(app_str2str)/sizeof(*app_str2str))
893
894
895 static void test_RtlAppendStringToString(void)
896 {
897     CHAR dest_buf[257];
898     CHAR src_buf[257];
899     STRING dest_str;
900     STRING src_str;
901     NTSTATUS result;
902     unsigned int test_num;
903
904     for (test_num = 0; test_num < NB_APP_STR2STR; test_num++) {
905         dest_str.Length        = app_str2str[test_num].dest_Length;
906         dest_str.MaximumLength = app_str2str[test_num].dest_MaximumLength;
907         if (app_str2str[test_num].dest_buf != NULL) {
908             memcpy(dest_buf, app_str2str[test_num].dest_buf, app_str2str[test_num].dest_buf_size);
909             dest_buf[app_str2str[test_num].dest_buf_size] = '\0';
910             dest_str.Buffer = dest_buf;
911         } else {
912             dest_str.Buffer = NULL;
913         }
914         src_str.Length         = app_str2str[test_num].src_Length;
915         src_str.MaximumLength  = app_str2str[test_num].src_MaximumLength;
916         if (app_str2str[test_num].src_buf != NULL) {
917             memcpy(src_buf, app_str2str[test_num].src_buf, app_str2str[test_num].src_buf_size);
918             src_buf[app_str2str[test_num].src_buf_size] = '\0';
919             src_str.Buffer = src_buf;
920         } else {
921             src_str.Buffer = NULL;
922         }
923         result = pRtlAppendStringToString(&dest_str, &src_str);
924         ok(result == app_str2str[test_num].result,
925            "(test %d): RtlAppendStringToString(dest, src) has result %x, expected %x\n",
926            test_num, result, app_str2str[test_num].result);
927         ok(dest_str.Length == app_str2str[test_num].res_Length,
928            "(test %d): RtlAppendStringToString(dest, src) dest has Length %d, expected %d\n",
929            test_num, dest_str.Length, app_str2str[test_num].res_Length);
930         ok(dest_str.MaximumLength == app_str2str[test_num].res_MaximumLength,
931            "(test %d): RtlAppendStringToString(dest, src) dest has MaximumLength %d, expected %d\n",
932            test_num, dest_str.MaximumLength, app_str2str[test_num].res_MaximumLength);
933         if (dest_str.Buffer == dest_buf) {
934             ok(memcmp(dest_buf, app_str2str[test_num].res_buf, app_str2str[test_num].res_buf_size) == 0,
935                "(test %d): RtlAppendStringToString(dest, src) has dest \"%s\" expected \"%s\"\n",
936                test_num, dest_buf, app_str2str[test_num].res_buf);
937         } else {
938             ok(dest_str.Buffer == app_str2str[test_num].res_buf,
939                "(test %d): RtlAppendStringToString(dest, src) dest has Buffer %p expected %p\n",
940                test_num, dest_str.Buffer, app_str2str[test_num].res_buf);
941         }
942     }
943 }
944
945
946 typedef struct {
947     int dest_Length;
948     int dest_MaximumLength;
949     int dest_buf_size;
950     const char *dest_buf;
951     const char *src;
952     int res_Length;
953     int res_MaximumLength;
954     int res_buf_size;
955     const char *res_buf;
956     NTSTATUS result;
957 } app_uni2str_t;
958
959 static const app_uni2str_t app_uni2str[] = {
960     { 4, 12, 14,     "Fake0123abcdef",    "Ustr\0",  8, 12, 14,  "FakeUstr\0\0cdef", STATUS_SUCCESS},
961     { 4, 11, 14,     "Fake0123abcdef",    "Ustr\0",  8, 11, 14,  "FakeUstr\0\0cdef", STATUS_SUCCESS},
962     { 4, 10, 14,     "Fake0123abcdef",    "Ustr\0",  8, 10, 14,  "FakeUstr\0\0cdef", STATUS_SUCCESS},
963 /* In the following test the native function writes beyond MaximumLength
964  *  { 4,  9, 14,     "Fake0123abcdef",    "Ustr\0",  8,  9, 14,    "FakeUstrabcdef", STATUS_SUCCESS},
965  */
966     { 4,  8, 14,     "Fake0123abcdef",    "Ustr\0",  8,  8, 14,    "FakeUstrabcdef", STATUS_SUCCESS},
967     { 4,  7, 14,     "Fake0123abcdef",    "Ustr\0",  4,  7, 14,    "Fake0123abcdef", STATUS_BUFFER_TOO_SMALL},
968     { 4,  0, 14,     "Fake0123abcdef",    "Ustr\0",  4,  0, 14,    "Fake0123abcdef", STATUS_BUFFER_TOO_SMALL},
969     { 4, 14, 14,     "Fake0123abcdef",    "Ustr\0",  8, 14, 14,  "FakeUstr\0\0cdef", STATUS_SUCCESS},
970     { 4, 14, 14,     "Fake0123abcdef",        NULL,  4, 14, 14,    "Fake0123abcdef", STATUS_SUCCESS},
971     { 4, 14, 14,                 NULL,        NULL,  4, 14, 14,                NULL, STATUS_SUCCESS},
972     { 4, 14, 14,     "Fake0123abcdef", "U\0stri\0", 10, 14, 14, "FakeU\0stri\0\0ef", STATUS_SUCCESS},
973     { 6, 14, 16, "Te\0\0stabcdefghij",  "St\0\0ri",  8, 14, 16, "Te\0\0stSt\0\0efghij", STATUS_SUCCESS},
974 };
975 #define NB_APP_UNI2STR (sizeof(app_uni2str)/sizeof(*app_uni2str))
976
977
978 static void test_RtlAppendUnicodeToString(void)
979 {
980     WCHAR dest_buf[257];
981     UNICODE_STRING dest_str;
982     NTSTATUS result;
983     unsigned int test_num;
984
985     for (test_num = 0; test_num < NB_APP_UNI2STR; test_num++) {
986         dest_str.Length        = app_uni2str[test_num].dest_Length;
987         dest_str.MaximumLength = app_uni2str[test_num].dest_MaximumLength;
988         if (app_uni2str[test_num].dest_buf != NULL) {
989             memcpy(dest_buf, app_uni2str[test_num].dest_buf, app_uni2str[test_num].dest_buf_size);
990             dest_buf[app_uni2str[test_num].dest_buf_size/sizeof(WCHAR)] = '\0';
991             dest_str.Buffer = dest_buf;
992         } else {
993             dest_str.Buffer = NULL;
994         }
995         result = pRtlAppendUnicodeToString(&dest_str, (LPCWSTR) app_uni2str[test_num].src);
996         ok(result == app_uni2str[test_num].result,
997            "(test %d): RtlAppendUnicodeToString(dest, src) has result %x, expected %x\n",
998            test_num, result, app_uni2str[test_num].result);
999         ok(dest_str.Length == app_uni2str[test_num].res_Length,
1000            "(test %d): RtlAppendUnicodeToString(dest, src) dest has Length %d, expected %d\n",
1001            test_num, dest_str.Length, app_uni2str[test_num].res_Length);
1002         ok(dest_str.MaximumLength == app_uni2str[test_num].res_MaximumLength,
1003            "(test %d): RtlAppendUnicodeToString(dest, src) dest has MaximumLength %d, expected %d\n",
1004            test_num, dest_str.MaximumLength, app_uni2str[test_num].res_MaximumLength);
1005         if (dest_str.Buffer == dest_buf) {
1006             ok(memcmp(dest_buf, app_uni2str[test_num].res_buf, app_uni2str[test_num].res_buf_size) == 0,
1007                "(test %d): RtlAppendUnicodeToString(dest, src) has dest \"%s\" expected \"%s\"\n",
1008                test_num, (char *) dest_buf, app_uni2str[test_num].res_buf);
1009         } else {
1010             ok(dest_str.Buffer == (WCHAR *) app_uni2str[test_num].res_buf,
1011                "(test %d): RtlAppendUnicodeToString(dest, src) dest has Buffer %p expected %p\n",
1012                test_num, dest_str.Buffer, app_uni2str[test_num].res_buf);
1013         }
1014     }
1015 }
1016
1017
1018 typedef struct {
1019     int dest_Length;
1020     int dest_MaximumLength;
1021     int dest_buf_size;
1022     const char *dest_buf;
1023     int src_Length;
1024     int src_MaximumLength;
1025     int src_buf_size;
1026     const char *src_buf;
1027     int res_Length;
1028     int res_MaximumLength;
1029     int res_buf_size;
1030     const char *res_buf;
1031     NTSTATUS result;
1032 } app_ustr2str_t;
1033
1034 static const app_ustr2str_t app_ustr2str[] = {
1035     { 4, 12, 14,     "Fake0123abcdef", 4, 6, 8,   "UstrZYXW",  8, 12, 14,   "FakeUstr\0\0cdef", STATUS_SUCCESS},
1036     { 4, 11, 14,     "Fake0123abcdef", 4, 6, 8,   "UstrZYXW",  8, 11, 14,   "FakeUstr\0\0cdef", STATUS_SUCCESS},
1037     { 4, 10, 14,     "Fake0123abcdef", 4, 6, 8,   "UstrZYXW",  8, 10, 14,   "FakeUstr\0\0cdef", STATUS_SUCCESS},
1038 /* In the following test the native function writes beyond MaximumLength 
1039  *  { 4,  9, 14,     "Fake0123abcdef", 4, 6, 8,   "UstrZYXW",  8,  9, 14,     "FakeUstrabcdef", STATUS_SUCCESS},
1040  */
1041     { 4,  8, 14,     "Fake0123abcdef", 4, 6, 8,   "UstrZYXW",  8,  8, 14,     "FakeUstrabcdef", STATUS_SUCCESS},
1042     { 4,  7, 14,     "Fake0123abcdef", 4, 6, 8,   "UstrZYXW",  4,  7, 14,     "Fake0123abcdef", STATUS_BUFFER_TOO_SMALL},
1043     { 4,  0, 14,     "Fake0123abcdef", 0, 0, 8,   "UstrZYXW",  4,  0, 14,     "Fake0123abcdef", STATUS_SUCCESS},
1044     { 4, 14, 14,     "Fake0123abcdef", 0, 0, 8,   "UstrZYXW",  4, 14, 14,     "Fake0123abcdef", STATUS_SUCCESS},
1045     { 4, 14, 14,     "Fake0123abcdef", 0, 0, 8,         NULL,  4, 14, 14,     "Fake0123abcdef", STATUS_SUCCESS},
1046     { 4, 14, 14,                 NULL, 0, 0, 8,         NULL,  4, 14, 14,                 NULL, STATUS_SUCCESS},
1047     { 6, 14, 16, "Te\0\0stabcdefghij", 6, 8, 8, "St\0\0riZY", 12, 14, 16, "Te\0\0stSt\0\0ri\0\0ij", STATUS_SUCCESS},
1048 };
1049 #define NB_APP_USTR2STR (sizeof(app_ustr2str)/sizeof(*app_ustr2str))
1050
1051
1052 static void test_RtlAppendUnicodeStringToString(void)
1053 {
1054     WCHAR dest_buf[257];
1055     WCHAR src_buf[257];
1056     UNICODE_STRING dest_str;
1057     UNICODE_STRING src_str;
1058     NTSTATUS result;
1059     unsigned int test_num;
1060
1061     for (test_num = 0; test_num < NB_APP_USTR2STR; test_num++) {
1062         dest_str.Length        = app_ustr2str[test_num].dest_Length;
1063         dest_str.MaximumLength = app_ustr2str[test_num].dest_MaximumLength;
1064         if (app_ustr2str[test_num].dest_buf != NULL) {
1065             memcpy(dest_buf, app_ustr2str[test_num].dest_buf, app_ustr2str[test_num].dest_buf_size);
1066             dest_buf[app_ustr2str[test_num].dest_buf_size/sizeof(WCHAR)] = '\0';
1067             dest_str.Buffer = dest_buf;
1068         } else {
1069             dest_str.Buffer = NULL;
1070         }
1071         src_str.Length         = app_ustr2str[test_num].src_Length;
1072         src_str.MaximumLength  = app_ustr2str[test_num].src_MaximumLength;
1073         if (app_ustr2str[test_num].src_buf != NULL) {
1074             memcpy(src_buf, app_ustr2str[test_num].src_buf, app_ustr2str[test_num].src_buf_size);
1075             src_buf[app_ustr2str[test_num].src_buf_size/sizeof(WCHAR)] = '\0';
1076             src_str.Buffer = src_buf;
1077         } else {
1078             src_str.Buffer = NULL;
1079         }
1080         result = pRtlAppendUnicodeStringToString(&dest_str, &src_str);
1081         ok(result == app_ustr2str[test_num].result,
1082            "(test %d): RtlAppendStringToString(dest, src) has result %x, expected %x\n",
1083            test_num, result, app_ustr2str[test_num].result);
1084         ok(dest_str.Length == app_ustr2str[test_num].res_Length,
1085            "(test %d): RtlAppendStringToString(dest, src) dest has Length %d, expected %d\n",
1086            test_num, dest_str.Length, app_ustr2str[test_num].res_Length);
1087         ok(dest_str.MaximumLength == app_ustr2str[test_num].res_MaximumLength,
1088            "(test %d): RtlAppendStringToString(dest, src) dest has MaximumLength %d, expected %d\n",
1089            test_num, dest_str.MaximumLength, app_ustr2str[test_num].res_MaximumLength);
1090         if (dest_str.Buffer == dest_buf) {
1091             ok(memcmp(dest_buf, app_ustr2str[test_num].res_buf, app_ustr2str[test_num].res_buf_size) == 0,
1092                "(test %d): RtlAppendStringToString(dest, src) has dest \"%s\" expected \"%s\"\n",
1093                test_num, (char *) dest_buf, app_ustr2str[test_num].res_buf);
1094         } else {
1095             ok(dest_str.Buffer == (WCHAR *) app_ustr2str[test_num].res_buf,
1096                "(test %d): RtlAppendStringToString(dest, src) dest has Buffer %p expected %p\n",
1097                test_num, dest_str.Buffer, app_ustr2str[test_num].res_buf);
1098         }
1099     }
1100 }
1101
1102
1103 typedef struct {
1104     int flags;
1105     const char *main_str;
1106     const char *search_chars;
1107     USHORT pos;
1108     NTSTATUS result;
1109 } find_ch_in_ustr_t;
1110
1111 static const find_ch_in_ustr_t find_ch_in_ustr[] = {
1112     { 0, "Some Wild String",           "S",       2, STATUS_SUCCESS},
1113     { 0, "This is a String",           "String",  6, STATUS_SUCCESS},
1114     { 1, "This is a String",           "String", 30, STATUS_SUCCESS},
1115     { 2, "This is a String",           "String",  2, STATUS_SUCCESS},
1116     { 3, "This is a String",           "String", 18, STATUS_SUCCESS},
1117     { 0, "This is a String",           "Wild",    6, STATUS_SUCCESS},
1118     { 1, "This is a String",           "Wild",   26, STATUS_SUCCESS},
1119     { 2, "This is a String",           "Wild",    2, STATUS_SUCCESS},
1120     { 3, "This is a String",           "Wild",   30, STATUS_SUCCESS},
1121     { 0, "abcdefghijklmnopqrstuvwxyz", "",        0, STATUS_NOT_FOUND},
1122     { 0, "abcdefghijklmnopqrstuvwxyz", "123",     0, STATUS_NOT_FOUND},
1123     { 0, "abcdefghijklmnopqrstuvwxyz", "a",       2, STATUS_SUCCESS},
1124     { 0, "abcdefghijklmnopqrstuvwxyz", "12a34",   2, STATUS_SUCCESS},
1125     { 0, "abcdefghijklmnopqrstuvwxyz", "12b34",   4, STATUS_SUCCESS},
1126     { 0, "abcdefghijklmnopqrstuvwxyz", "12y34",  50, STATUS_SUCCESS},
1127     { 0, "abcdefghijklmnopqrstuvwxyz", "12z34",  52, STATUS_SUCCESS},
1128     { 0, "abcdefghijklmnopqrstuvwxyz", "rvz",    36, STATUS_SUCCESS},
1129     { 0, "abcdefghijklmmlkjihgfedcba", "egik",   10, STATUS_SUCCESS},
1130     { 1, "abcdefghijklmnopqrstuvwxyz", "",        0, STATUS_NOT_FOUND},
1131     { 1, "abcdefghijklmnopqrstuvwxyz", "rvz",    50, STATUS_SUCCESS},
1132     { 1, "abcdefghijklmnopqrstuvwxyz", "ravy",   48, STATUS_SUCCESS},
1133     { 1, "abcdefghijklmnopqrstuvwxyz", "raxv",   46, STATUS_SUCCESS},
1134     { 2, "abcdefghijklmnopqrstuvwxyz", "",        2, STATUS_SUCCESS},
1135     { 2, "abcdefghijklmnopqrstuvwxyz", "rvz",     2, STATUS_SUCCESS},
1136     { 2, "abcdefghijklmnopqrstuvwxyz", "vaz",     4, STATUS_SUCCESS},
1137     { 2, "abcdefghijklmnopqrstuvwxyz", "ravbz",   6, STATUS_SUCCESS},
1138     { 3, "abcdefghijklmnopqrstuvwxyz", "",       50, STATUS_SUCCESS},
1139     { 3, "abcdefghijklmnopqrstuvwxyz", "123",    50, STATUS_SUCCESS},
1140     { 3, "abcdefghijklmnopqrstuvwxyz", "ahp",    50, STATUS_SUCCESS},
1141     { 3, "abcdefghijklmnopqrstuvwxyz", "rvz",    48, STATUS_SUCCESS},
1142     { 0, NULL,                         "abc",     0, STATUS_NOT_FOUND},
1143     { 1, NULL,                         "abc",     0, STATUS_NOT_FOUND},
1144     { 2, NULL,                         "abc",     0, STATUS_NOT_FOUND},
1145     { 3, NULL,                         "abc",     0, STATUS_NOT_FOUND},
1146     { 0, "abcdefghijklmnopqrstuvwxyz", NULL,      0, STATUS_NOT_FOUND},
1147     { 1, "abcdefghijklmnopqrstuvwxyz", NULL,      0, STATUS_NOT_FOUND},
1148     { 2, "abcdefghijklmnopqrstuvwxyz", NULL,      2, STATUS_SUCCESS},
1149     { 3, "abcdefghijklmnopqrstuvwxyz", NULL,     50, STATUS_SUCCESS},
1150     { 0, NULL,                         NULL,      0, STATUS_NOT_FOUND},
1151     { 1, NULL,                         NULL,      0, STATUS_NOT_FOUND},
1152     { 2, NULL,                         NULL,      0, STATUS_NOT_FOUND},
1153     { 3, NULL,                         NULL,      0, STATUS_NOT_FOUND},
1154     { 0, "abcdabcdabcdabcdabcdabcd",   "abcd",    2, STATUS_SUCCESS},
1155     { 1, "abcdabcdabcdabcdabcdabcd",   "abcd",   46, STATUS_SUCCESS},
1156     { 2, "abcdabcdabcdabcdabcdabcd",   "abcd",    0, STATUS_NOT_FOUND},
1157     { 3, "abcdabcdabcdabcdabcdabcd",   "abcd",    0, STATUS_NOT_FOUND},
1158 };
1159 #define NB_FIND_CH_IN_USTR (sizeof(find_ch_in_ustr)/sizeof(*find_ch_in_ustr))
1160
1161
1162 static void test_RtlFindCharInUnicodeString(void)
1163 {
1164     WCHAR main_str_buf[257];
1165     WCHAR search_chars_buf[257];
1166     UNICODE_STRING main_str;
1167     UNICODE_STRING search_chars;
1168     USHORT pos;
1169     NTSTATUS result;
1170     unsigned int idx;
1171     unsigned int test_num;
1172
1173     for (test_num = 0; test_num < NB_FIND_CH_IN_USTR; test_num++) {
1174         if (find_ch_in_ustr[test_num].main_str != NULL) {
1175             main_str.Length        = strlen(find_ch_in_ustr[test_num].main_str) * sizeof(WCHAR);
1176             main_str.MaximumLength = main_str.Length + sizeof(WCHAR);
1177             for (idx = 0; idx < main_str.Length / sizeof(WCHAR); idx++) {
1178                 main_str_buf[idx] = find_ch_in_ustr[test_num].main_str[idx];
1179             }
1180             main_str.Buffer = main_str_buf;
1181         } else {
1182             main_str.Length        = 0;
1183             main_str.MaximumLength = 0;
1184             main_str.Buffer        = NULL;
1185         }
1186         if (find_ch_in_ustr[test_num].search_chars != NULL) {
1187             search_chars.Length        = strlen(find_ch_in_ustr[test_num].search_chars) * sizeof(WCHAR);
1188             search_chars.MaximumLength = search_chars.Length + sizeof(WCHAR);
1189             for (idx = 0; idx < search_chars.Length / sizeof(WCHAR); idx++) {
1190                 search_chars_buf[idx] = find_ch_in_ustr[test_num].search_chars[idx];
1191             }
1192             search_chars.Buffer = search_chars_buf;
1193         } else {
1194             search_chars.Length        = 0;
1195             search_chars.MaximumLength = 0;
1196             search_chars.Buffer        = NULL;
1197         }
1198         pos = 12345;
1199         result = pRtlFindCharInUnicodeString(find_ch_in_ustr[test_num].flags, &main_str, &search_chars, &pos);
1200         ok(result == find_ch_in_ustr[test_num].result,
1201            "(test %d): RtlFindCharInUnicodeString(%d, %s, %s, [out]) has result %x, expected %x\n",
1202            test_num, find_ch_in_ustr[test_num].flags,
1203            find_ch_in_ustr[test_num].main_str, find_ch_in_ustr[test_num].search_chars,
1204            result, find_ch_in_ustr[test_num].result);
1205         ok(pos == find_ch_in_ustr[test_num].pos,
1206            "(test %d): RtlFindCharInUnicodeString(%d, %s, %s, [out]) assigns %d to pos, expected %d\n",
1207            test_num, find_ch_in_ustr[test_num].flags,
1208            find_ch_in_ustr[test_num].main_str, find_ch_in_ustr[test_num].search_chars,
1209            pos, find_ch_in_ustr[test_num].pos);
1210     }
1211 }
1212
1213
1214 typedef struct {
1215     int base;
1216     const char *str;
1217     int value;
1218     NTSTATUS result;
1219 } str2int_t;
1220
1221 static const str2int_t str2int[] = {
1222     { 0, "1011101100",   1011101100, STATUS_SUCCESS},
1223     { 0, "1234567",         1234567, STATUS_SUCCESS},
1224     { 0, "-214",               -214, STATUS_SUCCESS},
1225     { 0, "+214",                214, STATUS_SUCCESS}, /* The + sign is allowed also */
1226     { 0, "--214",                 0, STATUS_SUCCESS}, /* Do not accept more than one sign */
1227     { 0, "-+214",                 0, STATUS_SUCCESS},
1228     { 0, "++214",                 0, STATUS_SUCCESS},
1229     { 0, "+-214",                 0, STATUS_SUCCESS},
1230     { 0, "\001\002\003\00411",   11, STATUS_SUCCESS}, /* whitespace char  1 to  4 */
1231     { 0, "\005\006\007\01012",   12, STATUS_SUCCESS}, /* whitespace char  5 to  8 */
1232     { 0, "\011\012\013\01413",   13, STATUS_SUCCESS}, /* whitespace char  9 to 12 */
1233     { 0, "\015\016\017\02014",   14, STATUS_SUCCESS}, /* whitespace char 13 to 16 */
1234     { 0, "\021\022\023\02415",   15, STATUS_SUCCESS}, /* whitespace char 17 to 20 */
1235     { 0, "\025\026\027\03016",   16, STATUS_SUCCESS}, /* whitespace char 21 to 24 */
1236     { 0, "\031\032\033\03417",   17, STATUS_SUCCESS}, /* whitespace char 25 to 28 */
1237     { 0, "\035\036\037\04018",   18, STATUS_SUCCESS}, /* whitespace char 29 to 32 */
1238     { 0, " \n \r \t214",        214, STATUS_SUCCESS},
1239     { 0, " \n \r \t+214",       214, STATUS_SUCCESS}, /* Signs can be used after whitespace */
1240     { 0, " \n \r \t-214",      -214, STATUS_SUCCESS},
1241     { 0, "+214 0",              214, STATUS_SUCCESS}, /* Space terminates the number */
1242     { 0, " 214.01",             214, STATUS_SUCCESS}, /* Decimal point not accepted */
1243     { 0, " 214,01",             214, STATUS_SUCCESS}, /* Decimal comma not accepted */
1244     { 0, "f81",                   0, STATUS_SUCCESS},
1245     { 0, "0x12345",         0x12345, STATUS_SUCCESS}, /* Hex */
1246     { 0, "00x12345",              0, STATUS_SUCCESS},
1247     { 0, "0xx12345",              0, STATUS_SUCCESS},
1248     { 0, "1x34",                  1, STATUS_SUCCESS},
1249     { 0, "-9999999999", -1410065407, STATUS_SUCCESS}, /* Big negative integer */
1250     { 0, "-2147483649",  2147483647, STATUS_SUCCESS}, /* Too small to fit in 32 Bits */
1251     { 0, "-2147483648", 0x80000000L, STATUS_SUCCESS}, /* Smallest negative integer */
1252     { 0, "-2147483647", -2147483647, STATUS_SUCCESS},
1253     { 0, "-1",                   -1, STATUS_SUCCESS},
1254     { 0, "0",                     0, STATUS_SUCCESS},
1255     { 0, "1",                     1, STATUS_SUCCESS},
1256     { 0, "2147483646",   2147483646, STATUS_SUCCESS},
1257     { 0, "2147483647",   2147483647, STATUS_SUCCESS}, /* Largest signed positive integer */
1258     { 0, "2147483648",  0x80000000L, STATUS_SUCCESS}, /* Positive int equal to smallest negative int */
1259     { 0, "2147483649",  -2147483647, STATUS_SUCCESS},
1260     { 0, "4294967294",           -2, STATUS_SUCCESS},
1261     { 0, "4294967295",           -1, STATUS_SUCCESS}, /* Largest unsigned integer */
1262     { 0, "4294967296",            0, STATUS_SUCCESS}, /* Too big to fit in 32 Bits */
1263     { 0, "9999999999",   1410065407, STATUS_SUCCESS}, /* Big positive integer */
1264     { 0, "056789",            56789, STATUS_SUCCESS}, /* Leading zero and still decimal */
1265     { 0, "b1011101100",           0, STATUS_SUCCESS}, /* Binary (b-notation) */
1266     { 0, "-b1011101100",          0, STATUS_SUCCESS}, /* Negative Binary (b-notation) */
1267     { 0, "b10123456789",          0, STATUS_SUCCESS}, /* Binary with nonbinary digits (2-9) */
1268     { 0, "0b1011101100",        748, STATUS_SUCCESS}, /* Binary (0b-notation) */
1269     { 0, "-0b1011101100",      -748, STATUS_SUCCESS}, /* Negative binary (0b-notation) */
1270     { 0, "0b10123456789",         5, STATUS_SUCCESS}, /* Binary with nonbinary digits (2-9) */
1271     { 0, "-0b10123456789",       -5, STATUS_SUCCESS}, /* Negative binary with nonbinary digits (2-9) */
1272     { 0, "0b1",                   1, STATUS_SUCCESS}, /* one digit binary */
1273     { 0, "0b2",                   0, STATUS_SUCCESS}, /* empty binary */
1274     { 0, "0b",                    0, STATUS_SUCCESS}, /* empty binary */
1275     { 0, "o1234567",              0, STATUS_SUCCESS}, /* Octal (o-notation) */
1276     { 0, "-o1234567",             0, STATUS_SUCCESS}, /* Negative Octal (o-notation) */
1277     { 0, "o56789",                0, STATUS_SUCCESS}, /* Octal with nonoctal digits (8 and 9) */
1278     { 0, "0o1234567",      01234567, STATUS_SUCCESS}, /* Octal (0o-notation) */
1279     { 0, "-0o1234567",    -01234567, STATUS_SUCCESS}, /* Negative octal (0o-notation) */
1280     { 0, "0o56789",            0567, STATUS_SUCCESS}, /* Octal with nonoctal digits (8 and 9) */
1281     { 0, "-0o56789",          -0567, STATUS_SUCCESS}, /* Negative octal with nonoctal digits (8 and 9) */
1282     { 0, "0o7",                   7, STATUS_SUCCESS}, /* one digit octal */
1283     { 0, "0o8",                   0, STATUS_SUCCESS}, /* empty octal */
1284     { 0, "0o",                    0, STATUS_SUCCESS}, /* empty octal */
1285     { 0, "0d1011101100",          0, STATUS_SUCCESS}, /* explizit decimal with 0d */
1286     { 0, "x89abcdef",             0, STATUS_SUCCESS}, /* Hex with lower case digits a-f (x-notation) */
1287     { 0, "xFEDCBA00",             0, STATUS_SUCCESS}, /* Hex with upper case digits A-F (x-notation) */
1288     { 0, "-xFEDCBA00",            0, STATUS_SUCCESS}, /* Negative Hexadecimal (x-notation) */
1289     { 0, "0x89abcdef",   0x89abcdef, STATUS_SUCCESS}, /* Hex with lower case digits a-f (0x-notation) */
1290     { 0, "0xFEDCBA00",   0xFEDCBA00, STATUS_SUCCESS}, /* Hex with upper case digits A-F (0x-notation) */
1291     { 0, "-0xFEDCBA00",    19088896, STATUS_SUCCESS}, /* Negative Hexadecimal (0x-notation) */
1292     { 0, "0xabcdefgh",     0xabcdef, STATUS_SUCCESS}, /* Hex with illegal lower case digits (g-z) */
1293     { 0, "0xABCDEFGH",     0xABCDEF, STATUS_SUCCESS}, /* Hex with illegal upper case digits (G-Z) */
1294     { 0, "0xF",                 0xf, STATUS_SUCCESS}, /* one digit hexadecimal */
1295     { 0, "0xG",                   0, STATUS_SUCCESS}, /* empty hexadecimal */
1296     { 0, "0x",                    0, STATUS_SUCCESS}, /* empty hexadecimal */
1297     { 0, "",                      0, STATUS_SUCCESS}, /* empty string */
1298     { 2, "1011101100",          748, STATUS_SUCCESS},
1299     { 2, "-1011101100",        -748, STATUS_SUCCESS},
1300     { 2, "2",                     0, STATUS_SUCCESS},
1301     { 2, "0b1011101100",          0, STATUS_SUCCESS},
1302     { 2, "0o1011101100",          0, STATUS_SUCCESS},
1303     { 2, "0d1011101100",          0, STATUS_SUCCESS},
1304     { 2, "0x1011101100",          0, STATUS_SUCCESS},
1305     { 2, "",                      0, STATUS_SUCCESS}, /* empty string */
1306     { 8, "1011101100",    136610368, STATUS_SUCCESS},
1307     { 8, "-1011101100",  -136610368, STATUS_SUCCESS},
1308     { 8, "8",                     0, STATUS_SUCCESS},
1309     { 8, "0b1011101100",          0, STATUS_SUCCESS},
1310     { 8, "0o1011101100",          0, STATUS_SUCCESS},
1311     { 8, "0d1011101100",          0, STATUS_SUCCESS},
1312     { 8, "0x1011101100",          0, STATUS_SUCCESS},
1313     { 8, "",                      0, STATUS_SUCCESS}, /* empty string */
1314     {10, "1011101100",   1011101100, STATUS_SUCCESS},
1315     {10, "-1011101100", -1011101100, STATUS_SUCCESS},
1316     {10, "0b1011101100",          0, STATUS_SUCCESS},
1317     {10, "0o1011101100",          0, STATUS_SUCCESS},
1318     {10, "0d1011101100",          0, STATUS_SUCCESS},
1319     {10, "0x1011101100",          0, STATUS_SUCCESS},
1320     {10, "o12345",                0, STATUS_SUCCESS}, /* Octal although base is 10 */
1321     {10, "",                      0, STATUS_SUCCESS}, /* empty string */
1322     {16, "1011101100",    286265600, STATUS_SUCCESS},
1323     {16, "-1011101100",  -286265600, STATUS_SUCCESS},
1324     {16, "G",                     0, STATUS_SUCCESS},
1325     {16, "g",                     0, STATUS_SUCCESS},
1326     {16, "0b1011101100",  286265600, STATUS_SUCCESS},
1327     {16, "0o1011101100",          0, STATUS_SUCCESS},
1328     {16, "0d1011101100",  286265600, STATUS_SUCCESS},
1329     {16, "0x1011101100",          0, STATUS_SUCCESS},
1330     {16, "",                      0, STATUS_SUCCESS}, /* empty string */
1331     {20, "0",            0xdeadbeef, STATUS_INVALID_PARAMETER}, /* illegal base */
1332     {-8, "0",            0xdeadbeef, STATUS_INVALID_PARAMETER}, /* Negative base */
1333 /*    { 0, NULL,                    0, STATUS_SUCCESS}, */ /* NULL as string */
1334 };
1335 #define NB_STR2INT (sizeof(str2int)/sizeof(*str2int))
1336
1337
1338 static void test_RtlUnicodeStringToInteger(void)
1339 {
1340     unsigned int test_num;
1341     int value;
1342     NTSTATUS result;
1343     WCHAR *wstr;
1344     UNICODE_STRING uni;
1345
1346     for (test_num = 0; test_num < NB_STR2INT; test_num++) {
1347         wstr = AtoW(str2int[test_num].str);
1348         value = 0xdeadbeef;
1349         pRtlInitUnicodeString(&uni, wstr);
1350         result = pRtlUnicodeStringToInteger(&uni, str2int[test_num].base, &value);
1351         ok(result == str2int[test_num].result,
1352            "(test %d): RtlUnicodeStringToInteger(\"%s\", %d, [out]) has result %x, expected: %x\n",
1353            test_num, str2int[test_num].str, str2int[test_num].base, result, str2int[test_num].result);
1354         ok(value == str2int[test_num].value,
1355            "(test %d): RtlUnicodeStringToInteger(\"%s\", %d, [out]) assigns value %d, expected: %d\n",
1356            test_num, str2int[test_num].str, str2int[test_num].base, value, str2int[test_num].value);
1357         free(wstr);
1358     }
1359
1360     wstr = AtoW(str2int[1].str);
1361     pRtlInitUnicodeString(&uni, wstr);
1362     result = pRtlUnicodeStringToInteger(&uni, str2int[1].base, NULL);
1363     ok(result == STATUS_ACCESS_VIOLATION,
1364        "call failed: RtlUnicodeStringToInteger(\"%s\", %d, NULL) has result %x\n",
1365        str2int[1].str, str2int[1].base, result);
1366     result = pRtlUnicodeStringToInteger(&uni, 20, NULL);
1367     ok(result == STATUS_INVALID_PARAMETER,
1368        "call failed: RtlUnicodeStringToInteger(\"%s\", 20, NULL) has result %x\n",
1369        str2int[1].str, result);
1370
1371     uni.Length = 10; /* Make Length shorter (5 WCHARS instead of 7) */
1372     result = pRtlUnicodeStringToInteger(&uni, str2int[1].base, &value);
1373     ok(result == STATUS_SUCCESS,
1374        "call failed: RtlUnicodeStringToInteger(\"12345\", %d, [out]) has result %x\n",
1375        str2int[1].base, result);
1376     ok(value == 12345,
1377        "didn't return expected value (test a): expected: %d, got: %d\n",
1378        12345, value);
1379
1380     uni.Length = 5; /* Use odd Length (2.5 WCHARS) */
1381     result = pRtlUnicodeStringToInteger(&uni, str2int[1].base, &value);
1382     ok(result == STATUS_SUCCESS,
1383        "call failed: RtlUnicodeStringToInteger(\"12\", %d, [out]) has result %x\n",
1384        str2int[1].base, result);
1385     ok(value == 12,
1386        "didn't return expected value (test b): expected: %d, got: %d\n",
1387        12, value);
1388
1389     uni.Length = 2;
1390     result = pRtlUnicodeStringToInteger(&uni, str2int[1].base, &value);
1391     ok(result == STATUS_SUCCESS,
1392        "call failed: RtlUnicodeStringToInteger(\"1\", %d, [out]) has result %x\n",
1393        str2int[1].base, result);
1394     ok(value == 1,
1395        "didn't return expected value (test c): expected: %d, got: %d\n",
1396        1, value);
1397     /* w2k: uni.Length = 0 returns value 11234567 instead of 0 */
1398     free(wstr);
1399 }
1400
1401
1402 static void test_RtlCharToInteger(void)
1403 {
1404     unsigned int test_num;
1405     int value;
1406     NTSTATUS result;
1407
1408     for (test_num = 0; test_num < NB_STR2INT; test_num++) {
1409         /* w2k skips a leading '\0' and processes the string after */
1410         if (str2int[test_num].str[0] != '\0') {
1411             value = 0xdeadbeef;
1412             result = pRtlCharToInteger(str2int[test_num].str, str2int[test_num].base, &value);
1413             ok(result == str2int[test_num].result,
1414                "(test %d): call failed: RtlCharToInteger(\"%s\", %d, [out]) has result %x, expected: %x\n",
1415                test_num, str2int[test_num].str, str2int[test_num].base, result, str2int[test_num].result);
1416             ok(value == str2int[test_num].value,
1417                "(test %d): call failed: RtlCharToInteger(\"%s\", %d, [out]) assigns value %d, expected: %d\n",
1418                test_num, str2int[test_num].str, str2int[test_num].base, value, str2int[test_num].value);
1419         }
1420     }
1421
1422     result = pRtlCharToInteger(str2int[1].str, str2int[1].base, NULL);
1423     ok(result == STATUS_ACCESS_VIOLATION,
1424        "call failed: RtlCharToInteger(\"%s\", %d, NULL) has result %x\n",
1425        str2int[1].str, str2int[1].base, result);
1426
1427     result = pRtlCharToInteger(str2int[1].str, 20, NULL);
1428     ok(result == STATUS_INVALID_PARAMETER,
1429        "call failed: RtlCharToInteger(\"%s\", 20, NULL) has result %x\n",
1430        str2int[1].str, result);
1431 }
1432
1433
1434 #define STRI_BUFFER_LENGTH 35
1435
1436 typedef struct {
1437     int base;
1438     ULONG value;
1439     USHORT Length;
1440     USHORT MaximumLength;
1441     const char *Buffer;
1442     NTSTATUS result;
1443 } int2str_t;
1444
1445 static const int2str_t int2str[] = {
1446     {10,          123,  3, 11, "123\0-------------------------------", STATUS_SUCCESS},
1447
1448     { 0,  0x80000000U, 10, 11, "2147483648\0------------------------", STATUS_SUCCESS}, /* min signed int */
1449     { 0,  -2147483647, 10, 11, "2147483649\0------------------------", STATUS_SUCCESS},
1450     { 0,           -2, 10, 11, "4294967294\0------------------------", STATUS_SUCCESS},
1451     { 0,           -1, 10, 11, "4294967295\0------------------------", STATUS_SUCCESS},
1452     { 0,            0,  1, 11, "0\0---------------------------------", STATUS_SUCCESS},
1453     { 0,            1,  1, 11, "1\0---------------------------------", STATUS_SUCCESS},
1454     { 0,           12,  2, 11, "12\0--------------------------------", STATUS_SUCCESS},
1455     { 0,          123,  3, 11, "123\0-------------------------------", STATUS_SUCCESS},
1456     { 0,         1234,  4, 11, "1234\0------------------------------", STATUS_SUCCESS},
1457     { 0,        12345,  5, 11, "12345\0-----------------------------", STATUS_SUCCESS},
1458     { 0,       123456,  6, 11, "123456\0----------------------------", STATUS_SUCCESS},
1459     { 0,      1234567,  7, 11, "1234567\0---------------------------", STATUS_SUCCESS},
1460     { 0,     12345678,  8, 11, "12345678\0--------------------------", STATUS_SUCCESS},
1461     { 0,    123456789,  9, 11, "123456789\0-------------------------", STATUS_SUCCESS},
1462     { 0,   2147483646, 10, 11, "2147483646\0------------------------", STATUS_SUCCESS},
1463     { 0,   2147483647, 10, 11, "2147483647\0------------------------", STATUS_SUCCESS}, /* max signed int */
1464     { 0,  2147483648U, 10, 11, "2147483648\0------------------------", STATUS_SUCCESS}, /* uint = -max int */
1465     { 0,  2147483649U, 10, 11, "2147483649\0------------------------", STATUS_SUCCESS},
1466     { 0,  4294967294U, 10, 11, "4294967294\0------------------------", STATUS_SUCCESS},
1467     { 0,  4294967295U, 10, 11, "4294967295\0------------------------", STATUS_SUCCESS}, /* max unsigned int */
1468
1469     { 2,  0x80000000U, 32, 33, "10000000000000000000000000000000\0--", STATUS_SUCCESS}, /* min signed int */
1470     { 2,  -2147483647, 32, 33, "10000000000000000000000000000001\0--", STATUS_SUCCESS},
1471     { 2,           -2, 32, 33, "11111111111111111111111111111110\0--", STATUS_SUCCESS},
1472     { 2,           -1, 32, 33, "11111111111111111111111111111111\0--", STATUS_SUCCESS},
1473     { 2,            0,  1, 33, "0\0---------------------------------", STATUS_SUCCESS},
1474     { 2,            1,  1, 33, "1\0---------------------------------", STATUS_SUCCESS},
1475     { 2,           10,  4, 33, "1010\0------------------------------", STATUS_SUCCESS},
1476     { 2,          100,  7, 33, "1100100\0---------------------------", STATUS_SUCCESS},
1477     { 2,         1000, 10, 33, "1111101000\0------------------------", STATUS_SUCCESS},
1478     { 2,        10000, 14, 33, "10011100010000\0--------------------", STATUS_SUCCESS},
1479     { 2,        32767, 15, 33, "111111111111111\0-------------------", STATUS_SUCCESS},
1480     { 2,        32768, 16, 33, "1000000000000000\0------------------", STATUS_SUCCESS},
1481     { 2,        65535, 16, 33, "1111111111111111\0------------------", STATUS_SUCCESS},
1482     { 2,        65536, 17, 33, "10000000000000000\0-----------------", STATUS_SUCCESS},
1483     { 2,       100000, 17, 33, "11000011010100000\0-----------------", STATUS_SUCCESS},
1484     { 2,      1000000, 20, 33, "11110100001001000000\0--------------", STATUS_SUCCESS},
1485     { 2,     10000000, 24, 33, "100110001001011010000000\0----------", STATUS_SUCCESS},
1486     { 2,    100000000, 27, 33, "101111101011110000100000000\0-------", STATUS_SUCCESS},
1487     { 2,   1000000000, 30, 33, "111011100110101100101000000000\0----", STATUS_SUCCESS},
1488     { 2,   1073741823, 30, 33, "111111111111111111111111111111\0----", STATUS_SUCCESS},
1489     { 2,   2147483646, 31, 33, "1111111111111111111111111111110\0---", STATUS_SUCCESS},
1490     { 2,   2147483647, 31, 33, "1111111111111111111111111111111\0---", STATUS_SUCCESS}, /* max signed int */
1491     { 2,  2147483648U, 32, 33, "10000000000000000000000000000000\0--", STATUS_SUCCESS}, /* uint = -max int */
1492     { 2,  2147483649U, 32, 33, "10000000000000000000000000000001\0--", STATUS_SUCCESS},
1493     { 2,  4294967294U, 32, 33, "11111111111111111111111111111110\0--", STATUS_SUCCESS},
1494     { 2,  4294967295U, 32, 33, "11111111111111111111111111111111\0--", STATUS_SUCCESS}, /* max unsigned int */
1495
1496     { 8,  0x80000000U, 11, 12, "20000000000\0-----------------------", STATUS_SUCCESS}, /* min signed int */
1497     { 8,  -2147483647, 11, 12, "20000000001\0-----------------------", STATUS_SUCCESS},
1498     { 8,           -2, 11, 12, "37777777776\0-----------------------", STATUS_SUCCESS},
1499     { 8,           -1, 11, 12, "37777777777\0-----------------------", STATUS_SUCCESS},
1500     { 8,            0,  1, 12, "0\0---------------------------------", STATUS_SUCCESS},
1501     { 8,            1,  1, 12, "1\0---------------------------------", STATUS_SUCCESS},
1502     { 8,   2147483646, 11, 12, "17777777776\0-----------------------", STATUS_SUCCESS},
1503     { 8,   2147483647, 11, 12, "17777777777\0-----------------------", STATUS_SUCCESS}, /* max signed int */
1504     { 8,  2147483648U, 11, 12, "20000000000\0-----------------------", STATUS_SUCCESS}, /* uint = -max int */
1505     { 8,  2147483649U, 11, 12, "20000000001\0-----------------------", STATUS_SUCCESS},
1506     { 8,  4294967294U, 11, 12, "37777777776\0-----------------------", STATUS_SUCCESS},
1507     { 8,  4294967295U, 11, 12, "37777777777\0-----------------------", STATUS_SUCCESS}, /* max unsigned int */
1508
1509     {10,  0x80000000U, 10, 11, "2147483648\0------------------------", STATUS_SUCCESS}, /* min signed int */
1510     {10,  -2147483647, 10, 11, "2147483649\0------------------------", STATUS_SUCCESS},
1511     {10,           -2, 10, 11, "4294967294\0------------------------", STATUS_SUCCESS},
1512     {10,           -1, 10, 11, "4294967295\0------------------------", STATUS_SUCCESS},
1513     {10,            0,  1, 11, "0\0---------------------------------", STATUS_SUCCESS},
1514     {10,            1,  1, 11, "1\0---------------------------------", STATUS_SUCCESS},
1515     {10,   2147483646, 10, 11, "2147483646\0------------------------", STATUS_SUCCESS},
1516     {10,   2147483647, 10, 11, "2147483647\0------------------------", STATUS_SUCCESS}, /* max signed int */
1517     {10,  2147483648U, 10, 11, "2147483648\0------------------------", STATUS_SUCCESS}, /* uint = -max int */
1518     {10,  2147483649U, 10, 11, "2147483649\0------------------------", STATUS_SUCCESS},
1519     {10,  4294967294U, 10, 11, "4294967294\0------------------------", STATUS_SUCCESS},
1520     {10,  4294967295U, 10, 11, "4294967295\0------------------------", STATUS_SUCCESS}, /* max unsigned int */
1521
1522     {16,  0x80000000U,  8,  9, "80000000\0--------------------------", STATUS_SUCCESS}, /* min signed int */
1523     {16,  -2147483647,  8,  9, "80000001\0--------------------------", STATUS_SUCCESS},
1524     {16,           -2,  8,  9, "FFFFFFFE\0--------------------------", STATUS_SUCCESS},
1525     {16,           -1,  8,  9, "FFFFFFFF\0--------------------------", STATUS_SUCCESS},
1526     {16,            0,  1,  9, "0\0---------------------------------", STATUS_SUCCESS},
1527     {16,            1,  1,  9, "1\0---------------------------------", STATUS_SUCCESS},
1528     {16,   2147483646,  8,  9, "7FFFFFFE\0--------------------------", STATUS_SUCCESS},
1529     {16,   2147483647,  8,  9, "7FFFFFFF\0--------------------------", STATUS_SUCCESS}, /* max signed int */
1530     {16,  2147483648U,  8,  9, "80000000\0--------------------------", STATUS_SUCCESS}, /* uint = -max int */
1531     {16,  2147483649U,  8,  9, "80000001\0--------------------------", STATUS_SUCCESS},
1532     {16,  4294967294U,  8,  9, "FFFFFFFE\0--------------------------", STATUS_SUCCESS},
1533     {16,  4294967295U,  8,  9, "FFFFFFFF\0--------------------------", STATUS_SUCCESS}, /* max unsigned int */
1534
1535     { 2,        32768, 16, 17, "1000000000000000\0------------------", STATUS_SUCCESS},
1536     { 2,        32768, 16, 16, "1000000000000000-------------------",  STATUS_SUCCESS},
1537     { 2,        65536, 17, 18, "10000000000000000\0-----------------", STATUS_SUCCESS},
1538     { 2,        65536, 17, 17, "10000000000000000------------------",  STATUS_SUCCESS},
1539     { 2,       131072, 18, 19, "100000000000000000\0----------------", STATUS_SUCCESS},
1540     { 2,       131072, 18, 18, "100000000000000000-----------------",  STATUS_SUCCESS},
1541     {16,   0xffffffff,  8,  9, "FFFFFFFF\0--------------------------", STATUS_SUCCESS},
1542     {16,   0xffffffff,  8,  8, "FFFFFFFF---------------------------",  STATUS_SUCCESS}, /* No \0 term */
1543     {16,   0xffffffff,  8,  7, "-----------------------------------",  STATUS_BUFFER_OVERFLOW}, /* Too short */
1544     {16,          0xa,  1,  2, "A\0---------------------------------", STATUS_SUCCESS},
1545     {16,          0xa,  1,  1, "A----------------------------------",  STATUS_SUCCESS}, /* No \0 term */
1546     {16,            0,  1,  0, "-----------------------------------",  STATUS_BUFFER_OVERFLOW},
1547     {20,   0xdeadbeef,  0,  9, "-----------------------------------",  STATUS_INVALID_PARAMETER}, /* ill. base */
1548     {-8,     07654321,  0, 12, "-----------------------------------",  STATUS_INVALID_PARAMETER}, /* neg. base */
1549 };
1550 #define NB_INT2STR (sizeof(int2str)/sizeof(*int2str))
1551
1552
1553 static void one_RtlIntegerToUnicodeString_test(int test_num, const int2str_t *int2str)
1554 {
1555     int pos;
1556     WCHAR expected_str_Buffer[STRI_BUFFER_LENGTH + 1];
1557     UNICODE_STRING expected_unicode_string;
1558     STRING expected_ansi_str;
1559     WCHAR str_Buffer[STRI_BUFFER_LENGTH + 1];
1560     UNICODE_STRING unicode_string;
1561     STRING ansi_str;
1562     NTSTATUS result;
1563
1564     for (pos = 0; pos < STRI_BUFFER_LENGTH; pos++) {
1565         expected_str_Buffer[pos] = int2str->Buffer[pos];
1566     }
1567     expected_unicode_string.Length = int2str->Length * sizeof(WCHAR);
1568     expected_unicode_string.MaximumLength = int2str->MaximumLength * sizeof(WCHAR);
1569     expected_unicode_string.Buffer = expected_str_Buffer;
1570     pRtlUnicodeStringToAnsiString(&expected_ansi_str, &expected_unicode_string, 1);
1571
1572     for (pos = 0; pos < STRI_BUFFER_LENGTH; pos++) {
1573         str_Buffer[pos] = '-';
1574     }
1575     unicode_string.Length = 0;
1576     unicode_string.MaximumLength = int2str->MaximumLength * sizeof(WCHAR);
1577     unicode_string.Buffer = str_Buffer;
1578
1579     result = pRtlIntegerToUnicodeString(int2str->value, int2str->base, &unicode_string);
1580     pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
1581     if (result == STATUS_BUFFER_OVERFLOW) {
1582         /* On BUFFER_OVERFLOW the string Buffer should be unchanged */
1583         for (pos = 0; pos < STRI_BUFFER_LENGTH; pos++) {
1584             expected_str_Buffer[pos] = '-';
1585         }
1586         /* w2k: The native function has two reasons for BUFFER_OVERFLOW: */
1587         /* If the value is too large to convert: The Length is unchanged */
1588         /* If str is too small to hold the string: Set str->Length to the length */
1589         /* the string would have (which can be larger than the MaximumLength). */
1590         /* To allow all this in the tests we do the following: */
1591         if (expected_unicode_string.Length > 32 && unicode_string.Length == 0) {
1592             /* The value is too large to convert only triggerd when testing native */
1593             expected_unicode_string.Length = 0;
1594         }
1595     } else {
1596         ok(result == int2str->result,
1597            "(test %d): RtlIntegerToUnicodeString(%u, %d, [out]) has result %x, expected: %x\n",
1598            test_num, int2str->value, int2str->base, result, int2str->result);
1599         if (result == STATUS_SUCCESS) {
1600             ok(unicode_string.Buffer[unicode_string.Length/sizeof(WCHAR)] == '\0',
1601                "(test %d): RtlIntegerToUnicodeString(%u, %d, [out]) string \"%s\" is not NULL terminated\n",
1602                test_num, int2str->value, int2str->base, ansi_str.Buffer);
1603         }
1604     }
1605     ok(memcmp(unicode_string.Buffer, expected_unicode_string.Buffer, STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
1606        "(test %d): RtlIntegerToUnicodeString(%u, %d, [out]) assigns string \"%s\", expected: \"%s\"\n",
1607        test_num, int2str->value, int2str->base, ansi_str.Buffer, expected_ansi_str.Buffer);
1608     ok(unicode_string.Length == expected_unicode_string.Length,
1609        "(test %d): RtlIntegerToUnicodeString(%u, %d, [out]) string has Length %d, expected: %d\n",
1610        test_num, int2str->value, int2str->base, unicode_string.Length, expected_unicode_string.Length);
1611     ok(unicode_string.MaximumLength == expected_unicode_string.MaximumLength,
1612        "(test %d): RtlIntegerToUnicodeString(%u, %d, [out]) string has MaximumLength %d, expected: %d\n",
1613        test_num, int2str->value, int2str->base, unicode_string.MaximumLength, expected_unicode_string.MaximumLength);
1614     pRtlFreeAnsiString(&expected_ansi_str);
1615     pRtlFreeAnsiString(&ansi_str);
1616 }
1617
1618
1619 static void test_RtlIntegerToUnicodeString(void)
1620 {
1621     size_t test_num;
1622
1623     for (test_num = 0; test_num < NB_INT2STR; test_num++)
1624         one_RtlIntegerToUnicodeString_test(test_num, &int2str[test_num]);
1625 }
1626
1627
1628 static void one_RtlIntegerToChar_test(int test_num, const int2str_t *int2str)
1629 {
1630     NTSTATUS result;
1631     char dest_str[STRI_BUFFER_LENGTH + 1];
1632
1633     memset(dest_str, '-', STRI_BUFFER_LENGTH);
1634     dest_str[STRI_BUFFER_LENGTH] = '\0';
1635     result = pRtlIntegerToChar(int2str->value, int2str->base, int2str->MaximumLength, dest_str);
1636     ok(result == int2str->result,
1637        "(test %d): RtlIntegerToChar(%u, %d, %d, [out]) has result %x, expected: %x\n",
1638        test_num, int2str->value, int2str->base, int2str->MaximumLength, result, int2str->result);
1639     ok(memcmp(dest_str, int2str->Buffer, STRI_BUFFER_LENGTH) == 0,
1640        "(test %d): RtlIntegerToChar(%u, %d, %d, [out]) assigns string \"%s\", expected: \"%s\"\n",
1641        test_num, int2str->value, int2str->base, int2str->MaximumLength, dest_str, int2str->Buffer);
1642 }
1643
1644
1645 static void test_RtlIntegerToChar(void)
1646 {
1647     NTSTATUS result;
1648     size_t test_num;
1649
1650     for (test_num = 0; test_num < NB_INT2STR; test_num++)
1651       one_RtlIntegerToChar_test(test_num, &int2str[test_num]);
1652
1653     result = pRtlIntegerToChar(int2str[0].value, 20, int2str[0].MaximumLength, NULL);
1654     ok(result == STATUS_INVALID_PARAMETER,
1655        "(test a): RtlIntegerToChar(%u, %d, %d, NULL) has result %x, expected: %x\n",
1656        int2str[0].value, 20, int2str[0].MaximumLength, result, STATUS_INVALID_PARAMETER);
1657
1658     result = pRtlIntegerToChar(int2str[0].value, 20, 0, NULL);
1659     ok(result == STATUS_INVALID_PARAMETER,
1660        "(test b): RtlIntegerToChar(%u, %d, %d, NULL) has result %x, expected: %x\n",
1661        int2str[0].value, 20, 0, result, STATUS_INVALID_PARAMETER);
1662
1663     result = pRtlIntegerToChar(int2str[0].value, int2str[0].base, 0, NULL);
1664     ok(result == STATUS_BUFFER_OVERFLOW,
1665        "(test c): RtlIntegerToChar(%u, %d, %d, NULL) has result %x, expected: %x\n",
1666        int2str[0].value, int2str[0].base, 0, result, STATUS_BUFFER_OVERFLOW);
1667
1668     result = pRtlIntegerToChar(int2str[0].value, int2str[0].base, int2str[0].MaximumLength, NULL);
1669     ok(result == STATUS_ACCESS_VIOLATION,
1670        "(test d): RtlIntegerToChar(%u, %d, %d, NULL) has result %x, expected: %x\n",
1671        int2str[0].value, int2str[0].base, int2str[0].MaximumLength, result, STATUS_ACCESS_VIOLATION);
1672 }
1673
1674 static void test_RtlIsTextUnicode(void)
1675 {
1676     char ascii[] = "A simple string";
1677     WCHAR unicode[] = {'A',' ','U','n','i','c','o','d','e',' ','s','t','r','i','n','g',0};
1678     WCHAR *be_unicode;
1679     int flags;
1680     int i;
1681
1682     ok(!pRtlIsTextUnicode(ascii, sizeof(ascii), NULL), "ASCII text detected as Unicode\n");
1683
1684     ok(pRtlIsTextUnicode(unicode, sizeof(unicode), NULL), "Text should be Unicode\n");
1685     ok(!pRtlIsTextUnicode(unicode, sizeof(unicode) - 1, NULL), "Text should be Unicode\n");
1686
1687     flags =  IS_TEXT_UNICODE_UNICODE_MASK;
1688     ok(pRtlIsTextUnicode(unicode, sizeof(unicode), &flags), "Text should not pass a Unicode\n");
1689     todo_wine
1690     ok(flags == (IS_TEXT_UNICODE_STATISTICS | IS_TEXT_UNICODE_CONTROLS),
1691        "Expected flags 0x6, obtained %x\n", flags);
1692
1693     flags =  IS_TEXT_UNICODE_REVERSE_MASK;
1694     ok(!pRtlIsTextUnicode(unicode, sizeof(unicode), &flags), "Text should not pass reverse Unicode tests\n");
1695     ok(flags == 0, "Expected flags 0, obtained %x\n", flags);
1696
1697     flags = IS_TEXT_UNICODE_ODD_LENGTH;
1698     ok(!pRtlIsTextUnicode(unicode, sizeof(unicode) - 1, &flags), "Odd length test should have passed\n");
1699     ok(flags == IS_TEXT_UNICODE_ODD_LENGTH, "Expected flags 0x200, obtained %x\n", flags);
1700
1701     be_unicode = HeapAlloc(GetProcessHeap(), 0, sizeof(unicode) + sizeof(WCHAR));
1702     be_unicode[0] = 0xfffe;
1703     for (i = 0; i < sizeof(unicode)/sizeof(unicode[0]); i++)
1704     {
1705         be_unicode[i + 1] = (unicode[i] >> 8) | ((unicode[i] & 0xff) << 8);
1706     }
1707     ok(!pRtlIsTextUnicode(be_unicode, sizeof(unicode) + 2, NULL), "Reverse endian should not be Unicode\n");
1708     todo_wine ok(!pRtlIsTextUnicode(&be_unicode[1], sizeof(unicode), NULL), "Reverse endian should not be Unicode\n");
1709
1710     flags = IS_TEXT_UNICODE_REVERSE_MASK;
1711     ok(!pRtlIsTextUnicode(&be_unicode[1], sizeof(unicode), &flags), "Reverse endian should be Unicode\n");
1712     todo_wine
1713     ok(flags == (IS_TEXT_UNICODE_REVERSE_ASCII16 | IS_TEXT_UNICODE_REVERSE_STATISTICS | IS_TEXT_UNICODE_REVERSE_CONTROLS),
1714        "Expected flags 0x70, obtained %x\n", flags);
1715
1716     flags = IS_TEXT_UNICODE_REVERSE_MASK;
1717     ok(!pRtlIsTextUnicode(be_unicode, sizeof(unicode) + 2, &flags), "Reverse endian should be Unicode\n");
1718     todo_wine
1719     ok(flags == (IS_TEXT_UNICODE_REVERSE_CONTROLS | IS_TEXT_UNICODE_REVERSE_SIGNATURE),
1720        "Expected flags 0xc0, obtained %x\n", flags);
1721     HeapFree(GetProcessHeap(), 0, be_unicode);
1722 }
1723
1724 static const WCHAR szGuid[] = { '{','0','1','0','2','0','3','0','4','-',
1725   '0','5','0','6','-'  ,'0','7','0','8','-','0','9','0','A','-',
1726   '0','B','0','C','0','D','0','E','0','F','0','A','}','\0' };
1727 static const WCHAR szGuid2[] = { '{','0','1','0','2','0','3','0','4','-',
1728   '0','5','0','6','-'  ,'0','7','0','8','-','0','9','0','A','-',
1729   '0','B','0','C','0','D','0','E','0','F','0','A',']','\0' };
1730 DEFINE_GUID(IID_Endianess, 0x01020304, 0x0506, 0x0708, 0x09, 0x0A, 0x0B,
1731             0x0C, 0x0D, 0x0E, 0x0F, 0x0A);
1732
1733 static void test_RtlGUIDFromString(void)
1734 {
1735   GUID guid;
1736   UNICODE_STRING str;
1737   NTSTATUS ret;
1738
1739   str.Length = str.MaximumLength = sizeof(szGuid) - sizeof(WCHAR);
1740   str.Buffer = (LPWSTR)szGuid;
1741
1742   ret = pRtlGUIDFromString(&str, &guid);
1743   ok(ret == 0, "expected ret=0, got 0x%0x\n", ret);
1744   ok(memcmp(&guid, &IID_Endianess, sizeof(guid)) == 0, "Endianess broken\n");
1745
1746   str.Length = str.MaximumLength = sizeof(szGuid2) - sizeof(WCHAR);
1747   str.Buffer = (LPWSTR)szGuid2;
1748
1749   ret = pRtlGUIDFromString(&str, &guid);
1750   ok(ret, "expected ret!=0\n");
1751 }
1752
1753 static void test_RtlStringFromGUID(void)
1754 {
1755   UNICODE_STRING str;
1756   NTSTATUS ret;
1757
1758   str.Length = str.MaximumLength = 0;
1759   str.Buffer = NULL;
1760
1761   ret = pRtlStringFromGUID(&IID_Endianess, &str);
1762   ok(ret == 0, "expected ret=0, got 0x%0x\n", ret);
1763   ok(str.Buffer && !lstrcmpiW(str.Buffer, szGuid), "Endianess broken\n");
1764 }
1765
1766 START_TEST(rtlstr)
1767 {
1768     InitFunctionPtrs();
1769     if (pRtlInitAnsiString) {
1770         test_RtlInitString();
1771         test_RtlInitUnicodeString();
1772         test_RtlCopyString();
1773         test_RtlUnicodeStringToInteger();
1774         test_RtlCharToInteger();
1775         test_RtlIntegerToUnicodeString();
1776         test_RtlIntegerToChar();
1777         test_RtlUpperChar();
1778         test_RtlUpperString();
1779         test_RtlUnicodeStringToAnsiString();
1780         test_RtlAppendAsciizToString();
1781         test_RtlAppendStringToString();
1782         test_RtlAppendUnicodeToString();
1783         test_RtlAppendUnicodeStringToString();
1784     }
1785
1786     if (pRtlInitUnicodeStringEx)
1787         test_RtlInitUnicodeStringEx();
1788     if (pRtlDuplicateUnicodeString)
1789         test_RtlDuplicateUnicodeString();
1790     if (pRtlFindCharInUnicodeString)
1791         test_RtlFindCharInUnicodeString();
1792     if (pRtlGUIDFromString)
1793         test_RtlGUIDFromString();
1794     if (pRtlStringFromGUID)
1795         test_RtlStringFromGUID();
1796     if (pRtlIsTextUnicode)
1797         test_RtlIsTextUnicode();
1798     if(0)
1799     {
1800         test_RtlUpcaseUnicodeChar();
1801         test_RtlUpcaseUnicodeString();
1802         test_RtlDowncaseUnicodeString();
1803     }
1804 }