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