1 /*
2  * Unit test suite for string functions.
3  *
4  * Copyright 2004 Uwe Bonnes
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 
21 #include "wine/test.h"
22 #include <string.h>
23 #include <mbstring.h>
24 #include <wchar.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <mbctype.h>
28 #include <locale.h>
29 #include <errno.h>
30 #include <limits.h>
31 #include <math.h>
32 
33 /* make it use a definition from string.h */
34 #undef strncpy
35 #include "winbase.h"
36 #include "winnls.h"
37 
38 static char *buf_to_string(const unsigned char *bin, int len, int nr)
39 {
40     static char buf[2][1024];
41     char *w = buf[nr];
42     int i;
43 
44     for (i = 0; i < len; i++)
45     {
46         sprintf(w, "%02x ", (unsigned char)bin[i]);
47         w += strlen(w);
48     }
49     return buf[nr];
50 }
51 
52 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
53 #define expect_bin(buf, value, len) { ok(memcmp((buf), value, len) == 0, "Binary buffer mismatch - expected %s, got %s\n", buf_to_string((unsigned char *)value, len, 1), buf_to_string((buf), len, 0)); }
54 
55 static void* (__cdecl *pmemcpy)(void *, const void *, size_t n);
56 static int (__cdecl *p_memcpy_s)(void *, size_t, const void *, size_t);
57 static int (__cdecl *p_memmove_s)(void *, size_t, const void *, size_t);
58 static int* (__cdecl *pmemcmp)(void *, const void *, size_t n);
59 static int (__cdecl *p_strcpy)(char *dst, const char *src);
60 static int (__cdecl *pstrcpy_s)(char *dst, size_t len, const char *src);
61 static int (__cdecl *pstrcat_s)(char *dst, size_t len, const char *src);
62 static int (__cdecl *p_mbscat_s)(unsigned char *dst, size_t size, const unsigned char *src);
63 static int (__cdecl *p_mbsnbcat_s)(unsigned char *dst, size_t size, const unsigned char *src, size_t count);
64 static int (__cdecl *p_mbsnbcpy_s)(unsigned char * dst, size_t size, const unsigned char * src, size_t count);
65 static int (__cdecl *p__mbscpy_s)(unsigned char*, size_t, const unsigned char*);
66 static int (__cdecl *p_wcscpy_s)(wchar_t *wcDest, size_t size, const wchar_t *wcSrc);
67 static int (__cdecl *p_wcsncpy_s)(wchar_t *wcDest, size_t size, const wchar_t *wcSrc, size_t count);
68 static int (__cdecl *p_wcsncat_s)(wchar_t *dst, size_t elem, const wchar_t *src, size_t count);
69 static int (__cdecl *p_wcsupr_s)(wchar_t *str, size_t size);
70 static size_t (__cdecl *p_strnlen)(const char *, size_t);
71 static __int64 (__cdecl *p_strtoi64)(const char *, char **, int);
72 static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int);
73 static __int64 (__cdecl *p_wcstoi64)(const wchar_t *, wchar_t **, int);
74 static unsigned __int64 (__cdecl *p_wcstoui64)(const wchar_t *, wchar_t **, int);
75 static int (__cdecl *pwcstombs_s)(size_t*,char*,size_t,const wchar_t*,size_t);
76 static int (__cdecl *pmbstowcs_s)(size_t*,wchar_t*,size_t,const char*,size_t);
77 static size_t (__cdecl *p_mbsrtowcs)(wchar_t*, const char**, size_t, mbstate_t*);
78 static int (__cdecl *p_mbsrtowcs_s)(size_t*,wchar_t*,size_t,const char**,size_t,mbstate_t*);
79 static size_t (__cdecl *pwcsrtombs)(char*, const wchar_t**, size_t, int*);
80 static errno_t (__cdecl *p_gcvt_s)(char*,size_t,double,int);
81 static errno_t (__cdecl *p_itoa_s)(int,char*,size_t,int);
82 static errno_t (__cdecl *p_strlwr_s)(char*,size_t);
83 static errno_t (__cdecl *p_ultoa_s)(__msvcrt_ulong,char*,size_t,int);
84 static int *p__mb_cur_max;
85 static unsigned char *p_mbctype;
86 static int (__cdecl *p_wcslwr_s)(wchar_t*,size_t);
87 static errno_t (__cdecl *p_mbsupr_s)(unsigned char *str, size_t numberOfElements);
88 static errno_t (__cdecl *p_mbslwr_s)(unsigned char *str, size_t numberOfElements);
89 static int (__cdecl *p_wctob)(wint_t);
90 static size_t (__cdecl *p_wcrtomb)(char*, wchar_t, mbstate_t*);
91 static int (__cdecl *p_tolower)(int);
92 static int (__cdecl *p_towlower)(wint_t);
93 static int (__cdecl *p__towlower_l)(wint_t, _locale_t);
94 static int (__cdecl *p_towupper)(wint_t);
95 static int (__cdecl *p__towupper_l)(wint_t, _locale_t);
96 static _locale_t(__cdecl *p__create_locale)(int, const char*);
97 static void(__cdecl *p__free_locale)(_locale_t);
98 static size_t (__cdecl *p_mbrlen)(const char*, size_t, mbstate_t*);
99 static size_t (__cdecl *p_mbrtowc)(wchar_t*, const char*, size_t, mbstate_t*);
100 static int (__cdecl *p__atodbl_l)(_CRT_DOUBLE*,char*,_locale_t);
101 static double (__cdecl *p__atof_l)(const char*,_locale_t);
102 static double (__cdecl *p__strtod_l)(const char *,char**,_locale_t);
103 static int (__cdecl *p__strnset_s)(char*,size_t,int,size_t);
104 static int (__cdecl *p__wcsset_s)(wchar_t*,size_t,wchar_t);
105 static size_t (__cdecl *p__mbsnlen)(const unsigned char*, size_t);
106 static int (__cdecl *p__mbccpy_s)(unsigned char*, size_t, int*, const unsigned char*);
107 static int (__cdecl *p__memicmp)(const char*, const char*, size_t);
108 static int (__cdecl *p__memicmp_l)(const char*, const char*, size_t, _locale_t);
109 static size_t (__cdecl *p___strncnt)(const char*, size_t);
110 
111 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y)
112 #define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y)
113 
114 static HMODULE hMsvcrt;
115 
116 static void test_swab( void ) {
117     char original[]  = "BADCFEHGJILKNMPORQTSVUXWZY@#";
118     char expected1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ@#";
119     char expected2[] = "ABCDEFGHIJKLMNOPQRSTUVWX$";
120     char expected3[] = "$";
121 
122     char from[30];
123     char to[30];
124 
125     int testsize;
126 
127     /* Test 1 - normal even case */
128     memset(to,'$', sizeof(to));
129     memset(from,'@', sizeof(from));
130     testsize = 26;
131     memcpy(from, original, testsize);
132     _swab( from, to, testsize );
133     ok(memcmp(to,expected1,testsize) == 0, "Testing even size %d returned '%*.*s'\n", testsize, testsize, testsize, to);
134 
135     /* Test 2 - uneven case  */
136     memset(to,'$', sizeof(to));
137     memset(from,'@', sizeof(from));
138     testsize = 25;
139     memcpy(from, original, testsize);
140     _swab( from, to, testsize );
141     ok(memcmp(to,expected2,testsize) == 0, "Testing odd size %d returned '%*.*s'\n", testsize, testsize, testsize, to);
142 
143     /* Test 3 - from = to */
144     memset(to,'$', sizeof(to));
145     memset(from,'@', sizeof(from));
146     testsize = 26;
147     memcpy(to, original, testsize);
148     _swab( to, to, testsize );
149     ok(memcmp(to,expected1,testsize) == 0, "Testing overlapped size %d returned '%*.*s'\n", testsize, testsize, testsize, to);
150 
151     /* Test 4 - 1 bytes */
152     memset(to,'$', sizeof(to));
153     memset(from,'@', sizeof(from));
154     testsize = 1;
155     memcpy(from, original, testsize);
156     _swab( from, to, testsize );
157     ok(memcmp(to,expected3,testsize) == 0, "Testing small size %d returned '%*.*s'\n", testsize, testsize, testsize, to);
158 }
159 
160 #if 0      /* use this to generate more tests */
161 
162 static void test_codepage(int cp)
163 {
164     int i;
165     int prev;
166     int count = 1;
167 
168     ok(_setmbcp(cp) == 0, "Couldn't set mbcp\n");
169 
170     prev = p_mbctype[0];
171     printf("static int result_cp_%d_mbctype[] = { ", cp);
172     for (i = 1; i < 257; i++)
173     {
174         if (p_mbctype[i] != prev)
175         {
176             printf("0x%x,%d, ", prev, count);
177             prev = p_mbctype[i];
178             count = 1;
179         }
180         else
181             count++;
182     }
183     printf("0x%x,%d };\n", prev, count);
184 }
185 
186 #else
187 
188 /* RLE-encoded mbctype tables for given codepages */
189 static int result_cp_932_mbctype[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,4,
190   0x0,1, 0x8,1, 0xc,31, 0x8,1, 0xa,5, 0x9,58, 0xc,29, 0,3 };
191 static int result_cp_936_mbctype[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,6,
192   0xc,126, 0,1 };
193 static int result_cp_949_mbctype[] = { 0x0,66, 0x18,26, 0x8,6, 0x28,26, 0x8,6, 0xc,126,
194   0,1 };
195 static int result_cp_950_mbctype[] = { 0x0,65, 0x8,1, 0x18,26, 0x8,6, 0x28,26, 0x8,4,
196   0x0,2, 0x4,32, 0xc,94, 0,1 };
197 
198 static void test_cp_table(int cp, int *result)
199 {
200     int i;
201     int count = 0;
202     int curr = 0;
203     _setmbcp(cp);
204     for (i = 0; i < 256; i++)
205     {
206         if (count == 0)
207         {
208             curr = result[0];
209             count = result[1];
210             result += 2;
211         }
212         ok(p_mbctype[i] == curr, "CP%d: Mismatch in ctype for character %d - %d instead of %d\n", cp, i-1, p_mbctype[i], curr);
213         count--;
214     }
215 }
216 
217 #define test_codepage(num) test_cp_table(num, result_cp_##num##_mbctype);
218 
219 #endif
220 
221 static void test_mbcp(void)
222 {
223     int mb_orig_max = *p__mb_cur_max;
224     int curr_mbcp = _getmbcp();
225     unsigned char *mbstring = (unsigned char *)"\xb0\xb1\xb2 \xb3\xb4 \xb5"; /* incorrect string */
226     unsigned char *mbstring2 = (unsigned char *)"\xb0\xb1\xb2\xb3Q\xb4\xb5"; /* correct string */
227     unsigned char *mbsonlylead = (unsigned char *)"\xb0\0\xb1\xb2 \xb3";
228     unsigned char buf[16];
229     int step;
230     CPINFO cp_info;
231 
232     /* _mbtype tests */
233 
234     /* An SBCS codepage test. The ctype of characters on e.g. CP1252 or CP1250 differs slightly
235      * between versions of Windows. Also Windows 9x seems to ignore the codepage and always uses
236      * CP1252 (or the ACP?) so we test only a few ASCII characters */
237     _setmbcp(1252);
238     expect_eq(p_mbctype[10], 0, char, "%x");
239     expect_eq(p_mbctype[50], 0, char, "%x");
240     expect_eq(p_mbctype[66], _SBUP, char, "%x");
241     expect_eq(p_mbctype[100], _SBLOW, char, "%x");
242     expect_eq(p_mbctype[128], 0, char, "%x");
243     _setmbcp(1250);
244     expect_eq(p_mbctype[10], 0, char, "%x");
245     expect_eq(p_mbctype[50], 0, char, "%x");
246     expect_eq(p_mbctype[66], _SBUP, char, "%x");
247     expect_eq(p_mbctype[100], _SBLOW, char, "%x");
248     expect_eq(p_mbctype[128], 0, char, "%x");
249 
250     /* double byte code pages */
251     test_codepage(932);
252     test_codepage(936);
253     test_codepage(949);
254     test_codepage(950);
255 
256     _setmbcp(936);
257     ok(*p__mb_cur_max == mb_orig_max, "__mb_cur_max shouldn't be updated (is %d != %d)\n", *p__mb_cur_max, mb_orig_max);
258     ok(_ismbblead('\354'), "\354 should be a lead byte\n");
259     ok(_ismbblead(' ') == FALSE, "' ' should not be a lead byte\n");
260     ok(_ismbblead(0x1234b0), "0x1234b0 should not be a lead byte\n");
261     ok(_ismbblead(0x123420) == FALSE, "0x123420 should not be a lead byte\n");
262     ok(_ismbbtrail('\xb0'), "\xa0 should be a trail byte\n");
263     ok(_ismbbtrail(' ') == FALSE, "' ' should not be a trail byte\n");
264 
265     /* _ismbslead */
266     expect_eq(_ismbslead(mbstring, &mbstring[0]), -1, int, "%d");
267     expect_eq(_ismbslead(mbstring, &mbstring[1]), FALSE, int, "%d");
268     expect_eq(_ismbslead(mbstring, &mbstring[2]), -1, int, "%d");
269     expect_eq(_ismbslead(mbstring, &mbstring[3]), FALSE, int, "%d");
270     expect_eq(_ismbslead(mbstring, &mbstring[4]), -1, int, "%d");
271     expect_eq(_ismbslead(mbstring, &mbstring[5]), FALSE, int, "%d");
272     expect_eq(_ismbslead(mbstring, &mbstring[6]), FALSE, int, "%d");
273     expect_eq(_ismbslead(mbstring, &mbstring[7]), -1, int, "%d");
274     expect_eq(_ismbslead(mbstring, &mbstring[8]), FALSE, int, "%d");
275 
276     expect_eq(_ismbslead(mbsonlylead, &mbsonlylead[0]), -1, int, "%d");
277     expect_eq(_ismbslead(mbsonlylead, &mbsonlylead[1]), FALSE, int, "%d");
278     expect_eq(_ismbslead(mbsonlylead, &mbsonlylead[2]), FALSE, int, "%d");
279     expect_eq(_ismbslead(mbsonlylead, &mbsonlylead[5]), FALSE, int, "%d");
280 
281     /* _ismbstrail */
282     expect_eq(_ismbstrail(mbstring, &mbstring[0]), FALSE, int, "%d");
283     expect_eq(_ismbstrail(mbstring, &mbstring[1]), -1, int, "%d");
284     expect_eq(_ismbstrail(mbstring, &mbstring[2]), FALSE, int, "%d");
285     expect_eq(_ismbstrail(mbstring, &mbstring[3]), -1, int, "%d");
286     expect_eq(_ismbstrail(mbstring, &mbstring[4]), FALSE, int, "%d");
287     expect_eq(_ismbstrail(mbstring, &mbstring[5]), -1, int, "%d");
288     expect_eq(_ismbstrail(mbstring, &mbstring[6]), FALSE, int, "%d");
289     expect_eq(_ismbstrail(mbstring, &mbstring[7]), FALSE, int, "%d");
290     expect_eq(_ismbstrail(mbstring, &mbstring[8]), -1, int, "%d");
291 
292     expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[0]), FALSE, int, "%d");
293     expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[1]), -1, int, "%d");
294     expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[2]), FALSE, int, "%d");
295     expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[3]), FALSE, int, "%d");
296     expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[4]), FALSE, int, "%d");
297     expect_eq(_ismbstrail(mbsonlylead, &mbsonlylead[5]), FALSE, int, "%d");
298 
299     /* _mbsbtype */
300     expect_eq(_mbsbtype(mbstring, 0), _MBC_LEAD, int, "%d");
301     expect_eq(_mbsbtype(mbstring, 1), _MBC_TRAIL, int, "%d");
302     expect_eq(_mbsbtype(mbstring, 2), _MBC_LEAD, int, "%d");
303     expect_eq(_mbsbtype(mbstring, 3), _MBC_ILLEGAL, int, "%d");
304     expect_eq(_mbsbtype(mbstring, 4), _MBC_LEAD, int, "%d");
305     expect_eq(_mbsbtype(mbstring, 5), _MBC_TRAIL, int, "%d");
306     expect_eq(_mbsbtype(mbstring, 6), _MBC_SINGLE, int, "%d");
307     expect_eq(_mbsbtype(mbstring, 7), _MBC_LEAD, int, "%d");
308     expect_eq(_mbsbtype(mbstring, 8), _MBC_ILLEGAL, int, "%d");
309 
310     expect_eq(_mbsbtype(mbsonlylead, 0), _MBC_LEAD, int, "%d");
311     expect_eq(_mbsbtype(mbsonlylead, 1), _MBC_ILLEGAL, int, "%d");
312     expect_eq(_mbsbtype(mbsonlylead, 2), _MBC_ILLEGAL, int, "%d");
313     expect_eq(_mbsbtype(mbsonlylead, 3), _MBC_ILLEGAL, int, "%d");
314     expect_eq(_mbsbtype(mbsonlylead, 4), _MBC_ILLEGAL, int, "%d");
315     expect_eq(_mbsbtype(mbsonlylead, 5), _MBC_ILLEGAL, int, "%d");
316 
317     /* _mbsnextc */
318     expect_eq(_mbsnextc(mbstring), 0xb0b1, int, "%x");
319     expect_eq(_mbsnextc(&mbstring[2]), 0xb220, int, "%x");  /* lead + invalid tail */
320     expect_eq(_mbsnextc(&mbstring[3]), 0x20, int, "%x");    /* single char */
321 
322     /* _mbclen/_mbslen */
323     expect_eq(_mbclen(mbstring), 2, int, "%d");
324     expect_eq(_mbclen(&mbstring[2]), 2, int, "%d");
325     expect_eq(_mbclen(&mbstring[3]), 1, int, "%d");
326     expect_eq(_mbslen(mbstring2), 4, int, "%d");
327     expect_eq(_mbslen(mbsonlylead), 0, int, "%d");          /* lead + NUL not counted as character */
328     expect_eq(_mbslen(mbstring), 4, int, "%d");             /* lead + invalid trail counted */
329 
330     if(!p__mbsnlen) {
331         win_skip("_mbsnlen tests\n");
332     }else {
333         expect_eq(p__mbsnlen(mbstring, 8), 8, int, "%d");
334         expect_eq(p__mbsnlen(mbstring, 9), 4, int, "%d");
335         expect_eq(p__mbsnlen(mbstring, 10), 4, int, "%d");
336         expect_eq(p__mbsnlen(mbsonlylead, 0), 0, int, "%d");
337         expect_eq(p__mbsnlen(mbsonlylead, 1), 1, int, "%d");
338         expect_eq(p__mbsnlen(mbsonlylead, 2), 0, int, "%d");
339         expect_eq(p__mbsnlen(mbstring2, 7), 7, int, "%d");
340         expect_eq(p__mbsnlen(mbstring2, 8), 4, int, "%d");
341         expect_eq(p__mbsnlen(mbstring2, 9), 4, int, "%d");
342     }
343 
344     /* mbrlen */
345     if(!setlocale(LC_ALL, ".936") || !p_mbrlen) {
346         win_skip("mbrlen tests\n");
347     }else {
348         mbstate_t state = 0;
349         expect_eq(p_mbrlen((const char*)mbstring, 2, NULL), 2, int, "%d");
350         expect_eq(p_mbrlen((const char*)&mbstring[2], 2, NULL), 2, int, "%d");
351         expect_eq(p_mbrlen((const char*)&mbstring[3], 2, NULL), 1, int, "%d");
352         expect_eq(p_mbrlen((const char*)mbstring, 1, NULL), -2, int, "%d");
353         expect_eq(p_mbrlen((const char*)mbstring, 1, &state), -2, int, "%d");
354         ok(state == mbstring[0], "incorrect state value (%x)\n", state);
355         expect_eq(p_mbrlen((const char*)&mbstring[1], 1, &state), 2, int, "%d");
356     }
357 
358     /* mbrtowc */
359     if(!setlocale(LC_ALL, ".936") || !p_mbrtowc) {
360         win_skip("mbrtowc tests\n");
361     }else {
362         mbstate_t state = 0;
363         wchar_t dst;
364         expect_eq(p_mbrtowc(&dst, (const char*)mbstring, 2, NULL), 2, int, "%d");
365         ok(dst == 0x6c28, "dst = %x, expected 0x6c28\n", dst);
366         expect_eq(p_mbrtowc(&dst, (const char*)mbstring+2, 2, NULL), 2, int, "%d");
367         ok(dst == 0x3f, "dst = %x, expected 0x3f\n", dst);
368         expect_eq(p_mbrtowc(&dst, (const char*)mbstring+3, 2, NULL), 1, int, "%d");
369         ok(dst == 0x20, "dst = %x, expected 0x20\n", dst);
370         expect_eq(p_mbrtowc(&dst, (const char*)mbstring, 1, NULL), -2, int, "%d");
371         ok(dst == 0, "dst = %x, expected 0\n", dst);
372         expect_eq(p_mbrtowc(&dst, (const char*)mbstring, 1, &state), -2, int, "%d");
373         ok(dst == 0, "dst = %x, expected 0\n", dst);
374         ok(state == mbstring[0], "incorrect state value (%x)\n", state);
375         expect_eq(p_mbrtowc(&dst, (const char*)mbstring+1, 1, &state), 2, int, "%d");
376         ok(dst == 0x6c28, "dst = %x, expected 0x6c28\n", dst);
377         ok(state == 0, "incorrect state value (%x)\n", state);
378     }
379     setlocale(LC_ALL, "C");
380 
381     /* _mbccpy/_mbsncpy */
382     memset(buf, 0xff, sizeof(buf));
383     _mbccpy(buf, mbstring);
384     expect_bin(buf, "\xb0\xb1\xff", 3);
385 
386     if(!p__mbccpy_s) {
387         win_skip("_mbccpy_s tests\n");
388     }else {
389         int err, copied;
390 
391         memset(buf, 0xff, sizeof(buf));
392         copied = -1;
393         err = p__mbccpy_s(buf, 0, &copied, mbstring);
394         ok(err == EINVAL, "_mbccpy_s returned %d\n", err);
395         ok(!copied, "copied = %d\n", copied);
396         ok(buf[0] == 0xff, "buf[0] = %x\n", buf[0]);
397 
398         memset(buf, 0xff, sizeof(buf));
399         copied = -1;
400         err = p__mbccpy_s(buf, 1, &copied, mbstring);
401         ok(err == ERANGE, "_mbccpy_s returned %d\n", err);
402         ok(!copied, "copied = %d\n", copied);
403         ok(!buf[0], "buf[0] = %x\n", buf[0]);
404 
405         memset(buf, 0xff, sizeof(buf));
406         copied = -1;
407         err = p__mbccpy_s(buf, 2, &copied, mbstring);
408         ok(!err, "_mbccpy_s returned %d\n", err);
409         ok(copied == 2, "copied = %d\n", copied);
410         expect_bin(buf, "\xb0\xb1\xff", 3);
411 
412         memset(buf, 0xff, sizeof(buf));
413         copied = -1;
414         err = p__mbccpy_s(buf, 2, &copied, (unsigned char *)"\xb0");
415         ok(err == EILSEQ, "_mbccpy_s returned %d\n", err);
416         ok(copied == 1, "copied = %d\n", copied);
417         expect_bin(buf, "\x00\xff", 2);
418     }
419 
420     memset(buf, 0xff, sizeof(buf));
421     _mbsncpy(buf, mbstring, 1);
422     expect_bin(buf, "\xb0\xb1\xff", 3);
423     memset(buf, 0xff, sizeof(buf));
424     _mbsncpy(buf, mbstring, 2);
425     expect_bin(buf, "\xb0\xb1\xb2 \xff", 5);
426     memset(buf, 0xff, sizeof(buf));
427     _mbsncpy(buf, mbstring, 3);
428     expect_bin(buf, "\xb0\xb1\xb2 \xb3\xb4\xff", 7);
429     memset(buf, 0xff, sizeof(buf));
430     _mbsncpy(buf, mbstring, 4);
431     expect_bin(buf, "\xb0\xb1\xb2 \xb3\xb4 \xff", 8);
432     memset(buf, 0xff, sizeof(buf));
433     _mbsncpy(buf, mbstring, 5);
434     expect_bin(buf, "\xb0\xb1\xb2 \xb3\xb4 \0\0\xff", 10);
435     memset(buf, 0xff, sizeof(buf));
436     _mbsncpy(buf, mbsonlylead, 6);
437     expect_bin(buf, "\0\0\0\0\0\0\0\xff", 8);
438 
439     memset(buf, 0xff, sizeof(buf));
440     _mbsnbcpy(buf, mbstring2, 2);
441     expect_bin(buf, "\xb0\xb1\xff", 3);
442     _mbsnbcpy(buf, mbstring2, 3);
443     expect_bin(buf, "\xb0\xb1\0\xff", 4);
444     _mbsnbcpy(buf, mbstring2, 4);
445     expect_bin(buf, "\xb0\xb1\xb2\xb3\xff", 5);
446     memset(buf, 0xff, sizeof(buf));
447     _mbsnbcpy(buf, mbsonlylead, 5);
448     expect_bin(buf, "\0\0\0\0\0\xff", 6);
449 
450     /* _mbsinc/mbsdec */
451     step = _mbsinc(mbstring) - mbstring;
452     ok(step == 2, "_mbsinc adds %d (exp. 2)\n", step);
453     step = _mbsinc(&mbstring[2]) - &mbstring[2];  /* lead + invalid tail */
454     ok(step == 2, "_mbsinc adds %d (exp. 2)\n", step);
455 
456     step = _mbsninc(mbsonlylead, 1) - mbsonlylead;
457     ok(step == 0, "_mbsninc adds %d (exp. 0)\n", step);
458     step = _mbsninc(mbsonlylead, 2) - mbsonlylead;  /* lead + NUL byte + lead + char */
459     ok(step == 0, "_mbsninc adds %d (exp. 0)\n", step);
460     step = _mbsninc(mbstring2, 0) - mbstring2;
461     ok(step == 0, "_mbsninc adds %d (exp. 2)\n", step);
462     step = _mbsninc(mbstring2, 1) - mbstring2;
463     ok(step == 2, "_mbsninc adds %d (exp. 2)\n", step);
464     step = _mbsninc(mbstring2, 2) - mbstring2;
465     ok(step == 4, "_mbsninc adds %d (exp. 4)\n", step);
466     step = _mbsninc(mbstring2, 3) - mbstring2;
467     ok(step == 5, "_mbsninc adds %d (exp. 5)\n", step);
468     step = _mbsninc(mbstring2, 4) - mbstring2;
469     ok(step == 7, "_mbsninc adds %d (exp. 7)\n", step);
470     step = _mbsninc(mbstring2, 5) - mbstring2;
471     ok(step == 7, "_mbsninc adds %d (exp. 7)\n", step);
472     step = _mbsninc(mbstring2, 17) - mbstring2;
473     ok(step == 7, "_mbsninc adds %d (exp. 7)\n", step);
474 
475     /* functions that depend on locale codepage, not mbcp.
476      * we hope the current locale to be SBCS because setlocale(LC_ALL, ".1252") seems not to work yet
477      * (as of Wine 0.9.43)
478      */
479     GetCPInfo(GetACP(), &cp_info);
480     if (cp_info.MaxCharSize == 1)
481     {
482         expect_eq(mblen((char *)mbstring, 3), 1, int, "%x");
483         expect_eq(_mbstrlen((char *)mbstring2), 7, int, "%d");
484     }
485     else
486         skip("Current locale has double-byte charset - could lead to false positives\n");
487 
488     _setmbcp(1361);
489     expect_eq(_ismbblead(0x80), 0, int, "%d");
490     todo_wine {
491       expect_eq(_ismbblead(0x81), 1, int, "%d");
492       expect_eq(_ismbblead(0x83), 1, int, "%d");
493     }
494     expect_eq(_ismbblead(0x84), 1, int, "%d");
495     expect_eq(_ismbblead(0xd3), 1, int, "%d");
496     expect_eq(_ismbblead(0xd7), 0, int, "%d");
497     expect_eq(_ismbblead(0xd8), 1, int, "%d");
498     expect_eq(_ismbblead(0xd9), 1, int, "%d");
499 
500     expect_eq(_ismbbtrail(0x30), 0, int, "%d");
501     expect_eq(_ismbbtrail(0x31), 1, int, "%d");
502     expect_eq(_ismbbtrail(0x7e), 1, int, "%d");
503     expect_eq(_ismbbtrail(0x7f), 0, int, "%d");
504     expect_eq(_ismbbtrail(0x80), 0, int, "%d");
505     expect_eq(_ismbbtrail(0x81), 1, int, "%d");
506     expect_eq(_ismbbtrail(0xfe), 1, int, "%d");
507     expect_eq(_ismbbtrail(0xff), 0, int, "%d");
508 
509     _setmbcp(curr_mbcp);
510 }
511 
512 static void test_mbsspn( void)
513 {
514     unsigned char str1[]="cabernet";
515     unsigned char str2[]="shiraz";
516     unsigned char set[]="abc";
517     unsigned char empty[]="";
518     int ret;
519     ret=_mbsspn( str1, set);
520     ok( ret==3, "_mbsspn returns %d should be 3\n", ret);
521     ret=_mbsspn( str2, set);
522     ok( ret==0, "_mbsspn returns %d should be 0\n", ret);
523     ret=_mbsspn( str1, empty);
524     ok( ret==0, "_mbsspn returns %d should be 0\n", ret);
525 }
526 
527 static void test_mbsspnp( void)
528 {
529     unsigned char str1[]="cabernet";
530     unsigned char str2[]="shiraz";
531     unsigned char set[]="abc";
532     unsigned char empty[]="";
533     unsigned char full[]="abcenrt";
534     unsigned char* ret;
535     ret=_mbsspnp( str1, set);
536     ok( ret[0]=='e', "_mbsspnp returns %c should be e\n", ret[0]);
537     ret=_mbsspnp( str2, set);
538     ok( ret[0]=='s', "_mbsspnp returns %c should be s\n", ret[0]);
539     ret=_mbsspnp( str1, empty);
540     ok( ret[0]=='c', "_mbsspnp returns %c should be c\n", ret[0]);
541     ret=_mbsspnp( str1, full);
542     ok( ret==NULL, "_mbsspnp returns %p should be NULL\n", ret);
543 }
544 
545 static void test_strdup(void)
546 {
547    char *str;
548    str = _strdup( 0 );
549    ok( str == 0, "strdup returns %s should be 0\n", str);
550    free( str );
551 }
552 
553 static void test_strcpy_s(void)
554 {
555     char dest[8];
556     const char small[] = "small";
557     const char big[] = "atoolongstringforthislittledestination";
558     int ret;
559 
560     if(!pstrcpy_s)
561     {
562         win_skip("strcpy_s not found\n");
563         return;
564     }
565 
566     memset(dest, 'X', sizeof(dest));
567     ret = pstrcpy_s(dest, sizeof(dest), small);
568     ok(ret == 0, "Copying a string into a big enough destination returned %d, expected 0\n", ret);
569     ok(dest[0] == 's' && dest[1] == 'm' && dest[2] == 'a' && dest[3] == 'l' &&
570        dest[4] == 'l' && dest[5] == '\0'&& dest[6] == 'X' && dest[7] == 'X',
571        "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
572        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
573 
574     memset(dest, 'X', sizeof(dest));
575     ret = pstrcpy_s(dest, 0, big);
576     ok(ret == EINVAL, "Copying into a destination of size 0 returned %d, expected EINVAL\n", ret);
577     ok(dest[0] == 'X' && dest[1] == 'X' && dest[2] == 'X' && dest[3] == 'X' &&
578        dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X',
579        "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
580        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
581     ret = pstrcpy_s(dest, 0, NULL);
582     ok(ret == EINVAL, "Copying into a destination of size 0 returned %d, expected EINVAL\n", ret);
583     ok(dest[0] == 'X' && dest[1] == 'X' && dest[2] == 'X' && dest[3] == 'X' &&
584        dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X',
585        "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
586        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
587 
588     memset(dest, 'X', sizeof(dest));
589     ret = pstrcpy_s(dest, sizeof(dest), big);
590     ok(ret == ERANGE, "Copying a big string in a small location returned %d, expected ERANGE\n", ret);
591     ok(dest[0] == '\0'&& dest[1] == 't' && dest[2] == 'o' && dest[3] == 'o' &&
592        dest[4] == 'l' && dest[5] == 'o' && dest[6] == 'n' && dest[7] == 'g',
593        "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
594        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
595 
596     memset(dest, 'X', sizeof(dest));
597     ret = pstrcpy_s(dest, sizeof(dest), NULL);
598     ok(ret == EINVAL, "Copying from a NULL source string returned %d, expected EINVAL\n", ret);
599     ok(dest[0] == '\0'&& dest[1] == 'X' && dest[2] == 'X' && dest[3] == 'X' &&
600        dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X',
601        "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
602        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
603 
604     ret = pstrcpy_s(NULL, sizeof(dest), small);
605     ok(ret == EINVAL, "Copying a big string a NULL dest returned %d, expected EINVAL\n", ret);
606 
607     /* strcpy overlapping buffers test */
608     memset(dest, 'X', sizeof(dest));
609     memcpy(dest+1, small, sizeof(small));
610     p_strcpy(dest, dest+1);
611     ok(dest[0] == 's' && dest[1] == 'm' && dest[2] == 'a' && dest[3] == 'l' &&
612             dest[4] == 'l' && dest[5] == '\0' && dest[6] == '\0' && dest[7] == 'X',
613             "Unexpected return data from strcpy: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
614             dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
615 }
616 
617 #define okchars(dst, b0, b1, b2, b3, b4, b5, b6, b7) \
618     ok(dst[0] == b0 && dst[1] == b1 && dst[2] == b2 && dst[3] == b3 && \
619        dst[4] == b4 && dst[5] == b5 && dst[6] == b6 && dst[7] == b7, \
620        "Bad result: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",\
621        dst[0], dst[1], dst[2], dst[3], dst[4], dst[5], dst[6], dst[7])
622 
623 static void test_memcpy_s(void)
624 {
625     static char dest[8], buf[32];
626     static const char tiny[] = {'T',0,'I','N','Y',0};
627     static const char big[] = {'a','t','o','o','l','o','n','g','s','t','r','i','n','g',0};
628     int ret;
629     if (!p_memcpy_s) {
630         win_skip("memcpy_s not found\n");
631         return;
632     }
633 
634     /* Normal */
635     memset(dest, 'X', sizeof(dest));
636     ret = p_memcpy_s(dest, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny));
637     ok(ret == 0, "Copying a buffer into a big enough destination returned %d, expected 0\n", ret);
638     okchars(dest, tiny[0], tiny[1], tiny[2], tiny[3], tiny[4], tiny[5], 'X', 'X');
639 
640     /* Vary source size */
641     errno = 0xdeadbeef;
642     memset(dest, 'X', sizeof(dest));
643     ret = p_memcpy_s(dest, ARRAY_SIZE(dest), big, ARRAY_SIZE(big));
644     ok(ret == ERANGE, "Copying a big buffer to a small destination returned %d, expected ERANGE\n", ret);
645     ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
646     okchars(dest, 0, 0, 0, 0, 0, 0, 0, 0);
647 
648     /* Replace source with NULL */
649     errno = 0xdeadbeef;
650     memset(dest, 'X', sizeof(dest));
651     ret = p_memcpy_s(dest, ARRAY_SIZE(dest), NULL, ARRAY_SIZE(tiny));
652     ok(ret == EINVAL, "Copying a NULL source buffer returned %d, expected EINVAL\n", ret);
653     ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
654     okchars(dest, 0, 0, 0, 0, 0, 0, 0, 0);
655 
656     /* Vary dest size */
657     errno = 0xdeadbeef;
658     memset(dest, 'X', sizeof(dest));
659     ret = p_memcpy_s(dest, 0, tiny, ARRAY_SIZE(tiny));
660     ok(ret == ERANGE, "Copying into a destination of size 0 returned %d, expected ERANGE\n", ret);
661     ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
662     okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
663 
664     /* Replace dest with NULL */
665     errno = 0xdeadbeef;
666     ret = p_memcpy_s(NULL, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny));
667     ok(ret == EINVAL, "Copying a tiny buffer to a big NULL destination returned %d, expected EINVAL\n", ret);
668     ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
669 
670     /* Combinations */
671     errno = 0xdeadbeef;
672     memset(dest, 'X', sizeof(dest));
673     ret = p_memcpy_s(dest, 0, NULL, ARRAY_SIZE(tiny));
674     ok(ret == EINVAL, "Copying a NULL buffer into a destination of size 0 returned %d, expected EINVAL\n", ret);
675     ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
676     okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
677 
678     ret = p_memcpy_s(buf, ARRAY_SIZE(buf), big, ARRAY_SIZE(big));
679     ok(!ret, "memcpy_s returned %d\n", ret);
680     ok(!memcmp(buf, big, sizeof(big)), "unexpected buf\n");
681 
682     ret = p_memcpy_s(buf + 1, ARRAY_SIZE(buf) - 1, buf, ARRAY_SIZE(big));
683     ok(!ret, "memcpy_s returned %d\n", ret);
684     ok(!memcmp(buf + 1, big, sizeof(big)), "unexpected buf\n");
685 
686     ret = p_memcpy_s(buf, ARRAY_SIZE(buf), buf + 1, ARRAY_SIZE(big));
687     ok(!ret, "memcpy_s returned %d\n", ret);
688     ok(!memcmp(buf, big, sizeof(big)), "unexpected buf\n");
689 }
690 
691 static void test_memmove_s(void)
692 {
693     static char dest[8];
694     static const char tiny[] = {'T',0,'I','N','Y',0};
695     static const char big[] = {'a','t','o','o','l','o','n','g','s','t','r','i','n','g',0};
696     int ret;
697     if (!p_memmove_s) {
698         win_skip("memmove_s not found\n");
699         return;
700     }
701 
702     /* Normal */
703     memset(dest, 'X', sizeof(dest));
704     ret = p_memmove_s(dest, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny));
705     ok(ret == 0, "Moving a buffer into a big enough destination returned %d, expected 0\n", ret);
706     okchars(dest, tiny[0], tiny[1], tiny[2], tiny[3], tiny[4], tiny[5], 'X', 'X');
707 
708     /* Overlapping */
709     memcpy(dest, big, sizeof(dest));
710     ret = p_memmove_s(dest+1, ARRAY_SIZE(dest)-1, dest, ARRAY_SIZE(dest)-1);
711     ok(ret == 0, "Moving a buffer up one char returned %d, expected 0\n", ret);
712     okchars(dest, big[0], big[0], big[1], big[2], big[3], big[4], big[5], big[6]);
713 
714     /* Vary source size */
715     errno = 0xdeadbeef;
716     memset(dest, 'X', sizeof(dest));
717     ret = p_memmove_s(dest, ARRAY_SIZE(dest), big, ARRAY_SIZE(big));
718     ok(ret == ERANGE, "Moving a big buffer to a small destination returned %d, expected ERANGE\n", ret);
719     ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
720     okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
721 
722     /* Replace source with NULL */
723     errno = 0xdeadbeef;
724     memset(dest, 'X', sizeof(dest));
725     ret = p_memmove_s(dest, ARRAY_SIZE(dest), NULL, ARRAY_SIZE(tiny));
726     ok(ret == EINVAL, "Moving a NULL source buffer returned %d, expected EINVAL\n", ret);
727     ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
728     okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
729 
730     /* Vary dest size */
731     errno = 0xdeadbeef;
732     memset(dest, 'X', sizeof(dest));
733     ret = p_memmove_s(dest, 0, tiny, ARRAY_SIZE(tiny));
734     ok(ret == ERANGE, "Moving into a destination of size 0 returned %d, expected ERANGE\n", ret);
735     ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
736     okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
737 
738     /* Replace dest with NULL */
739     errno = 0xdeadbeef;
740     ret = p_memmove_s(NULL, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny));
741     ok(ret == EINVAL, "Moving a tiny buffer to a big NULL destination returned %d, expected EINVAL\n", ret);
742     ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
743 
744     /* Combinations */
745     errno = 0xdeadbeef;
746     memset(dest, 'X', sizeof(dest));
747     ret = p_memmove_s(dest, 0, NULL, ARRAY_SIZE(tiny));
748     ok(ret == EINVAL, "Moving a NULL buffer into a destination of size 0 returned %d, expected EINVAL\n", ret);
749     ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
750     okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
751 }
752 
753 static void test_strcat_s(void)
754 {
755     char dest[8];
756     const char *small = "sma";
757     int ret;
758 
759     if(!pstrcat_s)
760     {
761         win_skip("strcat_s not found\n");
762         return;
763     }
764 
765     memset(dest, 'X', sizeof(dest));
766     dest[0] = '\0';
767     ret = pstrcat_s(dest, sizeof(dest), small);
768     ok(ret == 0, "strcat_s: Copying a string into a big enough destination returned %d, expected 0\n", ret);
769     ok(dest[0] == 's' && dest[1] == 'm' && dest[2] == 'a' && dest[3] == '\0'&&
770        dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X',
771        "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
772        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
773     ret = pstrcat_s(dest, sizeof(dest), small);
774     ok(ret == 0, "strcat_s: Attaching a string to a big enough destination returned %d, expected 0\n", ret);
775     ok(dest[0] == 's' && dest[1] == 'm' && dest[2] == 'a' && dest[3] == 's' &&
776        dest[4] == 'm' && dest[5] == 'a' && dest[6] == '\0'&& dest[7] == 'X',
777        "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
778        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
779 
780     ret = pstrcat_s(dest, sizeof(dest), small);
781     ok(ret == ERANGE, "strcat_s: Attaching a string to a filled up destination returned %d, expected ERANGE\n", ret);
782     ok(dest[0] == '\0'&& dest[1] == 'm' && dest[2] == 'a' && dest[3] == 's' &&
783        dest[4] == 'm' && dest[5] == 'a' && dest[6] == 's' && dest[7] == 'm',
784        "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
785        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
786 
787     memset(dest, 'X', sizeof(dest));
788     dest[0] = 'a';
789     dest[1] = '\0';
790 
791     ret = pstrcat_s(dest, 0, small);
792     ok(ret == EINVAL, "strcat_s: Source len = 0 returned %d, expected EINVAL\n", ret);
793     ok(dest[0] == 'a' && dest[1] == '\0'&& dest[2] == 'X' && dest[3] == 'X' &&
794        dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X',
795        "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
796        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
797 
798     ret = pstrcat_s(dest, 0, NULL);
799     ok(ret == EINVAL, "strcat_s: len = 0 and src = NULL returned %d, expected EINVAL\n", ret);
800     ok(dest[0] == 'a' && dest[1] == '\0'&& dest[2] == 'X' && dest[3] == 'X' &&
801        dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X',
802        "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
803        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
804 
805     ret = pstrcat_s(dest, sizeof(dest), NULL);
806     ok(ret == EINVAL, "strcat_s:  Sourcing from NULL returned %d, expected EINVAL\n", ret);
807     ok(dest[0] == '\0'&& dest[1] == '\0'&& dest[2] == 'X' && dest[3] == 'X' &&
808        dest[4] == 'X' && dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X',
809        "Unexpected return data from strcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
810        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
811 
812     ret = pstrcat_s(NULL, sizeof(dest), small);
813     ok(ret == EINVAL, "strcat_s: Writing to a NULL string returned %d, expected EINVAL\n", ret);
814 }
815 
816 static void test__mbscat_s(void)
817 {
818     unsigned char dst[8], src[4];
819     int err;
820     int prev_cp = _getmbcp();
821 
822     if(!p_mbscat_s)
823     {
824         win_skip("_mbscat_s not found\n");
825         return;
826     }
827 
828 
829     src[0] = dst[0] = 0;
830     err = p_mbscat_s(NULL, sizeof(dst), src);
831     ok(err == EINVAL, "_mbscat_s returned %d\n", err);
832 
833     err = p_mbscat_s(dst, sizeof(dst), NULL);
834     ok(err == EINVAL, "_mbscat_s returned %d\n", err);
835 
836     dst[0] = 'a';
837     err = p_mbscat_s(dst, 1, src);
838     ok(err == EINVAL, "_mbscat_s returned %d\n", err);
839 
840     memset(dst, 'a', sizeof(dst));
841     dst[6] = 0;
842     src[0] = 'b';
843     src[1] = 0;
844 
845     err = p_mbscat_s(dst, sizeof(dst), src);
846     ok(err == 0, "_mbscat_s returned %d\n", err);
847     ok(!memcmp(dst, "aaaaaab", 8), "dst = %s\n", dst);
848 
849     err = p_mbscat_s(dst, sizeof(dst), src);
850     ok(err == ERANGE, "_mbscat_s returned %d\n", err);
851     ok(!dst[0], "dst[0] = %c\n", dst[0]);
852     ok(dst[1] == 'a', "dst[1] = %c\n", dst[1]);
853 
854     _setmbcp(932);
855     /* test invalid str in dst */
856     dst[0] = 0x81;
857     dst[1] = 0x81;
858     dst[2] = 0x52;
859     dst[3] = 0;
860     src[0] = 'a';
861     src[1] = 0;
862     err = p_mbscat_s(dst, sizeof(dst), src);
863     ok(err == 0, "_mbscat_s returned %d\n", err);
864 
865     /* test invalid str in src */
866     dst[0] = 0;
867     src[0] = 0x81;
868     src[1] = 0x81;
869     src[2] = 0x52;
870     src[3] = 0;
871     err = p_mbscat_s(dst, sizeof(dst), src);
872     ok(err == 0, "_mbscat_s returned %d\n", err);
873 
874     /* test dst with leading byte on the end of buffer */
875     dst[0] = 'a';
876     dst[1] = 0x81;
877     dst[2] = 0;
878     src[0] = 'R';
879     src[1] = 0;
880     err = p_mbscat_s(dst, sizeof(dst), src);
881     ok(err == EILSEQ, "_mbscat_s returned %d\n", err);
882     ok(!memcmp(dst, "aR", 3), "dst = %s\n", dst);
883 
884     /* test src with leading byte on the end of buffer */
885     dst[0] = 'a';
886     dst[1] = 0;
887     src[0] = 'b';
888     src[1] = 0x81;
889     src[2] = 0;
890     err = p_mbscat_s(dst, sizeof(dst), src);
891     ok(err == EILSEQ, "_mbscat_s returned %d\n", err);
892     ok(!memcmp(dst, "ab", 3), "dst = %s\n", dst);
893     _setmbcp(prev_cp);
894 }
895 
896 static void test__mbsnbcpy_s(void)
897 {
898     unsigned char dest[8];
899     const unsigned char big[] = "atoolongstringforthislittledestination";
900     const unsigned char small[] = "small";
901     int ret;
902 
903     if(!p_mbsnbcpy_s)
904     {
905         win_skip("_mbsnbcpy_s not found\n");
906         return;
907     }
908 
909     memset(dest, 'X', sizeof(dest));
910     ret = p_mbsnbcpy_s(dest, sizeof(dest), small, sizeof(small));
911     ok(ret == 0, "_mbsnbcpy_s: Copying a string into a big enough destination returned %d, expected 0\n", ret);
912     ok(dest[0] == 's' && dest[1] == 'm' && dest[2] == 'a' && dest[3] == 'l' &&
913        dest[4] == 'l' && dest[5] == '\0'&& dest[6] == 'X' && dest[7] == 'X',
914        "Unexpected return data from _mbsnbcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
915        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
916 
917     /* WTF? */
918     memset(dest, 'X', sizeof(dest));
919     ret = p_mbsnbcpy_s(dest, sizeof(dest) - 2, big, sizeof(small));
920     ok(ret == ERANGE, "_mbsnbcpy_s: Copying a too long string returned %d, expected ERANGE\n", ret);
921     ok(dest[0] == '\0'&& dest[1] == 't' && dest[2] == 'o' && dest[3] == 'o' &&
922        dest[4] == 'l' && dest[5] == 'o' && dest[6] == 'X' && dest[7] == 'X',
923        "Unexpected return data from _mbsnbcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
924        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
925 
926     memset(dest, 'X', sizeof(dest));
927     ret = p_mbsnbcpy_s(dest, sizeof(dest) - 2, big, 4);
928     ok(ret == 0, "_mbsnbcpy_s: Copying a too long string with a count cap returned %d, expected 0\n", ret);
929     ok(dest[0] == 'a' && dest[1] == 't' && dest[2] == 'o' && dest[3] == 'o' &&
930        dest[4] == '\0'&& dest[5] == 'X' && dest[6] == 'X' && dest[7] == 'X',
931        "Unexpected return data from _mbsnbcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
932        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
933 
934     memset(dest, 'X', sizeof(dest));
935     ret = p_mbsnbcpy_s(dest, sizeof(dest) - 2, small, sizeof(small) + 10);
936     ok(ret == 0, "_mbsnbcpy_s: Copying more data than the source string len returned %d, expected 0\n", ret);
937     ok(dest[0] == 's' && dest[1] == 'm' && dest[2] == 'a' && dest[3] == 'l' &&
938        dest[4] == 'l' && dest[5] == '\0'&& dest[6] == 'X' && dest[7] == 'X',
939        "Unexpected return data from _mbsnbcpy_s: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
940        dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
941 }
942 
943 static void test__mbscpy_s(void)
944 {
945     const unsigned char src[] = "source string";
946     unsigned char dest[16];
947     int ret;
948 
949     if(!p__mbscpy_s)
950     {
951         win_skip("_mbscpy_s not found\n");
952         return;
953     }
954 
955     ret = p__mbscpy_s(NULL, 0, src);
956     ok(ret == EINVAL, "got %d\n", ret);
957     ret = p__mbscpy_s(NULL, sizeof(dest), src);
958     ok(ret == EINVAL, "got %d\n", ret);
959     ret = p__mbscpy_s(dest, 0, src);
960     ok(ret == EINVAL, "got %d\n", ret);
961     dest[0] = 'x';
962     ret = p__mbscpy_s(dest, sizeof(dest), NULL);
963     ok(ret == EINVAL, "got %d\n", ret);
964     ok(!dest[0], "dest buffer was not modified on invalid argument\n");
965 
966     memset(dest, 'X', sizeof(dest));
967     ret = p__mbscpy_s(dest, sizeof(dest), src);
968     ok(!ret, "got %d\n", ret);
969     ok(!memcmp(dest, src, sizeof(src)), "dest = %s\n", dest);
970     ok(dest[sizeof(src)] == 'X', "unused part of buffer was modified\n");
971 
972     memset(dest, 'X', sizeof(dest));
973     ret = p__mbscpy_s(dest, 4, src);
974     ok(ret == ERANGE, "got %d\n", ret);
975     ok(!dest[0], "incorrect dest buffer (%d)\n", dest[0]);
976     ok(dest[1] == src[1], "incorrect dest buffer (%d)\n", dest[1]);
977 }
978 
979 static void test_wcscpy_s(void)
980 {
981     static const WCHAR szLongText[] = { 'T','h','i','s','A','L','o','n','g','s','t','r','i','n','g',0 };
982     static WCHAR szDest[18];
983     static WCHAR szDestShort[8];
984     int ret;
985 
986     if(!p_wcscpy_s)
987     {
988         win_skip("wcscpy_s not found\n");
989         return;
990     }
991 
992     /* Test NULL Dest */
993     errno = EBADF;
994     ret = p_wcscpy_s(NULL, 18, szLongText);
995     ok(ret == EINVAL, "p_wcscpy_s expect EINVAL got %d\n", ret);
996     ok(errno == EINVAL, "expected errno EINVAL got %d\n", errno);
997 
998     /* Test NULL Source */
999     errno = EBADF;
1000     szDest[0] = 'A';
1001     ret = p_wcscpy_s(szDest, 18, NULL);
1002     ok(ret == EINVAL, "expected EINVAL got %d\n", ret);
1003     ok(errno == EINVAL, "expected errno EINVAL got %d\n", errno);
1004     ok(szDest[0] == 0, "szDest[0] not 0, got %c\n", szDest[0]);
1005 
1006     /* Test invalid size */
1007     errno = EBADF;
1008     szDest[0] = 'A';
1009     ret = p_wcscpy_s(szDest, 0, szLongText);
1010     /* Later versions changed the return value for this case to EINVAL,
1011      * and don't modify the result if the dest size is 0.
1012      */
1013     ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret);
1014     ok(errno == ERANGE || errno == EINVAL, "expected errno ERANGE/EINVAL got %d\n", errno);
1015     ok(szDest[0] == 0 || ret == EINVAL, "szDest[0] not 0\n");
1016 
1017     /* Copy same buffer size */
1018     ret = p_wcscpy_s(szDest, 18, szLongText);
1019     ok(ret == 0, "expected 0 got %d\n", ret);
1020     ok(lstrcmpW(szDest, szLongText) == 0, "szDest != szLongText\n");
1021 
1022     /* Copy smaller buffer size */
1023     errno = EBADF;
1024     szDest[0] = 'A';
1025     ret = p_wcscpy_s(szDestShort, 8, szLongText);
1026     ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret);
1027     ok(errno == ERANGE || errno == EINVAL, "expected errno ERANGE/EINVAL got %d\n", errno);
1028     ok(szDestShort[0] == 0, "szDestShort[0] not 0\n");
1029 
1030     if(!p_wcsncpy_s)
1031     {
1032         win_skip("wcsncpy_s not found\n");
1033         return;
1034     }
1035 
1036     ret = p_wcsncpy_s(NULL, 18, szLongText, ARRAY_SIZE(szLongText));
1037     ok(ret == EINVAL, "p_wcsncpy_s expect EINVAL got %d\n", ret);
1038 
1039     szDest[0] = 'A';
1040     ret = p_wcsncpy_s(szDest, 18, NULL, 1);
1041     ok(ret == EINVAL, "expected EINVAL got %d\n", ret);
1042     ok(szDest[0] == 0, "szDest[0] not 0\n");
1043 
1044     szDest[0] = 'A';
1045     ret = p_wcsncpy_s(szDest, 18, NULL, 0);
1046     ok(ret == 0, "expected ERROR_SUCCESS got %d\n", ret);
1047     ok(szDest[0] == 0, "szDest[0] not 0\n");
1048 
1049     szDest[0] = 'A';
1050     ret = p_wcsncpy_s(szDest, 0, szLongText, ARRAY_SIZE(szLongText));
1051     ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret);
1052     ok(szDest[0] == 0 || ret == EINVAL, "szDest[0] not 0\n");
1053 
1054     ret = p_wcsncpy_s(szDest, 18, szLongText, ARRAY_SIZE(szLongText));
1055     ok(ret == 0, "expected 0 got %d\n", ret);
1056     ok(lstrcmpW(szDest, szLongText) == 0, "szDest != szLongText\n");
1057 
1058     szDest[0] = 'A';
1059     ret = p_wcsncpy_s(szDestShort, 8, szLongText, ARRAY_SIZE(szLongText));
1060     ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret);
1061     ok(szDestShort[0] == 0, "szDestShort[0] not 0\n");
1062 
1063     szDest[0] = 'A';
1064     ret = p_wcsncpy_s(szDest, 5, szLongText, -1);
1065     ok(ret == STRUNCATE, "expected STRUNCATE got %d\n", ret);
1066     ok(szDest[4] == 0, "szDest[4] not 0\n");
1067     ok(!memcmp(szDest, szLongText, 4*sizeof(WCHAR)), "szDest = %s\n", wine_dbgstr_w(szDest));
1068 
1069     ret = p_wcsncpy_s(NULL, 0, (void*)0xdeadbeef, 0);
1070     ok(ret == 0, "ret = %d\n", ret);
1071 
1072     szDestShort[0] = '1';
1073     szDestShort[1] = 0;
1074     ret = p_wcsncpy_s(szDestShort+1, 4, szDestShort, -1);
1075     ok(ret == STRUNCATE, "expected ERROR_SUCCESS got %d\n", ret);
1076     ok(szDestShort[0]=='1' && szDestShort[1]=='1' && szDestShort[2]=='1' && szDestShort[3]=='1',
1077             "szDestShort = %s\n", wine_dbgstr_w(szDestShort));
1078 }
1079 
1080 static void test__wcsupr_s(void)
1081 {
1082     static const WCHAR mixedString[] = {'M', 'i', 'X', 'e', 'D', 'l', 'o', 'w',
1083                                         'e', 'r', 'U', 'P', 'P', 'E', 'R', 0};
1084     static const WCHAR expectedString[] = {'M', 'I', 'X', 'E', 'D', 'L', 'O',
1085                                            'W', 'E', 'R', 'U', 'P', 'P', 'E',
1086                                            'R', 0};
1087     WCHAR testBuffer[2*ARRAY_SIZE(mixedString)];
1088     int ret;
1089 
1090     if (!p_wcsupr_s)
1091     {
1092         win_skip("_wcsupr_s not found\n");
1093         return;
1094     }
1095 
1096     /* Test NULL input string and invalid size. */
1097     errno = EBADF;
1098     ret = p_wcsupr_s(NULL, 0);
1099     ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret);
1100     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
1101 
1102     /* Test NULL input string and valid size. */
1103     errno = EBADF;
1104     ret = p_wcsupr_s(NULL, ARRAY_SIZE(testBuffer));
1105     ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret);
1106     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
1107 
1108     /* Test empty string with zero size. */
1109     errno = EBADF;
1110     testBuffer[0] = '\0';
1111     ret = p_wcsupr_s(testBuffer, 0);
1112     ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret);
1113     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
1114     ok(testBuffer[0] == '\0', "Expected the buffer to be unchanged\n");
1115 
1116     /* Test empty string with size of one. */
1117     testBuffer[0] = '\0';
1118     ret = p_wcsupr_s(testBuffer, 1);
1119     ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret);
1120     ok(testBuffer[0] == '\0', "Expected the buffer to be unchanged\n");
1121 
1122     /* Test one-byte buffer with zero size. */
1123     errno = EBADF;
1124     testBuffer[0] = 'x';
1125     ret = p_wcsupr_s(testBuffer, 0);
1126     ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret);
1127     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
1128     ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n");
1129 
1130     /* Test one-byte buffer with size of one. */
1131     errno = EBADF;
1132     testBuffer[0] = 'x';
1133     ret = p_wcsupr_s(testBuffer, 1);
1134     ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret);
1135     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
1136     ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n");
1137 
1138     /* Test invalid size. */
1139     wcscpy(testBuffer, mixedString);
1140     errno = EBADF;
1141     ret = p_wcsupr_s(testBuffer, 0);
1142     ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret);
1143     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
1144     ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n");
1145 
1146     /* Test normal string uppercasing. */
1147     wcscpy(testBuffer, mixedString);
1148     ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(mixedString));
1149     ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret);
1150     ok(!wcscmp(testBuffer, expectedString), "Expected the string to be fully upper-case\n");
1151 
1152     /* Test uppercasing with a shorter buffer size count. */
1153     wcscpy(testBuffer, mixedString);
1154     errno = EBADF;
1155     ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(mixedString) - 1);
1156     ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret);
1157     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
1158     ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n");
1159 
1160     /* Test uppercasing with a longer buffer size count. */
1161     wcscpy(testBuffer, mixedString);
1162     ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(testBuffer));
1163     ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret);
1164     ok(!wcscmp(testBuffer, expectedString), "Expected the string to be fully upper-case\n");
1165 }
1166 
1167 static void test__wcslwr_s(void)
1168 {
1169     static const WCHAR mixedString[] = {'M', 'i', 'X', 'e', 'D', 'l', 'o', 'w',
1170                                         'e', 'r', 'U', 'P', 'P', 'E', 'R', 0};
1171     static const WCHAR expectedString[] = {'m', 'i', 'x', 'e', 'd', 'l', 'o',
1172                                            'w', 'e', 'r', 'u', 'p', 'p', 'e',
1173                                            'r', 0};
1174     WCHAR buffer[2*ARRAY_SIZE(mixedString)];
1175     int ret;
1176 
1177     if (!p_wcslwr_s)
1178     {
1179         win_skip("_wcslwr_s not found\n");
1180         return;
1181     }
1182 
1183     /* Test NULL input string and invalid size. */
1184     errno = EBADF;
1185     ret = p_wcslwr_s(NULL, 0);
1186     ok(ret == EINVAL, "expected EINVAL, got %d\n", ret);
1187     ok(errno == EINVAL, "expected errno EINVAL, got %d\n", errno);
1188 
1189     /* Test NULL input string and valid size. */
1190     errno = EBADF;
1191     ret = p_wcslwr_s(NULL, ARRAY_SIZE(buffer));
1192     ok(ret == EINVAL, "expected EINVAL, got %d\n", ret);
1193     ok(errno == EINVAL, "expected errno EINVAL, got %d\n", errno);
1194 
1195     /* Test empty string with zero size. */
1196     errno = EBADF;
1197     buffer[0] = 'a';
1198     ret = p_wcslwr_s(buffer, 0);
1199     ok(ret == EINVAL, "expected EINVAL, got %d\n", ret);
1200     ok(errno == EINVAL, "expected errno EINVAL, got %d\n", errno);
1201     ok(buffer[0] == 0, "expected empty string\n");
1202 
1203     /* Test empty string with size of one. */
1204     buffer[0] = 0;
1205     ret = p_wcslwr_s(buffer, 1);
1206     ok(ret == 0, "got %d\n", ret);
1207     ok(buffer[0] == 0, "expected buffer to be unchanged\n");
1208 
1209     /* Test one-byte buffer with zero size. */
1210     errno = EBADF;
1211     buffer[0] = 'x';
1212     ret = p_wcslwr_s(buffer, 0);
1213     ok(ret == EINVAL, "expected EINVAL, got %d\n", ret);
1214     ok(errno == EINVAL, "expected errno to be EINVAL, got %d\n", errno);
1215     ok(buffer[0] == '\0', "expected empty string\n");
1216 
1217     /* Test one-byte buffer with size of one. */
1218     errno = EBADF;
1219     buffer[0] = 'x';
1220     ret = p_wcslwr_s(buffer, 1);
1221     ok(ret == EINVAL, "expected EINVAL, got %d\n", ret);
1222     ok(errno == EINVAL, "expected errno to be EINVAL, got %d\n", errno);
1223     ok(buffer[0] == '\0', "expected empty string\n");
1224 
1225     /* Test invalid size. */
1226     wcscpy(buffer, mixedString);
1227     errno = EBADF;
1228     ret = p_wcslwr_s(buffer, 0);
1229     ok(ret == EINVAL, "Expected EINVAL, got %d\n", ret);
1230     ok(errno == EINVAL, "expected errno to be EINVAL, got %d\n", errno);
1231     ok(buffer[0] == '\0', "expected empty string\n");
1232 
1233     /* Test normal string uppercasing. */
1234     wcscpy(buffer, mixedString);
1235     ret = p_wcslwr_s(buffer, ARRAY_SIZE(mixedString));
1236     ok(ret == 0, "expected 0, got %d\n", ret);
1237     ok(!wcscmp(buffer, expectedString), "expected lowercase\n");
1238 
1239     /* Test uppercasing with a shorter buffer size count. */
1240     wcscpy(buffer, mixedString);
1241     errno = EBADF;
1242     ret = p_wcslwr_s(buffer, ARRAY_SIZE(mixedString) - 1);
1243     ok(ret == EINVAL, "expected EINVAL, got %d\n", ret);
1244     ok(errno == EINVAL, "expected errno to be EINVAL, got %d\n", errno);
1245     ok(buffer[0] == '\0', "expected empty string\n");
1246 
1247     /* Test uppercasing with a longer buffer size count. */
1248     wcscpy(buffer, mixedString);
1249     ret = p_wcslwr_s(buffer, ARRAY_SIZE(buffer));
1250     ok(ret == 0, "expected 0, got %d\n", ret);
1251     ok(!wcscmp(buffer, expectedString), "expected lowercase\n");
1252 }
1253 
1254 static void test_mbcjisjms(void)
1255 {
1256     /* List of value-pairs to test. The test assumes the last pair to be {0, ..} */
1257     unsigned int jisjms[][2] = { {0x2020, 0}, {0x2021, 0}, {0x2120, 0}, {0x2121, 0x8140},
1258                                  {0x7f7f, 0}, {0x7f7e, 0}, {0x7e7f, 0}, {0x7e7e, 0xeffc},
1259                                  {0x255f, 0x837e}, {0x2560, 0x8380}, {0x2561, 0x8381},
1260                                  {0x2121FFFF, 0}, {0x2223, 0x81a1}, {0x237e, 0x829e}, {0, 0}};
1261     int cp[] = { 932, 936, 939, 950, 1361, _MB_CP_SBCS };
1262     unsigned int i, j;
1263     int prev_cp = _getmbcp();
1264 
1265     for (i = 0; i < ARRAY_SIZE(cp); i++)
1266     {
1267         _setmbcp(cp[i]);
1268         for (j = 0; jisjms[j][0] != 0; j++)
1269         {
1270             unsigned int ret, exp;
1271             ret = _mbcjistojms(jisjms[j][0]);
1272             exp = (cp[i] == 932) ? jisjms[j][1] : jisjms[j][0];
1273             ok(ret == exp, "Expected 0x%x, got 0x%x (0x%x, codepage=%d)\n",
1274                exp, ret, jisjms[j][0], cp[i]);
1275         }
1276     }
1277     _setmbcp(prev_cp);
1278 }
1279 
1280 static void test_mbcjmsjis(void)
1281 {
1282     /* List of value-pairs to test. The test assumes the last pair to be {0, ..} */
1283     unsigned int jmsjis[][2] = { {0x80fc, 0}, {0x813f, 0}, {0x8140, 0x2121},
1284                                  {0x817e, 0x215f}, {0x817f, 0}, {0x8180, 0x2160},
1285                                  {0x819e, 0x217e}, {0x819f, 0x2221}, {0x81fc, 0x227e},
1286                                  {0x81fd, 0}, {0x9ffc, 0x5e7e}, {0x9ffd, 0},
1287                                  {0xa040, 0}, {0xdffc, 0}, {0xe040, 0x5f21},
1288                                  {0xeffc, 0x7e7e}, {0xf040, 0}, {0x21, 0}, {0, 0}};
1289     int cp[] = { 932, 936, 939, 950, 1361, _MB_CP_SBCS };
1290     unsigned int i, j;
1291     int prev_cp = _getmbcp();
1292 
1293     for (i = 0; i < ARRAY_SIZE(cp); i++)
1294     {
1295         _setmbcp(cp[i]);
1296         for (j = 0; jmsjis[j][0] != 0; j++)
1297         {
1298             unsigned int ret, exp;
1299             ret = _mbcjmstojis(jmsjis[j][0]);
1300             exp = (cp[i] == 932) ? jmsjis[j][1] : jmsjis[j][0];
1301             ok(ret == exp, "Expected 0x%x, got 0x%x (0x%x, codepage=%d)\n",
1302                exp, ret, jmsjis[j][0], cp[i]);
1303         }
1304     }
1305     _setmbcp(prev_cp);
1306 }
1307 
1308 static void test_mbctohira(void)
1309 {
1310     static const unsigned int mbchira_932[][2] = {
1311         {0x8152, 0x8152}, {0x8153, 0x8153}, {0x8154, 0x8154}, {0x8155, 0x8155},
1312         {0x82a0, 0x82a0}, {0x833f, 0x833f}, {0x8340, 0x829f}, {0x837e, 0x82dd},
1313         {0x837f, 0x837f}, {0x8380, 0x82de}, {0x8393, 0x82f1}, {0x8394, 0x8394},
1314         {0x8396, 0x8396}, {0x8397, 0x8397},
1315         {0xa5, 0xa5}, {0xb0, 0xb0}, {0xdd, 0xdd} };
1316     unsigned int i;
1317     unsigned int prev_cp = _getmbcp();
1318 
1319     _setmbcp(_MB_CP_SBCS);
1320     for (i = 0; i < ARRAY_SIZE(mbchira_932); i++)
1321     {
1322         int ret, exp = mbchira_932[i][0];
1323         ret = _mbctohira(mbchira_932[i][0]);
1324         ok(ret == exp, "Expected 0x%x, got 0x%x\n", exp, ret);
1325     }
1326 
1327     _setmbcp(932);
1328     for (i = 0; i < ARRAY_SIZE(mbchira_932); i++)
1329     {
1330         unsigned int ret, exp;
1331         ret = _mbctohira(mbchira_932[i][0]);
1332         exp = mbchira_932[i][1];
1333         ok(ret == exp, "Expected 0x%x, got 0x%x\n", exp, ret);
1334     }
1335     _setmbcp(prev_cp);
1336 }
1337 
1338 static void test_mbctokata(void)
1339 {
1340     static const unsigned int mbckata_932[][2] = {
1341         {0x8152, 0x8152}, {0x8153, 0x8153}, {0x8154, 0x8154}, {0x8155, 0x8155},
1342         {0x833f, 0x833f}, {0x829f, 0x8340}, {0x82dd, 0x837e}, {0x837f, 0x837f},
1343         {0x82de, 0x8380}, {0x8394, 0x8394}, {0x8397, 0x8397},
1344         {0xa5, 0xa5}, {0xb0, 0xb0}, {0xdd, 0xdd} };
1345     unsigned int i;
1346     unsigned int prev_cp = _getmbcp();
1347 
1348     _setmbcp(_MB_CP_SBCS);
1349     for (i = 0; i < ARRAY_SIZE(mbckata_932); i++)
1350     {
1351         int ret, exp = mbckata_932[i][0];
1352         ret = _mbctokata(mbckata_932[i][0]);
1353         ok(ret == exp, "Expected 0x%x, got 0x%x\n", exp, ret);
1354     }
1355 
1356     _setmbcp(932);
1357     for (i = 0; i < ARRAY_SIZE(mbckata_932); i++)
1358     {
1359         unsigned int ret, exp;
1360         ret = _mbctokata(mbckata_932[i][0]);
1361         exp = mbckata_932[i][1];
1362         ok(ret == exp, "Expected 0x%x, got 0x%x\n", exp, ret);
1363     }
1364     _setmbcp(prev_cp);
1365 }
1366 
1367 static void test_mbbtombc(void)
1368 {
1369     static const unsigned int mbbmbc[][2] = {
1370         {0x1f, 0x1f}, {0x20, 0x8140}, {0x39, 0x8258}, {0x40, 0x8197},
1371         {0x41, 0x8260}, {0x5e, 0x814f}, {0x7e, 0x8150}, {0x7f, 0x7f},
1372         {0x80, 0x80}, {0x81, 0x81}, {0xa0, 0xa0}, {0xa7, 0x8340},
1373         {0xb0, 0x815b}, {0xd1, 0x8380}, {0xff, 0xff}, {0,0}};
1374     int cp[] = { 932, 936, 939, 950, 1361, _MB_CP_SBCS };
1375     int i, j;
1376     int prev_cp = _getmbcp();
1377 
1378     for (i = 0; i < ARRAY_SIZE(cp); i++)
1379     {
1380         _setmbcp(cp[i]);
1381         for (j = 0; mbbmbc[j][0] != 0; j++)
1382         {
1383             unsigned int exp, ret;
1384             ret = _mbbtombc(mbbmbc[j][0]);
1385             exp = (cp[i] == 932) ? mbbmbc[j][1] : mbbmbc[j][0];
1386             ok(ret == exp, "Expected 0x%x, got 0x%x (0x%x, codepage %d)\n",
1387                exp, ret, mbbmbc[j][0], cp[i]);
1388         }
1389     }
1390     _setmbcp(prev_cp);
1391 }
1392 
1393 static void test_mbctombb(void)
1394 {
1395     static const unsigned int mbcmbb_932[][2] = {
1396         {0x829e, 0x829e}, {0x829f, 0xa7}, {0x82f1, 0xdd}, {0x82f2, 0x82f2},
1397         {0x833f, 0x833f}, {0x8340, 0xa7}, {0x837e, 0xd0}, {0x837f, 0x837f},
1398         {0x8380, 0xd1}, {0x8396, 0xb9}, {0x8397, 0x8397}, {0x813f, 0x813f},
1399         {0x8140, 0x20}, {0x814c, 0x814c}, {0x814f, 0x5e}, {0x8197, 0x40},
1400         {0x8198, 0x8198}, {0x8258, 0x39}, {0x8259, 0x8259}, {0x825f, 0x825f},
1401         {0x8260, 0x41}, {0x82f1, 0xdd}, {0x82f2, 0x82f2}, {0,0}};
1402     unsigned int exp, ret, i;
1403     unsigned int prev_cp = _getmbcp();
1404 
1405     _setmbcp(932);
1406     for (i = 0; mbcmbb_932[i][0] != 0; i++)
1407     {
1408         ret = _mbctombb(mbcmbb_932[i][0]);
1409         exp = mbcmbb_932[i][1];
1410         ok(ret == exp, "Expected 0x%x, got 0x%x\n", exp, ret);
1411     }
1412     _setmbcp(prev_cp);
1413 }
1414 
1415 static void test_ismbckata(void) {
1416     struct katakana_pair {
1417         UINT c;
1418         BOOL exp;
1419     };
1420     static const struct katakana_pair tests[] = {
1421         {0x8152, FALSE}, {0x8153, FALSE}, {0x8154, FALSE}, {0x8155, FALSE},
1422         {0x82a0, FALSE}, {0x833f, FALSE}, {0x8340, TRUE }, {0x837e, TRUE },
1423         {0x837f, FALSE}, {0x8380, TRUE }, {0x8396, TRUE }, {0x8397, FALSE},
1424         {0xa5, FALSE}, {0xb0, FALSE}, {0xdd, FALSE}
1425     };
1426     unsigned int prev_cp = _getmbcp();
1427     int ret;
1428     unsigned int i;
1429 
1430     _setmbcp(_MB_CP_SBCS);
1431     for (i = 0; i < ARRAY_SIZE(tests); i++) {
1432         ret = _ismbckata(tests[i].c);
1433         ok(!ret, "expected 0, got %d for %04x\n", ret, tests[i].c);
1434     }
1435 
1436     _setmbcp(932);
1437     for (i = 0; i < ARRAY_SIZE(tests); i++) {
1438         ret = _ismbckata(tests[i].c);
1439         ok(!!ret == tests[i].exp, "expected %d, got %d for %04x\n",
1440            tests[i].exp, !!ret, tests[i].c);
1441     }
1442 
1443     _setmbcp(prev_cp);
1444 }
1445 
1446 static void test_ismbclegal(void) {
1447     unsigned int prev_cp = _getmbcp();
1448     int ret, exp, err;
1449     unsigned int i;
1450 
1451     _setmbcp(932); /* Japanese */
1452     err = 0;
1453     for(i = 0; i < 0x10000; i++) {
1454         ret = _ismbclegal(i);
1455         exp = ((HIBYTE(i) >= 0x81 && HIBYTE(i) <= 0x9F) ||
1456                (HIBYTE(i) >= 0xE0 && HIBYTE(i) <= 0xFC)) &&
1457               ((LOBYTE(i) >= 0x40 && LOBYTE(i) <= 0x7E) ||
1458                (LOBYTE(i) >= 0x80 && LOBYTE(i) <= 0xFC));
1459         if(ret != exp) {
1460             err = 1;
1461             break;
1462         }
1463     }
1464     ok(!err, "_ismbclegal (932) : Expected 0x%x, got 0x%x (0x%x)\n", exp, ret, i);
1465     _setmbcp(936); /* Chinese (GBK) */
1466     err = 0;
1467     for(i = 0; i < 0x10000; i++) {
1468         ret = _ismbclegal(i);
1469         exp = HIBYTE(i) >= 0x81 && HIBYTE(i) <= 0xFE &&
1470               LOBYTE(i) >= 0x40 && LOBYTE(i) <= 0xFE;
1471         if(ret != exp) {
1472             err = 1;
1473             break;
1474         }
1475     }
1476     ok(!err, "_ismbclegal (936) : Expected 0x%x, got 0x%x (0x%x)\n", exp, ret, i);
1477     _setmbcp(949); /* Korean */
1478     err = 0;
1479     for(i = 0; i < 0x10000; i++) {
1480         ret = _ismbclegal(i);
1481         exp = HIBYTE(i) >= 0x81 && HIBYTE(i) <= 0xFE &&
1482               LOBYTE(i) >= 0x41 && LOBYTE(i) <= 0xFE;
1483         if(ret != exp) {
1484             err = 1;
1485             break;
1486         }
1487     }
1488     ok(!err, "_ismbclegal (949) : Expected 0x%x, got 0x%x (0x%x)\n", exp, ret, i);
1489     _setmbcp(950); /* Chinese (Big5) */
1490     err = 0;
1491     for(i = 0; i < 0x10000; i++) {
1492         ret = _ismbclegal(i);
1493         exp = HIBYTE(i) >= 0x81 && HIBYTE(i) <= 0xFE &&
1494             ((LOBYTE(i) >= 0x40 && LOBYTE(i) <= 0x7E) ||
1495              (LOBYTE(i) >= 0xA1 && LOBYTE(i) <= 0xFE));
1496         if(ret != exp) {
1497             err = 1;
1498             break;
1499         }
1500     }
1501     ok(!err, "_ismbclegal (950) : Expected 0x%x, got 0x%x (0x%x)\n", exp, ret, i);
1502     _setmbcp(1361); /* Korean (Johab) */
1503     err = 0;
1504     for(i = 0; i < 0x10000; i++) {
1505         ret = _ismbclegal(i);
1506         exp = ((HIBYTE(i) >= 0x81 && HIBYTE(i) <= 0xD3) ||
1507                (HIBYTE(i) >= 0xD8 && HIBYTE(i) <= 0xF9)) &&
1508               ((LOBYTE(i) >= 0x31 && LOBYTE(i) <= 0x7E) ||
1509                (LOBYTE(i) >= 0x81 && LOBYTE(i) <= 0xFE)) &&
1510                 HIBYTE(i) != 0xDF;
1511         if(ret != exp) {
1512             err = 1;
1513             break;
1514         }
1515     }
1516     todo_wine ok(!err, "_ismbclegal (1361) : Expected 0x%x, got 0x%x (0x%x)\n", exp, ret, i);
1517 
1518     _setmbcp(prev_cp);
1519 }
1520 
1521 static const struct {
1522     const char* string;
1523     const char* delimiter;
1524     int exp_offsetret1; /* returned offset from string after first call to strtok()
1525                            -1 means NULL  */
1526     int exp_offsetret2; /* returned offset from string after second call to strtok()
1527                            -1 means NULL  */
1528     int exp_offsetret3; /* returned offset from string after third call to strtok()
1529                            -1 means NULL  */
1530 } testcases_strtok[] = {
1531     { "red cabernet", " ", 0, 4, -1 },
1532     { "sparkling white riesling", " ", 0, 10, 16 },
1533     { " pale cream sherry", "e ", 1, 6, 9 },
1534     /* end mark */
1535     { 0}
1536 };
1537 
1538 static void test_strtok(void)
1539 {
1540     int i;
1541     char *strret;
1542     char teststr[100];
1543     for( i = 0; testcases_strtok[i].string; i++){
1544         strcpy( teststr, testcases_strtok[i].string);
1545         strret = strtok( teststr, testcases_strtok[i].delimiter);
1546         ok( (int)(strret - teststr) ==  testcases_strtok[i].exp_offsetret1 ||
1547                 (!strret && testcases_strtok[i].exp_offsetret1 == -1),
1548                 "string (%p) \'%s\' return %p\n",
1549                 teststr, testcases_strtok[i].string, strret);
1550         if( !strret) continue;
1551         strret = strtok( NULL, testcases_strtok[i].delimiter);
1552         ok( (int)(strret - teststr) ==  testcases_strtok[i].exp_offsetret2 ||
1553                 (!strret && testcases_strtok[i].exp_offsetret2 == -1),
1554                 "second call string (%p) \'%s\' return %p\n",
1555                 teststr, testcases_strtok[i].string, strret);
1556         if( !strret) continue;
1557         strret = strtok( NULL, testcases_strtok[i].delimiter);
1558         ok( (int)(strret - teststr) ==  testcases_strtok[i].exp_offsetret3 ||
1559                 (!strret && testcases_strtok[i].exp_offsetret3 == -1),
1560                 "third call string (%p) \'%s\' return %p\n",
1561                 teststr, testcases_strtok[i].string, strret);
1562     }
1563 }
1564 
1565 static void test_strtol(void)
1566 {
1567     static char neg[] = "-0x";
1568 
1569     char* e;
1570     LONG l;
1571     ULONG ul;
1572 
1573     /* errno is only set in case of error, so reset errno to EBADF to check for errno modification */
1574     /* errno is modified on W2K8+ */
1575     errno = EBADF;
1576     l = strtol("-1234", &e, 0);
1577     ok(l==-1234, "wrong value %d\n", l);
1578     ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno);
1579     errno = EBADF;
1580     ul = strtoul("1234", &e, 0);
1581     ok(ul==1234, "wrong value %u\n", ul);
1582     ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno);
1583 
1584     errno = EBADF;
1585     l = strtol("2147483647L", &e, 0);
1586     ok(l==2147483647, "wrong value %d\n", l);
1587     ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno);
1588     errno = EBADF;
1589     l = strtol("-2147483648L", &e, 0);
1590     ok(l==-2147483647L - 1, "wrong value %d\n", l);
1591     ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno);
1592     errno = EBADF;
1593     ul = strtoul("4294967295UL", &e, 0);
1594     ok(ul==4294967295ul, "wrong value %u\n", ul);
1595     ok(errno == EBADF || broken(errno == 0), "wrong errno %d\n", errno);
1596 
1597     errno = 0;
1598     l = strtol("9223372036854775807L", &e, 0);
1599     ok(l==2147483647, "wrong value %d\n", l);
1600     ok(errno == ERANGE, "wrong errno %d\n", errno);
1601     errno = 0;
1602     ul = strtoul("9223372036854775807L", &e, 0);
1603     ok(ul==4294967295ul, "wrong value %u\n", ul);
1604     ok(errno == ERANGE, "wrong errno %d\n", errno);
1605 
1606     errno = 0;
1607     ul = strtoul("-2", NULL, 0);
1608     ok(ul == -2, "wrong value %u\n", ul);
1609     ok(errno == 0, "wrong errno %d\n", errno);
1610 
1611     errno = 0;
1612     ul = strtoul("-4294967294", NULL, 0);
1613     ok(ul == 2, "wrong value %u\n", ul);
1614     ok(errno == 0, "wrong errno %d\n", errno);
1615 
1616     errno = 0;
1617     ul = strtoul("-4294967295", NULL, 0);
1618     ok(ul==1, "wrong value %u\n", ul);
1619     ok(errno == 0, "wrong errno %d\n", errno);
1620 
1621     errno = 0;
1622     ul = strtoul("-4294967296", NULL, 0);
1623     ok(ul == 1, "wrong value %u\n", ul);
1624     ok(errno == ERANGE, "wrong errno %d\n", errno);
1625 
1626     errno = 0;
1627     l = strtol(neg, &e, 0);
1628     ok(l == 0, "wrong value %d\n", l);
1629     ok(errno == 0, "wrong errno %d\n", errno);
1630     ok(e == neg, "e = %p, neg = %p\n", e, neg);
1631 }
1632 
1633 static void test_strnlen(void)
1634 {
1635     static const char str[] = "string";
1636     size_t res;
1637 
1638     if(!p_strnlen) {
1639         win_skip("strnlen not found\n");
1640         return;
1641     }
1642 
1643     res = p_strnlen(str, 20);
1644     ok(res == 6, "Returned length = %d\n", (int)res);
1645 
1646     res = p_strnlen(str, 3);
1647     ok(res == 3, "Returned length = %d\n", (int)res);
1648 
1649     res = p_strnlen(NULL, 0);
1650     ok(res == 0, "Returned length = %d\n", (int)res);
1651 }
1652 
1653 static void test__strtoi64(void)
1654 {
1655     static const char no1[] = "31923";
1656     static const char no2[] = "-213312";
1657     static const char no3[] = "12aa";
1658     static const char no4[] = "abc12";
1659     static const char overflow[] = "99999999999999999999";
1660     static const char neg_overflow[] = "-99999999999999999999";
1661     static const char hex[] = "0x123";
1662     static const char oct[] = "000123";
1663     static const char blanks[] = "        12 212.31";
1664 
1665     __int64 res;
1666     unsigned __int64 ures;
1667     char *endpos;
1668 
1669     if(!p_strtoi64 || !p_strtoui64) {
1670         win_skip("_strtoi64 or _strtoui64 not found\n");
1671         return;
1672     }
1673 
1674     errno = 0xdeadbeef;
1675     res = p_strtoi64(no1, NULL, 10);
1676     ok(res == 31923, "res != 31923\n");
1677     res = p_strtoi64(no2, NULL, 10);
1678     ok(res == -213312, "res != -213312\n");
1679     res = p_strtoi64(no3, NULL, 10);
1680     ok(res == 12, "res != 12\n");
1681     res = p_strtoi64(no4, &endpos, 10);
1682     ok(res == 0, "res != 0\n");
1683     ok(endpos == no4, "Scanning was not stopped on first character\n");
1684     res = p_strtoi64(hex, &endpos, 10);
1685     ok(res == 0, "res != 0\n");
1686     ok(endpos == hex+1, "Incorrect endpos (%p-%p)\n", hex, endpos);
1687     res = p_strtoi64(oct, &endpos, 10);
1688     ok(res == 123, "res != 123\n");
1689     ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos);
1690     res = p_strtoi64(blanks, &endpos, 10);
1691     ok(res == 12, "res != 12\n");
1692     ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos);
1693     ok(errno == 0xdeadbeef, "errno = %x\n", errno);
1694 
1695     errno = 0xdeadbeef;
1696     res = p_strtoi64(overflow, &endpos, 10);
1697     ok(res == _I64_MAX, "res != _I64_MAX\n");
1698     ok(endpos == overflow+strlen(overflow), "Incorrect endpos (%p-%p)\n", overflow, endpos);
1699     ok(errno == ERANGE, "errno = %x\n", errno);
1700 
1701     errno = 0xdeadbeef;
1702     res = p_strtoi64(neg_overflow, &endpos, 10);
1703     ok(res == _I64_MIN, "res != _I64_MIN\n");
1704     ok(endpos == neg_overflow+strlen(neg_overflow), "Incorrect endpos (%p-%p)\n", neg_overflow, endpos);
1705     ok(errno == ERANGE, "errno = %x\n", errno);
1706 
1707     errno = 0xdeadbeef;
1708     res = p_strtoi64(no1, &endpos, 16);
1709     ok(res == 203043, "res != 203043\n");
1710     ok(endpos == no1+strlen(no1), "Incorrect endpos (%p-%p)\n", no1, endpos);
1711     res = p_strtoi64(no2, &endpos, 16);
1712     ok(res == -2175762, "res != -2175762\n");
1713     ok(endpos == no2+strlen(no2), "Incorrect endpos (%p-%p)\n", no2, endpos);
1714     res = p_strtoi64(no3, &endpos, 16);
1715     ok(res == 4778, "res != 4778\n");
1716     ok(endpos == no3+strlen(no3), "Incorrect endpos (%p-%p)\n", no3, endpos);
1717     res = p_strtoi64(no4, &endpos, 16);
1718     ok(res == 703506, "res != 703506\n");
1719     ok(endpos == no4+strlen(no4), "Incorrect endpos (%p-%p)\n", no4, endpos);
1720     res = p_strtoi64(hex, &endpos, 16);
1721     ok(res == 291, "res != 291\n");
1722     ok(endpos == hex+strlen(hex), "Incorrect endpos (%p-%p)\n", hex, endpos);
1723     res = p_strtoi64(oct, &endpos, 16);
1724     ok(res == 291, "res != 291\n");
1725     ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos);
1726     res = p_strtoi64(blanks, &endpos, 16);
1727     ok(res == 18, "res != 18\n");
1728     ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos);
1729     ok(errno == 0xdeadbeef, "errno = %x\n", errno);
1730 
1731     errno = 0xdeadbeef;
1732     res = p_strtoi64(hex, &endpos, 36);
1733     ok(res == 1541019, "res != 1541019\n");
1734     ok(endpos == hex+strlen(hex), "Incorrect endpos (%p-%p)\n", hex, endpos);
1735     ok(errno == 0xdeadbeef, "errno = %x\n", errno);
1736 
1737     errno = 0xdeadbeef;
1738     res = p_strtoi64(no1, &endpos, 0);
1739     ok(res == 31923, "res != 31923\n");
1740     ok(endpos == no1+strlen(no1), "Incorrect endpos (%p-%p)\n", no1, endpos);
1741     res = p_strtoi64(no2, &endpos, 0);
1742     ok(res == -213312, "res != -213312\n");
1743     ok(endpos == no2+strlen(no2), "Incorrect endpos (%p-%p)\n", no2, endpos);
1744     res = p_strtoi64(no3, &endpos, 10);
1745     ok(res == 12, "res != 12\n");
1746     ok(endpos == no3+2, "Incorrect endpos (%p-%p)\n", no3, endpos);
1747     res = p_strtoi64(no4, &endpos, 10);
1748     ok(res == 0, "res != 0\n");
1749     ok(endpos == no4, "Incorrect endpos (%p-%p)\n", no4, endpos);
1750     res = p_strtoi64(hex, &endpos, 10);
1751     ok(res == 0, "res != 0\n");
1752     ok(endpos == hex+1, "Incorrect endpos (%p-%p)\n", hex, endpos);
1753     res = p_strtoi64(oct, &endpos, 10);
1754     ok(res == 123, "res != 123\n");
1755     ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos);
1756     res = p_strtoi64(blanks, &endpos, 10);
1757     ok(res == 12, "res != 12\n");
1758     ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos);
1759     ok(errno == 0xdeadbeef, "errno = %x\n", errno);
1760 
1761     errno = 0xdeadbeef;
1762     ures = p_strtoui64(no1, &endpos, 0);
1763     ok(ures == 31923, "ures != 31923\n");
1764     ok(endpos == no1+strlen(no1), "Incorrect endpos (%p-%p)\n", no1, endpos);
1765     ures = p_strtoui64(no2, &endpos, 0);
1766     ok(ures == -213312, "ures != -213312\n");
1767     ok(endpos == no2+strlen(no2), "Incorrect endpos (%p-%p)\n", no2, endpos);
1768     ures = p_strtoui64(no3, &endpos, 10);
1769     ok(ures == 12, "ures != 12\n");
1770     ok(endpos == no3+2, "Incorrect endpos (%p-%p)\n", no3, endpos);
1771     ures = p_strtoui64(no4, &endpos, 10);
1772     ok(ures == 0, "ures != 0\n");
1773     ok(endpos == no4, "Incorrect endpos (%p-%p)\n", no4, endpos);
1774     ures = p_strtoui64(hex, &endpos, 10);
1775     ok(ures == 0, "ures != 0\n");
1776     ok(endpos == hex+1, "Incorrect endpos (%p-%p)\n", hex, endpos);
1777     ures = p_strtoui64(oct, &endpos, 10);
1778     ok(ures == 123, "ures != 123\n");
1779     ok(endpos == oct+strlen(oct), "Incorrect endpos (%p-%p)\n", oct, endpos);
1780     ures = p_strtoui64(blanks, &endpos, 10);
1781     ok(ures == 12, "ures != 12\n");
1782     ok(endpos == blanks+10, "Incorrect endpos (%p-%p)\n", blanks, endpos);
1783     ok(errno == 0xdeadbeef, "errno = %x\n", errno);
1784 
1785     errno = 0xdeadbeef;
1786     ures = p_strtoui64(overflow, &endpos, 10);
1787     ok(ures == _UI64_MAX, "ures != _UI64_MAX\n");
1788     ok(endpos == overflow+strlen(overflow), "Incorrect endpos (%p-%p)\n", overflow, endpos);
1789     ok(errno == ERANGE, "errno = %x\n", errno);
1790 
1791     errno = 0xdeadbeef;
1792     ures = p_strtoui64(neg_overflow, &endpos, 10);
1793     ok(ures == 1, "ures != 1\n");
1794     ok(endpos == neg_overflow+strlen(neg_overflow), "Incorrect endpos (%p-%p)\n", neg_overflow, endpos);
1795     ok(errno == ERANGE, "errno = %x\n", errno);
1796 }
1797 
1798 static inline BOOL almost_equal(double d1, double d2) {
1799     if(d1-d2>-1e-30 && d1-d2<1e-30)
1800         return TRUE;
1801     return FALSE;
1802 }
1803 
1804 static void test__strtod(void)
1805 {
1806     const char double1[] = "12.1";
1807     const char double2[] = "-13.721";
1808     const char double3[] = "INF";
1809     const char double4[] = ".21e12";
1810     const char double5[] = "214353e-3";
1811     const char double6[] = "NAN";
1812     const char overflow[] = "1d9999999999999999999";
1813     const char white_chars[] = "  d10";
1814 
1815     char *end;
1816     double d;
1817 
1818     d = strtod(double1, &end);
1819     ok(almost_equal(d, 12.1), "d = %lf\n", d);
1820     ok(end == double1+4, "incorrect end (%d)\n", (int)(end-double1));
1821 
1822     d = strtod(double2, &end);
1823     ok(almost_equal(d, -13.721), "d = %lf\n", d);
1824     ok(end == double2+7, "incorrect end (%d)\n", (int)(end-double2));
1825 
1826     d = strtod(double3, &end);
1827     ok(almost_equal(d, 0), "d = %lf\n", d);
1828     ok(end == double3, "incorrect end (%d)\n", (int)(end-double3));
1829 
1830     d = strtod(double4, &end);
1831     ok(almost_equal(d, 210000000000.0), "d = %lf\n", d);
1832     ok(end == double4+6, "incorrect end (%d)\n", (int)(end-double4));
1833 
1834     d = strtod(double5, &end);
1835     ok(almost_equal(d, 214.353), "d = %lf\n", d);
1836     ok(end == double5+9, "incorrect end (%d)\n", (int)(end-double5));
1837 
1838     d = strtod(double6, &end);
1839     ok(almost_equal(d, 0), "d = %lf\n", d);
1840     ok(end == double6, "incorrect end (%d)\n", (int)(end-double6));
1841 
1842     d = strtod("12.1d2", NULL);
1843     ok(almost_equal(d, 12.1e2), "d = %lf\n", d);
1844 
1845     d = strtod(white_chars, &end);
1846     ok(almost_equal(d, 0), "d = %lf\n", d);
1847     ok(end == white_chars, "incorrect end (%d)\n", (int)(end-white_chars));
1848 
1849     if (!p__strtod_l)
1850         win_skip("_strtod_l not found\n");
1851     else
1852     {
1853         errno = EBADF;
1854         d = strtod(NULL, NULL);
1855         ok(almost_equal(d, 0.0), "d = %lf\n", d);
1856         ok(errno == EINVAL, "errno = %x\n", errno);
1857 
1858         errno = EBADF;
1859         end = (char *)0xdeadbeef;
1860         d = strtod(NULL, &end);
1861         ok(almost_equal(d, 0.0), "d = %lf\n", d);
1862         ok(errno == EINVAL, "errno = %x\n", errno);
1863         ok(!end, "incorrect end ptr %p\n", end);
1864 
1865         errno = EBADF;
1866         d = p__strtod_l(NULL, NULL, NULL);
1867         ok(almost_equal(d, 0.0), "d = %lf\n", d);
1868         ok(errno == EINVAL, "errno = %x\n", errno);
1869     }
1870 
1871     /* Set locale with non '.' decimal point (',') */
1872     if(!setlocale(LC_ALL, "Polish")) {
1873         win_skip("system with limited locales\n");
1874         return;
1875     }
1876 
1877     d = strtod("12.1", NULL);
1878     ok(almost_equal(d, 12.0), "d = %lf\n", d);
1879 
1880     d = strtod("12,1", NULL);
1881     ok(almost_equal(d, 12.1), "d = %lf\n", d);
1882 
1883     setlocale(LC_ALL, "C");
1884 
1885     /* Precision tests */
1886     d = strtod("0.1", NULL);
1887     ok(almost_equal(d, 0.1), "d = %lf\n", d);
1888     d = strtod("-0.1", NULL);
1889     ok(almost_equal(d, -0.1), "d = %lf\n", d);
1890     d = strtod("0.1281832188491894198128921", NULL);
1891     ok(almost_equal(d, 0.1281832188491894198128921), "d = %lf\n", d);
1892     d = strtod("0.82181281288121", NULL);
1893     ok(almost_equal(d, 0.82181281288121), "d = %lf\n", d);
1894     d = strtod("21921922352523587651128218821", NULL);
1895     ok(almost_equal(d, 21921922352523587651128218821.0), "d = %lf\n", d);
1896     d = strtod("0.1d238", NULL);
1897     ok(almost_equal(d, 0.1e238L), "d = %lf\n", d);
1898     d = strtod("0.1D-4736", NULL);
1899     ok(almost_equal(d, 0.1e-4736L), "d = %lf\n", d);
1900 
1901     errno = 0xdeadbeef;
1902     strtod(overflow, &end);
1903     ok(errno == ERANGE, "errno = %x\n", errno);
1904     ok(end == overflow+21, "incorrect end (%d)\n", (int)(end-overflow));
1905 
1906     errno = 0xdeadbeef;
1907     strtod("-1d309", NULL);
1908     ok(errno == ERANGE, "errno = %x\n", errno);
1909 }
1910 
1911 static void test_mbstowcs(void)
1912 {
1913     static const wchar_t wSimple[] = { 't','e','x','t',0 };
1914     static const wchar_t wHiragana[] = { 0x3042,0x3043,0 };
1915     static const wchar_t wEmpty[] = { 0 };
1916     static const char mSimple[] = "text";
1917     static const char mHiragana[] = { 0x82,0xa0,0x82,0xa1,0 };
1918     static const char mEmpty[] = { 0 };
1919 
1920     const wchar_t *pwstr;
1921     wchar_t wOut[6];
1922     char mOut[6];
1923     size_t ret;
1924     int err;
1925     const char *pmbstr;
1926     mbstate_t state;
1927 
1928     wOut[4] = '!'; wOut[5] = '\0';
1929     mOut[4] = '!'; mOut[5] = '\0';
1930 
1931     if(pmbstowcs_s) {
1932         /* crashes on some systems */
1933         errno = 0xdeadbeef;
1934         ret = mbstowcs(wOut, NULL, 4);
1935         ok(ret == -1, "mbstowcs did not return -1\n");
1936         ok(errno == EINVAL, "errno = %d\n", errno);
1937     }
1938 
1939     ret = mbstowcs(NULL, mSimple, 0);
1940     ok(ret == 4, "mbstowcs did not return 4\n");
1941 
1942     ret = mbstowcs(wOut, mSimple, 4);
1943     ok(ret == 4, "mbstowcs did not return 4\n");
1944     ok(!memcmp(wOut, wSimple, 4*sizeof(wchar_t)), "wOut = %s\n", wine_dbgstr_w(wOut));
1945     ok(wOut[4] == '!', "wOut[4] != \'!\'\n");
1946 
1947     ret = mbstowcs(NULL, mEmpty, 1);
1948     ok(ret == 0, "mbstowcs did not return 0, got %d\n", (int)ret);
1949 
1950     ret = mbstowcs(wOut, mEmpty, 1);
1951     ok(ret == 0, "mbstowcs did not return 0, got %d\n", (int)ret);
1952     ok(!memcmp(wOut, wEmpty, sizeof(wEmpty)), "wOut = %s\n", wine_dbgstr_w(wOut));
1953 
1954     ret = wcstombs(NULL, wSimple, 0);
1955     ok(ret == 4, "wcstombs did not return 4\n");
1956 
1957     ret = wcstombs(mOut, wSimple, 6);
1958     ok(ret == 4, "wcstombs did not return 4\n");
1959     ok(!memcmp(mOut, mSimple, 5*sizeof(char)), "mOut = %s\n", mOut);
1960 
1961     ret = wcstombs(mOut, wSimple, 2);
1962     ok(ret == 2, "wcstombs did not return 2\n");
1963     ok(!memcmp(mOut, mSimple, 5*sizeof(char)), "mOut = %s\n", mOut);
1964 
1965     ret = wcstombs(NULL, wEmpty, 1);
1966     ok(ret == 0, "wcstombs did not return 0, got %d\n", (int)ret);
1967 
1968     ret = wcstombs(mOut, wEmpty, 1);
1969     ok(ret == 0, "wcstombs did not return 0, got %d\n", (int)ret);
1970     ok(!memcmp(mOut, mEmpty, sizeof(mEmpty)), "mOut = %s\n", mOut);
1971 
1972     if(!setlocale(LC_ALL, "Japanese_Japan.932")) {
1973         win_skip("Japanese_Japan.932 locale not available\n");
1974         return;
1975     }
1976 
1977     ret = mbstowcs(wOut, mHiragana, 6);
1978     ok(ret == 2, "mbstowcs did not return 2\n");
1979     ok(!memcmp(wOut, wHiragana, sizeof(wHiragana)), "wOut = %s\n", wine_dbgstr_w(wOut));
1980 
1981     ret = mbstowcs(wOut, mEmpty, 6);
1982     ok(ret == 0, "mbstowcs did not return 0, got %d\n", (int)ret);
1983     ok(!memcmp(wOut, wEmpty, sizeof(wEmpty)), "wOut = %s\n", wine_dbgstr_w(wOut));
1984 
1985     ret = wcstombs(mOut, wHiragana, 6);
1986     ok(ret == 4, "wcstombs did not return 4\n");
1987     ok(!memcmp(mOut, mHiragana, sizeof(mHiragana)), "mOut = %s\n", mOut);
1988 
1989     ret = wcstombs(mOut, wEmpty, 6);
1990     ok(ret == 0, "wcstombs did not return 0, got %d\n", (int)ret);
1991     ok(!memcmp(mOut, mEmpty, sizeof(mEmpty)), "mOut = %s\n", mOut);
1992 
1993     if(!pmbstowcs_s || !pwcstombs_s) {
1994         setlocale(LC_ALL, "C");
1995         win_skip("mbstowcs_s or wcstombs_s not available\n");
1996         return;
1997     }
1998 
1999     err = pmbstowcs_s(&ret, wOut, 6, mSimple, _TRUNCATE);
2000     ok(err == 0, "err = %d\n", err);
2001     ok(ret == 5, "mbstowcs_s did not return 5\n");
2002     ok(!memcmp(wOut, wSimple, sizeof(wSimple)), "wOut = %s\n", wine_dbgstr_w(wOut));
2003 
2004     err = pmbstowcs_s(&ret, wOut, 6, mHiragana, _TRUNCATE);
2005     ok(err == 0, "err = %d\n", err);
2006     ok(ret == 3, "mbstowcs_s did not return 3\n");
2007     ok(!memcmp(wOut, wHiragana, sizeof(wHiragana)), "wOut = %s\n", wine_dbgstr_w(wOut));
2008 
2009     err = pmbstowcs_s(&ret, wOut, 6, mEmpty, _TRUNCATE);
2010     ok(err == 0, "err = %d\n", err);
2011     ok(ret == 1, "mbstowcs_s did not return 1, got %d\n", (int)ret);
2012     ok(!memcmp(wOut, wEmpty, sizeof(wEmpty)), "wOut = %s\n", wine_dbgstr_w(wOut));
2013 
2014     err = pmbstowcs_s(&ret, NULL, 0, mHiragana, 1);
2015     ok(err == 0, "err = %d\n", err);
2016     ok(ret == 3, "mbstowcs_s did not return 3\n");
2017 
2018     err = pwcstombs_s(&ret, mOut, 6, wSimple, _TRUNCATE);
2019     ok(err == 0, "err = %d\n", err);
2020     ok(ret == 5, "wcstombs_s did not return 5\n");
2021     ok(!memcmp(mOut, mSimple, sizeof(mSimple)), "mOut = %s\n", mOut);
2022 
2023     err = pwcstombs_s(&ret, mOut, 6, wHiragana, _TRUNCATE);
2024     ok(err == 0, "err = %d\n", err);
2025     ok(ret == 5, "wcstombs_s did not return 5\n");
2026     ok(!memcmp(mOut, mHiragana, sizeof(mHiragana)), "mOut = %s\n", mOut);
2027 
2028     err = pwcstombs_s(&ret, mOut, 6, wEmpty, _TRUNCATE);
2029     ok(err == 0, "err = %d\n", err);
2030     ok(ret == 1, "wcstombs_s did not return 1, got %d\n", (int)ret);
2031     ok(!memcmp(mOut, mEmpty, sizeof(mEmpty)), "mOut = %s\n", mOut);
2032 
2033     err = pwcstombs_s(&ret, NULL, 0, wHiragana, 1);
2034     ok(err == 0, "err = %d\n", err);
2035     ok(ret == 5, "wcstombs_s did not return 5\n");
2036 
2037     if(!pwcsrtombs) {
2038         setlocale(LC_ALL, "C");
2039         win_skip("wcsrtombs not available\n");
2040         return;
2041     }
2042 
2043     pwstr = wSimple;
2044     err = -3;
2045     ret = pwcsrtombs(mOut, &pwstr, 4, &err);
2046     ok(ret == 4, "wcsrtombs did not return 4\n");
2047     ok(err == 0, "err = %d\n", err);
2048     ok(pwstr == wSimple+4, "pwstr = %p (wszSimple = %p)\n", pwstr, wSimple);
2049     ok(!memcmp(mOut, mSimple, ret), "mOut = %s\n", mOut);
2050 
2051     pwstr = wSimple;
2052     ret = pwcsrtombs(mOut, &pwstr, 5, NULL);
2053     ok(ret == 4, "wcsrtombs did not return 4\n");
2054     ok(pwstr == NULL, "pwstr != NULL\n");
2055     ok(!memcmp(mOut, mSimple, sizeof(mSimple)), "mOut = %s\n", mOut);
2056 
2057     if(!p_mbsrtowcs) {
2058         setlocale(LC_ALL, "C");
2059         win_skip("mbsrtowcs not available\n");
2060         return;
2061     }
2062 
2063     pmbstr = mHiragana;
2064     ret = p_mbsrtowcs(NULL, &pmbstr, 6, NULL);
2065     ok(ret == 2, "mbsrtowcs did not return 2\n");
2066     ok(pmbstr == mHiragana, "pmbstr = %p, expected %p\n", pmbstr, mHiragana);
2067 
2068     pmbstr = mHiragana;
2069     ret = p_mbsrtowcs(wOut, &pmbstr, 6, NULL);
2070     ok(ret == 2, "mbsrtowcs did not return 2\n");
2071     ok(!memcmp(wOut, wHiragana, sizeof(wHiragana)), "wOut = %s\n", wine_dbgstr_w(wOut));
2072     ok(!pmbstr, "pmbstr != NULL\n");
2073 
2074     state = mHiragana[0];
2075     pmbstr = mHiragana+1;
2076     ret = p_mbsrtowcs(wOut, &pmbstr, 6, &state);
2077     ok(ret == 2, "mbsrtowcs did not return 2\n");
2078     ok(wOut[0] == 0x3042, "wOut[0] = %x\n", wOut[0]);
2079     ok(wOut[1] == 0xff61, "wOut[1] = %x\n", wOut[1]);
2080     ok(wOut[2] == 0, "wOut[2] = %x\n", wOut[2]);
2081     ok(!pmbstr, "pmbstr != NULL\n");
2082 
2083     errno = EBADF;
2084     ret = p_mbsrtowcs(wOut, NULL, 6, &state);
2085     ok(ret == -1, "mbsrtowcs did not return -1\n");
2086     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2087 
2088     if(!p_mbsrtowcs_s) {
2089         setlocale(LC_ALL, "C");
2090         win_skip("mbsrtowcs_s not available\n");
2091         return;
2092     }
2093 
2094     pmbstr = mHiragana;
2095     err = p_mbsrtowcs_s(&ret, NULL, 0, NULL, 6, NULL);
2096     ok(ret == -1, "mbsrtowcs_s did not return -1\n");
2097     ok(err == EINVAL, "err = %d\n", err);
2098     err = p_mbsrtowcs_s(&ret, NULL, 1, &pmbstr, 6, NULL);
2099     ok(ret == -1, "mbsrtowcs_s did not return -1\n");
2100     ok(err == EINVAL, "err = %d\n", err);
2101     err = p_mbsrtowcs_s(&ret, wOut, 0, &pmbstr, 6, NULL);
2102     ok(ret == -1, "mbsrtowcs_s did not return -1\n");
2103     ok(err == EINVAL, "err = %d\n", err);
2104 
2105     pmbstr = mHiragana;
2106     errno = 0;
2107     err = p_mbsrtowcs_s(&ret, NULL, 0, &pmbstr, 6, NULL);
2108     ok(ret == 3, "mbsrtowcs_s did not return 3\n");
2109     ok(err == 0, "err = %d\n", err);
2110     ok(pmbstr == mHiragana, "pmbstr = %p, expected %p\n", pmbstr, mHiragana);
2111     ok(errno == 0, "errno = %d\n", errno);
2112 
2113     pmbstr = mHiragana;
2114     err = p_mbsrtowcs_s(&ret, wOut, 1, &pmbstr, 6, NULL);
2115     ok(ret == 2, "mbsrtowcs_s did not return 2\n");
2116     ok(err == 0, "err = %d\n", err);
2117     ok(!wOut[0], "wOut[0] = '%c'\n", wOut[0]);
2118     ok(pmbstr == mHiragana+2, "pmbstr = %p, expected %p\n", pmbstr, mHiragana+2);
2119     ok(errno == 0, "errno = %d\n", errno);
2120 
2121     pmbstr = mHiragana;
2122     err = p_mbsrtowcs_s(&ret, wOut, 2, &pmbstr, 6, NULL);
2123     ok(ret == 3, "mbsrtowcs_s did not return 3\n");
2124     ok(err == 0, "err = %d\n", err);
2125     ok(!wOut[0], "wOut[0] = '%c'\n", wOut[0]);
2126     ok(pmbstr == mHiragana+4, "pmbstr = %p, expected %p\n", pmbstr, mHiragana+4);
2127     ok(errno == 0, "errno = %d\n", errno);
2128 
2129     pmbstr = mHiragana;
2130     err = p_mbsrtowcs_s(&ret, wOut, 3, &pmbstr, 6, NULL);
2131     ok(ret == 3, "mbsrtowcs_s did not return 3\n");
2132     ok(err == 0, "err = %d\n", err);
2133     ok(!pmbstr, "pmbstr != NULL\n");
2134     ok(errno == 0, "errno = %d\n", errno);
2135 
2136     setlocale(LC_ALL, "C");
2137 }
2138 
2139 static void test_gcvt(void)
2140 {
2141     char buf[1024], *res;
2142     errno_t err;
2143 
2144     if(!p_gcvt_s) {
2145         win_skip("Skipping _gcvt tests\n");
2146         return;
2147     }
2148 
2149     errno = 0;
2150     res = _gcvt(1.2, -1, buf);
2151     ok(res == NULL, "res != NULL\n");
2152     ok(errno == ERANGE, "errno = %d\n", errno);
2153 
2154     errno = 0;
2155     res = _gcvt(1.2, 5, NULL);
2156     ok(res == NULL, "res != NULL\n");
2157     ok(errno == EINVAL, "errno = %d\n", errno);
2158 
2159     res = gcvt(1.2, 5, buf);
2160     ok(res == buf, "res != buf\n");
2161     ok(!strcmp(buf, "1.2"), "buf = %s\n", buf);
2162 
2163     buf[0] = 'x';
2164     err = p_gcvt_s(buf, 5, 1.2, 10);
2165     ok(err == ERANGE, "err = %d\n", err);
2166     ok(buf[0] == '\0', "buf[0] = %c\n", buf[0]);
2167 
2168     buf[0] = 'x';
2169     err = p_gcvt_s(buf, 4, 123456, 2);
2170     ok(err == ERANGE, "err = %d\n", err);
2171     ok(buf[0] == '\0', "buf[0] = %c\n", buf[0]);
2172 }
2173 
2174 static void test__itoa_s(void)
2175 {
2176     errno_t ret;
2177     char buffer[33];
2178 
2179     if (!p_itoa_s)
2180     {
2181         win_skip("Skipping _itoa_s tests\n");
2182         return;
2183     }
2184 
2185     errno = EBADF;
2186     ret = p_itoa_s(0, NULL, 0, 0);
2187     ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
2188     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2189 
2190     memset(buffer, 'X', sizeof(buffer));
2191     errno = EBADF;
2192     ret = p_itoa_s(0, buffer, 0, 0);
2193     ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
2194     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2195     ok(buffer[0] == 'X', "Expected the output buffer to be untouched\n");
2196 
2197     memset(buffer, 'X', sizeof(buffer));
2198     errno = EBADF;
2199     ret = p_itoa_s(0, buffer, sizeof(buffer), 0);
2200     ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
2201     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2202     ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
2203 
2204     memset(buffer, 'X', sizeof(buffer));
2205     errno = EBADF;
2206     ret = p_itoa_s(0, buffer, sizeof(buffer), 64);
2207     ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
2208     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2209     ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
2210 
2211     memset(buffer, 'X', sizeof(buffer));
2212     errno = EBADF;
2213     ret = p_itoa_s(12345678, buffer, 4, 10);
2214     ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
2215     ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno);
2216     ok(!memcmp(buffer, "\000765", 4),
2217        "Expected the output buffer to be null terminated with truncated output\n");
2218 
2219     memset(buffer, 'X', sizeof(buffer));
2220     errno = EBADF;
2221     ret = p_itoa_s(12345678, buffer, 8, 10);
2222     ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
2223     ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno);
2224     ok(!memcmp(buffer, "\0007654321", 8),
2225        "Expected the output buffer to be null terminated with truncated output\n");
2226 
2227     memset(buffer, 'X', sizeof(buffer));
2228     errno = EBADF;
2229     ret = p_itoa_s(-12345678, buffer, 9, 10);
2230     ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
2231     ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno);
2232     ok(!memcmp(buffer, "\00087654321", 9),
2233        "Expected the output buffer to be null terminated with truncated output\n");
2234 
2235     ret = p_itoa_s(12345678, buffer, 9, 10);
2236     ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
2237     ok(!strcmp(buffer, "12345678"),
2238        "Expected output buffer string to be \"12345678\", got \"%s\"\n",
2239        buffer);
2240 
2241     ret = p_itoa_s(43690, buffer, sizeof(buffer), 2);
2242     ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
2243     ok(!strcmp(buffer, "1010101010101010"),
2244        "Expected output buffer string to be \"1010101010101010\", got \"%s\"\n",
2245        buffer);
2246 
2247     ret = p_itoa_s(1092009, buffer, sizeof(buffer), 36);
2248     ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
2249     ok(!strcmp(buffer, "nell"),
2250        "Expected output buffer string to be \"nell\", got \"%s\"\n",
2251        buffer);
2252 
2253     ret = p_itoa_s(5704, buffer, sizeof(buffer), 18);
2254     ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
2255     ok(!strcmp(buffer, "hag"),
2256        "Expected output buffer string to be \"hag\", got \"%s\"\n",
2257        buffer);
2258 
2259     ret = p_itoa_s(-12345678, buffer, sizeof(buffer), 10);
2260     ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
2261     ok(!strcmp(buffer, "-12345678"),
2262        "Expected output buffer string to be \"-12345678\", got \"%s\"\n",
2263        buffer);
2264 
2265     itoa(100, buffer, 100);
2266     ok(!strcmp(buffer, "10"),
2267             "Expected output buffer string to be \"10\", got \"%s\"\n", buffer);
2268 }
2269 
2270 static void test__strlwr_s(void)
2271 {
2272     errno_t ret;
2273     char buffer[20];
2274 
2275     if (!p_strlwr_s)
2276     {
2277         win_skip("Skipping _strlwr_s tests\n");
2278         return;
2279     }
2280 
2281     errno = EBADF;
2282     ret = p_strlwr_s(NULL, 0);
2283     ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
2284     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2285 
2286     errno = EBADF;
2287     ret = p_strlwr_s(NULL, sizeof(buffer));
2288     ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
2289     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2290 
2291     errno = EBADF;
2292     ret = p_strlwr_s(buffer, 0);
2293     ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
2294     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2295 
2296     strcpy(buffer, "GoRrIsTeR");
2297     errno = EBADF;
2298     ret = p_strlwr_s(buffer, 5);
2299     ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
2300     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2301     ok(!memcmp(buffer, "\0oRrIsTeR", sizeof("\0oRrIsTeR")),
2302        "Expected the output buffer to be \"\\0oRrIsTeR\"\n");
2303 
2304     strcpy(buffer, "GoRrIsTeR");
2305     errno = EBADF;
2306     ret = p_strlwr_s(buffer, sizeof("GoRrIsTeR") - 1);
2307     ok(ret == EINVAL, "Expected _strlwr_s to return EINVAL, got %d\n", ret);
2308     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2309     ok(!memcmp(buffer, "\0oRrIsTeR", sizeof("\0oRrIsTeR")),
2310        "Expected the output buffer to be \"\\0oRrIsTeR\"\n");
2311 
2312     strcpy(buffer, "GoRrIsTeR");
2313     ret = p_strlwr_s(buffer, sizeof("GoRrIsTeR"));
2314     ok(ret == 0, "Expected _strlwr_s to return 0, got %d\n", ret);
2315     ok(!strcmp(buffer, "gorrister"),
2316        "Expected the output buffer to be \"gorrister\", got \"%s\"\n",
2317        buffer);
2318 
2319     memcpy(buffer, "GoRrIsTeR\0ELLEN", sizeof("GoRrIsTeR\0ELLEN"));
2320     ret = p_strlwr_s(buffer, sizeof(buffer));
2321     ok(ret == 0, "Expected _strlwr_s to return 0, got %d\n", ret);
2322     ok(!memcmp(buffer, "gorrister\0ELLEN", sizeof("gorrister\0ELLEN")),
2323        "Expected the output buffer to be \"gorrister\\0ELLEN\", got \"%s\"\n",
2324        buffer);
2325 }
2326 
2327 static void test_wcsncat_s(void)
2328 {
2329     static wchar_t abcW[] = {'a','b','c',0};
2330     int ret;
2331     wchar_t dst[4];
2332     wchar_t src[4];
2333 
2334     if (!p_wcsncat_s)
2335     {
2336         win_skip("skipping wcsncat_s tests\n");
2337         return;
2338     }
2339 
2340     memcpy(src, abcW, sizeof(abcW));
2341     dst[0] = 0;
2342     ret = p_wcsncat_s(NULL, 4, src, 4);
2343     ok(ret == EINVAL, "err = %d\n", ret);
2344     ret = p_wcsncat_s(dst, 0, src, 4);
2345     ok(ret == EINVAL, "err = %d\n", ret);
2346     ret = p_wcsncat_s(dst, 0, src, _TRUNCATE);
2347     ok(ret == EINVAL, "err = %d\n", ret);
2348     ret = p_wcsncat_s(dst, 4, NULL, 0);
2349     ok(ret == 0, "err = %d\n", ret);
2350 
2351     dst[0] = 0;
2352     ret = p_wcsncat_s(dst, 2, src, 4);
2353     ok(ret == ERANGE, "err = %d\n", ret);
2354 
2355     dst[0] = 0;
2356     ret = p_wcsncat_s(dst, 2, src, _TRUNCATE);
2357     ok(ret == STRUNCATE, "err = %d\n", ret);
2358     ok(dst[0] == 'a' && dst[1] == 0, "dst is %s\n", wine_dbgstr_w(dst));
2359 
2360     memcpy(dst, abcW, sizeof(abcW));
2361     dst[3] = 'd';
2362     ret = p_wcsncat_s(dst, 4, src, 4);
2363     ok(ret == EINVAL, "err = %d\n", ret);
2364 }
2365 
2366 static void test__mbsnbcat_s(void)
2367 {
2368     unsigned char dest[16];
2369     const unsigned char first[] = "dinosaur";
2370     const unsigned char second[] = "duck";
2371     int ret;
2372 
2373     if (!p_mbsnbcat_s)
2374     {
2375         win_skip("Skipping _mbsnbcat_s tests\n");
2376         return;
2377     }
2378 
2379     /* Test invalid arguments. */
2380     ret = p_mbsnbcat_s(NULL, 0, NULL, 0);
2381     ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret);
2382 
2383     errno = EBADF;
2384     ret = p_mbsnbcat_s(NULL, 10, NULL, 0);
2385     ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret);
2386     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2387 
2388     errno = EBADF;
2389     ret = p_mbsnbcat_s(NULL, 0, NULL, 10);
2390     ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret);
2391     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2392 
2393     memset(dest, 'X', sizeof(dest));
2394     errno = EBADF;
2395     ret = p_mbsnbcat_s(dest, 0, NULL, 0);
2396     ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret);
2397     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2398     ok(dest[0] == 'X', "Expected the output buffer to be untouched\n");
2399 
2400     memset(dest, 'X', sizeof(dest));
2401     errno = EBADF;
2402     ret = p_mbsnbcat_s(dest, 0, second, 0);
2403     ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret);
2404     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2405     ok(dest[0] == 'X', "Expected the output buffer to be untouched\n");
2406 
2407     memset(dest, 'X', sizeof(dest));
2408     errno = EBADF;
2409     ret = p_mbsnbcat_s(dest, sizeof(dest), NULL, 0);
2410     ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret);
2411     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2412     ok(dest[0] == '\0', "Expected the output buffer to be null terminated\n");
2413 
2414     memset(dest, 'X', sizeof(dest));
2415     errno = EBADF;
2416     ret = p_mbsnbcat_s(dest, sizeof(dest), NULL, 10);
2417     ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret);
2418     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2419     ok(dest[0] == '\0', "Expected the output buffer to be null terminated\n");
2420 
2421     memset(dest, 'X', sizeof(dest));
2422     dest[0] = '\0';
2423     ret = p_mbsnbcat_s(dest, sizeof(dest), second, sizeof(second));
2424     ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret);
2425     ok(!memcmp(dest, second, sizeof(second)),
2426        "Expected the output buffer string to be \"duck\"\n");
2427 
2428     /* Test source truncation behavior. */
2429     memset(dest, 'X', sizeof(dest));
2430     memcpy(dest, first, sizeof(first));
2431     ret = p_mbsnbcat_s(dest, sizeof(dest), second, 0);
2432     ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret);
2433     ok(!memcmp(dest, first, sizeof(first)),
2434        "Expected the output buffer string to be \"dinosaur\"\n");
2435 
2436     memset(dest, 'X', sizeof(dest));
2437     memcpy(dest, first, sizeof(first));
2438     ret = p_mbsnbcat_s(dest, sizeof(dest), second, sizeof(second));
2439     ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret);
2440     ok(!memcmp(dest, "dinosaurduck", sizeof("dinosaurduck")),
2441        "Expected the output buffer string to be \"dinosaurduck\"\n");
2442 
2443     memset(dest, 'X', sizeof(dest));
2444     memcpy(dest, first, sizeof(first));
2445     ret = p_mbsnbcat_s(dest, sizeof(dest), second, sizeof(second) + 1);
2446     ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret);
2447     ok(!memcmp(dest, "dinosaurduck", sizeof("dinosaurduck")),
2448        "Expected the output buffer string to be \"dinosaurduck\"\n");
2449 
2450     memset(dest, 'X', sizeof(dest));
2451     memcpy(dest, first, sizeof(first));
2452     ret = p_mbsnbcat_s(dest, sizeof(dest), second, sizeof(second) - 1);
2453     ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret);
2454     ok(!memcmp(dest, "dinosaurduck", sizeof("dinosaurduck")),
2455        "Expected the output buffer string to be \"dinosaurduck\"\n");
2456 
2457     memset(dest, 'X', sizeof(dest));
2458     memcpy(dest, first, sizeof(first));
2459     ret = p_mbsnbcat_s(dest, sizeof(dest), second, sizeof(second) - 2);
2460     ok(ret == 0, "Expected _mbsnbcat_s to return 0, got %d\n", ret);
2461     ok(!memcmp(dest, "dinosaurduc", sizeof("dinosaurduc")),
2462        "Expected the output buffer string to be \"dinosaurduc\"\n");
2463 
2464     /* Test destination truncation behavior. */
2465     memset(dest, 'X', sizeof(dest));
2466     memcpy(dest, first, sizeof(first));
2467     errno = EBADF;
2468     ret = p_mbsnbcat_s(dest, sizeof(first) - 1, second, sizeof(second));
2469     ok(ret == EINVAL, "Expected _mbsnbcat_s to return EINVAL, got %d\n", ret);
2470     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2471     ok(!memcmp(dest, "\0inosaur", sizeof("\0inosaur") - 1),
2472        "Expected the output buffer string to be \"\\0inosaur\" without ending null terminator\n");
2473 
2474     memset(dest, 'X', sizeof(dest));
2475     memcpy(dest, first, sizeof(first));
2476     errno = EBADF;
2477     ret = p_mbsnbcat_s(dest, sizeof(first), second, sizeof(second));
2478     ok(ret == ERANGE, "Expected _mbsnbcat_s to return ERANGE, got %d\n", ret);
2479     ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno);
2480     ok(!memcmp(dest, "\0inosaurd", sizeof("\0inosaurd") - 1),
2481        "Expected the output buffer string to be \"\\0inosaurd\" without ending null terminator\n");
2482 
2483     memset(dest, 'X', sizeof(dest));
2484     memcpy(dest, first, sizeof(first));
2485     errno = EBADF;
2486     ret = p_mbsnbcat_s(dest, sizeof(first) + 1, second, sizeof(second));
2487     ok(ret == ERANGE, "Expected _mbsnbcat_s to return ERANGE, got %d\n", ret);
2488     ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno);
2489     ok(!memcmp(dest, "\0inosaurdu", sizeof("\0inosaurdu") - 1),
2490        "Expected the output buffer string to be \"\\0inosaurdu\" without ending null terminator\n");
2491 }
2492 
2493 static void test__mbsupr_s(void)
2494 {
2495     errno_t ret;
2496     unsigned char buffer[20];
2497 
2498     if (!p_mbsupr_s)
2499     {
2500         win_skip("Skipping _mbsupr_s tests\n");
2501         return;
2502     }
2503 
2504     errno = EBADF;
2505     ret = p_mbsupr_s(NULL, 0);
2506     ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret);
2507 
2508     errno = EBADF;
2509     ret = p_mbsupr_s(NULL, sizeof(buffer));
2510     ok(ret == EINVAL, "Expected _mbsupr_s to return EINVAL, got %d\n", ret);
2511     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2512 
2513     errno = EBADF;
2514     ret = p_mbsupr_s(buffer, 0);
2515     ok(ret == EINVAL, "Expected _mbsupr_s to return EINVAL, got %d\n", ret);
2516     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2517 
2518     memcpy(buffer, "abcdefgh", sizeof("abcdefgh"));
2519     errno = EBADF;
2520     ret = p_mbsupr_s(buffer, sizeof("abcdefgh"));
2521     ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret);
2522     ok(!memcmp(buffer, "ABCDEFGH", sizeof("ABCDEFGH")),
2523        "Expected the output buffer to be \"ABCDEFGH\", got \"%s\"\n",
2524        buffer);
2525 
2526     memcpy(buffer, "abcdefgh", sizeof("abcdefgh"));
2527     errno = EBADF;
2528     ret = p_mbsupr_s(buffer, sizeof(buffer));
2529     ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret);
2530     ok(!memcmp(buffer, "ABCDEFGH", sizeof("ABCDEFGH")),
2531        "Expected the output buffer to be \"ABCDEFGH\", got \"%s\"\n",
2532        buffer);
2533 
2534     memcpy(buffer, "abcdefgh", sizeof("abcdefgh"));
2535     errno = EBADF;
2536     ret = p_mbsupr_s(buffer, 4);
2537     ok(ret == EINVAL, "Expected _mbsupr_s to return EINVAL, got %d\n", ret);
2538     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2539 
2540     memcpy(buffer, "abcdefgh\0ijklmnop", sizeof("abcdefgh\0ijklmnop"));
2541     errno = EBADF;
2542     ret = p_mbsupr_s(buffer, sizeof(buffer));
2543     ok(ret == 0, "Expected _mbsupr_s to return 0, got %d\n", ret);
2544     ok(!memcmp(buffer, "ABCDEFGH\0ijklmnop", sizeof("ABCDEFGH\0ijklmnop")),
2545        "Expected the output buffer to be \"ABCDEFGH\\0ijklmnop\", got \"%s\"\n",
2546        buffer);
2547 
2548 }
2549 
2550 static void test__mbslwr_s(void)
2551 {
2552     errno_t ret;
2553     unsigned char buffer[20];
2554 
2555     if (!p_mbslwr_s)
2556     {
2557         win_skip("Skipping _mbslwr_s tests\n");
2558         return;
2559     }
2560 
2561     errno = EBADF;
2562     ret = p_mbslwr_s(NULL, 0);
2563     ok(ret == 0, "Expected _mbslwr_s to return 0, got %d\n", ret);
2564 
2565     errno = EBADF;
2566     ret = p_mbslwr_s(NULL, sizeof(buffer));
2567     ok(ret == EINVAL, "Expected _mbslwr_s to return EINVAL, got %d\n", ret);
2568     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2569 
2570     errno = EBADF;
2571     ret = p_mbslwr_s(buffer, 0);
2572     ok(ret == EINVAL, "Expected _mbslwr_s to return EINVAL, got %d\n", ret);
2573     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2574 
2575     memcpy(buffer, "ABCDEFGH", sizeof("ABCDEFGH"));
2576     errno = EBADF;
2577     ret = p_mbslwr_s(buffer, sizeof("ABCDEFGH"));
2578     ok(ret == 0, "Expected _mbslwr_s to return 0, got %d\n", ret);
2579     ok(!memcmp(buffer, "abcdefgh", sizeof("abcdefgh")),
2580        "Expected the output buffer to be \"abcdefgh\", got \"%s\"\n",
2581        buffer);
2582 
2583     memcpy(buffer, "ABCDEFGH", sizeof("ABCDEFGH"));
2584     errno = EBADF;
2585     ret = p_mbslwr_s(buffer, sizeof(buffer));
2586     ok(ret == 0, "Expected _mbslwr_s to return 0, got %d\n", ret);
2587     ok(!memcmp(buffer, "abcdefgh", sizeof("abcdefgh")),
2588        "Expected the output buffer to be \"abcdefgh\", got \"%s\"\n",
2589        buffer);
2590 
2591     memcpy(buffer, "ABCDEFGH", sizeof("ABCDEFGH"));
2592     errno = EBADF;
2593     ret = p_mbslwr_s(buffer, 4);
2594     ok(ret == EINVAL, "Expected _mbslwr_s to return EINVAL, got %d\n", ret);
2595     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2596 
2597     memcpy(buffer, "ABCDEFGH\0IJKLMNOP", sizeof("ABCDEFGH\0IJKLMNOP"));
2598     errno = EBADF;
2599     ret = p_mbslwr_s(buffer, sizeof(buffer));
2600     ok(ret == 0, "Expected _mbslwr_s to return 0, got %d\n", ret);
2601     ok(!memcmp(buffer, "abcdefgh\0IJKLMNOP", sizeof("abcdefgh\0IJKLMNOP")),
2602        "Expected the output buffer to be \"abcdefgh\\0IJKLMNOP\", got \"%s\"\n",
2603        buffer);
2604 }
2605 
2606 static void test__mbstok(void)
2607 {
2608     const unsigned char delim[] = "t";
2609 
2610     char str[] = "!.!test";
2611     unsigned char *ret;
2612 
2613     strtok(str, "!");
2614 
2615     ret = _mbstok(NULL, delim);
2616     /* most versions of msvcrt use the same buffer for strtok and _mbstok */
2617     ok(!ret || broken((char*)ret==str+4),
2618             "_mbstok(NULL, \"t\") = %p, expected NULL (%p)\n", ret, str);
2619 
2620     ret = _mbstok(NULL, delim);
2621     ok(!ret, "_mbstok(NULL, \"t\") = %p, expected NULL\n", ret);
2622 }
2623 
2624 static void test__ultoa_s(void)
2625 {
2626     errno_t ret;
2627     char buffer[33];
2628 
2629     if (!p_ultoa_s)
2630     {
2631         win_skip("Skipping _ultoa_s tests\n");
2632         return;
2633     }
2634 
2635     errno = EBADF;
2636     ret = p_ultoa_s(0, NULL, 0, 0);
2637     ok(ret == EINVAL, "Expected _ultoa_s to return EINVAL, got %d\n", ret);
2638     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2639 
2640     memset(buffer, 'X', sizeof(buffer));
2641     errno = EBADF;
2642     ret = p_ultoa_s(0, buffer, 0, 0);
2643     ok(ret == EINVAL, "Expected _ultoa_s to return EINVAL, got %d\n", ret);
2644     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2645     ok(buffer[0] == 'X', "Expected the output buffer to be untouched\n");
2646 
2647     memset(buffer, 'X', sizeof(buffer));
2648     errno = EBADF;
2649     ret = p_ultoa_s(0, buffer, sizeof(buffer), 0);
2650     ok(ret == EINVAL, "Expected _ultoa_s to return EINVAL, got %d\n", ret);
2651     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2652     ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
2653 
2654     memset(buffer, 'X', sizeof(buffer));
2655     errno = EBADF;
2656     ret = p_ultoa_s(0, buffer, sizeof(buffer), 64);
2657     ok(ret == EINVAL, "Expected _ultoa_s to return EINVAL, got %d\n", ret);
2658     ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
2659     ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
2660 
2661     memset(buffer, 'X', sizeof(buffer));
2662     errno = EBADF;
2663     ret = p_ultoa_s(12345678, buffer, 4, 10);
2664     ok(ret == ERANGE, "Expected _ultoa_s to return ERANGE, got %d\n", ret);
2665     ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno);
2666     ok(!memcmp(buffer, "\000765", 4),
2667        "Expected the output buffer to be null terminated with truncated output\n");
2668 
2669     memset(buffer, 'X', sizeof(buffer));
2670     errno = EBADF;
2671     ret = p_ultoa_s(12345678, buffer, 8, 10);
2672     ok(ret == ERANGE, "Expected _ultoa_s to return ERANGE, got %d\n", ret);
2673     ok(errno == ERANGE, "Expected errno to be ERANGE, got %d\n", errno);
2674     ok(!memcmp(buffer, "\0007654321", 8),
2675        "Expected the output buffer to be null terminated with truncated output\n");
2676 
2677     ret = p_ultoa_s(12345678, buffer, 9, 10);
2678     ok(ret == 0, "Expected _ultoa_s to return 0, got %d\n", ret);
2679     ok(!strcmp(buffer, "12345678"),
2680        "Expected output buffer string to be \"12345678\", got \"%s\"\n",
2681        buffer);
2682 
2683     ret = p_ultoa_s(43690, buffer, sizeof(buffer), 2);
2684     ok(ret == 0, "Expected _ultoa_s to return 0, got %d\n", ret);
2685     ok(!strcmp(buffer, "1010101010101010"),
2686        "Expected output buffer string to be \"1010101010101010\", got \"%s\"\n",
2687        buffer);
2688 
2689     ret = p_ultoa_s(1092009, buffer, sizeof(buffer), 36);
2690     ok(ret == 0, "Expected _ultoa_s to return 0, got %d\n", ret);
2691     ok(!strcmp(buffer, "nell"),
2692        "Expected output buffer string to be \"nell\", got \"%s\"\n",
2693        buffer);
2694 
2695     ret = p_ultoa_s(5704, buffer, sizeof(buffer), 18);
2696     ok(ret == 0, "Expected _ultoa_s to return 0, got %d\n", ret);
2697     ok(!strcmp(buffer, "hag"),
2698        "Expected output buffer string to be \"hag\", got \"%s\"\n",
2699        buffer);
2700 }
2701 
2702 static void test_wctob(void)
2703 {
2704     int ret;
2705 
2706     if(!p_wctob || !setlocale(LC_ALL, "chinese-traditional")) {
2707         win_skip("Skipping wctob tests\n");
2708         return;
2709     }
2710 
2711     ret = p_wctob(0x8141);
2712     ok(ret == EOF, "ret = %x\n", ret);
2713 
2714     ret = p_wctob(0x81);
2715     ok(ret == EOF, "ret = %x\n", ret);
2716 
2717     ret = p_wctob(0xe0);
2718     ok(ret == 0x61, "ret = %x\n", ret);
2719 
2720     _setmbcp(1250);
2721     ret = p_wctob(0x81);
2722     ok(ret == EOF, "ret = %x\n", ret);
2723 
2724     setlocale(LC_ALL, "C");
2725     ret = p_wctob(0x8141);
2726     ok(ret == EOF, "ret = %x\n", ret);
2727 
2728     ret = p_wctob(0x81);
2729     ok(ret == (int)(char)0x81, "ret = %x\n", ret);
2730 
2731     ret = p_wctob(0x9f);
2732     ok(ret == (int)(char)0x9f, "ret = %x\n", ret);
2733 
2734     ret = p_wctob(0xe0);
2735     ok(ret == (int)(char)0xe0, "ret = %x\n", ret);
2736 }
2737 static void test_wctomb(void)
2738 {
2739     mbstate_t state;
2740     unsigned char dst[10];
2741     size_t ret;
2742 
2743     if(!p_wcrtomb || !setlocale(LC_ALL, "Japanese_Japan.932")) {
2744         win_skip("wcrtomb tests\n");
2745         return;
2746     }
2747 
2748     ret = p_wcrtomb(NULL, 0x3042, NULL);
2749     ok(ret == 2, "wcrtomb did not return 2\n");
2750 
2751     state = 1;
2752     dst[2] = 'a';
2753     ret = p_wcrtomb((char*)dst, 0x3042, &state);
2754     ok(ret == 2, "wcrtomb did not return 2\n");
2755     ok(state == 0, "state != 0\n");
2756     ok(dst[0] == 0x82, "dst[0] = %x, expected 0x82\n", dst[0]);
2757     ok(dst[1] == 0xa0, "dst[1] = %x, expected 0xa0\n", dst[1]);
2758     ok(dst[2] == 'a', "dst[2] != 'a'\n");
2759 
2760     ret = p_wcrtomb((char*)dst, 0x3043, NULL);
2761     ok(ret == 2, "wcrtomb did not return 2\n");
2762     ok(dst[0] == 0x82, "dst[0] = %x, expected 0x82\n", dst[0]);
2763     ok(dst[1] == 0xa1, "dst[1] = %x, expected 0xa1\n", dst[1]);
2764 
2765     ret = p_wcrtomb((char*)dst, 0x20, NULL);
2766     ok(ret == 1, "wcrtomb did not return 1\n");
2767     ok(dst[0] == 0x20, "dst[0] = %x, expected 0x20\n", dst[0]);
2768 
2769     ret = p_wcrtomb((char*)dst, 0xffff, NULL);
2770     ok(ret == -1, "wcrtomb did not return -1\n");
2771     ok(dst[0] == 0x3f, "dst[0] = %x, expected 0x3f\n", dst[0]);
2772 
2773     setlocale(LC_ALL, "C");
2774 }
2775 
2776 static void test_tolower(void)
2777 {
2778     WCHAR chw, lower;
2779     char ch, lch;
2780     int ret, len;
2781 
2782     /* test C locale when locale was never changed */
2783     ret = p_tolower(0x41);
2784     ok(ret == 0x61, "ret = %x\n", ret);
2785 
2786     ret = p_tolower(0xF4);
2787     ok(ret == 0xF4, "ret = %x\n", ret);
2788 
2789     errno = 0xdeadbeef;
2790     ret = p_tolower((char)0xF4);
2791     todo_wine ok(ret == (char)0xF4, "ret = %x\n", ret);
2792     todo_wine ok(errno == 0xdeadbeef, "errno = %d\n", errno);
2793 
2794     errno = 0xdeadbeef;
2795     ret = p_tolower((char)0xD0);
2796     todo_wine ok(ret == (char)0xD0, "ret = %x\n", ret);
2797     todo_wine ok(errno == 0xdeadbeef, "errno = %d\n", errno);
2798 
2799     /* test C locale after setting locale */
2800     if(!setlocale(LC_ALL, "us")) {
2801         win_skip("skipping tolower tests that depends on locale\n");
2802         return;
2803     }
2804     setlocale(LC_ALL, "C");
2805 
2806     ch = 0xF4;
2807     errno = 0xdeadbeef;
2808     ret = p_tolower(ch);
2809     if(!MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, &ch, 1, &chw, 1) ||
2810             LCMapStringW(CP_ACP, LCMAP_LOWERCASE, &chw, 1, &lower, 1) != 1 ||
2811             (len = WideCharToMultiByte(CP_ACP, 0, &lower, 1, &lch, 1, NULL, NULL)) != 1)
2812         len = 0;
2813     if(len)
2814         ok(ret==(unsigned char)lch || broken(ret==ch)/*WinXP-*/, "ret = %x\n", ret);
2815     else
2816         ok(ret == ch, "ret = %x\n", ret);
2817     if(!len || ret==(unsigned char)lch)
2818         ok(errno == EILSEQ, "errno = %d\n", errno);
2819 
2820     ch = 0xD0;
2821     errno = 0xdeadbeef;
2822     ret = p_tolower(ch);
2823     if(!MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, &ch, 1, &chw, 1) ||
2824             LCMapStringW(CP_ACP, LCMAP_LOWERCASE, &chw, 1, &lower, 1) != 1 ||
2825             (len = WideCharToMultiByte(CP_ACP, 0, &lower, 1, &lch, 1, NULL, NULL)) != 1)
2826         len = 0;
2827     if(len)
2828         ok(ret==(unsigned char)lch || broken(ret==ch)/*WinXP-*/, "ret = %x\n", ret);
2829     else
2830         ok(ret == ch, "ret = %x\n", ret);
2831     if(!len || ret==(unsigned char)lch)
2832         ok(errno == EILSEQ, "errno = %d\n", errno);
2833 
2834     ret = p_tolower(0xD0);
2835     ok(ret == 0xD0, "ret = %x\n", ret);
2836 
2837     ok(setlocale(LC_ALL, "us") != NULL, "setlocale failed\n");
2838 
2839     ret = p_tolower((char)0xD0);
2840     ok(ret == 0xF0, "ret = %x\n", ret);
2841 
2842     ret = p_tolower(0xD0);
2843     ok(ret == 0xF0, "ret = %x\n", ret);
2844 
2845     setlocale(LC_ALL, "C");
2846 }
2847 
2848 static void test__atodbl(void)
2849 {
2850     _CRT_DOUBLE d;
2851     char num[32];
2852     int ret;
2853 
2854     if(!p__atodbl_l) {
2855         /* Old versions of msvcrt use different values for _OVERFLOW and _UNDERFLOW
2856          * Because of this lets skip _atodbl tests when _atodbl_l is not available */
2857         win_skip("_atodbl_l is not available\n");
2858         return;
2859     }
2860 
2861     num[0] = 0;
2862     ret = p__atodbl_l(&d, num, NULL);
2863     ok(ret == 0, "_atodbl_l(&d, \"\", NULL) returned %d, expected 0\n", ret);
2864     ok(d.x == 0, "d.x = %lf, expected 0\n", d.x);
2865     ret = _atodbl(&d, num);
2866     ok(ret == 0, "_atodbl(&d, \"\") returned %d, expected 0\n", ret);
2867     ok(d.x == 0, "d.x = %lf, expected 0\n", d.x);
2868 
2869     strcpy(num, "t");
2870     ret = p__atodbl_l(&d, num, NULL);
2871     ok(ret == 0, "_atodbl_l(&d, \"t\", NULL) returned %d, expected 0\n", ret);
2872     ok(d.x == 0, "d.x = %lf, expected 0\n", d.x);
2873     ret = _atodbl(&d, num);
2874     ok(ret == 0, "_atodbl(&d, \"t\") returned %d, expected 0\n", ret);
2875     ok(d.x == 0, "d.x = %lf, expected 0\n", d.x);
2876 
2877     strcpy(num, "0");
2878     ret = p__atodbl_l(&d, num, NULL);
2879     ok(ret == 0, "_atodbl_l(&d, \"0\", NULL) returned %d, expected 0\n", ret);
2880     ok(d.x == 0, "d.x = %lf, expected 0\n", d.x);
2881     ret = _atodbl(&d, num);
2882     ok(ret == 0, "_atodbl(&d, \"0\") returned %d, expected 0\n", ret);
2883     ok(d.x == 0, "d.x = %lf, expected 0\n", d.x);
2884 
2885     strcpy(num, "123");
2886     ret = p__atodbl_l(&d, num, NULL);
2887     ok(ret == 0, "_atodbl_l(&d, \"123\", NULL) returned %d, expected 0\n", ret);
2888     ok(d.x == 123, "d.x = %lf, expected 123\n", d.x);
2889     ret = _atodbl(&d, num);
2890     ok(ret == 0, "_atodbl(&d, \"123\") returned %d, expected 0\n", ret);
2891     ok(d.x == 123, "d.x = %lf, expected 123\n", d.x);
2892 
2893     strcpy(num, "1e-309");
2894     ret = p__atodbl_l(&d, num, NULL);
2895     ok(ret == _UNDERFLOW, "_atodbl_l(&d, \"1e-309\", NULL) returned %d, expected _UNDERFLOW\n", ret);
2896     ok(d.x!=0 && almost_equal(d.x, 0), "d.x = %le, expected 0\n", d.x);
2897     ret = _atodbl(&d, num);
2898     ok(ret == _UNDERFLOW, "_atodbl(&d, \"1e-309\") returned %d, expected _UNDERFLOW\n", ret);
2899     ok(d.x!=0 && almost_equal(d.x, 0), "d.x = %le, expected 0\n", d.x);
2900 
2901     strcpy(num, "1e309");
2902     ret = p__atodbl_l(&d, num, NULL);
2903     ok(ret == _OVERFLOW, "_atodbl_l(&d, \"1e309\", NULL) returned %d, expected _OVERFLOW\n", ret);
2904     ret = _atodbl(&d, num);
2905     ok(ret == _OVERFLOW, "_atodbl(&d, \"1e309\") returned %d, expected _OVERFLOW\n", ret);
2906 }
2907 
2908 static void test__stricmp(void)
2909 {
2910     int ret;
2911 
2912     ret = _stricmp("test", "test");
2913     ok(ret == 0, "_stricmp returned %d\n", ret);
2914     ret = _stricmp("a", "z");
2915     ok(ret < 0, "_stricmp returned %d\n", ret);
2916     ret = _stricmp("z", "a");
2917     ok(ret > 0, "_stricmp returned %d\n", ret);
2918     ret = _stricmp("\xa5", "\xb9");
2919     ok(ret < 0, "_stricmp returned %d\n", ret);
2920 
2921     if(!setlocale(LC_ALL, "polish")) {
2922         win_skip("stricmp tests\n");
2923         return;
2924     }
2925 
2926     ret = _stricmp("test", "test");
2927     ok(ret == 0, "_stricmp returned %d\n", ret);
2928     ret = _stricmp("a", "z");
2929     ok(ret < 0, "_stricmp returned %d\n", ret);
2930     ret = _stricmp("z", "a");
2931     ok(ret > 0, "_stricmp returned %d\n", ret);
2932     ret = _stricmp("\xa5", "\xb9");
2933     ok(ret == 0, "_stricmp returned %d\n", ret);
2934     ret = _stricmp("a", "\xb9");
2935     ok(ret < 0, "_stricmp returned %d\n", ret);
2936 
2937     setlocale(LC_ALL, "C");
2938 }
2939 
2940 static void test__wcstoi64(void)
2941 {
2942     static const WCHAR digit[] = { '9', 0 };
2943     static const WCHAR space[] = { ' ', 0 };
2944     static const WCHAR stock[] = { 0x3231, 0 }; /* PARENTHESIZED IDEOGRAPH STOCK */
2945     static const WCHAR cjk_1[] = { 0x4e00, 0 }; /* CJK Ideograph, First */
2946     static const WCHAR tamil[] = { 0x0bef, 0 }; /* TAMIL DIGIT NINE */
2947     static const WCHAR thai[]  = { 0x0e59, 0 }; /* THAI DIGIT NINE */
2948     static const WCHAR fullwidth[] = { 0xff19, 0 }; /* FULLWIDTH DIGIT NINE */
2949     static const WCHAR superscript1[] = { 0xb9, 0 }; /* SUPERSCRIPT ONE */
2950     static const WCHAR minus_0x91[]  = { '-', 0x0e50, 'x', 0xff19, '1', 0 };
2951     static const WCHAR plus_071[]  = { '+', 0x0e50, 0xff17, '1', 0 };
2952     static const WCHAR hex[] = { 0xff19, 'f', 0x0e59, 0xff46, 0 };
2953     static const WCHAR zeros[] = {
2954         0x660, 0x6f0, 0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xc66, 0xce6,
2955         0xd66, 0xe50, 0xed0, 0xf20, 0x1040, 0x17e0, 0x1810, 0xff10
2956     };
2957     int i;
2958 
2959     __int64 res;
2960     unsigned __int64 ures;
2961     WCHAR *endpos;
2962 
2963     if (!p_wcstoi64 || !p_wcstoui64) {
2964         win_skip("_wcstoi64 or _wcstoui64 not found\n");
2965         return;
2966     }
2967 
2968     res = p_wcstoi64(digit, NULL, 10);
2969     ok(res == 9, "res != 9\n");
2970     res = p_wcstoi64(space, &endpos, 0);
2971     ok(endpos == space, "endpos != space\n");
2972     res = p_wcstoi64(stock, &endpos, 10);
2973     ok(res == 0, "res != 0\n");
2974     ok(endpos == stock, "Incorrect endpos (%p-%p)\n", stock, endpos);
2975     res = p_wcstoi64(cjk_1, NULL, 0);
2976     ok(res == 0, "res != 0\n");
2977     res = p_wcstoi64(tamil, &endpos, 10);
2978     ok(res == 0, "res != 0\n");
2979     ok(endpos == tamil, "Incorrect endpos (%p-%p)\n", tamil, endpos);
2980     res = p_wcstoi64(thai, NULL, 10);
2981     ok(res == 9, "res != 9\n");
2982     res = p_wcstoi64(fullwidth, NULL, 10);
2983     ok(res == 9, "res != 9\n");
2984     res = p_wcstoi64(superscript1, NULL, 10);
2985     ok(res == 0, "res != 0\n");
2986     res = p_wcstoi64(hex, NULL, 16);
2987     ok(res == 0x9f9, "res != 0x9f9\n");
2988     res = p_wcstoi64(minus_0x91, NULL, 0);
2989     ok(res == -0x91, "res != -0x91\n");
2990     res = p_wcstoi64(plus_071, NULL, 0);
2991     ok(res == 071, "res != 071\n");
2992 
2993     ures = p_wcstoui64(digit, NULL, 10);
2994     ok(ures == 9, "ures != 9\n");
2995     ures = p_wcstoui64(space, &endpos, 0);
2996     ok(endpos == space, "endpos != space\n");
2997     ures = p_wcstoui64(stock, &endpos, 10);
2998     ok(ures == 0, "ures != 0\n");
2999     ok(endpos == stock, "Incorrect endpos (%p-%p)\n", stock, endpos);
3000     ures = p_wcstoui64(tamil, &endpos, 10);
3001     ok(ures == 0, "ures != 0\n");
3002     ok(endpos == tamil, "Incorrect endpos (%p-%p)\n", tamil, endpos);
3003     ures = p_wcstoui64(thai, NULL, 10);
3004     ok(ures == 9, "ures != 9\n");
3005     ures = p_wcstoui64(fullwidth, NULL, 10);
3006     ok(ures == 9, "ures != 9\n");
3007     ures = p_wcstoui64(superscript1, NULL, 10);
3008     ok(ures == 0, "ures != 0\n");
3009     ures = p_wcstoui64(hex, NULL, 16);
3010     ok(ures == 0x9f9, "ures != 0x9f9\n");
3011     ures = p_wcstoui64(plus_071, NULL, 0);
3012     ok(ures == 071, "ures != 071\n");
3013 
3014     /* Test various unicode digits */
3015     for (i = 0; i < ARRAY_SIZE(zeros); ++i) {
3016         WCHAR tmp[] = {zeros[i] + 4, zeros[i], zeros[i] + 5, 0};
3017         res = p_wcstoi64(tmp, NULL, 0);
3018         ok(res == 405, "with zero = U+%04X: got %d, expected 405\n", zeros[i], (int)res);
3019         tmp[1] = zeros[i] + 10;
3020         res = p_wcstoi64(tmp, NULL, 16);
3021         ok(res == 4, "with zero = U+%04X: got %d, expected 4\n", zeros[i], (int)res);
3022     }
3023 
3024     return;
3025 }
3026 
3027 static void test_atoi(void)
3028 {
3029     int r;
3030 
3031     r = atoi("0");
3032     ok(r == 0, "atoi(0) = %d\n", r);
3033 
3034     r = atoi("-1");
3035     ok(r == -1, "atoi(-1) = %d\n", r);
3036 
3037     r = atoi("1");
3038     ok(r == 1, "atoi(1) = %d\n", r);
3039 
3040     r = atoi("4294967296");
3041     ok(r == 0, "atoi(4294967296) = %d\n", r);
3042 }
3043 
3044 static void test_atof(void)
3045 {
3046     double d;
3047 
3048     d = atof("0.0");
3049     ok(almost_equal(d, 0.0), "d = %lf\n", d);
3050 
3051     d = atof("1.0");
3052     ok(almost_equal(d, 1.0), "d = %lf\n", d);
3053 
3054     d = atof("-1.0");
3055     ok(almost_equal(d, -1.0), "d = %lf\n", d);
3056 
3057     if (!p__atof_l)
3058     {
3059         win_skip("_atof_l not found\n");
3060         return;
3061     }
3062 
3063     errno = EBADF;
3064     d = atof(NULL);
3065     ok(almost_equal(d, 0.0), "d = %lf\n", d);
3066     ok(errno == EINVAL, "errno = %x\n", errno);
3067 
3068     errno = EBADF;
3069     d = p__atof_l(NULL, NULL);
3070     ok(almost_equal(d, 0.0), "d = %lf\n", d);
3071     ok(errno == EINVAL, "errno = %x\n", errno);
3072 }
3073 
3074 static void test_strncpy(void)
3075 {
3076 #define TEST_STRNCPY_LEN 10
3077     char *ret;
3078     char dst[TEST_STRNCPY_LEN + 1];
3079     char not_null_terminated[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
3080 
3081     /* strlen(src) > TEST_STRNCPY_LEN */
3082     ret = strncpy(dst, "01234567890123456789", TEST_STRNCPY_LEN);
3083     ok(ret == dst, "ret != dst\n");
3084     ok(!strncmp(dst, "0123456789", TEST_STRNCPY_LEN), "dst != 0123456789\n");
3085 
3086     /* without null-terminated */
3087     ret = strncpy(dst, not_null_terminated, TEST_STRNCPY_LEN);
3088     ok(ret == dst, "ret != dst\n");
3089     ok(!strncmp(dst, "0123456789", TEST_STRNCPY_LEN), "dst != 0123456789\n");
3090 
3091     /* strlen(src) < TEST_STRNCPY_LEN */
3092     strcpy(dst, "0123456789");
3093     ret = strncpy(dst, "012345", TEST_STRNCPY_LEN);
3094     ok(ret == dst, "ret != dst\n");
3095     ok(!strcmp(dst, "012345"), "dst != 012345\n");
3096     ok(dst[TEST_STRNCPY_LEN - 1] == '\0', "dst[TEST_STRNCPY_LEN - 1] != 0\n");
3097 
3098     /* strlen(src) == TEST_STRNCPY_LEN */
3099     ret = strncpy(dst, "0123456789", TEST_STRNCPY_LEN);
3100     ok(ret == dst, "ret != dst\n");
3101     ok(!strncmp(dst, "0123456789", TEST_STRNCPY_LEN), "dst != 0123456789\n");
3102 }
3103 
3104 static void test_strxfrm(void)
3105 {
3106     char dest[256];
3107     size_t ret;
3108 
3109     /* crashes on old version of msvcrt */
3110     if(p__atodbl_l) {
3111         errno = 0xdeadbeef;
3112         ret = strxfrm(NULL, "src", 1);
3113         ok(ret == INT_MAX, "ret = %d\n", (int)ret);
3114         ok(errno == EINVAL, "errno = %d\n", errno);
3115 
3116         errno = 0xdeadbeef;
3117         ret = strxfrm(dest, NULL, 100);
3118         ok(ret == INT_MAX, "ret = %d\n", (int)ret);
3119         ok(errno == EINVAL, "errno = %d\n", errno);
3120     }
3121 
3122     ret = strxfrm(NULL, "src", 0);
3123     ok(ret == 3, "ret = %d\n", (int)ret);
3124     dest[0] = 'a';
3125     ret = strxfrm(dest, "src", 0);
3126     ok(ret == 3, "ret = %d\n", (int)ret);
3127     ok(dest[0] == 'a', "dest[0] = %d\n", dest[0]);
3128 
3129     dest[3] = 'a';
3130     ret = strxfrm(dest, "src", 5);
3131     ok(ret == 3, "ret = %d\n", (int)ret);
3132     ok(!strcmp(dest, "src"), "dest = %s\n", dest);
3133 
3134     errno = 0xdeadbeef;
3135     dest[1] = 'a';
3136     ret = strxfrm(dest, "src", 1);
3137     ok(ret == 3, "ret = %d\n", (int)ret);
3138     ok(dest[0] == 's', "dest[0] = %d\n", dest[0]);
3139     ok(dest[1] == 'a', "dest[1] = %d\n", dest[1]);
3140     ok(errno == 0xdeadbeef, "errno = %d\n", errno);
3141 
3142     ret = strxfrm(dest, "", 5);
3143     ok(ret == 0, "ret = %d\n", (int)ret);
3144     ok(!dest[0], "dest[0] = %d\n", dest[0]);
3145 
3146     if(!setlocale(LC_ALL, "polish")) {
3147         win_skip("stxfrm tests\n");
3148         return;
3149     }
3150 
3151     ret = strxfrm(NULL, "src", 0);
3152     ok(ret < sizeof(dest)-1, "ret = %d\n", (int)ret);
3153     dest[0] = 'a';
3154     ret = strxfrm(dest, "src", 0);
3155     ok(ret < sizeof(dest)-1, "ret = %d\n", (int)ret);
3156     ok(dest[0] == 'a', "dest[0] = %d\n", dest[0]);
3157 
3158     ret = strxfrm(dest, "src", ret+1);
3159     ok(ret < sizeof(dest)-1, "ret = %d\n", (int)ret);
3160     ok(dest[0], "dest[0] = 0\n");
3161 
3162     errno = 0xdeadbeef;
3163     dest[0] = 'a';
3164     ret = strxfrm(dest, "src", 5);
3165     ok(ret>5 && ret<sizeof(dest)-1, "ret = %d\n", (int)ret);
3166     ok(!dest[0] || broken(!p__atodbl_l && dest[0]=='a'), "dest[0] = %d\n", dest[0]);
3167 
3168     setlocale(LC_ALL, "C");
3169 }
3170 
3171 static void test__strnset_s(void)
3172 {
3173     char buf[5] = {0};
3174     int r;
3175 
3176     if(!p__strnset_s) {
3177         win_skip("_strnset_s not available\n");
3178         return;
3179     }
3180 
3181     r = p__strnset_s(NULL, 0, 'a', 0);
3182     ok(r == 0, "r = %d\n", r);
3183 
3184     buf[0] = buf[1] = buf[2] = 'b';
3185     r = p__strnset_s(buf, sizeof(buf), 'a', 2);
3186     ok(r == 0, "r = %d\n", r);
3187     ok(!strcmp(buf, "aab"), "buf = %s\n", buf);
3188 
3189     r = p__strnset_s(buf, 0, 'a', 0);
3190     ok(r == EINVAL, "r = %d\n", r);
3191 
3192     r = p__strnset_s(NULL, 0, 'a', 1);
3193     ok(r == EINVAL, "r = %d\n", r);
3194 
3195     buf[3] = 'b';
3196     r = p__strnset_s(buf, sizeof(buf)-1, 'c', 2);
3197     ok(r == EINVAL, "r = %d\n", r);
3198     ok(!buf[0] && buf[1]=='c' && buf[2]=='b', "buf = %s\n", buf);
3199 }
3200 
3201 static void test__wcsset_s(void)
3202 {
3203     wchar_t str[10];
3204     int r;
3205 
3206     if(!p__wcsset_s) {
3207         win_skip("_wcsset_s not available\n");
3208         return;
3209     }
3210 
3211     r = p__wcsset_s(NULL, 0, 'a');
3212     ok(r == EINVAL, "r = %d\n", r);
3213 
3214     str[0] = 'a';
3215     r = p__wcsset_s(str, 0, 'a');
3216     ok(r == EINVAL, "r = %d\n", r);
3217     ok(str[0] == 'a', "str[0] = %d\n", str[0]);
3218 
3219     str[0] = 'a';
3220     str[1] = 'b';
3221     r = p__wcsset_s(str, 2, 'c');
3222     ok(r == EINVAL, "r = %d\n", r);
3223     ok(!str[0], "str[0] = %d\n", str[0]);
3224     ok(str[1] == 'b', "str[1] = %d\n", str[1]);
3225 
3226     str[0] = 'a';
3227     str[1] = 0;
3228     str[2] = 'b';
3229     r = p__wcsset_s(str, 3, 'c');
3230     ok(str[0] == 'c', "str[0] = %d\n", str[0]);
3231     ok(str[1] == 0, "str[1] = %d\n", str[1]);
3232     ok(str[2] == 'b', "str[2] = %d\n", str[2]);
3233 }
3234 
3235 static void test__mbscmp(void)
3236 {
3237     static const unsigned char a[] = {'a',0}, b[] = {'b',0};
3238     int ret;
3239 
3240     if (!p_mbrlen)
3241     {
3242         win_skip("_mbscmp tests\n");
3243         return;
3244     }
3245 
3246     ret = _mbscmp(NULL, NULL);
3247     ok(ret == INT_MAX, "got %d\n", ret);
3248 
3249     ret = _mbscmp(a, NULL);
3250     ok(ret == INT_MAX, "got %d\n", ret);
3251 
3252     ret = _mbscmp(NULL, a);
3253     ok(ret == INT_MAX, "got %d\n", ret);
3254 
3255     ret = _mbscmp(a, a);
3256     ok(!ret, "got %d\n", ret);
3257 
3258     ret = _mbscmp(a, b);
3259     ok(ret == -1, "got %d\n", ret);
3260 
3261     ret = _mbscmp(b, a);
3262     ok(ret == 1, "got %d\n", ret);
3263 }
3264 
3265 static void test__ismbclx(void)
3266 {
3267     int cp, ret;
3268 
3269     ret = _ismbcl0(0);
3270     ok(!ret, "got %d\n", ret);
3271 
3272     cp = _setmbcp(1252);
3273 
3274     ret = _ismbcl0(0x8140);
3275     ok(!ret, "got %d\n", ret);
3276 
3277     _setmbcp(932);
3278 
3279     ret = _ismbcl0(0);
3280     ok(!ret, "got %d\n", ret);
3281 
3282     ret = _ismbcl0(0x8140);
3283     ok(ret, "got %d\n", ret);
3284 
3285     _setmbcp(cp);
3286 }
3287 
3288 static void test__memicmp(void)
3289 {
3290     static const char *s1 = "abc";
3291     static const char *s2 = "aBd";
3292     int ret;
3293 
3294     ret = p__memicmp(NULL, NULL, 0);
3295     ok(!ret, "got %d\n", ret);
3296 
3297     ret = p__memicmp(s1, s2, 2);
3298     ok(!ret, "got %d\n", ret);
3299 
3300     ret = p__memicmp(s1, s2, 3);
3301     ok(ret == -1, "got %d\n", ret);
3302 
3303     if (!p__memicmp_l)
3304         return;
3305 
3306     /* Following calls crash on WinXP/W2k3. */
3307     errno = 0xdeadbeef;
3308     ret = p__memicmp(NULL, NULL, 1);
3309     ok(ret == _NLSCMPERROR, "got %d\n", ret);
3310     ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
3311 
3312     errno = 0xdeadbeef;
3313     ret = p__memicmp(s1, NULL, 1);
3314     ok(ret == _NLSCMPERROR, "got %d\n", ret);
3315     ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
3316 
3317     errno = 0xdeadbeef;
3318     ret = p__memicmp(NULL, s2, 1);
3319     ok(ret == _NLSCMPERROR, "got %d\n", ret);
3320     ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
3321 }
3322 
3323 static void test__memicmp_l(void)
3324 {
3325     static const char *s1 = "abc";
3326     static const char *s2 = "aBd";
3327     int ret;
3328 
3329     if (!p__memicmp_l)
3330     {
3331         win_skip("_memicmp_l not found.\n");
3332         return;
3333     }
3334 
3335     errno = 0xdeadbeef;
3336     ret = p__memicmp_l(NULL, NULL, 0, NULL);
3337     ok(!ret, "got %d\n", ret);
3338     ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno);
3339 
3340     errno = 0xdeadbeef;
3341     ret = p__memicmp_l(NULL, NULL, 1, NULL);
3342     ok(ret == _NLSCMPERROR, "got %d\n", ret);
3343     ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
3344 
3345     errno = 0xdeadbeef;
3346     ret = p__memicmp_l(s1, NULL, 1, NULL);
3347     ok(ret == _NLSCMPERROR, "got %d\n", ret);
3348     ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
3349 
3350     errno = 0xdeadbeef;
3351     ret = p__memicmp_l(NULL, s2, 1, NULL);
3352     ok(ret == _NLSCMPERROR, "got %d\n", ret);
3353     ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
3354 
3355     errno = 0xdeadbeef;
3356     ret = p__memicmp_l(s1, s2, 2, NULL);
3357     ok(!ret, "got %d\n", ret);
3358     ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno);
3359 
3360     errno = 0xdeadbeef;
3361     ret = p__memicmp_l(s1, s2, 3, NULL);
3362     ok(ret == -1, "got %d\n", ret);
3363     ok(errno == 0xdeadbeef, "errno is %d, expected 0xdeadbeef\n", errno);
3364 }
3365 
3366 static void test__strupr(void)
3367 {
3368     const char str[] = "123";
3369     char str2[4];
3370     char *mem, *p;
3371     DWORD prot;
3372 
3373     mem = VirtualAlloc(NULL, sizeof(str), MEM_COMMIT, PAGE_READWRITE);
3374     ok(mem != NULL, "VirtualAlloc failed\n");
3375     memcpy(mem, str, sizeof(str));
3376     ok(VirtualProtect(mem, sizeof(str), PAGE_READONLY, &prot), "VirtualProtect failed\n");
3377 
3378     strcpy(str2, "aBc");
3379     p = _strupr(str2);
3380     ok(p == str2, "_strupr returned %p\n", p);
3381     ok(!strcmp(str2, "ABC"), "str2 = %s\n", str2);
3382 
3383     p = _strupr(mem);
3384     ok(p == mem, "_strupr returned %p\n", p);
3385     ok(!strcmp(mem, "123"), "mem = %s\n", mem);
3386 
3387     if(!setlocale(LC_ALL, "english")) {
3388         VirtualFree(mem, sizeof(str), MEM_RELEASE);
3389         win_skip("English locale _strupr tests\n");
3390         return;
3391     }
3392 
3393     strcpy(str2, "aBc");
3394     p = _strupr(str2);
3395     ok(p == str2, "_strupr returned %p\n", p);
3396     ok(!strcmp(str2, "ABC"), "str2 = %s\n", str2);
3397 
3398     if (0) /* crashes on Windows */
3399     {
3400         p = _strupr(mem);
3401         ok(p == mem, "_strupr returned %p\n", p);
3402         ok(!strcmp(mem, "123"), "mem = %s\n", mem);
3403     }
3404 
3405     setlocale(LC_ALL, "C");
3406     VirtualFree(mem, sizeof(str), MEM_RELEASE);
3407 }
3408 
3409 static void test__tcsncoll(void)
3410 {
3411     struct test {
3412         const char *locale;
3413         const char *str1;
3414         const char *str2;
3415         size_t count;
3416         int exp;
3417     };
3418     static const struct test tests[] = {
3419         { "English", "ABCD", "ABCD",  4,  0 },
3420         { "English", "ABCD", "ABCD", 10,  0 },
3421 
3422         { "English", "ABC",  "ABCD",  3,  0 },
3423         { "English", "ABC",  "ABCD",  4, -1 },
3424         { "English", "ABC",  "ABCD", 10, -1 },
3425 
3426         { "English", "ABCD",  "ABC",  3,  0 },
3427         { "English", "ABCD",  "ABC",  4,  1 },
3428         { "English", "ABCD",  "ABC", 10,  1 },
3429 
3430         { "English", "ABCe", "ABCf",  3,  0 },
3431         { "English", "abcd", "ABCD", 10, -1 },
3432 
3433         { "C",       "ABCD", "ABCD",  4,  0 },
3434         { "C",       "ABCD", "ABCD", 10,  0 },
3435 
3436         { "C",       "ABC",  "ABCD",  3,  0 },
3437         { "C",       "ABC",  "ABCD", 10, -1 },
3438 
3439         { "C",       "ABCD",  "ABC",  3,  0 },
3440         { "C",       "ABCD",  "ABC", 10,  1 },
3441 
3442         { "C",       "ABCe", "ABCf",  3,  0 },
3443         { "C",       "abcd", "ABCD", 10,  1 },
3444     };
3445     WCHAR str1W[16];
3446     WCHAR str2W[16];
3447     char str1[16];
3448     char str2[16];
3449     size_t len;
3450     int i, ret;
3451 
3452     for (i = 0; i < ARRAY_SIZE(tests); i++)
3453     {
3454         if (!setlocale(LC_ALL, tests[i].locale))
3455         {
3456             win_skip("%s locale _tcsncoll tests\n", tests[i].locale);
3457             for (; i+1 < ARRAY_SIZE(tests); i++)
3458                 if (strcmp(tests[i].locale, tests[i+1].locale)) break;
3459             continue;
3460         }
3461 
3462         memset(str1, 0xee, sizeof(str1));
3463         strcpy(str1, tests[i].str1);
3464 
3465         memset(str2, 0xff, sizeof(str2));
3466         strcpy(str2, tests[i].str2);
3467 
3468         ret = _strncoll(str1, str2, tests[i].count);
3469         if (!tests[i].exp)
3470             ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count);
3471         else if (tests[i].exp < 0)
3472             ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count);
3473         else
3474             ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count);
3475 
3476         memset(str1W, 0xee, sizeof(str1W));
3477         len = mbstowcs(str1W, str1, ARRAY_SIZE(str1W));
3478         str1W[len] = 0;
3479 
3480         memset(str2W, 0xff, sizeof(str2W));
3481         len = mbstowcs(str2W, str2, ARRAY_SIZE(str2W));
3482         str2W[len] = 0;
3483 
3484         ret = _wcsncoll(str1W, str2W, tests[i].count);
3485         if (!tests[i].exp)
3486             ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count);
3487         else if (tests[i].exp < 0)
3488             ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count);
3489         else
3490             ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count);
3491     }
3492 }
3493 
3494 static void test__tcsnicoll(void)
3495 {
3496     struct test {
3497         const char *locale;
3498         const char *str1;
3499         const char *str2;
3500         size_t count;
3501         int exp;
3502     };
3503     static const struct test tests[] = {
3504         { "English", "abcd", "ABCD",  4,  0 },
3505         { "English", "abcd", "ABCD", 10,  0 },
3506 
3507         { "English", "abc",  "ABCD",  3,  0 },
3508         { "English", "abc",  "ABCD",  4, -1 },
3509         { "English", "abc",  "ABCD", 10, -1 },
3510 
3511         { "English", "abcd",  "ABC",  3,  0 },
3512         { "English", "abcd",  "ABC",  4,  1 },
3513         { "English", "abcd",  "ABC", 10,  1 },
3514 
3515         { "English", "abcE", "ABCF",  3,  0 },
3516 
3517         { "C",       "abcd", "ABCD",  4,  0 },
3518         { "C",       "abcd", "ABCD", 10,  0 },
3519 
3520         { "C",       "abc",  "ABCD",  3,  0 },
3521         { "C",       "abc",  "ABCD", 10, -1 },
3522 
3523         { "C",       "abcd",  "ABC",  3,  0 },
3524         { "C",       "abcd",  "ABC", 10,  1 },
3525 
3526         { "C",       "abce", "ABCf",  3,  0 },
3527     };
3528     WCHAR str1W[16];
3529     WCHAR str2W[16];
3530     char str1[16];
3531     char str2[16];
3532     size_t len;
3533     int i, ret;
3534 
3535     for (i = 0; i < ARRAY_SIZE(tests); i++)
3536     {
3537         if (!setlocale(LC_ALL, tests[i].locale))
3538         {
3539             win_skip("%s locale _tcsnicoll tests\n", tests[i].locale);
3540             for (; i+1 < ARRAY_SIZE(tests); i++)
3541                 if (strcmp(tests[i].locale, tests[i+1].locale)) break;
3542             continue;
3543         }
3544 
3545         memset(str1, 0xee, sizeof(str1));
3546         strcpy(str1, tests[i].str1);
3547 
3548         memset(str2, 0xff, sizeof(str2));
3549         strcpy(str2, tests[i].str2);
3550 
3551         ret = _strnicoll(str1, str2, tests[i].count);
3552         if (!tests[i].exp)
3553             ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count);
3554         else if (tests[i].exp < 0)
3555             ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count);
3556         else
3557             ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count);
3558 
3559         memset(str1W, 0xee, sizeof(str1W));
3560         len = mbstowcs(str1W, str1, ARRAY_SIZE(str1W));
3561         str1W[len] = 0;
3562 
3563         memset(str2W, 0xff, sizeof(str2W));
3564         len = mbstowcs(str2W, str2, ARRAY_SIZE(str2W));
3565         str2W[len] = 0;
3566 
3567         ret = _wcsnicoll(str1W, str2W, tests[i].count);
3568         if (!tests[i].exp)
3569             ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count);
3570         else if (tests[i].exp < 0)
3571             ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count);
3572         else
3573             ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count);
3574     }
3575 }
3576 
3577 static void test___strncnt(void)
3578 {
3579     static const struct
3580     {
3581         const char *str;
3582         size_t size;
3583         size_t ret;
3584     }
3585     strncnt_tests[] =
3586     {
3587         { NULL, 0, 0 },
3588         { "a", 0, 0 },
3589         { "a", 1, 1 },
3590         { "a", 10, 1 },
3591         { "abc", 1, 1 },
3592     };
3593     unsigned int i;
3594     size_t ret;
3595 
3596     if (!p___strncnt)
3597     {
3598         win_skip("__strncnt() is not available.\n");
3599         return;
3600     }
3601 
3602     if (0) /* crashes */
3603         ret = p___strncnt(NULL, 1);
3604 
3605     for (i = 0; i < ARRAY_SIZE(strncnt_tests); ++i)
3606     {
3607         ret = p___strncnt(strncnt_tests[i].str, strncnt_tests[i].size);
3608         ok(ret == strncnt_tests[i].ret, "%u: unexpected return value %u.\n", i, (int)ret);
3609     }
3610 }
3611 
3612 static void test_C_locale(void)
3613 {
3614     int i, j;
3615     wint_t ret, exp;
3616     _locale_t locale;
3617     static const char *locales[] = { NULL, "C" };
3618 
3619     /* C locale only converts case for [a-zA-Z] */
3620     setlocale(LC_ALL, "C");
3621     for (i = 0; i <= 0xffff; i++)
3622     {
3623         ret = p_towlower(i);
3624         if (i >= 'A' && i <= 'Z')
3625         {
3626             exp = i + 'a' - 'A';
3627             ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
3628         }
3629         else
3630         todo_wine_if(ret != i)
3631             ok(ret == i, "expected self %x, got %x for C locale\n", i, ret);
3632 
3633         ret = p_towupper(i);
3634         if (i >= 'a' && i <= 'z')
3635         {
3636             exp = i + 'A' - 'a';
3637             ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
3638         }
3639         else
3640         todo_wine_if(ret != i)
3641             ok(ret == i, "expected self %x, got %x for C locale\n", i, ret);
3642     }
3643 
3644     if (!p__towlower_l || !p__towupper_l || !p__create_locale)
3645     {
3646         win_skip("_towlower_l/_towupper_l/_create_locale not available\n");
3647         return;
3648     }
3649 
3650     for (i = 0; i < ARRAY_SIZE(locales); i++) {
3651         locale = locales[i] ? p__create_locale(LC_ALL, locales[i]) : NULL;
3652 
3653         for (j = 0; j <= 0xffff; j++) {
3654             ret = p__towlower_l(j, locale);
3655             if (j >= 'A' && j <= 'Z')
3656             {
3657                 exp = j + 'a' - 'A';
3658                 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
3659             }
3660             else
3661             todo_wine_if(ret != j)
3662                 ok(ret == j, "expected self %x, got %x for C locale\n", j, ret);
3663 
3664             ret = p__towupper_l(j, locale);
3665             if (j >= 'a' && j <= 'z')
3666             {
3667                 exp = j + 'A' - 'a';
3668                 ok(ret == exp, "expected %x, got %x for C locale\n", exp, ret);
3669             }
3670             else
3671             todo_wine_if(ret != j)
3672                 ok(ret == j, "expected self %x, got %x for C locale\n", j, ret);
3673         }
3674 
3675         p__free_locale(locale);
3676     }
3677 }
3678 
3679 START_TEST(string)
3680 {
3681     char mem[100];
3682     static const char xilstring[]="c:/xilinx";
3683     int nLen;
3684 
3685     hMsvcrt = GetModuleHandleA("msvcrt.dll");
3686     if (!hMsvcrt)
3687         hMsvcrt = GetModuleHandleA("msvcrtd.dll");
3688     ok(hMsvcrt != 0, "GetModuleHandleA failed\n");
3689     SET(pmemcpy,"memcpy");
3690     p_memcpy_s = (void*)GetProcAddress( hMsvcrt, "memcpy_s" );
3691     p_memmove_s = (void*)GetProcAddress( hMsvcrt, "memmove_s" );
3692     SET(pmemcmp,"memcmp");
3693     SET(p_mbctype,"_mbctype");
3694     SET(p__mb_cur_max,"__mb_cur_max");
3695     SET(p_strcpy, "strcpy");
3696     pstrcpy_s = (void *)GetProcAddress( hMsvcrt,"strcpy_s" );
3697     pstrcat_s = (void *)GetProcAddress( hMsvcrt,"strcat_s" );
3698     p_mbscat_s = (void*)GetProcAddress( hMsvcrt, "_mbscat_s" );
3699     p_mbsnbcat_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcat_s" );
3700     p_mbsnbcpy_s = (void *)GetProcAddress( hMsvcrt,"_mbsnbcpy_s" );
3701     p__mbscpy_s = (void *)GetProcAddress( hMsvcrt,"_mbscpy_s" );
3702     p_wcscpy_s = (void *)GetProcAddress( hMsvcrt,"wcscpy_s" );
3703     p_wcsncpy_s = (void *)GetProcAddress( hMsvcrt,"wcsncpy_s" );
3704     p_wcsncat_s = (void *)GetProcAddress( hMsvcrt,"wcsncat_s" );
3705     p_wcsupr_s = (void *)GetProcAddress( hMsvcrt,"_wcsupr_s" );
3706     p_strnlen = (void *)GetProcAddress( hMsvcrt,"strnlen" );
3707     p_strtoi64 = (void *)GetProcAddress(hMsvcrt, "_strtoi64");
3708     p_strtoui64 = (void *)GetProcAddress(hMsvcrt, "_strtoui64");
3709     p_wcstoi64 = (void *)GetProcAddress(hMsvcrt, "_wcstoi64");
3710     p_wcstoui64 = (void *)GetProcAddress(hMsvcrt, "_wcstoui64");
3711     pmbstowcs_s = (void *)GetProcAddress(hMsvcrt, "mbstowcs_s");
3712     pwcstombs_s = (void *)GetProcAddress(hMsvcrt, "wcstombs_s");
3713     pwcsrtombs = (void *)GetProcAddress(hMsvcrt, "wcsrtombs");
3714     p_gcvt_s = (void *)GetProcAddress(hMsvcrt, "_gcvt_s");
3715     p_itoa_s = (void *)GetProcAddress(hMsvcrt, "_itoa_s");
3716     p_strlwr_s = (void *)GetProcAddress(hMsvcrt, "_strlwr_s");
3717     p_ultoa_s = (void *)GetProcAddress(hMsvcrt, "_ultoa_s");
3718     p_wcslwr_s = (void*)GetProcAddress(hMsvcrt, "_wcslwr_s");
3719     p_mbsupr_s = (void*)GetProcAddress(hMsvcrt, "_mbsupr_s");
3720     p_mbslwr_s = (void*)GetProcAddress(hMsvcrt, "_mbslwr_s");
3721     p_wctob = (void*)GetProcAddress(hMsvcrt, "wctob");
3722     p_wcrtomb = (void*)GetProcAddress(hMsvcrt, "wcrtomb");
3723     p_tolower = (void*)GetProcAddress(hMsvcrt, "tolower");
3724     p_towlower = (void*)GetProcAddress(hMsvcrt, "towlower");
3725     p__towlower_l = (void*)GetProcAddress(hMsvcrt, "_towlower_l");
3726     p_towupper = (void*)GetProcAddress(hMsvcrt, "towupper");
3727     p__towupper_l = (void*)GetProcAddress(hMsvcrt, "_towupper_l");
3728     p__create_locale = (void*)GetProcAddress(hMsvcrt, "_create_locale");
3729     p__free_locale = (void*)GetProcAddress(hMsvcrt, "_free_locale");
3730     p_mbrlen = (void*)GetProcAddress(hMsvcrt, "mbrlen");
3731     p_mbrtowc = (void*)GetProcAddress(hMsvcrt, "mbrtowc");
3732     p_mbsrtowcs = (void*)GetProcAddress(hMsvcrt, "mbsrtowcs");
3733     p_mbsrtowcs_s = (void*)GetProcAddress(hMsvcrt, "mbsrtowcs_s");
3734     p__atodbl_l = (void*)GetProcAddress(hMsvcrt, "_atodbl_l");
3735     p__atof_l = (void*)GetProcAddress(hMsvcrt, "_atof_l");
3736     p__strtod_l = (void*)GetProcAddress(hMsvcrt, "_strtod_l");
3737     p__strnset_s = (void*)GetProcAddress(hMsvcrt, "_strnset_s");
3738     p__wcsset_s = (void*)GetProcAddress(hMsvcrt, "_wcsset_s");
3739     p__mbsnlen = (void*)GetProcAddress(hMsvcrt, "_mbsnlen");
3740     p__mbccpy_s = (void*)GetProcAddress(hMsvcrt, "_mbccpy_s");
3741     p__memicmp = (void*)GetProcAddress(hMsvcrt, "_memicmp");
3742     p__memicmp_l = (void*)GetProcAddress(hMsvcrt, "_memicmp_l");
3743     p___strncnt = (void*)GetProcAddress(hMsvcrt, "__strncnt");
3744 
3745     /* MSVCRT memcpy behaves like memmove for overlapping moves,
3746        MFC42 CString::Insert seems to rely on that behaviour */
3747     strcpy(mem,xilstring);
3748     nLen=strlen(xilstring);
3749     pmemcpy(mem+5, mem,nLen+1);
3750     ok(pmemcmp(mem+5,xilstring, nLen) == 0,
3751        "Got result %s\n",mem+5);
3752 
3753     /* run tolower tests first */
3754     test_tolower();
3755     test_swab();
3756     test_mbcp();
3757     test_mbsspn();
3758     test_mbsspnp();
3759     test_strdup();
3760     test_strcpy_s();
3761     test_memcpy_s();
3762     test_memmove_s();
3763     test_strcat_s();
3764     test__mbscat_s();
3765     test__mbsnbcpy_s();
3766     test__mbscpy_s();
3767     test_mbcjisjms();
3768     test_mbcjmsjis();
3769     test_mbctohira();
3770     test_mbctokata();
3771     test_mbbtombc();
3772     test_mbctombb();
3773     test_ismbckata();
3774     test_ismbclegal();
3775     test_strtok();
3776     test__mbstok();
3777     test_wcscpy_s();
3778     test__wcsupr_s();
3779     test_strtol();
3780     test_strnlen();
3781     test__strtoi64();
3782     test__strtod();
3783     test_mbstowcs();
3784     test_gcvt();
3785     test__itoa_s();
3786     test__strlwr_s();
3787     test_wcsncat_s();
3788     test__mbsnbcat_s();
3789     test__ultoa_s();
3790     test__wcslwr_s();
3791     test__mbsupr_s();
3792     test__mbslwr_s();
3793     test_wctob();
3794     test_wctomb();
3795     test__atodbl();
3796     test__stricmp();
3797     test__wcstoi64();
3798     test_atoi();
3799     test_atof();
3800     test_strncpy();
3801     test_strxfrm();
3802     test__strnset_s();
3803     test__wcsset_s();
3804     test__mbscmp();
3805     test__ismbclx();
3806     test__memicmp();
3807     test__memicmp_l();
3808     test__strupr();
3809     test__tcsncoll();
3810     test__tcsnicoll();
3811     test___strncnt();
3812     test_C_locale();
3813 }
3814