1 /* Unit test suite for string functions and some wcstring functions
2  *
3  * Copyright 2003 Thomas Mertes
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  *
19  * NOTES
20  * We use function pointers here as there is no import library for NTDLL on
21  * windows.
22  */
23 
24 #include <stdlib.h>
25 
26 #include "ntdll_test.h"
27 
28 
29 /* Function ptrs for ntdll calls */
30 static HMODULE hntdll = 0;
31 static NTSTATUS (WINAPI *pRtlUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN);
32 static VOID     (WINAPI *pRtlFreeAnsiString)(PSTRING);
33 static BOOLEAN  (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING,LPCSTR);
34 static VOID     (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
35 
36 static int      (WINAPIV *patoi)(const char *);
37 static long     (WINAPIV *patol)(const char *);
38 static LONGLONG (WINAPIV *p_atoi64)(const char *);
39 static LPSTR    (WINAPIV *p_itoa)(int, LPSTR, INT);
40 static LPSTR    (WINAPIV *p_ltoa)(LONG, LPSTR, INT);
41 static LPSTR    (WINAPIV *p_ultoa)(ULONG, LPSTR, INT);
42 static LPSTR    (WINAPIV *p_i64toa)(LONGLONG, LPSTR, INT);
43 static LPSTR    (WINAPIV *p_ui64toa)(ULONGLONG, LPSTR, INT);
44 
45 static int      (WINAPIV *p_wtoi)(LPWSTR);
46 static long     (WINAPIV *p_wtol)(LPWSTR);
47 static LONGLONG (WINAPIV *p_wtoi64)(LPWSTR);
48 static LPWSTR   (WINAPIV *p_itow)(int, LPWSTR, int);
49 static LPWSTR   (WINAPIV *p_ltow)(LONG, LPWSTR, INT);
50 static LPWSTR   (WINAPIV *p_ultow)(ULONG, LPWSTR, INT);
51 static LPWSTR   (WINAPIV *p_i64tow)(LONGLONG, LPWSTR, INT);
52 static LPWSTR   (WINAPIV *p_ui64tow)(ULONGLONG, LPWSTR, INT);
53 
54 static LPWSTR   (__cdecl *p_wcslwr)(LPWSTR);
55 static LPWSTR   (__cdecl *p_wcsupr)(LPWSTR);
56 
57 static LPWSTR   (WINAPIV *p_wcschr)(LPCWSTR, WCHAR);
58 static LPWSTR   (WINAPIV *p_wcsrchr)(LPCWSTR, WCHAR);
59 
60 static void     (__cdecl *p_qsort)(void *,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
61 static void*    (__cdecl *p_bsearch)(void *,void*,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
62 static int      (__cdecl *p__snprintf)(char *, size_t, const char *, ...);
63 
64 
65 static void InitFunctionPtrs(void)
66 {
67     hntdll = LoadLibraryA("ntdll.dll");
68     ok(hntdll != 0, "LoadLibrary failed\n");
69     if (hntdll) {
70 	pRtlUnicodeStringToAnsiString = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToAnsiString");
71 	pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString");
72 	pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
73 	pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
74 
75 	patoi = (void *)GetProcAddress(hntdll, "atoi");
76 	patol = (void *)GetProcAddress(hntdll, "atol");
77 	p_atoi64 = (void *)GetProcAddress(hntdll, "_atoi64");
78 	p_itoa = (void *)GetProcAddress(hntdll, "_itoa");
79 	p_ltoa = (void *)GetProcAddress(hntdll, "_ltoa");
80 	p_ultoa = (void *)GetProcAddress(hntdll, "_ultoa");
81 	p_i64toa = (void *)GetProcAddress(hntdll, "_i64toa");
82 	p_ui64toa = (void *)GetProcAddress(hntdll, "_ui64toa");
83 
84 	p_wtoi = (void *)GetProcAddress(hntdll, "_wtoi");
85 	p_wtol = (void *)GetProcAddress(hntdll, "_wtol");
86 	p_wtoi64 = (void *)GetProcAddress(hntdll, "_wtoi64");
87 	p_itow = (void *)GetProcAddress(hntdll, "_itow");
88 	p_ltow = (void *)GetProcAddress(hntdll, "_ltow");
89 	p_ultow = (void *)GetProcAddress(hntdll, "_ultow");
90 	p_i64tow = (void *)GetProcAddress(hntdll, "_i64tow");
91 	p_ui64tow = (void *)GetProcAddress(hntdll, "_ui64tow");
92 
93         p_wcslwr = (void *)GetProcAddress(hntdll, "_wcslwr");
94         p_wcsupr = (void *)GetProcAddress(hntdll, "_wcsupr");
95 
96 	p_wcschr= (void *)GetProcAddress(hntdll, "wcschr");
97 	p_wcsrchr= (void *)GetProcAddress(hntdll, "wcsrchr");
98 	p_qsort= (void *)GetProcAddress(hntdll, "qsort");
99 	p_bsearch= (void *)GetProcAddress(hntdll, "bsearch");
100 
101         p__snprintf = (void *)GetProcAddress(hntdll, "_snprintf");
102     } /* if */
103 }
104 
105 
106 #define LARGE_STRI_BUFFER_LENGTH 67
107 
108 typedef struct {
109     int base;
110     ULONG value;
111     const char *Buffer;
112     int mask; /* ntdll/msvcrt: 0x01=itoa, 0x02=ltoa, 0x04=ultoa */
113               /*               0x10=itow, 0x20=ltow, 0x40=ultow */
114 } ulong2str_t;
115 
116 static const ulong2str_t ulong2str[] = {
117     {10,         123, "123\0---------------------------------------------------------------", 0x77},
118 
119     { 2, 0x80000000U, "10000000000000000000000000000000\0----------------------------------", 0x67},
120     { 2, -2147483647, "10000000000000000000000000000001\0----------------------------------", 0x67},
121     { 2,      -65537, "11111111111111101111111111111111\0----------------------------------", 0x67},
122     { 2,      -65536, "11111111111111110000000000000000\0----------------------------------", 0x67},
123     { 2,      -65535, "11111111111111110000000000000001\0----------------------------------", 0x67},
124     { 2,      -32768, "11111111111111111000000000000000\0----------------------------------", 0x67},
125     { 2,      -32767, "11111111111111111000000000000001\0----------------------------------", 0x67},
126     { 2,          -2, "11111111111111111111111111111110\0----------------------------------", 0x67},
127     { 2,          -1, "11111111111111111111111111111111\0----------------------------------", 0x67},
128     { 2,           0, "0\0-----------------------------------------------------------------", 0x77},
129     { 2,           1, "1\0-----------------------------------------------------------------", 0x77},
130     { 2,          10, "1010\0--------------------------------------------------------------", 0x77},
131     { 2,         100, "1100100\0-----------------------------------------------------------", 0x77},
132     { 2,        1000, "1111101000\0--------------------------------------------------------", 0x77},
133     { 2,       10000, "10011100010000\0----------------------------------------------------", 0x77},
134     { 2,       32767, "111111111111111\0---------------------------------------------------", 0x77},
135     { 2,       32768, "1000000000000000\0--------------------------------------------------", 0x77},
136     { 2,       65535, "1111111111111111\0--------------------------------------------------", 0x77},
137     { 2,      100000, "11000011010100000\0-------------------------------------------------", 0x77},
138     { 2,      234567, "111001010001000111\0------------------------------------------------", 0x77},
139     { 2,      300000, "1001001001111100000\0-----------------------------------------------", 0x77},
140     { 2,      524287, "1111111111111111111\0-----------------------------------------------", 0x77},
141     { 2,      524288, "10000000000000000000\0----------------------------------------------", 0x67},
142     { 2,     1000000, "11110100001001000000\0----------------------------------------------", 0x67},
143     { 2,    10000000, "100110001001011010000000\0------------------------------------------", 0x67},
144     { 2,   100000000, "101111101011110000100000000\0---------------------------------------", 0x67},
145     { 2,  1000000000, "111011100110101100101000000000\0------------------------------------", 0x67},
146     { 2,  1073741823, "111111111111111111111111111111\0------------------------------------", 0x67},
147     { 2,  2147483646, "1111111111111111111111111111110\0-----------------------------------", 0x67},
148     { 2,  2147483647, "1111111111111111111111111111111\0-----------------------------------", 0x67},
149     { 2, 2147483648U, "10000000000000000000000000000000\0----------------------------------", 0x67},
150     { 2, 2147483649U, "10000000000000000000000000000001\0----------------------------------", 0x67},
151     { 2, 4294967294U, "11111111111111111111111111111110\0----------------------------------", 0x67},
152     { 2,  0xFFFFFFFF, "11111111111111111111111111111111\0----------------------------------", 0x67},
153 
154     { 8, 0x80000000U, "20000000000\0-------------------------------------------------------", 0x77},
155     { 8, -2147483647, "20000000001\0-------------------------------------------------------", 0x77},
156     { 8,          -2, "37777777776\0-------------------------------------------------------", 0x77},
157     { 8,          -1, "37777777777\0-------------------------------------------------------", 0x77},
158     { 8,           0, "0\0-----------------------------------------------------------------", 0x77},
159     { 8,           1, "1\0-----------------------------------------------------------------", 0x77},
160     { 8,  2147483646, "17777777776\0-------------------------------------------------------", 0x77},
161     { 8,  2147483647, "17777777777\0-------------------------------------------------------", 0x77},
162     { 8, 2147483648U, "20000000000\0-------------------------------------------------------", 0x77},
163     { 8, 2147483649U, "20000000001\0-------------------------------------------------------", 0x77},
164     { 8, 4294967294U, "37777777776\0-------------------------------------------------------", 0x77},
165     { 8, 4294967295U, "37777777777\0-------------------------------------------------------", 0x77},
166 
167     {10, 0x80000000U, "-2147483648\0-------------------------------------------------------", 0x33},
168     {10, 0x80000000U, "2147483648\0--------------------------------------------------------", 0x44},
169     {10, -2147483647, "-2147483647\0-------------------------------------------------------", 0x33},
170     {10, -2147483647, "2147483649\0--------------------------------------------------------", 0x44},
171     {10,          -2, "-2\0----------------------------------------------------------------", 0x33},
172     {10,          -2, "4294967294\0--------------------------------------------------------", 0x44},
173     {10,          -1, "-1\0----------------------------------------------------------------", 0x33},
174     {10,          -1, "4294967295\0--------------------------------------------------------", 0x44},
175     {10,           0, "0\0-----------------------------------------------------------------", 0x77},
176     {10,           1, "1\0-----------------------------------------------------------------", 0x77},
177     {10,          12, "12\0----------------------------------------------------------------", 0x77},
178     {10,         123, "123\0---------------------------------------------------------------", 0x77},
179     {10,        1234, "1234\0--------------------------------------------------------------", 0x77},
180     {10,       12345, "12345\0-------------------------------------------------------------", 0x77},
181     {10,      123456, "123456\0------------------------------------------------------------", 0x77},
182     {10,     1234567, "1234567\0-----------------------------------------------------------", 0x77},
183     {10,    12345678, "12345678\0----------------------------------------------------------", 0x77},
184     {10,   123456789, "123456789\0---------------------------------------------------------", 0x77},
185     {10,  2147483646, "2147483646\0--------------------------------------------------------", 0x77},
186     {10,  2147483647, "2147483647\0--------------------------------------------------------", 0x77},
187     {10, 2147483648U, "-2147483648\0-------------------------------------------------------", 0x33},
188     {10, 2147483648U, "2147483648\0--------------------------------------------------------", 0x44},
189     {10, 2147483649U, "-2147483647\0-------------------------------------------------------", 0x33},
190     {10, 2147483649U, "2147483649\0--------------------------------------------------------", 0x44},
191     {10, 4294967294U, "-2\0----------------------------------------------------------------", 0x33},
192     {10, 4294967294U, "4294967294\0--------------------------------------------------------", 0x44},
193     {10, 4294967295U, "-1\0----------------------------------------------------------------", 0x33},
194     {10, 4294967295U, "4294967295\0--------------------------------------------------------", 0x44},
195 
196     {16,           0, "0\0-----------------------------------------------------------------", 0x77},
197     {16,           1, "1\0-----------------------------------------------------------------", 0x77},
198     {16,  2147483646, "7ffffffe\0----------------------------------------------------------", 0x77},
199     {16,  2147483647, "7fffffff\0----------------------------------------------------------", 0x77},
200     {16,  0x80000000, "80000000\0----------------------------------------------------------", 0x77},
201     {16,  0x80000001, "80000001\0----------------------------------------------------------", 0x77},
202     {16,  0xFFFFFFFE, "fffffffe\0----------------------------------------------------------", 0x77},
203     {16,  0xFFFFFFFF, "ffffffff\0----------------------------------------------------------", 0x77},
204 
205     { 2,       32768, "1000000000000000\0--------------------------------------------------", 0x77},
206     { 2,       65536, "10000000000000000\0-------------------------------------------------", 0x77},
207     { 2,      131072, "100000000000000000\0------------------------------------------------", 0x77},
208     {16,  0xffffffff, "ffffffff\0----------------------------------------------------------", 0x77},
209     {16,         0xa, "a\0-----------------------------------------------------------------", 0x77},
210     {16,           0, "0\0-----------------------------------------------------------------", 0x77},
211     {20,     3368421, "111111\0------------------------------------------------------------", 0x77},
212     {36,    62193781, "111111\0------------------------------------------------------------", 0x77},
213     {37,    71270178, "111111\0------------------------------------------------------------", 0x77},
214 };
215 #define NB_ULONG2STR (sizeof(ulong2str)/sizeof(*ulong2str))
216 
217 
218 static void one_itoa_test(int test_num, const ulong2str_t *ulong2str)
219 {
220     char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
221     int value;
222     LPSTR result;
223 
224     memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
225     dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
226     value = ulong2str->value;
227     result = p_itoa(value, dest_str, ulong2str->base);
228     ok(result == dest_str,
229        "(test %d): _itoa(%d, [out], %d) has result %p, expected: %p\n",
230        test_num, value, ulong2str->base, result, dest_str);
231     ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
232        "(test %d): _itoa(%d, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
233        test_num, value, ulong2str->base, dest_str, ulong2str->Buffer);
234 }
235 
236 
237 static void one_ltoa_test(int test_num, const ulong2str_t *ulong2str)
238 {
239     char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
240     LONG value;
241     LPSTR result;
242 
243     memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
244     dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
245     value = ulong2str->value;
246     result = p_ltoa(ulong2str->value, dest_str, ulong2str->base);
247     ok(result == dest_str,
248        "(test %d): _ltoa(%d, [out], %d) has result %p, expected: %p\n",
249        test_num, value, ulong2str->base, result, dest_str);
250     ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
251        "(test %d): _ltoa(%d, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
252        test_num, value, ulong2str->base, dest_str, ulong2str->Buffer);
253 }
254 
255 
256 static void one_ultoa_test(int test_num, const ulong2str_t *ulong2str)
257 {
258     char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
259     ULONG value;
260     LPSTR result;
261 
262     memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
263     dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
264     value = ulong2str->value;
265     result = p_ultoa(ulong2str->value, dest_str, ulong2str->base);
266     ok(result == dest_str,
267        "(test %d): _ultoa(%u, [out], %d) has result %p, expected: %p\n",
268        test_num, value, ulong2str->base, result, dest_str);
269     ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
270        "(test %d): _ultoa(%u, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
271        test_num, value, ulong2str->base, dest_str, ulong2str->Buffer);
272 }
273 
274 
275 static void test_ulongtoa(void)
276 {
277     int test_num;
278 
279     for (test_num = 0; test_num < NB_ULONG2STR; test_num++) {
280 	if (ulong2str[test_num].mask & 0x01) {
281 	    one_itoa_test(test_num, &ulong2str[test_num]);
282 	} /* if */
283 	if (ulong2str[test_num].mask & 0x02) {
284 	    one_ltoa_test(test_num, &ulong2str[test_num]);
285 	} /* if */
286 	if (ulong2str[test_num].mask & 0x04) {
287 	    one_ultoa_test(test_num, &ulong2str[test_num]);
288 	} /* if */
289     } /* for */
290 }
291 
292 
293 static void one_itow_test(int test_num, const ulong2str_t *ulong2str)
294 {
295     int pos;
296     WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
297     WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
298     UNICODE_STRING unicode_string;
299     STRING ansi_str;
300     int value;
301     LPWSTR result;
302 
303     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
304 	expected_wstr[pos] = ulong2str->Buffer[pos];
305     } /* for */
306     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
307 
308     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
309 	dest_wstr[pos] = '-';
310     } /* for */
311     dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
312     unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
313     unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
314     unicode_string.Buffer = dest_wstr;
315     value = ulong2str->value;
316     result = p_itow(value, dest_wstr, ulong2str->base);
317     pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
318     ok(result == dest_wstr,
319        "(test %d): _itow(%d, [out], %d) has result %p, expected: %p\n",
320        test_num, value, ulong2str->base, result, dest_wstr);
321     ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
322        "(test %d): _itow(%d, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
323        test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer);
324     pRtlFreeAnsiString(&ansi_str);
325 }
326 
327 
328 static void one_ltow_test(int test_num, const ulong2str_t *ulong2str)
329 {
330     int pos;
331     WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
332     WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
333     UNICODE_STRING unicode_string;
334     STRING ansi_str;
335     LONG value;
336     LPWSTR result;
337 
338     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
339 	expected_wstr[pos] = ulong2str->Buffer[pos];
340     } /* for */
341     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
342 
343     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
344 	dest_wstr[pos] = '-';
345     } /* for */
346     dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
347     unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
348     unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
349     unicode_string.Buffer = dest_wstr;
350 
351     value = ulong2str->value;
352     result = p_ltow(value, dest_wstr, ulong2str->base);
353     pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
354     ok(result == dest_wstr,
355        "(test %d): _ltow(%d, [out], %d) has result %p, expected: %p\n",
356        test_num, value, ulong2str->base, result, dest_wstr);
357     ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
358        "(test %d): _ltow(%d, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
359        test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer);
360     pRtlFreeAnsiString(&ansi_str);
361 }
362 
363 
364 static void one_ultow_test(int test_num, const ulong2str_t *ulong2str)
365 {
366     int pos;
367     WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
368     WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
369     UNICODE_STRING unicode_string;
370     STRING ansi_str;
371     ULONG value;
372     LPWSTR result;
373 
374     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
375 	expected_wstr[pos] = ulong2str->Buffer[pos];
376     } /* for */
377     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
378 
379     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
380 	dest_wstr[pos] = '-';
381     } /* for */
382     dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
383     unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
384     unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
385     unicode_string.Buffer = dest_wstr;
386 
387     value = ulong2str->value;
388     result = p_ultow(value, dest_wstr, ulong2str->base);
389     pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
390     ok(result == dest_wstr,
391        "(test %d): _ultow(%u, [out], %d) has result %p, expected: %p\n",
392        test_num, value, ulong2str->base, result, dest_wstr);
393     ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
394        "(test %d): _ultow(%u, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
395        test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer);
396     pRtlFreeAnsiString(&ansi_str);
397 }
398 
399 
400 static void test_ulongtow(void)
401 {
402     int test_num;
403     LPWSTR result;
404 
405     for (test_num = 0; test_num < NB_ULONG2STR; test_num++) {
406 	if (ulong2str[test_num].mask & 0x10) {
407 	    one_itow_test(test_num, &ulong2str[test_num]);
408 	} /* if */
409 	if (ulong2str[test_num].mask & 0x20) {
410 	    one_ltow_test(test_num, &ulong2str[test_num]);
411 	} /* if */
412 	if (ulong2str[test_num].mask & 0x40) {
413 	    one_ultow_test(test_num, &ulong2str[test_num]);
414 	} /* if */
415     } /* for */
416 
417     if (0) {
418         /* Crashes on XP and W2K3 */
419         result = p_itow(ulong2str[0].value, NULL, 10);
420         ok(result == NULL,
421            "(test a): _itow(%d, NULL, 10) has result %p, expected: NULL\n",
422            ulong2str[0].value, result);
423     }
424 
425     if (0) {
426         /* Crashes on XP and W2K3 */
427         result = p_ltow(ulong2str[0].value, NULL, 10);
428         ok(result == NULL,
429            "(test b): _ltow(%d, NULL, 10) has result %p, expected: NULL\n",
430            ulong2str[0].value, result);
431     }
432 
433     if (0) {
434         /* Crashes on XP and W2K3 */
435         result = p_ultow(ulong2str[0].value, NULL, 10);
436         ok(result == NULL,
437            "(test c): _ultow(%d, NULL, 10) has result %p, expected: NULL\n",
438            ulong2str[0].value, result);
439     }
440 }
441 
442 #define ULL(a,b) (((ULONGLONG)(a) << 32) | (b))
443 
444 typedef struct {
445     int base;
446     ULONGLONG value;
447     const char *Buffer;
448     int mask; /* ntdll/msvcrt: 0x01=i64toa, 0x02=ui64toa, 0x04=wrong _i64toa try next example */
449               /*               0x10=i64tow, 0x20=ui64tow, 0x40=wrong _i64tow try next example */
450 } ulonglong2str_t;
451 
452 static const ulonglong2str_t ulonglong2str[] = {
453     {10,          123, "123\0---------------------------------------------------------------", 0x33},
454 
455     { 2,  0x80000000U, "10000000000000000000000000000000\0----------------------------------", 0x33},
456     { 2,  -2147483647, "1111111111111111111111111111111110000000000000000000000000000001\0--", 0x33},
457     { 2,       -65537, "1111111111111111111111111111111111111111111111101111111111111111\0--", 0x33},
458     { 2,       -65536, "1111111111111111111111111111111111111111111111110000000000000000\0--", 0x33},
459     { 2,       -65535, "1111111111111111111111111111111111111111111111110000000000000001\0--", 0x33},
460     { 2,       -32768, "1111111111111111111111111111111111111111111111111000000000000000\0--", 0x33},
461     { 2,       -32767, "1111111111111111111111111111111111111111111111111000000000000001\0--", 0x33},
462     { 2,           -2, "1111111111111111111111111111111111111111111111111111111111111110\0--", 0x33},
463     { 2,           -1, "1111111111111111111111111111111111111111111111111111111111111111\0--", 0x33},
464     { 2,            0, "0\0-----------------------------------------------------------------", 0x33},
465     { 2,            1, "1\0-----------------------------------------------------------------", 0x33},
466     { 2,           10, "1010\0--------------------------------------------------------------", 0x33},
467     { 2,          100, "1100100\0-----------------------------------------------------------", 0x33},
468     { 2,         1000, "1111101000\0--------------------------------------------------------", 0x33},
469     { 2,        10000, "10011100010000\0----------------------------------------------------", 0x33},
470     { 2,        32767, "111111111111111\0---------------------------------------------------", 0x33},
471     { 2,        32768, "1000000000000000\0--------------------------------------------------", 0x33},
472     { 2,        65535, "1111111111111111\0--------------------------------------------------", 0x33},
473     { 2,       100000, "11000011010100000\0-------------------------------------------------", 0x33},
474     { 2,       234567, "111001010001000111\0------------------------------------------------", 0x33},
475     { 2,       300000, "1001001001111100000\0-----------------------------------------------", 0x33},
476     { 2,       524287, "1111111111111111111\0-----------------------------------------------", 0x33},
477     { 2,       524288, "10000000000000000000\0----------------------------------------------", 0x33},
478     { 2,      1000000, "11110100001001000000\0----------------------------------------------", 0x33},
479     { 2,     10000000, "100110001001011010000000\0------------------------------------------", 0x33},
480     { 2,    100000000, "101111101011110000100000000\0---------------------------------------", 0x33},
481     { 2,   1000000000, "111011100110101100101000000000\0------------------------------------", 0x33},
482     { 2,   1073741823, "111111111111111111111111111111\0------------------------------------", 0x33},
483     { 2,   2147483646, "1111111111111111111111111111110\0-----------------------------------", 0x33},
484     { 2,   2147483647, "1111111111111111111111111111111\0-----------------------------------", 0x33},
485     { 2,  2147483648U, "10000000000000000000000000000000\0----------------------------------", 0x33},
486     { 2,  2147483649U, "10000000000000000000000000000001\0----------------------------------", 0x33},
487     { 2,  4294967294U, "11111111111111111111111111111110\0----------------------------------", 0x33},
488     { 2,   0xFFFFFFFF, "11111111111111111111111111111111\0----------------------------------", 0x33},
489     { 2, ULL(0x1,0xffffffff), "111111111111111111111111111111111\0---------------------------------", 0x33},
490     { 2, ((ULONGLONG)100000)*100000, "1001010100000010111110010000000000\0--------------------------------", 0x33},
491     { 2, ULL(0x3,0xffffffff), "1111111111111111111111111111111111\0--------------------------------", 0x33},
492     { 2, ULL(0x7,0xffffffff), "11111111111111111111111111111111111\0-------------------------------", 0x33},
493     { 2, ULL(0xf,0xffffffff), "111111111111111111111111111111111111\0------------------------------", 0x33},
494     { 2, ((ULONGLONG)100000)*1000000, "1011101001000011101101110100000000000\0-----------------------------", 0x33},
495     { 2, ULL(0x1f,0xffffffff), "1111111111111111111111111111111111111\0-----------------------------", 0x33},
496     { 2, ULL(0x3f,0xffffffff), "11111111111111111111111111111111111111\0----------------------------", 0x33},
497     { 2, ULL(0x7f,0xffffffff), "111111111111111111111111111111111111111\0---------------------------", 0x33},
498     { 2, ULL(0xff,0xffffffff), "1111111111111111111111111111111111111111\0--------------------------", 0x33},
499 
500     { 8,  0x80000000U, "20000000000\0-------------------------------------------------------", 0x33},
501     { 8,  -2147483647, "1777777777760000000001\0--------------------------------------------", 0x33},
502     { 8,           -2, "1777777777777777777776\0--------------------------------------------", 0x33},
503     { 8,           -1, "1777777777777777777777\0--------------------------------------------", 0x33},
504     { 8,            0, "0\0-----------------------------------------------------------------", 0x33},
505     { 8,            1, "1\0-----------------------------------------------------------------", 0x33},
506     { 8,   2147483646, "17777777776\0-------------------------------------------------------", 0x33},
507     { 8,   2147483647, "17777777777\0-------------------------------------------------------", 0x33},
508     { 8,  2147483648U, "20000000000\0-------------------------------------------------------", 0x33},
509     { 8,  2147483649U, "20000000001\0-------------------------------------------------------", 0x33},
510     { 8,  4294967294U, "37777777776\0-------------------------------------------------------", 0x33},
511     { 8,  4294967295U, "37777777777\0-------------------------------------------------------", 0x33},
512 
513     {10,  0x80000000U, "2147483648\0--------------------------------------------------------", 0x33},
514     {10,  -2147483647, "-2147483647\0-------------------------------------------------------", 0x55},
515     {10,  -2147483647, "-18446744071562067969\0---------------------------------------------", 0x00},
516     {10,  -2147483647, "18446744071562067969\0----------------------------------------------", 0x22},
517     {10,           -2, "-2\0----------------------------------------------------------------", 0x55},
518     {10,           -2, "-18446744073709551614\0---------------------------------------------", 0x00},
519     {10,           -2, "18446744073709551614\0----------------------------------------------", 0x22},
520     {10,           -1, "-1\0----------------------------------------------------------------", 0x55},
521     {10,           -1, "-18446744073709551615\0---------------------------------------------", 0x00},
522     {10,           -1, "18446744073709551615\0----------------------------------------------", 0x22},
523     {10,            0, "0\0-----------------------------------------------------------------", 0x33},
524     {10,            1, "1\0-----------------------------------------------------------------", 0x33},
525     {10,           12, "12\0----------------------------------------------------------------", 0x33},
526     {10,          123, "123\0---------------------------------------------------------------", 0x33},
527     {10,         1234, "1234\0--------------------------------------------------------------", 0x33},
528     {10,        12345, "12345\0-------------------------------------------------------------", 0x33},
529     {10,       123456, "123456\0------------------------------------------------------------", 0x33},
530     {10,      1234567, "1234567\0-----------------------------------------------------------", 0x33},
531     {10,     12345678, "12345678\0----------------------------------------------------------", 0x33},
532     {10,    123456789, "123456789\0---------------------------------------------------------", 0x33},
533     {10,   2147483646, "2147483646\0--------------------------------------------------------", 0x33},
534     {10,   2147483647, "2147483647\0--------------------------------------------------------", 0x33},
535     {10,  2147483648U, "2147483648\0--------------------------------------------------------", 0x33},
536     {10,  2147483649U, "2147483649\0--------------------------------------------------------", 0x33},
537     {10,  4294967294U, "4294967294\0--------------------------------------------------------", 0x33},
538     {10,  4294967295U, "4294967295\0--------------------------------------------------------", 0x33},
539     {10, ULL(0x2,0xdfdc1c35), "12345678901\0-------------------------------------------------------", 0x33},
540     {10, ULL(0xe5,0xf4c8f374), "987654321012\0------------------------------------------------------", 0x33},
541     {10, ULL(0x1c0,0xfc161e3e), "1928374656574\0-----------------------------------------------------", 0x33},
542     {10, ULL(0xbad,0xcafeface), "12841062955726\0----------------------------------------------------", 0x33},
543     {10, ULL(0x5bad,0xcafeface), "100801993177806\0---------------------------------------------------", 0x33},
544     {10, ULL(0xaface,0xbeefcafe), "3090515640699646\0--------------------------------------------------", 0x33},
545     {10, ULL(0xa5beef,0xabcdcafe), "46653307746110206\0-------------------------------------------------", 0x33},
546     {10, ULL(0x1f8cf9b,0xf2df3af1), "142091656963767025\0------------------------------------------------", 0x33},
547     {10, ULL(0x0fffffff,0xffffffff), "1152921504606846975\0-----------------------------------------------", 0x33},
548     {10, ULL(0x7fffffff,0xffffffff), "9223372036854775807\0-----------------------------------------------", 0x33},
549     {10, ULL(0x80000000,0x00000000), "-9223372036854775808\0----------------------------------------------", 0x11},
550     {10, ULL(0x80000000,0x00000000), "9223372036854775808\0-----------------------------------------------", 0x22},
551     {10, ULL(0x80000000,0x00000001), "-9223372036854775807\0----------------------------------------------", 0x55},
552     {10, ULL(0x80000000,0x00000001), "-9223372036854775809\0----------------------------------------------", 0x00},
553     {10, ULL(0x80000000,0x00000001), "9223372036854775809\0-----------------------------------------------", 0x22},
554     {10, ULL(0x80000000,0x00000002), "-9223372036854775806\0----------------------------------------------", 0x55},
555     {10, ULL(0x80000000,0x00000002), "-9223372036854775810\0----------------------------------------------", 0x00},
556     {10, ULL(0x80000000,0x00000002), "9223372036854775810\0-----------------------------------------------", 0x22},
557     {10, ULL(0xffffffff,0xfffffffe), "-2\0----------------------------------------------------------------", 0x55},
558     {10, ULL(0xffffffff,0xfffffffe), "-18446744073709551614\0---------------------------------------------", 0x00},
559     {10, ULL(0xffffffff,0xfffffffe), "18446744073709551614\0----------------------------------------------", 0x22},
560     {10, ULL(0xffffffff,0xffffffff), "-1\0----------------------------------------------------------------", 0x55},
561     {10, ULL(0xffffffff,0xffffffff), "-18446744073709551615\0---------------------------------------------", 0x00},
562     {10, ULL(0xffffffff,0xffffffff), "18446744073709551615\0----------------------------------------------", 0x22},
563 
564     {16,                  0, "0\0-----------------------------------------------------------------", 0x33},
565     {16,                  1, "1\0-----------------------------------------------------------------", 0x33},
566     {16,         2147483646, "7ffffffe\0----------------------------------------------------------", 0x33},
567     {16,         2147483647, "7fffffff\0----------------------------------------------------------", 0x33},
568     {16,         0x80000000, "80000000\0----------------------------------------------------------", 0x33},
569     {16,         0x80000001, "80000001\0----------------------------------------------------------", 0x33},
570     {16,         0xFFFFFFFE, "fffffffe\0----------------------------------------------------------", 0x33},
571     {16,         0xFFFFFFFF, "ffffffff\0----------------------------------------------------------", 0x33},
572     {16, ULL(0x1,0x00000000), "100000000\0---------------------------------------------------------", 0x33},
573     {16, ULL(0xbad,0xdeadbeef), "baddeadbeef\0-------------------------------------------------------", 0x33},
574     {16, ULL(0x80000000,0x00000000), "8000000000000000\0--------------------------------------------------", 0x33},
575     {16, ULL(0xfedcba98,0x76543210), "fedcba9876543210\0--------------------------------------------------", 0x33},
576     {16, ULL(0xffffffff,0x80000001), "ffffffff80000001\0--------------------------------------------------", 0x33},
577     {16, ULL(0xffffffff,0xfffffffe), "fffffffffffffffe\0--------------------------------------------------", 0x33},
578     {16, ULL(0xffffffff,0xffffffff), "ffffffffffffffff\0--------------------------------------------------", 0x33},
579 
580     { 2,        32768, "1000000000000000\0--------------------------------------------------", 0x33},
581     { 2,        65536, "10000000000000000\0-------------------------------------------------", 0x33},
582     { 2,       131072, "100000000000000000\0------------------------------------------------", 0x33},
583     {16,   0xffffffff, "ffffffff\0----------------------------------------------------------", 0x33},
584     {16,          0xa, "a\0-----------------------------------------------------------------", 0x33},
585     {16,            0, "0\0-----------------------------------------------------------------", 0x33},
586     {20,      3368421, "111111\0------------------------------------------------------------", 0x33},
587     {36,     62193781, "111111\0------------------------------------------------------------", 0x33},
588     {37,     71270178, "111111\0------------------------------------------------------------", 0x33},
589     {99, ULL(0x2,0x3c9e468c), "111111\0------------------------------------------------------------", 0x33},
590 };
591 #define NB_ULONGLONG2STR (sizeof(ulonglong2str)/sizeof(*ulonglong2str))
592 
593 
594 static void one_i64toa_test(int test_num, const ulonglong2str_t *ulonglong2str)
595 {
596     LPSTR result;
597     char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
598 
599     memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
600     dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
601     result = p_i64toa(ulonglong2str->value, dest_str, ulonglong2str->base);
602     ok(result == dest_str,
603        "(test %d): _i64toa(%08x%08x, [out], %d) has result %p, expected: %p\n",
604        test_num, (DWORD)(ulonglong2str->value >> 32), (DWORD)ulonglong2str->value,
605        ulonglong2str->base, result, dest_str);
606     if (ulonglong2str->mask & 0x04) {
607 	if (memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) != 0) {
608 	    if (memcmp(dest_str, ulonglong2str[1].Buffer, LARGE_STRI_BUFFER_LENGTH) != 0) {
609 		ok(memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
610 		   "(test %d): _i64toa(%08x%08x, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
611 		   test_num, (DWORD)(ulonglong2str->value >> 32), (DWORD)ulonglong2str->value,
612                    ulonglong2str->base, dest_str, ulonglong2str->Buffer);
613 	    } /* if */
614 	} /* if */
615     } else {
616 	ok(memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
617 	   "(test %d): _i64toa(%08x%08x, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
618 	   test_num, (DWORD)(ulonglong2str->value >> 32), (DWORD)ulonglong2str->value,
619            ulonglong2str->base, dest_str, ulonglong2str->Buffer);
620     } /* if */
621 }
622 
623 
624 static void one_ui64toa_test(int test_num, const ulonglong2str_t *ulonglong2str)
625 {
626     LPSTR result;
627     char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
628 
629     memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
630     dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
631     result = p_ui64toa(ulonglong2str->value, dest_str, ulonglong2str->base);
632     ok(result == dest_str,
633        "(test %d): _ui64toa(%08x%08x, [out], %d) has result %p, expected: %p\n",
634        test_num, (DWORD)(ulonglong2str->value >> 32), (DWORD)ulonglong2str->value,
635        ulonglong2str->base, result, dest_str);
636     ok(memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
637        "(test %d): _ui64toa(%08x%08x, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
638        test_num, (DWORD)(ulonglong2str->value >> 32), (DWORD)ulonglong2str->value,
639        ulonglong2str->base, dest_str, ulonglong2str->Buffer);
640 }
641 
642 
643 static void test_ulonglongtoa(void)
644 {
645     int test_num;
646 
647     for (test_num = 0; test_num < NB_ULONGLONG2STR; test_num++) {
648 	if (ulonglong2str[test_num].mask & 0x01) {
649 	    one_i64toa_test(test_num, &ulonglong2str[test_num]);
650 	} /* if */
651         if (p_ui64toa != NULL) {
652 	    if (ulonglong2str[test_num].mask & 0x02) {
653 		one_ui64toa_test(test_num, &ulonglong2str[test_num]);
654 	    } /* if */
655 	} /* if */
656     } /* for */
657 }
658 
659 
660 static void one_i64tow_test(int test_num, const ulonglong2str_t *ulonglong2str)
661 {
662     int pos;
663     WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
664     WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
665     UNICODE_STRING unicode_string;
666     STRING ansi_str;
667     LPWSTR result;
668 
669     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
670 	expected_wstr[pos] = ulonglong2str->Buffer[pos];
671     } /* for */
672     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
673 
674     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
675 	dest_wstr[pos] = '-';
676     } /* for */
677     dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
678     unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
679     unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
680     unicode_string.Buffer = dest_wstr;
681 
682     result = p_i64tow(ulonglong2str->value, dest_wstr, ulonglong2str->base);
683     pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
684     ok(result == dest_wstr,
685        "(test %d): _i64tow(0x%x%08x, [out], %d) has result %p, expected: %p\n",
686        test_num, (DWORD)(ulonglong2str->value >> 32), (DWORD)ulonglong2str->value,
687        ulonglong2str->base, result, dest_wstr);
688     if (ulonglong2str->mask & 0x04) {
689 	if (memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) != 0) {
690 	    for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
691 		expected_wstr[pos] = ulonglong2str[1].Buffer[pos];
692 	    } /* for */
693 	    expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
694 	    if (memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) != 0) {
695 		ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
696                    "(test %d): _i64tow(0x%x%08x, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
697 		   test_num, (DWORD)(ulonglong2str->value >> 32), (DWORD)ulonglong2str->value,
698 		   ulonglong2str->base, ansi_str.Buffer, ulonglong2str->Buffer);
699 	    } /* if */
700 	} /* if */
701     } else {
702 	ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
703            "(test %d): _i64tow(0x%x%08x, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
704 	   test_num, (DWORD)(ulonglong2str->value >> 32), (DWORD)ulonglong2str->value,
705 	   ulonglong2str->base, ansi_str.Buffer, ulonglong2str->Buffer);
706     } /* if */
707     pRtlFreeAnsiString(&ansi_str);
708 }
709 
710 
711 static void one_ui64tow_test(int test_num, const ulonglong2str_t *ulonglong2str)
712 {
713     int pos;
714     WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
715     WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1];
716     UNICODE_STRING unicode_string;
717     STRING ansi_str;
718     LPWSTR result;
719 
720     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
721 	expected_wstr[pos] = ulonglong2str->Buffer[pos];
722     } /* for */
723     expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
724 
725     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
726 	dest_wstr[pos] = '-';
727     } /* for */
728     dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0';
729     unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR);
730     unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR);
731     unicode_string.Buffer = dest_wstr;
732 
733     result = p_ui64tow(ulonglong2str->value, dest_wstr, ulonglong2str->base);
734     pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
735     ok(result == dest_wstr,
736        "(test %d): _ui64tow(0x%x%08x, [out], %d) has result %p, expected: %p\n",
737        test_num, (DWORD)(ulonglong2str->value >> 32), (DWORD)ulonglong2str->value,
738        ulonglong2str->base, result, dest_wstr);
739     ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
740        "(test %d): _ui64tow(0x%x%08x, [out], %d) assigns string \"%s\", expected: \"%s\"\n",
741        test_num, (DWORD)(ulonglong2str->value >> 32), (DWORD)ulonglong2str->value,
742        ulonglong2str->base, ansi_str.Buffer, ulonglong2str->Buffer);
743     pRtlFreeAnsiString(&ansi_str);
744 }
745 
746 
747 static void test_ulonglongtow(void)
748 {
749     int test_num;
750     LPWSTR result;
751 
752     for (test_num = 0; test_num < NB_ULONGLONG2STR; test_num++) {
753 	if (ulonglong2str[test_num].mask & 0x10) {
754 	    one_i64tow_test(test_num, &ulonglong2str[test_num]);
755 	} /* if */
756 	if (p_ui64tow) {
757 	    if (ulonglong2str[test_num].mask & 0x20) {
758 		one_ui64tow_test(test_num, &ulonglong2str[test_num]);
759 	    } /* if */
760 	} /* if */
761     } /* for */
762 
763     if (0) {
764         /* Crashes on XP and W2K3 */
765         result = p_i64tow(ulonglong2str[0].value, NULL, 10);
766         ok(result == NULL,
767            "(test d): _i64tow(0x%x%08x, NULL, 10) has result %p, expected: NULL\n",
768            (DWORD)(ulonglong2str[0].value >> 32), (DWORD)ulonglong2str[0].value, result);
769     }
770 
771     if (p_ui64tow) {
772         if (0) {
773             /* Crashes on XP and W2K3 */
774 	    result = p_ui64tow(ulonglong2str[0].value, NULL, 10);
775 	    ok(result == NULL,
776                "(test e): _ui64tow(0x%x%08x, NULL, 10) has result %p, expected: NULL\n",
777 	       (DWORD)(ulonglong2str[0].value >> 32), (DWORD)ulonglong2str[0].value, result);
778         }
779     } /* if */
780 }
781 
782 
783 typedef struct {
784     const char *str;
785     LONG value;
786 } str2long_t;
787 
788 static const str2long_t str2long[] = {
789     { "1011101100",   1011101100   },
790     { "1234567",         1234567   },
791     { "-214",               -214   },
792     { "+214",                214   }, /* The + sign is allowed also */
793     { "--214",                 0   }, /* Do not accept more than one sign */
794     { "-+214",                 0   },
795     { "++214",                 0   },
796     { "+-214",                 0   },
797     { "\00141",                0   }, /* not whitespace char  1 */
798     { "\00242",                0   }, /* not whitespace char  2 */
799     { "\00343",                0   }, /* not whitespace char  3 */
800     { "\00444",                0   }, /* not whitespace char  4 */
801     { "\00545",                0   }, /* not whitespace char  5 */
802     { "\00646",                0   }, /* not whitespace char  6 */
803     { "\00747",                0   }, /* not whitespace char  7 */
804     { "\01050",                0   }, /* not whitespace char  8 */
805     { "\01151",               51   }, /*  is whitespace char  9 (tab) */
806     { "\01252",               52   }, /*  is whitespace char 10 (lf) */
807     { "\01353",               53   }, /*  is whitespace char 11 (vt) */
808     { "\01454",               54   }, /*  is whitespace char 12 (ff) */
809     { "\01555",               55   }, /*  is whitespace char 13 (cr) */
810     { "\01656",                0   }, /* not whitespace char 14 */
811     { "\01757",                0   }, /* not whitespace char 15 */
812     { "\02060",                0   }, /* not whitespace char 16 */
813     { "\02161",                0   }, /* not whitespace char 17 */
814     { "\02262",                0   }, /* not whitespace char 18 */
815     { "\02363",                0   }, /* not whitespace char 19 */
816     { "\02464",                0   }, /* not whitespace char 20 */
817     { "\02565",                0   }, /* not whitespace char 21 */
818     { "\02666",                0   }, /* not whitespace char 22 */
819     { "\02767",                0   }, /* not whitespace char 23 */
820     { "\03070",                0   }, /* not whitespace char 24 */
821     { "\03171",                0   }, /* not whitespace char 25 */
822     { "\03272",                0   }, /* not whitespace char 26 */
823     { "\03373",                0   }, /* not whitespace char 27 */
824     { "\03474",                0   }, /* not whitespace char 28 */
825     { "\03575",                0   }, /* not whitespace char 29 */
826     { "\03676",                0   }, /* not whitespace char 30 */
827     { "\03777",                0   }, /* not whitespace char 31 */
828     { "\04080",               80   }, /*  is whitespace char 32 (space) */
829     { " \n \r \t214",        214   },
830     { " \n \r \t+214",       214   }, /* Signs can be used after whitespace */
831     { " \n \r \t-214",      -214   },
832     { "+214 0",              214   }, /* Space terminates the number */
833     { " 214.01",             214   }, /* Decimal point not accepted */
834     { " 214,01",             214   }, /* Decimal comma not accepted */
835     { "f81",                   0   },
836     { "0x12345",               0   }, /* Hex not accepted */
837     { "00x12345",              0   },
838     { "0xx12345",              0   },
839     { "1x34",                  1   },
840     { "-9999999999", -1410065407   }, /* Big negative integer */
841     { "-2147483649",  2147483647   }, /* Too small to fit in 32 Bits */
842     { "-2147483648",  0x80000000   }, /* Smallest negative integer */
843     { "-2147483647", -2147483647   },
844     { "-1",                   -1   },
845     { "0",                     0   },
846     { "1",                     1   },
847     { "2147483646",   2147483646   },
848     { "2147483647",   2147483647   }, /* Largest signed positive integer */
849     { "2147483648",   2147483648UL }, /* Positive int equal to smallest negative int */
850     { "2147483649",   2147483649UL },
851     { "4294967294",   4294967294UL },
852     { "4294967295",   4294967295UL }, /* Largest unsigned integer */
853     { "4294967296",            0   }, /* Too big to fit in 32 Bits */
854     { "9999999999",   1410065407   }, /* Big positive integer */
855     { "056789",            56789   }, /* Leading zero and still decimal */
856     { "b1011101100",           0   }, /* Binary (b-notation) */
857     { "-b1011101100",          0   }, /* Negative Binary (b-notation) */
858     { "b10123456789",          0   }, /* Binary with nonbinary digits (2-9) */
859     { "0b1011101100",          0   }, /* Binary (0b-notation) */
860     { "-0b1011101100",         0   }, /* Negative binary (0b-notation) */
861     { "0b10123456789",         0   }, /* Binary with nonbinary digits (2-9) */
862     { "-0b10123456789",        0   }, /* Negative binary with nonbinary digits (2-9) */
863     { "0b1",                   0   }, /* one digit binary */
864     { "0b2",                   0   }, /* empty binary */
865     { "0b",                    0   }, /* empty binary */
866     { "o1234567",              0   }, /* Octal (o-notation) */
867     { "-o1234567",             0   }, /* Negative Octal (o-notation) */
868     { "o56789",                0   }, /* Octal with nonoctal digits (8 and 9) */
869     { "0o1234567",             0   }, /* Octal (0o-notation) */
870     { "-0o1234567",            0   }, /* Negative octal (0o-notation) */
871     { "0o56789",               0   }, /* Octal with nonoctal digits (8 and 9) */
872     { "-0o56789",              0   }, /* Negative octal with nonoctal digits (8 and 9) */
873     { "0o7",                   0   }, /* one digit octal */
874     { "0o8",                   0   }, /* empty octal */
875     { "0o",                    0   }, /* empty octal */
876     { "0d1011101100",          0   }, /* explicit decimal with 0d */
877     { "x89abcdef",             0   }, /* Hex with lower case digits a-f (x-notation) */
878     { "xFEDCBA00",             0   }, /* Hex with upper case digits A-F (x-notation) */
879     { "-xFEDCBA00",            0   }, /* Negative Hexadecimal (x-notation) */
880     { "0x89abcdef",            0   }, /* Hex with lower case digits a-f (0x-notation) */
881     { "0xFEDCBA00",            0   }, /* Hex with upper case digits A-F (0x-notation) */
882     { "-0xFEDCBA00",           0   }, /* Negative Hexadecimal (0x-notation) */
883     { "0xabcdefgh",            0   }, /* Hex with illegal lower case digits (g-z) */
884     { "0xABCDEFGH",            0   }, /* Hex with illegal upper case digits (G-Z) */
885     { "0xF",                   0   }, /* one digit hexadecimal */
886     { "0xG",                   0   }, /* empty hexadecimal */
887     { "0x",                    0   }, /* empty hexadecimal */
888     { "",                      0   }, /* empty string */
889 /*  { NULL,                    0   }, */ /* NULL as string */
890 };
891 #define NB_STR2LONG (sizeof(str2long)/sizeof(*str2long))
892 
893 
894 static void test_wtoi(void)
895 {
896     int test_num;
897     UNICODE_STRING uni;
898     int result;
899 
900     for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
901 	pRtlCreateUnicodeStringFromAsciiz(&uni, str2long[test_num].str);
902 	result = p_wtoi(uni.Buffer);
903 	ok(result == str2long[test_num].value,
904            "(test %d): call failed: _wtoi(\"%s\") has result %d, expected: %d\n",
905 	   test_num, str2long[test_num].str, result, str2long[test_num].value);
906 	pRtlFreeUnicodeString(&uni);
907     } /* for */
908 }
909 
910 static void test_atoi(void)
911 {
912     int test_num;
913     int result;
914 
915     for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
916         result = patoi(str2long[test_num].str);
917         ok(result == str2long[test_num].value,
918            "(test %d): call failed: _atoi(\"%s\") has result %d, expected: %d\n",
919            test_num, str2long[test_num].str, result, str2long[test_num].value);
920     }
921 }
922 
923 static void test_atol(void)
924 {
925     int test_num;
926     int result;
927 
928     for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
929         result = patol(str2long[test_num].str);
930         ok(result == str2long[test_num].value,
931            "(test %d): call failed: _atol(\"%s\") has result %d, expected: %d\n",
932            test_num, str2long[test_num].str, result, str2long[test_num].value);
933     }
934 }
935 
936 static void test_wtol(void)
937 {
938     int test_num;
939     UNICODE_STRING uni;
940     LONG result;
941 
942     for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
943 	pRtlCreateUnicodeStringFromAsciiz(&uni, str2long[test_num].str);
944 	result = p_wtol(uni.Buffer);
945 	ok(result == str2long[test_num].value,
946            "(test %d): call failed: _wtol(\"%s\") has result %d, expected: %d\n",
947 	   test_num, str2long[test_num].str, result, str2long[test_num].value);
948 	pRtlFreeUnicodeString(&uni);
949     } /* for */
950 }
951 
952 
953 typedef struct {
954     const char *str;
955     LONGLONG value;
956     int overflow;
957 } str2longlong_t;
958 
959 static const str2longlong_t str2longlong[] = {
960     { "1011101100",   1011101100   },
961     { "1234567",         1234567   },
962     { "-214",               -214   },
963     { "+214",                214   }, /* The + sign is allowed also */
964     { "--214",                 0   }, /* Do not accept more than one sign */
965     { "-+214",                 0   },
966     { "++214",                 0   },
967     { "+-214",                 0   },
968     { "\00141",                0   }, /* not whitespace char  1 */
969     { "\00242",                0   }, /* not whitespace char  2 */
970     { "\00343",                0   }, /* not whitespace char  3 */
971     { "\00444",                0   }, /* not whitespace char  4 */
972     { "\00545",                0   }, /* not whitespace char  5 */
973     { "\00646",                0   }, /* not whitespace char  6 */
974     { "\00747",                0   }, /* not whitespace char  7 */
975     { "\01050",                0   }, /* not whitespace char  8 */
976     { "\01151",               51   }, /*  is whitespace char  9 (tab) */
977     { "\01252",               52   }, /*  is whitespace char 10 (lf) */
978     { "\01353",               53   }, /*  is whitespace char 11 (vt) */
979     { "\01454",               54   }, /*  is whitespace char 12 (ff) */
980     { "\01555",               55   }, /*  is whitespace char 13 (cr) */
981     { "\01656",                0   }, /* not whitespace char 14 */
982     { "\01757",                0   }, /* not whitespace char 15 */
983     { "\02060",                0   }, /* not whitespace char 16 */
984     { "\02161",                0   }, /* not whitespace char 17 */
985     { "\02262",                0   }, /* not whitespace char 18 */
986     { "\02363",                0   }, /* not whitespace char 19 */
987     { "\02464",                0   }, /* not whitespace char 20 */
988     { "\02565",                0   }, /* not whitespace char 21 */
989     { "\02666",                0   }, /* not whitespace char 22 */
990     { "\02767",                0   }, /* not whitespace char 23 */
991     { "\03070",                0   }, /* not whitespace char 24 */
992     { "\03171",                0   }, /* not whitespace char 25 */
993     { "\03272",                0   }, /* not whitespace char 26 */
994     { "\03373",                0   }, /* not whitespace char 27 */
995     { "\03474",                0   }, /* not whitespace char 28 */
996     { "\03575",                0   }, /* not whitespace char 29 */
997     { "\03676",                0   }, /* not whitespace char 30 */
998     { "\03777",                0   }, /* not whitespace char 31 */
999     { "\04080",               80   }, /*  is whitespace char 32 (space) */
1000     { " \n \r \t214",        214   },
1001     { " \n \r \t+214",       214   }, /* Signs can be used after whitespace */
1002     { " \n \r \t-214",      -214   },
1003     { "+214 0",              214   }, /* Space terminates the number */
1004     { " 214.01",             214   }, /* Decimal point not accepted */
1005     { " 214,01",             214   }, /* Decimal comma not accepted */
1006     { "f81",                   0   },
1007     { "0x12345",               0   }, /* Hex not accepted */
1008     { "00x12345",              0   },
1009     { "0xx12345",              0   },
1010     { "1x34",                  1   },
1011     { "-99999999999999999999", -ULL(0x6bc75e2d,0x630fffff), -1 }, /* Big negative integer */
1012     { "-9223372036854775809",   ULL(0x7fffffff,0xffffffff), -1 }, /* Too small to fit in 64 bits */
1013     { "-9223372036854775808",   ULL(0x80000000,0x00000000) }, /* Smallest negative 64 bit integer */
1014     { "-9223372036854775807",  -ULL(0x7fffffff,0xffffffff) },
1015     { "-9999999999",           -ULL(0x00000002,0x540be3ff) },
1016     { "-2147483649",           -ULL(0x00000000,0x80000001) }, /* Too small to fit in 32 bits */
1017     { "-2147483648",           -ULL(0x00000000,0x80000000) }, /* Smallest 32 bits negative integer */
1018     { "-2147483647",                           -2147483647 },
1019     { "-1",                                             -1 },
1020     { "0",                                               0 },
1021     { "1",                                               1 },
1022     { "2147483646",                             2147483646 },
1023     { "2147483647",                             2147483647 }, /* Largest signed positive 32 bit integer */
1024     { "2147483648",             ULL(0x00000000,0x80000000) }, /* Pos int equal to smallest neg 32 bit int */
1025     { "2147483649",             ULL(0x00000000,0x80000001) },
1026     { "4294967294",             ULL(0x00000000,0xfffffffe) },
1027     { "4294967295",             ULL(0x00000000,0xffffffff) }, /* Largest unsigned 32 bit integer */
1028     { "4294967296",             ULL(0x00000001,0x00000000) }, /* Too big to fit in 32 Bits */
1029     { "9999999999",             ULL(0x00000002,0x540be3ff) },
1030     { "9223372036854775806",    ULL(0x7fffffff,0xfffffffe) },
1031     { "9223372036854775807",    ULL(0x7fffffff,0xffffffff) }, /* Largest signed positive 64 bit integer */
1032     { "9223372036854775808",    ULL(0x80000000,0x00000000), 1 }, /* Pos int equal to smallest neg 64 bit int */
1033     { "9223372036854775809",    ULL(0x80000000,0x00000001), 1 },
1034     { "18446744073709551614",   ULL(0xffffffff,0xfffffffe), 1 },
1035     { "18446744073709551615",   ULL(0xffffffff,0xffffffff), 1 }, /* Largest unsigned 64 bit integer */
1036     { "18446744073709551616",                            0, 1 }, /* Too big to fit in 64 bits */
1037     { "99999999999999999999",   ULL(0x6bc75e2d,0x630fffff), 1 }, /* Big positive integer */
1038     { "056789",            56789   }, /* Leading zero and still decimal */
1039     { "b1011101100",           0   }, /* Binary (b-notation) */
1040     { "-b1011101100",          0   }, /* Negative Binary (b-notation) */
1041     { "b10123456789",          0   }, /* Binary with nonbinary digits (2-9) */
1042     { "0b1011101100",          0   }, /* Binary (0b-notation) */
1043     { "-0b1011101100",         0   }, /* Negative binary (0b-notation) */
1044     { "0b10123456789",         0   }, /* Binary with nonbinary digits (2-9) */
1045     { "-0b10123456789",        0   }, /* Negative binary with nonbinary digits (2-9) */
1046     { "0b1",                   0   }, /* one digit binary */
1047     { "0b2",                   0   }, /* empty binary */
1048     { "0b",                    0   }, /* empty binary */
1049     { "o1234567",              0   }, /* Octal (o-notation) */
1050     { "-o1234567",             0   }, /* Negative Octal (o-notation) */
1051     { "o56789",                0   }, /* Octal with nonoctal digits (8 and 9) */
1052     { "0o1234567",             0   }, /* Octal (0o-notation) */
1053     { "-0o1234567",            0   }, /* Negative octal (0o-notation) */
1054     { "0o56789",               0   }, /* Octal with nonoctal digits (8 and 9) */
1055     { "-0o56789",              0   }, /* Negative octal with nonoctal digits (8 and 9) */
1056     { "0o7",                   0   }, /* one digit octal */
1057     { "0o8",                   0   }, /* empty octal */
1058     { "0o",                    0   }, /* empty octal */
1059     { "0d1011101100",          0   }, /* explicit decimal with 0d */
1060     { "x89abcdef",             0   }, /* Hex with lower case digits a-f (x-notation) */
1061     { "xFEDCBA00",             0   }, /* Hex with upper case digits A-F (x-notation) */
1062     { "-xFEDCBA00",            0   }, /* Negative Hexadecimal (x-notation) */
1063     { "0x89abcdef",            0   }, /* Hex with lower case digits a-f (0x-notation) */
1064     { "0xFEDCBA00",            0   }, /* Hex with upper case digits A-F (0x-notation) */
1065     { "-0xFEDCBA00",           0   }, /* Negative Hexadecimal (0x-notation) */
1066     { "0xabcdefgh",            0   }, /* Hex with illegal lower case digits (g-z) */
1067     { "0xABCDEFGH",            0   }, /* Hex with illegal upper case digits (G-Z) */
1068     { "0xF",                   0   }, /* one digit hexadecimal */
1069     { "0xG",                   0   }, /* empty hexadecimal */
1070     { "0x",                    0   }, /* empty hexadecimal */
1071     { "",                      0   }, /* empty string */
1072 /*  { NULL,                    0   }, */ /* NULL as string */
1073 };
1074 #define NB_STR2LONGLONG (sizeof(str2longlong)/sizeof(*str2longlong))
1075 
1076 
1077 static void test_atoi64(void)
1078 {
1079     int test_num;
1080     LONGLONG result;
1081 
1082     for (test_num = 0; test_num < NB_STR2LONGLONG; test_num++) {
1083 	result = p_atoi64(str2longlong[test_num].str);
1084         if (str2longlong[test_num].overflow)
1085             ok(result == str2longlong[test_num].value ||
1086                (result == ((str2longlong[test_num].overflow == -1) ?
1087                 ULL(0x80000000,0x00000000) : ULL(0x7fffffff,0xffffffff))),
1088                "(test %d): call failed: _atoi64(\"%s\") has result 0x%x%08x, expected: 0x%x%08x\n",
1089                test_num, str2longlong[test_num].str, (DWORD)(result >> 32), (DWORD)result,
1090                (DWORD)(str2longlong[test_num].value >> 32), (DWORD)str2longlong[test_num].value);
1091         else
1092             ok(result == str2longlong[test_num].value,
1093                "(test %d): call failed: _atoi64(\"%s\") has result 0x%x%08x, expected: 0x%x%08x\n",
1094                test_num, str2longlong[test_num].str, (DWORD)(result >> 32), (DWORD)result,
1095                (DWORD)(str2longlong[test_num].value >> 32), (DWORD)str2longlong[test_num].value);
1096     }
1097 }
1098 
1099 
1100 static void test_wtoi64(void)
1101 {
1102     int test_num;
1103     UNICODE_STRING uni;
1104     LONGLONG result;
1105 
1106     for (test_num = 0; test_num < NB_STR2LONGLONG; test_num++) {
1107 	pRtlCreateUnicodeStringFromAsciiz(&uni, str2longlong[test_num].str);
1108 	result = p_wtoi64(uni.Buffer);
1109         if (str2longlong[test_num].overflow)
1110             ok(result == str2longlong[test_num].value ||
1111                (result == ((str2longlong[test_num].overflow == -1) ?
1112                 ULL(0x80000000,0x00000000) : ULL(0x7fffffff,0xffffffff))),
1113                "(test %d): call failed: _atoi64(\"%s\") has result 0x%x%08x, expected: 0x%x%08x\n",
1114                test_num, str2longlong[test_num].str, (DWORD)(result >> 32), (DWORD)result,
1115                (DWORD)(str2longlong[test_num].value >> 32), (DWORD)str2longlong[test_num].value);
1116         else
1117             ok(result == str2longlong[test_num].value,
1118                "(test %d): call failed: _atoi64(\"%s\") has result 0x%x%08x, expected: 0x%x%08x\n",
1119                test_num, str2longlong[test_num].str, (DWORD)(result >> 32), (DWORD)result,
1120                (DWORD)(str2longlong[test_num].value >> 32), (DWORD)str2longlong[test_num].value);
1121 	pRtlFreeUnicodeString(&uni);
1122     }
1123 }
1124 
1125 static void test_wcschr(void)
1126 {
1127     static const WCHAR teststringW[] = {'a','b','r','a','c','a','d','a','b','r','a',0};
1128 
1129     ok(p_wcschr(teststringW, 'a') == teststringW + 0,
1130        "wcschr should have returned a pointer to the first 'a' character\n");
1131     ok(p_wcschr(teststringW, 0) == teststringW + 11,
1132        "wcschr should have returned a pointer to the null terminator\n");
1133     ok(p_wcschr(teststringW, 'x') == NULL,
1134        "wcschr should have returned NULL\n");
1135 }
1136 
1137 static void test_wcsrchr(void)
1138 {
1139     static const WCHAR teststringW[] = {'a','b','r','a','c','a','d','a','b','r','a',0};
1140 
1141     ok(p_wcsrchr(teststringW, 'a') == teststringW + 10,
1142        "wcsrchr should have returned a pointer to the last 'a' character\n");
1143     ok(p_wcsrchr(teststringW, 0) == teststringW + 11,
1144        "wcsrchr should have returned a pointer to the null terminator\n");
1145     ok(p_wcsrchr(teststringW, 'x') == NULL,
1146        "wcsrchr should have returned NULL\n");
1147 }
1148 
1149 static void test_wcslwrupr(void)
1150 {
1151     static WCHAR teststringW[] = {'a','b','r','a','c','a','d','a','b','r','a',0};
1152     static WCHAR emptyW[] = {0};
1153     static const WCHAR constemptyW[] = {0};
1154 
1155     if (0) /* crashes on native */
1156     {
1157         static const WCHAR conststringW[] = {'a','b','r','a','c','a','d','a','b','r','a',0};
1158         ok(p_wcslwr((LPWSTR)conststringW) == conststringW, "p_wcslwr returned different string\n");
1159         ok(p_wcsupr((LPWSTR)conststringW) == conststringW, "p_wcsupr returned different string\n");
1160         ok(p_wcslwr(NULL) == NULL, "p_wcslwr didn't returned NULL\n");
1161         ok(p_wcsupr(NULL) == NULL, "p_wcsupr didn't returned NULL\n");
1162     }
1163     ok(p_wcslwr(teststringW) == teststringW, "p_wcslwr returned different string\n");
1164     ok(p_wcsupr(teststringW) == teststringW, "p_wcsupr returned different string\n");
1165     ok(p_wcslwr(emptyW) == emptyW, "p_wcslwr returned different string\n");
1166     ok(p_wcsupr(emptyW) == emptyW, "p_wcsupr returned different string\n");
1167     ok(p_wcslwr((LPWSTR)constemptyW) == constemptyW, "p_wcslwr returned different string\n");
1168     ok(p_wcsupr((LPWSTR)constemptyW) == constemptyW, "p_wcsupr returned different string\n");
1169 }
1170 
1171 static int __cdecl intcomparefunc(const void *a, const void *b)
1172 {
1173     const int *p = a, *q = b;
1174 
1175     ok (a != b, "must never get the same pointer\n");
1176 
1177     return *p - *q;
1178 }
1179 
1180 static int __cdecl charcomparefunc(const void *a, const void *b)
1181 {
1182     const char *p = a, *q = b;
1183 
1184     ok (a != b, "must never get the same pointer\n");
1185 
1186     return *p - *q;
1187 }
1188 
1189 static int __cdecl strcomparefunc(const void *a, const void *b)
1190 {
1191     const char * const *p = a;
1192     const char * const *q = b;
1193 
1194     ok (a != b, "must never get the same pointer\n");
1195 
1196     return lstrcmpA(*p, *q);
1197 }
1198 
1199 static void test_qsort(void)
1200 {
1201     int arr[5] = { 23, 42, 8, 4, 16 };
1202     char carr[5] = { 42, 23, 4, 8, 16 };
1203     const char *strarr[7] = {
1204 	"Hello",
1205 	"Wine",
1206 	"World",
1207 	"!",
1208 	"Hopefully",
1209 	"Sorted",
1210 	"."
1211     };
1212 
1213     p_qsort ((void*)arr, 0, sizeof(int), intcomparefunc);
1214     ok(arr[0] == 23, "badly sorted, nmemb=0, arr[0] is %d\n", arr[0]);
1215     ok(arr[1] == 42, "badly sorted, nmemb=0, arr[1] is %d\n", arr[1]);
1216     ok(arr[2] == 8,  "badly sorted, nmemb=0, arr[2] is %d\n", arr[2]);
1217     ok(arr[3] == 4,  "badly sorted, nmemb=0, arr[3] is %d\n", arr[3]);
1218     ok(arr[4] == 16, "badly sorted, nmemb=0, arr[4] is %d\n", arr[4]);
1219 
1220     p_qsort ((void*)arr, 1, sizeof(int), intcomparefunc);
1221     ok(arr[0] == 23, "badly sorted, nmemb=1, arr[0] is %d\n", arr[0]);
1222     ok(arr[1] == 42, "badly sorted, nmemb=1, arr[1] is %d\n", arr[1]);
1223     ok(arr[2] == 8,  "badly sorted, nmemb=1, arr[2] is %d\n", arr[2]);
1224     ok(arr[3] == 4,  "badly sorted, nmemb=1, arr[3] is %d\n", arr[3]);
1225     ok(arr[4] == 16, "badly sorted, nmemb=1, arr[4] is %d\n", arr[4]);
1226 
1227     p_qsort ((void*)arr, 5, 0, intcomparefunc);
1228     ok(arr[0] == 23, "badly sorted, size=0, arr[0] is %d\n", arr[0]);
1229     ok(arr[1] == 42, "badly sorted, size=0, arr[1] is %d\n", arr[1]);
1230     ok(arr[2] == 8,  "badly sorted, size=0, arr[2] is %d\n", arr[2]);
1231     ok(arr[3] == 4,  "badly sorted, size=0, arr[3] is %d\n", arr[3]);
1232     ok(arr[4] == 16, "badly sorted, size=0, arr[4] is %d\n", arr[4]);
1233 
1234     p_qsort ((void*)arr, 5, sizeof(int), intcomparefunc);
1235     ok(arr[0] == 4,  "badly sorted, arr[0] is %d\n", arr[0]);
1236     ok(arr[1] == 8,  "badly sorted, arr[1] is %d\n", arr[1]);
1237     ok(arr[2] == 16, "badly sorted, arr[2] is %d\n", arr[2]);
1238     ok(arr[3] == 23, "badly sorted, arr[3] is %d\n", arr[3]);
1239     ok(arr[4] == 42, "badly sorted, arr[4] is %d\n", arr[4]);
1240 
1241     p_qsort ((void*)carr, 5, sizeof(char), charcomparefunc);
1242     ok(carr[0] == 4,  "badly sorted, carr[0] is %d\n", carr[0]);
1243     ok(carr[1] == 8,  "badly sorted, carr[1] is %d\n", carr[1]);
1244     ok(carr[2] == 16, "badly sorted, carr[2] is %d\n", carr[2]);
1245     ok(carr[3] == 23, "badly sorted, carr[3] is %d\n", carr[3]);
1246     ok(carr[4] == 42, "badly sorted, carr[4] is %d\n", carr[4]);
1247 
1248     p_qsort ((void*)strarr, 7, sizeof(char*), strcomparefunc);
1249     ok(!strcmp(strarr[0],"!"),  "badly sorted, strarr[0] is %s\n", strarr[0]);
1250     ok(!strcmp(strarr[1],"."),  "badly sorted, strarr[1] is %s\n", strarr[1]);
1251     ok(!strcmp(strarr[2],"Hello"),  "badly sorted, strarr[2] is %s\n", strarr[2]);
1252     ok(!strcmp(strarr[3],"Hopefully"),  "badly sorted, strarr[3] is %s\n", strarr[3]);
1253     ok(!strcmp(strarr[4],"Sorted"),  "badly sorted, strarr[4] is %s\n", strarr[4]);
1254     ok(!strcmp(strarr[5],"Wine"),  "badly sorted, strarr[5] is %s\n", strarr[5]);
1255     ok(!strcmp(strarr[6],"World"),  "badly sorted, strarr[6] is %s\n", strarr[6]);
1256 }
1257 
1258 static void test_bsearch(void)
1259 {
1260     int arr[7] = { 1, 3, 4, 8, 16, 23, 42 };
1261     int *x, l, i, j;
1262 
1263     /* just try all array sizes */
1264     for (j=1;j<sizeof(arr)/sizeof(arr[0]);j++) {
1265         for (i=0;i<j;i++) {
1266             l = arr[i];
1267             x = p_bsearch (&l, arr, j, sizeof(arr[0]), intcomparefunc);
1268             ok (x == &arr[i], "bsearch did not find %d entry in loopsize %d.\n", i, j);
1269         }
1270         l = 4242;
1271         x = p_bsearch (&l, arr, j, sizeof(arr[0]), intcomparefunc);
1272         ok (x == NULL, "bsearch did find 4242 entry in loopsize %d.\n", j);
1273     }
1274 }
1275 
1276 static void test__snprintf(void)
1277 {
1278     const char *origstring = "XXXXXXXXXXXX";
1279     const char *teststring = "hello world";
1280     char buffer[32];
1281     int res;
1282 
1283     res = p__snprintf(NULL, 0, teststring);
1284     ok(res == lstrlenA(teststring) || broken(res == -1) /* <= w2k */,
1285        "_snprintf returned %d, expected %d.\n", res, lstrlenA(teststring));
1286 
1287     if (res != -1)
1288     {
1289         res = p__snprintf(NULL, 1, teststring);
1290         ok(res == lstrlenA(teststring) /* WinXP */ || res < 0 /* Vista and greater */,
1291            "_snprintf returned %d, expected %d or < 0.\n", res, lstrlenA(teststring));
1292     }
1293     res = p__snprintf(buffer, strlen(teststring) - 1, teststring);
1294     ok(res < 0, "_snprintf returned %d, expected < 0.\n", res);
1295 
1296     strcpy(buffer,  origstring);
1297     res = p__snprintf(buffer, strlen(teststring), teststring);
1298     ok(res == lstrlenA(teststring), "_snprintf returned %d, expected %d.\n", res, lstrlenA(teststring));
1299     ok(!strcmp(buffer, "hello worldX"), "_snprintf returned buffer '%s', expected 'hello worldX'.\n", buffer);
1300 
1301     strcpy(buffer, origstring);
1302     res = p__snprintf(buffer, strlen(teststring) + 1, teststring);
1303     ok(res == lstrlenA(teststring), "_snprintf returned %d, expected %d.\n", res, lstrlenA(teststring));
1304     ok(!strcmp(buffer, teststring), "_snprintf returned buffer '%s', expected '%s'.\n", buffer, teststring);
1305 }
1306 
1307 START_TEST(string)
1308 {
1309     InitFunctionPtrs();
1310 
1311     if (p_ultoa)
1312         test_ulongtoa();
1313     if (p_ui64toa)
1314         test_ulonglongtoa();
1315     if (p_atoi64)
1316         test_atoi64();
1317     if (p_ultow)
1318         test_ulongtow();
1319     if (p_ui64tow)
1320         test_ulonglongtow();
1321     if (p_wtoi)
1322         test_wtoi();
1323     if (p_wtol)
1324         test_wtol();
1325     if (p_wtoi64)
1326         test_wtoi64();
1327     if (p_wcschr)
1328         test_wcschr();
1329     if (p_wcsrchr)
1330         test_wcsrchr();
1331     if (p_wcslwr && p_wcsupr)
1332         test_wcslwrupr();
1333     if (patoi)
1334         test_atoi();
1335     if (patol)
1336         test_atol();
1337     if (p_qsort)
1338         test_qsort();
1339     if (p_bsearch)
1340         test_bsearch();
1341     if (p__snprintf)
1342         test__snprintf();
1343 }
1344