Release 1.5.29.
[wine] / dlls / msvcr90 / tests / msvcr90.c
1 /*
2  * Copyright 2010 Detlef Riekenberg
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <fcntl.h>
24 #include <share.h>
25 #include <sys/stat.h>
26 #include <time.h>
27 #include <locale.h>
28
29 #include <windef.h>
30 #include <winbase.h>
31 #include <errno.h>
32 #include "wine/test.h"
33
34 #define DEFINE_EXPECT(func) \
35     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
36
37 #define SET_EXPECT(func) \
38     do { \
39         expect_ ## func = TRUE; \
40         errno = 0xdeadbeef; \
41     }while(0)
42
43 #define CHECK_EXPECT2(func) \
44     do { \
45         ok(expect_ ##func, "unexpected call " #func "\n"); \
46         called_ ## func = TRUE; \
47     }while(0)
48
49 #define CHECK_EXPECT(func) \
50     do { \
51         CHECK_EXPECT2(func); \
52         expect_ ## func = FALSE; \
53     }while(0)
54
55 #define CHECK_CALLED(func,error) \
56     do { \
57         ok(called_ ## func, "expected " #func "\n"); \
58         ok( errno == (error), "got errno %u instead of %u\n", errno, (error) ); \
59         expect_ ## func = called_ ## func = FALSE; \
60     }while(0)
61
62 DEFINE_EXPECT(invalid_parameter_handler);
63
64 static _invalid_parameter_handler (__cdecl *p_set_invalid_parameter_handler)(_invalid_parameter_handler);
65 typedef int (__cdecl *_INITTERM_E_FN)(void);
66 static int (__cdecl *p_initterm_e)(_INITTERM_E_FN *table, _INITTERM_E_FN *end);
67 static void* (__cdecl *p_encode_pointer)(void *);
68 static void* (__cdecl *p_decode_pointer)(void *);
69 static void* (__cdecl *p_encoded_null)(void);
70 static int *p_sys_nerr;
71 static int* (__cdecl *p__sys_nerr)(void);
72 static char **p_sys_errlist;
73 static char** (__cdecl *p__sys_errlist)(void);
74 static __int64 (__cdecl *p_strtoi64)(const char *, char **, int);
75 static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int);
76 static errno_t (__cdecl *p_itoa_s)(int,char*,size_t,int);
77 static int (__cdecl *p_wcsncat_s)(wchar_t *dst, size_t elem, const wchar_t *src, size_t count);
78 static void (__cdecl *p_qsort_s)(void *, size_t, size_t, int (__cdecl *)(void *, const void *, const void *), void *);
79 static void* (__cdecl *p_bsearch_s)(const void *, const void *, size_t, size_t,
80                                     int (__cdecl *compare)(void *, const void *, const void *), void *);
81 static int (__cdecl *p_controlfp_s)(unsigned int *, unsigned int, unsigned int);
82 static int (__cdecl *p_tmpfile_s)(FILE**);
83 static int (__cdecl *p_atoflt)(_CRT_FLOAT *, char *);
84 static unsigned int (__cdecl *p_set_abort_behavior)(unsigned int, unsigned int);
85 static int (__cdecl *p_sopen_s)(int*, const char*, int, int, int);
86 static int (__cdecl *p_wsopen_s)(int*, const wchar_t*, int, int, int);
87 static void* (__cdecl *p_realloc_crt)(void*, size_t);
88 static void* (__cdecl *p_malloc)(size_t);
89 static void (__cdecl *p_free)(void*);
90 static void* (__cdecl *p_getptd)(void);
91 static int* (__cdecl *p_errno)(void);
92 static __msvcrt_ulong* (__cdecl *p_doserrno)(void);
93 static void (__cdecl *p_srand)(unsigned int);
94 static char* (__cdecl *p_strtok)(char*, const char*);
95 static wchar_t* (__cdecl *p_wcstok)(wchar_t*, const wchar_t*);
96 static char* (__cdecl *p_strerror)(int);
97 static wchar_t* (__cdecl *p_wcserror)(int);
98 static char* (__cdecl *p_tmpnam)(char*);
99 static wchar_t* (__cdecl *p_wtmpnam)(wchar_t*);
100 static char* (__cdecl *p_asctime)(struct tm*);
101 static wchar_t* (__cdecl *p_wasctime)(struct tm*);
102 static struct tm* (__cdecl *p_localtime64)(__time64_t*);
103 static char* (__cdecl *p_ecvt)(double, int, int*, int*);
104 static int* (__cdecl *p_fpecode)(void);
105 static int (__cdecl *p_configthreadlocale)(int);
106 static void* (__cdecl *p_get_terminate)(void);
107 static void* (__cdecl *p_get_unexpected)(void);
108 static int (__cdecl *p__vswprintf_l)(wchar_t*, const wchar_t*, _locale_t, __ms_va_list);
109 static int (__cdecl *p_vswprintf_l)(wchar_t*, const wchar_t*, _locale_t, __ms_va_list);
110 static FILE* (__cdecl *p_fopen)(const char*, const char*);
111 static int (__cdecl *p_fclose)(FILE*);
112 static int (__cdecl *p_unlink)(const char*);
113 static void (__cdecl *p_lock_file)(FILE*);
114 static void (__cdecl *p_unlock_file)(FILE*);
115 static int (__cdecl *p_fileno)(FILE*);
116 static int (__cdecl *p_feof)(FILE*);
117 static int (__cdecl *p_ferror)(FILE*);
118 static int (__cdecl *p_flsbuf)(int, FILE*);
119 static unsigned long (__cdecl *p_byteswap_ulong)(unsigned long);
120 static void** (__cdecl *p__pxcptinfoptrs)(void);
121
122 /* make sure we use the correct errno */
123 #undef errno
124 #define errno (*p_errno())
125
126 /* type info */
127 typedef struct __type_info
128 {
129   void *vtable;
130   char *name;
131   char  mangled[16];
132 } type_info;
133
134
135 struct __type_info_node
136 {
137     void *memPtr;
138     struct __type_info_node* next;
139 };
140
141 static char* (WINAPI *p_type_info_name_internal_method)(type_info*, struct __type_info_node *);
142 static void  (WINAPI *ptype_info_dtor)(type_info*);
143
144 static void* (WINAPI *pEncodePointer)(void *);
145
146 static int cb_called[4];
147 static int g_qsort_s_context_counter;
148 static int g_bsearch_s_context_counter;
149
150 static inline int almost_equal_f(float f1, float f2)
151 {
152     return f1-f2 > -1e-30 && f1-f2 < 1e-30;
153 }
154
155 /* ########## */
156
157 /* thiscall emulation */
158 /* Emulate a __thiscall */
159 #ifdef __i386__
160 #ifdef _MSC_VER
161 static inline void* do_call_func1(void *func, void *_this)
162 {
163   volatile void* retval = 0;
164   __asm
165   {
166     push ecx
167     mov ecx, _this
168     call func
169     mov retval, eax
170     pop ecx
171   }
172   return (void*)retval;
173 }
174
175 static inline void* do_call_func2(void *func, void *_this, const void* arg)
176 {
177   volatile void* retval = 0;
178   __asm
179   {
180     push ecx
181     push arg
182     mov ecx, _this
183     call func
184     mov retval, eax
185     pop ecx
186   }
187   return (void*)retval;
188 }
189 #else
190 static void* do_call_func1(void *func, void *_this)
191 {
192   void *ret, *dummy;
193   __asm__ __volatile__ ("call *%2"
194                         : "=a" (ret), "=c" (dummy)
195                         : "g" (func), "1" (_this)
196                         : "edx", "memory" );
197   return ret;
198 }
199
200 static void* do_call_func2(void *func, void *_this, const void* arg)
201 {
202   void *ret, *dummy;
203   __asm__ __volatile__ ("pushl %3\n\tcall *%2"
204                         : "=a" (ret), "=c" (dummy)
205                         : "r" (func), "r" (arg), "1" (_this)
206                         : "edx", "memory" );
207   return ret;
208 }
209 #endif
210
211 #define call_func1(func,_this)   do_call_func1(func,_this)
212 #define call_func2(func,_this,a) do_call_func2(func,_this,(const void*)a)
213
214 #else
215
216 #define call_func1(func,_this) func(_this)
217 #define call_func2(func,_this,a) func(_this,a)
218
219 #endif /* __i386__ */
220
221 static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
222         const wchar_t *function, const wchar_t *file,
223         unsigned line, uintptr_t arg)
224 {
225     CHECK_EXPECT(invalid_parameter_handler);
226     ok(expression == NULL, "expression is not NULL\n");
227     ok(function == NULL, "function is not NULL\n");
228     ok(file == NULL, "file is not NULL\n");
229     ok(line == 0, "line = %u\n", line);
230     ok(arg == 0, "arg = %lx\n", (UINT_PTR)arg);
231     ok(errno != 0xdeadbeef, "errno not set\n");
232 }
233
234 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hcrt,y)
235 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
236 static BOOL init(void)
237 {
238     HMODULE hcrt;
239     HMODULE hkernel32;
240
241     SetLastError(0xdeadbeef);
242     hcrt = LoadLibraryA("msvcr90.dll");
243     if (!hcrt) {
244         win_skip("msvcr90.dll not installed (got %d)\n", GetLastError());
245         return FALSE;
246     }
247
248     SET(p_set_invalid_parameter_handler, "_set_invalid_parameter_handler");
249     if(p_set_invalid_parameter_handler)
250         ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
251                 "Invalid parameter handler was already set\n");
252
253     SET(p_initterm_e, "_initterm_e");
254     SET(p_encode_pointer, "_encode_pointer");
255     SET(p_decode_pointer, "_decode_pointer");
256     SET(p_encoded_null, "_encoded_null");
257     SET(p_sys_nerr, "_sys_nerr");
258     SET(p__sys_nerr, "__sys_nerr");
259     SET(p_sys_errlist, "_sys_errlist");
260     SET(p__sys_errlist, "__sys_errlist");
261     SET(p_strtoi64, "_strtoi64");
262     SET(p_strtoui64, "_strtoui64");
263     SET(p_itoa_s, "_itoa_s");
264     SET(p_wcsncat_s,"wcsncat_s" );
265     SET(p_qsort_s, "qsort_s");
266     SET(p_bsearch_s, "bsearch_s");
267     SET(p_controlfp_s, "_controlfp_s");
268     SET(p_tmpfile_s, "tmpfile_s");
269     SET(p_atoflt, "_atoflt");
270     SET(p_set_abort_behavior, "_set_abort_behavior");
271     SET(p_sopen_s, "_sopen_s");
272     SET(p_wsopen_s, "_wsopen_s");
273     SET(p_realloc_crt, "_realloc_crt");
274     SET(p_malloc, "malloc");
275     SET(p_free, "free");
276     SET(p_getptd, "_getptd");
277     SET(p_errno, "_errno");
278     SET(p_doserrno, "__doserrno");
279     SET(p_srand, "srand");
280     SET(p_strtok, "strtok");
281     SET(p_wcstok, "wcstok");
282     SET(p_strerror, "strerror");
283     SET(p_wcserror, "_wcserror");
284     SET(p_tmpnam, "tmpnam");
285     SET(p_wtmpnam, "_wtmpnam");
286     SET(p_asctime, "asctime");
287     SET(p_wasctime, "_wasctime");
288     SET(p_localtime64, "_localtime64");
289     SET(p_ecvt, "_ecvt");
290     SET(p_fpecode, "__fpecode");
291     SET(p_configthreadlocale, "_configthreadlocale");
292     SET(p_get_terminate, "_get_terminate");
293     SET(p_get_unexpected, "_get_unexpected");
294     SET(p__vswprintf_l, "__vswprintf_l");
295     SET(p_vswprintf_l, "_vswprintf_l");
296     SET(p_fopen, "fopen");
297     SET(p_fclose, "fclose");
298     SET(p_unlink, "_unlink");
299     SET(p_lock_file, "_lock_file");
300     SET(p_unlock_file, "_unlock_file");
301     SET(p_fileno, "_fileno");
302     SET(p_feof, "feof");
303     SET(p_ferror, "ferror");
304     SET(p_flsbuf, "_flsbuf");
305     SET(p_byteswap_ulong, "_byteswap_ulong");
306     SET(p__pxcptinfoptrs, "__pxcptinfoptrs");
307     if (sizeof(void *) == 8)
308     {
309         SET(p_type_info_name_internal_method, "?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z");
310         SET(ptype_info_dtor, "??1type_info@@UEAA@XZ");
311     }
312     else
313     {
314         SET(p_type_info_name_internal_method, "?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z");
315         SET(ptype_info_dtor, "??1type_info@@UAE@XZ");
316     }
317
318     hkernel32 = GetModuleHandleA("kernel32.dll");
319     pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
320     return TRUE;
321 }
322
323 static int __cdecl initterm_cb0(void)
324 {
325     cb_called[0]++;
326     return 0;
327 }
328
329 static int __cdecl initterm_cb1(void)
330 {
331     cb_called[1]++;
332     return 1;
333 }
334
335 static int __cdecl initterm_cb2(void)
336 {
337     cb_called[2]++;
338     return 2;
339 }
340
341
342 static void test__initterm_e(void)
343 {
344     _INITTERM_E_FN table[4];
345     int res;
346
347     memset(table, 0, sizeof(table));
348
349     memset(cb_called, 0, sizeof(cb_called));
350     errno = 0xdeadbeef;
351     res = p_initterm_e(table, table);
352     ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
353         "got %d with 0x%x {%d, %d, %d}\n",
354         res, errno, cb_called[0], cb_called[1], cb_called[2]);
355
356     memset(cb_called, 0, sizeof(cb_called));
357     errno = 0xdeadbeef;
358     res = p_initterm_e(table, NULL);
359     ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
360         "got %d with 0x%x {%d, %d, %d}\n",
361         res, errno, cb_called[0], cb_called[1], cb_called[2]);
362
363     if (0) {
364         /* this crash on Windows */
365         errno = 0xdeadbeef;
366         res = p_initterm_e(NULL, table);
367         trace("got %d with 0x%x\n", res, errno);
368     }
369
370     table[0] = initterm_cb0;
371     memset(cb_called, 0, sizeof(cb_called));
372     errno = 0xdeadbeef;
373     res = p_initterm_e(table, &table[1]);
374     ok( !res && (cb_called[0] == 1) && !cb_called[1] && !cb_called[2],
375         "got %d with 0x%x {%d, %d, %d}\n",
376         res, errno, cb_called[0], cb_called[1], cb_called[2]);
377
378
379     /* init-function returning failure */
380     table[1] = initterm_cb1;
381     memset(cb_called, 0, sizeof(cb_called));
382     errno = 0xdeadbeef;
383     res = p_initterm_e(table, &table[3]);
384     ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
385         "got %d with 0x%x {%d, %d, %d}\n",
386         res, errno, cb_called[0], cb_called[1], cb_called[2]);
387
388     /* init-function not called, when end < start */
389     memset(cb_called, 0, sizeof(cb_called));
390     errno = 0xdeadbeef;
391     res = p_initterm_e(&table[3], table);
392     ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
393         "got %d with 0x%x {%d, %d, %d}\n",
394         res, errno, cb_called[0], cb_called[1], cb_called[2]);
395
396     /* initialization stop after first non-zero result */
397     table[2] = initterm_cb0;
398     memset(cb_called, 0, sizeof(cb_called));
399     errno = 0xdeadbeef;
400     res = p_initterm_e(table, &table[3]);
401     ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
402         "got %d with 0x%x {%d, %d, %d}\n",
403         res, errno, cb_called[0], cb_called[1], cb_called[2]);
404
405     /* NULL pointer in the array are skipped */
406     table[1] = NULL;
407     table[2] = initterm_cb2;
408     memset(cb_called, 0, sizeof(cb_called));
409     errno = 0xdeadbeef;
410     res = p_initterm_e(table, &table[3]);
411     ok( (res == 2) && (cb_called[0] == 1) && !cb_called[1] && (cb_called[2] == 1),
412         "got %d with 0x%x {%d, %d, %d}\n",
413         res, errno, cb_called[0], cb_called[1], cb_called[2]);
414
415 }
416
417 /* Beware that _encode_pointer is a NOP before XP
418    (the parameter is returned unchanged) */
419 static void test__encode_pointer(void)
420 {
421     void *ptr, *res;
422
423     ptr = (void*)0xdeadbeef;
424     res = p_encode_pointer(ptr);
425     res = p_decode_pointer(res);
426     ok(res == ptr, "Pointers are different after encoding and decoding\n");
427
428     ok(p_encoded_null() == p_encode_pointer(NULL), "Error encoding null\n");
429
430     ptr = p_encode_pointer(p_encode_pointer);
431     ok(p_decode_pointer(ptr) == p_encode_pointer, "Error decoding pointer\n");
432
433     /* Not present before XP */
434     if (!pEncodePointer) {
435         win_skip("EncodePointer not found\n");
436         return;
437     }
438
439     res = pEncodePointer(p_encode_pointer);
440     ok(ptr == res, "_encode_pointer produced different result than EncodePointer\n");
441
442 }
443
444 static void test_error_messages(void)
445 {
446     int *size, size_copy;
447
448     size = p__sys_nerr();
449     size_copy = *size;
450     ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
451
452     *size = 20;
453     ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
454
455     *size = size_copy;
456
457     ok(*p_sys_errlist == *(p__sys_errlist()), "p_sys_errlist != p__sys_errlist()\n");
458 }
459
460 static void test__strtoi64(void)
461 {
462     __int64 res;
463     unsigned __int64 ures;
464
465     SET_EXPECT(invalid_parameter_handler);
466     res = p_strtoi64(NULL, NULL, 10);
467     ok(res == 0, "res != 0\n");
468     CHECK_CALLED(invalid_parameter_handler, EINVAL);
469
470     SET_EXPECT(invalid_parameter_handler);
471     res = p_strtoi64("123", NULL, 1);
472     ok(res == 0, "res != 0\n");
473     CHECK_CALLED(invalid_parameter_handler, EINVAL);
474
475     SET_EXPECT(invalid_parameter_handler);
476     res = p_strtoi64("123", NULL, 37);
477     ok(res == 0, "res != 0\n");
478     CHECK_CALLED(invalid_parameter_handler, EINVAL);
479
480     SET_EXPECT(invalid_parameter_handler);
481     ures = p_strtoui64(NULL, NULL, 10);
482     ok(ures == 0, "res = %d\n", (int)ures);
483     CHECK_CALLED(invalid_parameter_handler, EINVAL);
484
485     SET_EXPECT(invalid_parameter_handler);
486     ures = p_strtoui64("123", NULL, 1);
487     ok(ures == 0, "res = %d\n", (int)ures);
488     CHECK_CALLED(invalid_parameter_handler, EINVAL);
489
490     SET_EXPECT(invalid_parameter_handler);
491     ures = p_strtoui64("123", NULL, 37);
492     ok(ures == 0, "res = %d\n", (int)ures);
493     CHECK_CALLED(invalid_parameter_handler, EINVAL);
494 }
495
496 static void test__itoa_s(void)
497 {
498     errno_t ret;
499     char buffer[33];
500
501     SET_EXPECT(invalid_parameter_handler);
502     ret = p_itoa_s(0, NULL, 0, 0);
503     ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
504     CHECK_CALLED(invalid_parameter_handler, EINVAL);
505
506     memset(buffer, 'X', sizeof(buffer));
507     SET_EXPECT(invalid_parameter_handler);
508     ret = p_itoa_s(0, buffer, 0, 0);
509     ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
510     ok(buffer[0] == 'X', "Expected the output buffer to be untouched\n");
511     CHECK_CALLED(invalid_parameter_handler, EINVAL);
512
513     memset(buffer, 'X', sizeof(buffer));
514     SET_EXPECT(invalid_parameter_handler);
515     ret = p_itoa_s(0, buffer, sizeof(buffer), 0);
516     ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
517     ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
518     CHECK_CALLED(invalid_parameter_handler, EINVAL);
519
520     memset(buffer, 'X', sizeof(buffer));
521     SET_EXPECT(invalid_parameter_handler);
522     ret = p_itoa_s(0, buffer, sizeof(buffer), 64);
523     ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
524     ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
525     CHECK_CALLED(invalid_parameter_handler, EINVAL);
526
527     memset(buffer, 'X', sizeof(buffer));
528     SET_EXPECT(invalid_parameter_handler);
529     ret = p_itoa_s(12345678, buffer, 4, 10);
530     ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
531     ok(!memcmp(buffer, "\000765", 4),
532        "Expected the output buffer to be null terminated with truncated output\n");
533     CHECK_CALLED(invalid_parameter_handler, ERANGE);
534
535     memset(buffer, 'X', sizeof(buffer));
536     SET_EXPECT(invalid_parameter_handler);
537     ret = p_itoa_s(12345678, buffer, 8, 10);
538     ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
539     ok(!memcmp(buffer, "\0007654321", 8),
540        "Expected the output buffer to be null terminated with truncated output\n");
541     CHECK_CALLED(invalid_parameter_handler, ERANGE);
542
543     memset(buffer, 'X', sizeof(buffer));
544     SET_EXPECT(invalid_parameter_handler);
545     ret = p_itoa_s(-12345678, buffer, 9, 10);
546     ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
547     ok(!memcmp(buffer, "\00087654321", 9),
548        "Expected the output buffer to be null terminated with truncated output\n");
549     CHECK_CALLED(invalid_parameter_handler, ERANGE);
550
551     ret = p_itoa_s(12345678, buffer, 9, 10);
552     ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
553     ok(!strcmp(buffer, "12345678"),
554        "Expected output buffer string to be \"12345678\", got \"%s\"\n",
555        buffer);
556
557     ret = p_itoa_s(43690, buffer, sizeof(buffer), 2);
558     ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
559     ok(!strcmp(buffer, "1010101010101010"),
560        "Expected output buffer string to be \"1010101010101010\", got \"%s\"\n",
561        buffer);
562
563     ret = p_itoa_s(1092009, buffer, sizeof(buffer), 36);
564     ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
565     ok(!strcmp(buffer, "nell"),
566        "Expected output buffer string to be \"nell\", got \"%s\"\n",
567        buffer);
568
569     ret = p_itoa_s(5704, buffer, sizeof(buffer), 18);
570     ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
571     ok(!strcmp(buffer, "hag"),
572        "Expected output buffer string to be \"hag\", got \"%s\"\n",
573        buffer);
574
575     ret = p_itoa_s(-12345678, buffer, sizeof(buffer), 10);
576     ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
577     ok(!strcmp(buffer, "-12345678"),
578        "Expected output buffer string to be \"-12345678\", got \"%s\"\n",
579        buffer);
580 }
581
582 static void test_wcsncat_s(void)
583 {
584     static wchar_t abcW[] = {'a','b','c',0};
585     int ret;
586     wchar_t dst[4];
587     wchar_t src[4];
588
589     memcpy(src, abcW, sizeof(abcW));
590     dst[0] = 0;
591     SET_EXPECT(invalid_parameter_handler);
592     ret = p_wcsncat_s(NULL, 4, src, 4);
593     ok(ret == EINVAL, "err = %d\n", ret);
594     CHECK_CALLED(invalid_parameter_handler, EINVAL);
595
596     SET_EXPECT(invalid_parameter_handler);
597     ret = p_wcsncat_s(dst, 0, src, 4);
598     ok(ret == EINVAL, "err = %d\n", ret);
599     CHECK_CALLED(invalid_parameter_handler, EINVAL);
600
601     SET_EXPECT(invalid_parameter_handler);
602     ret = p_wcsncat_s(dst, 0, src, _TRUNCATE);
603     ok(ret == EINVAL, "err = %d\n", ret);
604     CHECK_CALLED(invalid_parameter_handler, EINVAL);
605
606     ret = p_wcsncat_s(dst, 4, NULL, 0);
607     ok(ret == 0, "err = %d\n", ret);
608
609     dst[0] = 0;
610     SET_EXPECT(invalid_parameter_handler);
611     ret = p_wcsncat_s(dst, 2, src, 4);
612     ok(ret == ERANGE, "err = %d\n", ret);
613     CHECK_CALLED(invalid_parameter_handler, ERANGE);
614
615     dst[0] = 0;
616     ret = p_wcsncat_s(dst, 2, src, _TRUNCATE);
617     ok(ret == STRUNCATE, "err = %d\n", ret);
618     ok(dst[0] == 'a' && dst[1] == 0, "dst is %s\n", wine_dbgstr_w(dst));
619
620     memcpy(dst, abcW, sizeof(abcW));
621     dst[3] = 'd';
622     SET_EXPECT(invalid_parameter_handler);
623     ret = p_wcsncat_s(dst, 4, src, 4);
624     ok(ret == EINVAL, "err = %d\n", ret);
625     CHECK_CALLED(invalid_parameter_handler, EINVAL);
626 }
627
628 /* Based on dlls/ntdll/tests/string.c */
629 static __cdecl int intcomparefunc(void *context, const void *a, const void *b)
630 {
631     const int *p = a, *q = b;
632
633     ok (a != b, "must never get the same pointer\n");
634     ++*(int *) context;
635
636     return *p - *q;
637 }
638
639 static __cdecl int charcomparefunc(void *context, const void *a, const void *b)
640 {
641     const char *p = a, *q = b;
642
643     ok (a != b, "must never get the same pointer\n");
644     ++*(int *) context;
645
646     return *p - *q;
647 }
648
649 static __cdecl int strcomparefunc(void *context, const void *a, const void *b)
650 {
651     const char * const *p = a;
652     const char * const *q = b;
653
654     ok (a != b, "must never get the same pointer\n");
655     ++*(int *) context;
656
657     return lstrcmpA(*p, *q);
658 }
659
660 static void test_qsort_s(void)
661 {
662     int arr[5] = { 23, 42, 8, 4, 16 };
663     int arr2[5] = { 23, 42, 8, 4, 16 };
664     char carr[5] = { 42, 23, 4, 8, 16 };
665     const char *strarr[7] = {
666     "Hello",
667     "Wine",
668     "World",
669     "!",
670     "Hopefully",
671     "Sorted",
672     "."
673     };
674
675     SET_EXPECT(invalid_parameter_handler);
676     p_qsort_s(NULL, 0, 0, NULL, NULL);
677     CHECK_CALLED(invalid_parameter_handler, EINVAL);
678
679     SET_EXPECT(invalid_parameter_handler);
680     p_qsort_s(NULL, 0, 0, intcomparefunc, NULL);
681     CHECK_CALLED(invalid_parameter_handler, EINVAL);
682
683     SET_EXPECT(invalid_parameter_handler);
684     p_qsort_s(NULL, 0, sizeof(int), NULL, NULL);
685     CHECK_CALLED(invalid_parameter_handler, EINVAL);
686
687     SET_EXPECT(invalid_parameter_handler);
688     p_qsort_s(NULL, 1, sizeof(int), intcomparefunc, NULL);
689     CHECK_CALLED(invalid_parameter_handler, EINVAL);
690
691     errno = 0xdeadbeef;
692     g_qsort_s_context_counter = 0;
693     p_qsort_s(NULL, 0, sizeof(int), intcomparefunc, NULL);
694     ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
695     ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
696
697     /* overflow without side effects, other overflow values crash */
698     errno = 0xdeadbeef;
699     g_qsort_s_context_counter = 0;
700     p_qsort_s((void*)arr2, (((size_t)1) << (8*sizeof(size_t) - 1)) + 1, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
701     ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
702     ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
703     ok(arr2[0] == 23, "should remain unsorted, arr2[0] is %d\n", arr2[0]);
704     ok(arr2[1] == 42, "should remain unsorted, arr2[1] is %d\n", arr2[1]);
705     ok(arr2[2] == 8,  "should remain unsorted, arr2[2] is %d\n", arr2[2]);
706     ok(arr2[3] == 4,  "should remain unsorted, arr2[3] is %d\n", arr2[3]);
707
708     errno = 0xdeadbeef;
709     g_qsort_s_context_counter = 0;
710     p_qsort_s((void*)arr, 0, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
711     ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
712     ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
713     ok(arr[0] == 23, "badly sorted, nmemb=0, arr[0] is %d\n", arr[0]);
714     ok(arr[1] == 42, "badly sorted, nmemb=0, arr[1] is %d\n", arr[1]);
715     ok(arr[2] == 8,  "badly sorted, nmemb=0, arr[2] is %d\n", arr[2]);
716     ok(arr[3] == 4,  "badly sorted, nmemb=0, arr[3] is %d\n", arr[3]);
717     ok(arr[4] == 16, "badly sorted, nmemb=0, arr[4] is %d\n", arr[4]);
718
719     errno = 0xdeadbeef;
720     g_qsort_s_context_counter = 0;
721     p_qsort_s((void*)arr, 1, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
722     ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
723     ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
724     ok(arr[0] == 23, "badly sorted, nmemb=1, arr[0] is %d\n", arr[0]);
725     ok(arr[1] == 42, "badly sorted, nmemb=1, arr[1] is %d\n", arr[1]);
726     ok(arr[2] == 8,  "badly sorted, nmemb=1, arr[2] is %d\n", arr[2]);
727     ok(arr[3] == 4,  "badly sorted, nmemb=1, arr[3] is %d\n", arr[3]);
728     ok(arr[4] == 16, "badly sorted, nmemb=1, arr[4] is %d\n", arr[4]);
729
730     SET_EXPECT(invalid_parameter_handler);
731     g_qsort_s_context_counter = 0;
732     p_qsort_s((void*)arr, 5, 0, intcomparefunc, &g_qsort_s_context_counter);
733     ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
734     ok(arr[0] == 23, "badly sorted, size=0, arr[0] is %d\n", arr[0]);
735     ok(arr[1] == 42, "badly sorted, size=0, arr[1] is %d\n", arr[1]);
736     ok(arr[2] == 8,  "badly sorted, size=0, arr[2] is %d\n", arr[2]);
737     ok(arr[3] == 4,  "badly sorted, size=0, arr[3] is %d\n", arr[3]);
738     ok(arr[4] == 16, "badly sorted, size=0, arr[4] is %d\n", arr[4]);
739     CHECK_CALLED(invalid_parameter_handler, EINVAL);
740
741     g_qsort_s_context_counter = 0;
742     p_qsort_s((void*)arr, 5, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
743     ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
744     ok(arr[0] == 4,  "badly sorted, arr[0] is %d\n", arr[0]);
745     ok(arr[1] == 8,  "badly sorted, arr[1] is %d\n", arr[1]);
746     ok(arr[2] == 16, "badly sorted, arr[2] is %d\n", arr[2]);
747     ok(arr[3] == 23, "badly sorted, arr[3] is %d\n", arr[3]);
748     ok(arr[4] == 42, "badly sorted, arr[4] is %d\n", arr[4]);
749
750     g_qsort_s_context_counter = 0;
751     p_qsort_s((void*)carr, 5, sizeof(char), charcomparefunc, &g_qsort_s_context_counter);
752     ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
753     ok(carr[0] == 4,  "badly sorted, carr[0] is %d\n", carr[0]);
754     ok(carr[1] == 8,  "badly sorted, carr[1] is %d\n", carr[1]);
755     ok(carr[2] == 16, "badly sorted, carr[2] is %d\n", carr[2]);
756     ok(carr[3] == 23, "badly sorted, carr[3] is %d\n", carr[3]);
757     ok(carr[4] == 42, "badly sorted, carr[4] is %d\n", carr[4]);
758
759     g_qsort_s_context_counter = 0;
760     p_qsort_s((void*)strarr, 7, sizeof(char*), strcomparefunc, &g_qsort_s_context_counter);
761     ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
762     ok(!strcmp(strarr[0],"!"),  "badly sorted, strarr[0] is %s\n", strarr[0]);
763     ok(!strcmp(strarr[1],"."),  "badly sorted, strarr[1] is %s\n", strarr[1]);
764     ok(!strcmp(strarr[2],"Hello"),  "badly sorted, strarr[2] is %s\n", strarr[2]);
765     ok(!strcmp(strarr[3],"Hopefully"),  "badly sorted, strarr[3] is %s\n", strarr[3]);
766     ok(!strcmp(strarr[4],"Sorted"),  "badly sorted, strarr[4] is %s\n", strarr[4]);
767     ok(!strcmp(strarr[5],"Wine"),  "badly sorted, strarr[5] is %s\n", strarr[5]);
768     ok(!strcmp(strarr[6],"World"),  "badly sorted, strarr[6] is %s\n", strarr[6]);
769 }
770
771 static void test_bsearch_s(void)
772 {
773     int arr[7] = { 1, 3, 4, 8, 16, 23, 42 };
774     int *x, l, i, j = 1;
775
776     SET_EXPECT(invalid_parameter_handler);
777     x = p_bsearch_s(NULL, NULL, 0, 0, NULL, NULL);
778     ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
779     CHECK_CALLED(invalid_parameter_handler, EINVAL);
780
781     g_bsearch_s_context_counter = 0;
782     SET_EXPECT(invalid_parameter_handler);
783     x = p_bsearch_s(&l, arr, j, 0, intcomparefunc, &g_bsearch_s_context_counter);
784     ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
785     ok(g_bsearch_s_context_counter == 0, "callback shouldn't have been called\n");
786     CHECK_CALLED(invalid_parameter_handler, EINVAL);
787
788     g_bsearch_s_context_counter = 0;
789     SET_EXPECT(invalid_parameter_handler);
790     x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), NULL, &g_bsearch_s_context_counter);
791     ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
792     ok(g_bsearch_s_context_counter == 0, "callback shouldn't have been called\n");
793     CHECK_CALLED(invalid_parameter_handler, EINVAL);
794
795     /* just try all array sizes */
796     for (j=1;j<sizeof(arr)/sizeof(arr[0]);j++) {
797         for (i=0;i<j;i++) {
798             l = arr[i];
799             g_bsearch_s_context_counter = 0;
800             x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), intcomparefunc, &g_bsearch_s_context_counter);
801             ok (x == &arr[i], "bsearch_s did not find %d entry in loopsize %d.\n", i, j);
802             ok(g_bsearch_s_context_counter > 0, "callback wasn't called\n");
803         }
804         l = 4242;
805         g_bsearch_s_context_counter = 0;
806         x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), intcomparefunc, &g_bsearch_s_context_counter);
807         ok (x == NULL, "bsearch_s did find 4242 entry in loopsize %d.\n", j);
808         ok(g_bsearch_s_context_counter > 0, "callback wasn't called\n");
809     }
810 }
811
812 static void test_controlfp_s(void)
813 {
814     unsigned int cur;
815     int ret;
816
817     SET_EXPECT(invalid_parameter_handler);
818     ret = p_controlfp_s( NULL, ~0, ~0 );
819     ok( ret == EINVAL, "wrong result %d\n", ret );
820     CHECK_CALLED(invalid_parameter_handler, EINVAL);
821
822     cur = 0xdeadbeef;
823     SET_EXPECT(invalid_parameter_handler);
824     ret = p_controlfp_s( &cur, ~0, ~0 );
825     ok( ret == EINVAL, "wrong result %d\n", ret );
826     ok( cur != 0xdeadbeef, "value not set\n" );
827     CHECK_CALLED(invalid_parameter_handler, EINVAL);
828
829     cur = 0xdeadbeef;
830     ret = p_controlfp_s( &cur, 0, 0 );
831     ok( !ret, "wrong result %d\n", ret );
832     ok( cur != 0xdeadbeef, "value not set\n" );
833
834     SET_EXPECT(invalid_parameter_handler);
835     cur = 0xdeadbeef;
836     ret = p_controlfp_s( &cur, 0x80000000, 0x80000000 );
837     ok( ret == EINVAL, "wrong result %d\n", ret );
838     ok( cur != 0xdeadbeef, "value not set\n" );
839     CHECK_CALLED(invalid_parameter_handler, EINVAL);
840
841     cur = 0xdeadbeef;
842     /* mask is only checked when setting invalid bits */
843     ret = p_controlfp_s( &cur, 0, 0x80000000 );
844     ok( !ret, "wrong result %d\n", ret );
845     ok( cur != 0xdeadbeef, "value not set\n" );
846 }
847
848 static void test_tmpfile_s( void )
849 {
850     int ret;
851
852     SET_EXPECT(invalid_parameter_handler);
853     ret = p_tmpfile_s(NULL);
854     ok(ret == EINVAL, "Expected tmpfile_s to return EINVAL, got %i\n", ret);
855     CHECK_CALLED(invalid_parameter_handler, EINVAL);
856 }
857
858 typedef struct
859 {
860     const char *str;
861     float flt;
862     int ret;
863 } _atoflt_test;
864
865 static const _atoflt_test _atoflt_testdata[] = {
866     { "12.1", 12.1, 0 },
867     { "-13.721", -13.721, 0 },
868     { "INF", 0.0, 0 },
869     { ".21e12", 0.21e12, 0 },
870     { "214353e-3", 214.353, 0 },
871     { "1d9999999999999999999", 0.0, _OVERFLOW },
872     { "  d10", 0.0, 0 },
873     /* more significant digits */
874     { "1.23456789", 1.23456789, 0 },
875     { "1.23456789e1", 12.3456789, 0 },
876     { "1e39", 0.0, _OVERFLOW },
877     { "1e-39", 0.0, _UNDERFLOW },
878     { NULL }
879 };
880
881 static void test__atoflt(void)
882 {
883     _CRT_FLOAT flt;
884     int ret, i = 0;
885
886 if (0)
887 {
888     /* crashes on native */
889     p_atoflt(NULL, NULL);
890     p_atoflt(NULL, (char*)_atoflt_testdata[0].str);
891     p_atoflt(&flt, NULL);
892 }
893
894     while (_atoflt_testdata[i].str)
895     {
896         ret = p_atoflt(&flt, (char*)_atoflt_testdata[i].str);
897         ok(ret == _atoflt_testdata[i].ret, "got ret %d, expected ret %d, for %s\n", ret,
898             _atoflt_testdata[i].ret, _atoflt_testdata[i].str);
899
900         if (ret == 0)
901           ok(almost_equal_f(flt.f, _atoflt_testdata[i].flt), "got %f, expected %f, for %s\n", flt.f,
902               _atoflt_testdata[i].flt, _atoflt_testdata[i].str);
903
904         i++;
905     }
906 }
907
908 static void test__set_abort_behavior(void)
909 {
910     unsigned int res;
911
912     /* default is _WRITE_ABORT_MSG | _CALL_REPORTFAULT */
913     res = p_set_abort_behavior(0, 0);
914     ok (res == (_WRITE_ABORT_MSG | _CALL_REPORTFAULT),
915         "got 0x%x (expected 0x%x)\n", res, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
916
917     /* no internal mask */
918     p_set_abort_behavior(0xffffffff, 0xffffffff);
919     res = p_set_abort_behavior(0, 0);
920     ok (res == 0xffffffff, "got 0x%x (expected 0x%x)\n", res, 0xffffffff);
921
922     /* set to default value */
923     p_set_abort_behavior(_WRITE_ABORT_MSG | _CALL_REPORTFAULT, 0xffffffff);
924 }
925
926 static void test__sopen_s(void)
927 {
928     int ret, fd;
929
930     SET_EXPECT(invalid_parameter_handler);
931     ret = p_sopen_s(NULL, "test", _O_RDONLY, _SH_DENYNO, _S_IREAD);
932     ok(ret == EINVAL, "got %d, expected EINVAL\n", ret);
933     CHECK_CALLED(invalid_parameter_handler, EINVAL);
934
935     fd = 0xdead;
936     ret = p_sopen_s(&fd, "test", _O_RDONLY, _SH_DENYNO, _S_IREAD);
937     ok(ret == ENOENT, "got %d, expected ENOENT\n", ret);
938     ok(fd == -1, "got %d\n", fd);
939 }
940
941 static void test__wsopen_s(void)
942 {
943     wchar_t testW[] = {'t','e','s','t',0};
944     int ret, fd;
945
946     SET_EXPECT(invalid_parameter_handler);
947     ret = p_wsopen_s(NULL, testW, _O_RDONLY, _SH_DENYNO, _S_IREAD);
948     ok(ret == EINVAL, "got %d, expected EINVAL\n", ret);
949     CHECK_CALLED(invalid_parameter_handler, EINVAL);
950
951     fd = 0xdead;
952     ret = p_wsopen_s(&fd, testW, _O_RDONLY, _SH_DENYNO, _S_IREAD);
953     ok(ret == ENOENT, "got %d, expected ENOENT\n", ret);
954     ok(fd == -1, "got %d\n", fd);
955 }
956
957 static void test__realloc_crt(void)
958 {
959     void *mem;
960
961 if (0)
962 {
963     /* crashes on some systems starting Vista */
964     p_realloc_crt(NULL, 10);
965 }
966
967     mem = p_malloc(10);
968     ok(mem != NULL, "memory not allocated\n");
969
970     mem = p_realloc_crt(mem, 20);
971     ok(mem != NULL, "memory not reallocated\n");
972
973     mem = p_realloc_crt(mem, 0);
974     ok(mem == NULL, "memory not freed\n");
975
976     mem = p_realloc_crt(NULL, 0);
977     ok(mem != NULL, "memory not (re)allocated for size 0\n");
978     p_free(mem);
979 }
980
981 static void test_typeinfo(void)
982 {
983     static type_info t1 = { NULL, NULL,{'.','?','A','V','t','e','s','t','1','@','@',0,0,0,0,0 } };
984     struct __type_info_node node;
985     char *name;
986
987     /* name */
988     t1.name = NULL;
989     node.memPtr = NULL;
990     node.next = NULL;
991     name = call_func2(p_type_info_name_internal_method, &t1, &node);
992     ok(name != NULL, "got %p\n", name);
993     ok(name && t1.name && !strcmp(name, t1.name), "bad name '%s' for t1\n", name);
994
995     ok(t1.name && !strcmp(t1.name, "class test1"), "demangled to '%s' for t1\n", t1.name);
996     call_func1(ptype_info_dtor, &t1);
997 }
998
999 /* Keep in sync with msvcrt/msvcrt.h */
1000 struct __thread_data {
1001     DWORD                           tid;
1002     HANDLE                          handle;
1003     int                             thread_errno;
1004     __msvcrt_ulong                  thread_doserrno;
1005     int                             unk1;
1006     unsigned int                    random_seed;
1007     char                            *strtok_next;
1008     wchar_t                         *wcstok_next;
1009     unsigned char                   *mbstok_next;
1010     char                            *strerror_buffer;
1011     wchar_t                         *wcserror_buffer;
1012     char                            *tmpnam_buffer;
1013     wchar_t                         *wtmpnam_buffer;
1014     void                            *unk2[2];
1015     char                            *asctime_buffer;
1016     wchar_t                         *wasctime_buffer;
1017     struct tm                       *time_buffer;
1018     char                            *efcvt_buffer;
1019     int                             unk3[2];
1020     void                            *unk4[3];
1021     EXCEPTION_POINTERS              *xcptinfo;
1022     int                             fpecode;
1023     pthreadmbcinfo                  mbcinfo;
1024     pthreadlocinfo                  locinfo;
1025     BOOL                            have_locale;
1026     int                             unk5[1];
1027     void*                           terminate_handler;
1028     void*                           unexpected_handler;
1029     void*                           se_translator;
1030     void                            *unk6[3];
1031     int                             unk7;
1032     EXCEPTION_RECORD                *exc_record;
1033 };
1034
1035 static void test_getptd(void)
1036 {
1037     struct __thread_data *ptd = p_getptd();
1038     DWORD tid = GetCurrentThreadId();
1039     wchar_t testW[] = {'t','e','s','t',0}, tW[] = {'t',0}, *wp;
1040     char test[] = "test", *p;
1041     struct tm time;
1042     __time64_t secs = 0;
1043     int dec, sign;
1044     void *mbcinfo, *locinfo;
1045
1046     ok(ptd->tid == tid, "ptd->tid = %x, expected %x\n", ptd->tid, tid);
1047     ok(ptd->handle == INVALID_HANDLE_VALUE, "ptd->handle = %p\n", ptd->handle);
1048     ok(p_errno() == &ptd->thread_errno, "ptd->thread_errno is different then _errno()\n");
1049     ok(p_doserrno() == &ptd->thread_doserrno, "ptd->thread_doserrno is different then __doserrno()\n");
1050     p_srand(1234);
1051     ok(ptd->random_seed == 1234, "ptd->random_seed = %d\n", ptd->random_seed);
1052     p = p_strtok(test, "t");
1053     ok(ptd->strtok_next == p+3, "ptd->strtok_next is incorrect\n");
1054     wp = p_wcstok(testW, tW);
1055     ok(ptd->wcstok_next == wp+3, "ptd->wcstok_next is incorrect\n");
1056     ok(p_strerror(0) == ptd->strerror_buffer, "ptd->strerror_buffer is incorrect\n");
1057     ok(p_wcserror(0) == ptd->wcserror_buffer, "ptd->wcserror_buffer is incorrect\n");
1058     ok(p_tmpnam(NULL) == ptd->tmpnam_buffer, "ptd->tmpnam_buffer is incorrect\n");
1059     ok(p_wtmpnam(NULL) == ptd->wtmpnam_buffer, "ptd->wtmpnam_buffer is incorrect\n");
1060     memset(&time, 0, sizeof(time));
1061     time.tm_mday = 1;
1062     ok(p_asctime(&time) == ptd->asctime_buffer, "ptd->asctime_buffer is incorrect\n");
1063     ok(p_wasctime(&time) == ptd->wasctime_buffer, "ptd->wasctime_buffer is incorrect\n");
1064     ok(p_localtime64(&secs) == ptd->time_buffer, "ptd->time_buffer is incorrect\n");
1065     ok(p_ecvt(3.12, 1, &dec, &sign) == ptd->efcvt_buffer, "ptd->efcvt_buffer is incorrect\n");
1066     ok(p__pxcptinfoptrs() == (void**)&ptd->xcptinfo, "ptd->xcptinfo is incorrect\n");
1067     ok(p_fpecode() == &ptd->fpecode, "ptd->fpecode is incorrect\n");
1068     mbcinfo = ptd->mbcinfo;
1069     locinfo = ptd->locinfo;
1070     todo_wine ok(ptd->have_locale == 1, "ptd->have_locale = %x\n", ptd->have_locale);
1071     p_configthreadlocale(1);
1072     todo_wine ok(mbcinfo == ptd->mbcinfo, "ptd->mbcinfo != mbcinfo\n");
1073     todo_wine ok(locinfo == ptd->locinfo, "ptd->locinfo != locinfo\n");
1074     todo_wine ok(ptd->have_locale == 3, "ptd->have_locale = %x\n", ptd->have_locale);
1075     ok(p_get_terminate() == ptd->terminate_handler, "ptd->terminate_handler != _get_terminate()\n");
1076     ok(p_get_unexpected() == ptd->unexpected_handler, "ptd->unexpected_handler != _get_unexpected()\n");
1077 }
1078
1079 static int __cdecl __vswprintf_l_wrapper(wchar_t *buf,
1080         const wchar_t *format, _locale_t locale, ...)
1081 {
1082     int ret;
1083     __ms_va_list valist;
1084     __ms_va_start(valist, locale);
1085     ret = p__vswprintf_l(buf, format, locale, valist);
1086     __ms_va_end(valist);
1087     return ret;
1088 }
1089
1090 static int __cdecl _vswprintf_l_wrapper(wchar_t *buf,
1091         const wchar_t *format, _locale_t locale, ...)
1092 {
1093     int ret;
1094     __ms_va_list valist;
1095     __ms_va_start(valist, locale);
1096     ret = p_vswprintf_l(buf, format, locale, valist);
1097     __ms_va_end(valist);
1098     return ret;
1099 }
1100
1101 static void test__vswprintf_l(void)
1102 {
1103     static const wchar_t format[] = {'t','e','s','t',0};
1104
1105     wchar_t buf[32];
1106     int ret;
1107
1108     ret = __vswprintf_l_wrapper(buf, format, NULL);
1109     ok(ret == 4, "ret = %d\n", ret);
1110     ok(!memcmp(buf, format, sizeof(format)), "buf = %s, expected %s\n",
1111             wine_dbgstr_w(buf), wine_dbgstr_w(format));
1112
1113     ret = _vswprintf_l_wrapper(buf, format, NULL);
1114     ok(ret == 4, "ret = %d\n", ret);
1115     ok(!memcmp(buf, format, sizeof(format)), "buf = %s, expected %s\n",
1116             wine_dbgstr_w(buf), wine_dbgstr_w(format));
1117 }
1118
1119 struct block_file_arg
1120 {
1121     FILE *read;
1122     FILE *write;
1123     HANDLE init;
1124     HANDLE finish;
1125 };
1126
1127 static DWORD WINAPI block_file(void *arg)
1128 {
1129     struct block_file_arg *files = arg;
1130
1131     p_lock_file(files->read);
1132     p_lock_file(files->write);
1133     SetEvent(files->init);
1134     WaitForSingleObject(files->finish, INFINITE);
1135     p_unlock_file(files->read);
1136     p_unlock_file(files->write);
1137     return 0;
1138 }
1139
1140 static void test_nonblocking_file_access(void)
1141 {
1142     HANDLE thread;
1143     struct block_file_arg arg;
1144     FILE *filer, *filew;
1145     int ret;
1146
1147     if(!p_lock_file || !p_unlock_file) {
1148         win_skip("_lock_file not available\n");
1149         return;
1150     }
1151
1152     filew = p_fopen("test_file", "w");
1153     ok(filew != NULL, "unable to create test file\n");
1154     if(!filew)
1155         return;
1156     filer = p_fopen("test_file", "r");
1157     ok(filer != NULL, "unable to open test file\n");
1158     if(!filer) {
1159         p_fclose(filew);
1160         p_unlink("test_file");
1161         return;
1162     }
1163
1164     arg.read = filer;
1165     arg.write = filew;
1166     arg.init = CreateEvent(NULL, FALSE, FALSE, NULL);
1167     arg.finish = CreateEvent(NULL, FALSE, FALSE, NULL);
1168     ok(arg.init != NULL, "CreateEvent failed\n");
1169     ok(arg.finish != NULL, "CreateEvent failed\n");
1170     thread = CreateThread(NULL, 0, block_file, (void*)&arg, 0, NULL);
1171     ok(thread != NULL, "CreateThread failed\n");
1172     WaitForSingleObject(arg.init, INFINITE);
1173
1174     ret = p_fileno(filer);
1175     ok(ret, "_fileno(filer) returned %d\n", ret);
1176     ret = p_fileno(filew);
1177     ok(ret, "_fileno(filew) returned %d\n", ret);
1178
1179     ret = p_feof(filer);
1180     ok(ret==0, "feof(filer) returned %d\n", ret);
1181     ret = p_feof(filew);
1182     ok(ret==0, "feof(filew) returned %d\n", ret);
1183
1184     ret = p_ferror(filer);
1185     ok(ret==0, "ferror(filer) returned %d\n", ret);
1186     ret = p_ferror(filew);
1187     ok(ret==0, "ferror(filew) returned %d\n", ret);
1188
1189     ret = p_flsbuf('a', filer);
1190     ok(ret==-1, "_flsbuf(filer) returned %d\n", ret);
1191     ret = p_flsbuf('a', filew);
1192     ok(ret=='a', "_flsbuf(filew) returned %d\n", ret);
1193
1194     SetEvent(arg.finish);
1195     WaitForSingleObject(thread, INFINITE);
1196     CloseHandle(arg.init);
1197     CloseHandle(arg.finish);
1198     CloseHandle(thread);
1199     p_fclose(filer);
1200     p_fclose(filew);
1201     p_unlink("test_file");
1202 }
1203
1204 static void test_byteswap(void)
1205 {
1206     unsigned long ret;
1207
1208     ret = p_byteswap_ulong(0x12345678);
1209     ok(ret == 0x78563412, "ret = %lx\n", ret);
1210
1211     ret = p_byteswap_ulong(0);
1212     ok(ret == 0, "ret = %lx\n", ret);
1213 }
1214
1215 START_TEST(msvcr90)
1216 {
1217     if(!init())
1218         return;
1219
1220     test__initterm_e();
1221     test__encode_pointer();
1222     test_error_messages();
1223     test__strtoi64();
1224     test__itoa_s();
1225     test_wcsncat_s();
1226     test_qsort_s();
1227     test_bsearch_s();
1228     test_controlfp_s();
1229     test_tmpfile_s();
1230     test__atoflt();
1231     test__set_abort_behavior();
1232     test__sopen_s();
1233     test__wsopen_s();
1234     test__realloc_crt();
1235     test_typeinfo();
1236     test_getptd();
1237     test__vswprintf_l();
1238     test_nonblocking_file_access();
1239     test_byteswap();
1240 }