msvcrt: _filbuf should not lock any file.
[wine.git] / dlls / msvcr90 / tests / msvcr90.c
blob184ce760bfceff618c538ca203d69b571e53f845
1 /*
2 * Copyright 2010 Detlef Riekenberg
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.
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.
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
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>
29 #include <windef.h>
30 #include <winbase.h>
31 #include <errno.h>
32 #include "wine/test.h"
34 #define DEFINE_EXPECT(func) \
35 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
37 #define SET_EXPECT(func) \
38 do { \
39 expect_ ## func = TRUE; \
40 errno = 0xdeadbeef; \
41 }while(0)
43 #define CHECK_EXPECT2(func) \
44 do { \
45 ok(expect_ ##func, "unexpected call " #func "\n"); \
46 called_ ## func = TRUE; \
47 }while(0)
49 #define CHECK_EXPECT(func) \
50 do { \
51 CHECK_EXPECT2(func); \
52 expect_ ## func = FALSE; \
53 }while(0)
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)
62 DEFINE_EXPECT(invalid_parameter_handler);
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 unsigned char* (__cdecl *p__mbstok)(unsigned char*, const unsigned char*);
97 static char* (__cdecl *p_strerror)(int);
98 static wchar_t* (__cdecl *p_wcserror)(int);
99 static char* (__cdecl *p_tmpnam)(char*);
100 static wchar_t* (__cdecl *p_wtmpnam)(wchar_t*);
101 static char* (__cdecl *p_asctime)(struct tm*);
102 static wchar_t* (__cdecl *p_wasctime)(struct tm*);
103 static struct tm* (__cdecl *p_localtime64)(__time64_t*);
104 static char* (__cdecl *p_ecvt)(double, int, int*, int*);
105 static int* (__cdecl *p_fpecode)(void);
106 static int (__cdecl *p_configthreadlocale)(int);
107 static void* (__cdecl *p_get_terminate)(void);
108 static void* (__cdecl *p_get_unexpected)(void);
109 static int (__cdecl *p__vswprintf_l)(wchar_t*, const wchar_t*, _locale_t, __ms_va_list);
110 static int (__cdecl *p_vswprintf_l)(wchar_t*, const wchar_t*, _locale_t, __ms_va_list);
111 static FILE* (__cdecl *p_fopen)(const char*, const char*);
112 static int (__cdecl *p_fclose)(FILE*);
113 static int (__cdecl *p_unlink)(const char*);
114 static int (__cdecl *p_access_s)(const char*, int);
115 static void (__cdecl *p_lock_file)(FILE*);
116 static void (__cdecl *p_unlock_file)(FILE*);
117 static int (__cdecl *p_fileno)(FILE*);
118 static int (__cdecl *p_feof)(FILE*);
119 static int (__cdecl *p_ferror)(FILE*);
120 static int (__cdecl *p_flsbuf)(int, FILE*);
121 static int (__cdecl *p_filbuf)(FILE*);
122 static unsigned long (__cdecl *p_byteswap_ulong)(unsigned long);
123 static void** (__cdecl *p__pxcptinfoptrs)(void);
124 static void* (__cdecl *p__AdjustPointer)(void*, const void*);
125 static int (__cdecl *p_fflush_nolock)(FILE*);
127 /* make sure we use the correct errno */
128 #undef errno
129 #define errno (*p_errno())
131 /* type info */
132 typedef struct __type_info
134 void *vtable;
135 char *name;
136 char mangled[16];
137 } type_info;
139 struct __type_info_node
141 void *memPtr;
142 struct __type_info_node* next;
145 static char* (WINAPI *p_type_info_name_internal_method)(type_info*, struct __type_info_node *);
146 static void (WINAPI *ptype_info_dtor)(type_info*);
148 #define CXX_FRAME_MAGIC_VC6 0x19930520
149 #define CXX_EXCEPTION 0xe06d7363
151 /* offsets for computing the this pointer */
152 typedef struct
154 int this_offset; /* offset of base class this pointer from start of object */
155 int vbase_descr; /* offset of virtual base class descriptor */
156 int vbase_offset; /* offset of this pointer offset in virtual base class descriptor */
157 } this_ptr_offsets;
159 typedef void (*cxx_copy_ctor)(void);
161 /* complete information about a C++ type */
162 #ifndef __x86_64__
163 typedef struct __cxx_type_info
165 UINT flags; /* flags (see CLASS_* flags below) */
166 const type_info *type_info; /* C++ type info */
167 this_ptr_offsets offsets; /* offsets for computing the this pointer */
168 unsigned int size; /* object size */
169 cxx_copy_ctor copy_ctor; /* copy constructor */
170 } cxx_type_info;
171 #else
172 typedef struct __cxx_type_info
174 UINT flags;
175 unsigned int type_info;
176 this_ptr_offsets offsets;
177 unsigned int size;
178 unsigned int copy_ctor;
179 } cxx_type_info;
180 #endif
182 /* table of C++ types that apply for a given object */
183 #ifndef __x86_64__
184 typedef struct __cxx_type_info_table
186 UINT count; /* number of types */
187 const cxx_type_info *info[3]; /* variable length, we declare it large enough for static RTTI */
188 } cxx_type_info_table;
189 #else
190 typedef struct __cxx_type_info_table
192 UINT count;
193 unsigned int info[3];
194 } cxx_type_info_table;
195 #endif
197 /* type information for an exception object */
198 #ifndef __x86_64__
199 typedef struct __cxx_exception_type
201 UINT flags; /* TYPE_FLAG flags */
202 void (*destructor)(void);/* exception object destructor */
203 void *custom_handler; /* custom handler for this exception */
204 const cxx_type_info_table *type_info_table; /* list of types for this exception object */
205 } cxx_exception_type;
206 #else
207 typedef struct
209 UINT flags;
210 unsigned int destructor;
211 unsigned int custom_handler;
212 unsigned int type_info_table;
213 } cxx_exception_type;
214 #endif
216 static int (__cdecl *p_is_exception_typeof)(const type_info*, EXCEPTION_POINTERS*);
218 static void* (WINAPI *pEncodePointer)(void *);
220 static int cb_called[4];
221 static int g_qsort_s_context_counter;
222 static int g_bsearch_s_context_counter;
224 static inline int almost_equal_f(float f1, float f2)
226 return f1-f2 > -1e-30 && f1-f2 < 1e-30;
229 /* ########## */
231 /* thiscall emulation */
232 /* Emulate a __thiscall */
233 #ifdef __i386__
234 #ifdef _MSC_VER
235 static inline void* do_call_func1(void *func, void *_this)
237 volatile void* retval = 0;
238 __asm
240 push ecx
241 mov ecx, _this
242 call func
243 mov retval, eax
244 pop ecx
246 return (void*)retval;
249 static inline void* do_call_func2(void *func, void *_this, const void* arg)
251 volatile void* retval = 0;
252 __asm
254 push ecx
255 push arg
256 mov ecx, _this
257 call func
258 mov retval, eax
259 pop ecx
261 return (void*)retval;
263 #else
264 static void* do_call_func1(void *func, void *_this)
266 void *ret, *dummy;
267 __asm__ __volatile__ ("call *%2"
268 : "=a" (ret), "=c" (dummy)
269 : "g" (func), "1" (_this)
270 : "edx", "memory" );
271 return ret;
274 static void* do_call_func2(void *func, void *_this, const void* arg)
276 void *ret, *dummy;
277 __asm__ __volatile__ ("pushl %3\n\tcall *%2"
278 : "=a" (ret), "=c" (dummy)
279 : "r" (func), "r" (arg), "1" (_this)
280 : "edx", "memory" );
281 return ret;
283 #endif
285 #define call_func1(func,_this) do_call_func1(func,_this)
286 #define call_func2(func,_this,a) do_call_func2(func,_this,(const void*)a)
288 #else
290 #define call_func1(func,_this) func(_this)
291 #define call_func2(func,_this,a) func(_this,a)
293 #endif /* __i386__ */
295 static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
296 const wchar_t *function, const wchar_t *file,
297 unsigned line, uintptr_t arg)
299 CHECK_EXPECT(invalid_parameter_handler);
300 ok(expression == NULL, "expression is not NULL\n");
301 ok(function == NULL, "function is not NULL\n");
302 ok(file == NULL, "file is not NULL\n");
303 ok(line == 0, "line = %u\n", line);
304 ok(arg == 0, "arg = %lx\n", (UINT_PTR)arg);
305 ok(errno != 0xdeadbeef, "errno not set\n");
308 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hcrt,y)
309 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
310 static BOOL init(void)
312 HMODULE hcrt;
313 HMODULE hkernel32;
315 SetLastError(0xdeadbeef);
316 hcrt = LoadLibraryA("msvcr90.dll");
317 if (!hcrt) {
318 win_skip("msvcr90.dll not installed (got %d)\n", GetLastError());
319 return FALSE;
322 SET(p_set_invalid_parameter_handler, "_set_invalid_parameter_handler");
323 if(p_set_invalid_parameter_handler)
324 ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
325 "Invalid parameter handler was already set\n");
327 SET(p_initterm_e, "_initterm_e");
328 SET(p_encode_pointer, "_encode_pointer");
329 SET(p_decode_pointer, "_decode_pointer");
330 SET(p_encoded_null, "_encoded_null");
331 SET(p_sys_nerr, "_sys_nerr");
332 SET(p__sys_nerr, "__sys_nerr");
333 SET(p_sys_errlist, "_sys_errlist");
334 SET(p__sys_errlist, "__sys_errlist");
335 SET(p_strtoi64, "_strtoi64");
336 SET(p_strtoui64, "_strtoui64");
337 SET(p_itoa_s, "_itoa_s");
338 SET(p_wcsncat_s,"wcsncat_s" );
339 SET(p_qsort_s, "qsort_s");
340 SET(p_bsearch_s, "bsearch_s");
341 SET(p_controlfp_s, "_controlfp_s");
342 SET(p_tmpfile_s, "tmpfile_s");
343 SET(p_atoflt, "_atoflt");
344 SET(p_set_abort_behavior, "_set_abort_behavior");
345 SET(p_sopen_s, "_sopen_s");
346 SET(p_wsopen_s, "_wsopen_s");
347 SET(p_realloc_crt, "_realloc_crt");
348 SET(p_malloc, "malloc");
349 SET(p_free, "free");
350 SET(p_getptd, "_getptd");
351 SET(p_errno, "_errno");
352 SET(p_doserrno, "__doserrno");
353 SET(p_srand, "srand");
354 SET(p_strtok, "strtok");
355 SET(p_wcstok, "wcstok");
356 SET(p__mbstok, "_mbstok");
357 SET(p_strerror, "strerror");
358 SET(p_wcserror, "_wcserror");
359 SET(p_tmpnam, "tmpnam");
360 SET(p_wtmpnam, "_wtmpnam");
361 SET(p_asctime, "asctime");
362 SET(p_wasctime, "_wasctime");
363 SET(p_localtime64, "_localtime64");
364 SET(p_ecvt, "_ecvt");
365 SET(p_fpecode, "__fpecode");
366 SET(p_configthreadlocale, "_configthreadlocale");
367 SET(p_get_terminate, "_get_terminate");
368 SET(p_get_unexpected, "_get_unexpected");
369 SET(p__vswprintf_l, "__vswprintf_l");
370 SET(p_vswprintf_l, "_vswprintf_l");
371 SET(p_fopen, "fopen");
372 SET(p_fclose, "fclose");
373 SET(p_unlink, "_unlink");
374 SET(p_access_s, "_access_s");
375 SET(p_lock_file, "_lock_file");
376 SET(p_unlock_file, "_unlock_file");
377 SET(p_fileno, "_fileno");
378 SET(p_feof, "feof");
379 SET(p_ferror, "ferror");
380 SET(p_flsbuf, "_flsbuf");
381 SET(p_filbuf, "_filbuf");
382 SET(p_byteswap_ulong, "_byteswap_ulong");
383 SET(p__pxcptinfoptrs, "__pxcptinfoptrs");
384 SET(p__AdjustPointer, "__AdjustPointer");
385 SET(p_fflush_nolock, "_fflush_nolock");
386 if (sizeof(void *) == 8)
388 SET(p_type_info_name_internal_method, "?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z");
389 SET(ptype_info_dtor, "??1type_info@@UEAA@XZ");
390 SET(p_is_exception_typeof, "?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z");
392 else
394 #ifdef __arm__
395 SET(p_type_info_name_internal_method, "?_name_internal_method@type_info@@QBAPBDPAU__type_info_node@@@Z");
396 SET(ptype_info_dtor, "??1type_info@@UAA@XZ");
397 #else
398 SET(p_type_info_name_internal_method, "?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z");
399 SET(ptype_info_dtor, "??1type_info@@UAE@XZ");
400 #endif
401 SET(p_is_exception_typeof, "?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z");
404 hkernel32 = GetModuleHandleA("kernel32.dll");
405 pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
406 return TRUE;
409 static int __cdecl initterm_cb0(void)
411 cb_called[0]++;
412 return 0;
415 static int __cdecl initterm_cb1(void)
417 cb_called[1]++;
418 return 1;
421 static int __cdecl initterm_cb2(void)
423 cb_called[2]++;
424 return 2;
428 static void test__initterm_e(void)
430 _INITTERM_E_FN table[4];
431 int res;
433 memset(table, 0, sizeof(table));
435 memset(cb_called, 0, sizeof(cb_called));
436 errno = 0xdeadbeef;
437 res = p_initterm_e(table, table);
438 ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
439 "got %d with 0x%x {%d, %d, %d}\n",
440 res, errno, cb_called[0], cb_called[1], cb_called[2]);
442 memset(cb_called, 0, sizeof(cb_called));
443 errno = 0xdeadbeef;
444 res = p_initterm_e(table, NULL);
445 ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
446 "got %d with 0x%x {%d, %d, %d}\n",
447 res, errno, cb_called[0], cb_called[1], cb_called[2]);
449 if (0) {
450 /* this crash on Windows */
451 errno = 0xdeadbeef;
452 res = p_initterm_e(NULL, table);
453 trace("got %d with 0x%x\n", res, errno);
456 table[0] = initterm_cb0;
457 memset(cb_called, 0, sizeof(cb_called));
458 errno = 0xdeadbeef;
459 res = p_initterm_e(table, &table[1]);
460 ok( !res && (cb_called[0] == 1) && !cb_called[1] && !cb_called[2],
461 "got %d with 0x%x {%d, %d, %d}\n",
462 res, errno, cb_called[0], cb_called[1], cb_called[2]);
465 /* init-function returning failure */
466 table[1] = initterm_cb1;
467 memset(cb_called, 0, sizeof(cb_called));
468 errno = 0xdeadbeef;
469 res = p_initterm_e(table, &table[3]);
470 ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
471 "got %d with 0x%x {%d, %d, %d}\n",
472 res, errno, cb_called[0], cb_called[1], cb_called[2]);
474 /* init-function not called, when end < start */
475 memset(cb_called, 0, sizeof(cb_called));
476 errno = 0xdeadbeef;
477 res = p_initterm_e(&table[3], table);
478 ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
479 "got %d with 0x%x {%d, %d, %d}\n",
480 res, errno, cb_called[0], cb_called[1], cb_called[2]);
482 /* initialization stop after first non-zero result */
483 table[2] = initterm_cb0;
484 memset(cb_called, 0, sizeof(cb_called));
485 errno = 0xdeadbeef;
486 res = p_initterm_e(table, &table[3]);
487 ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
488 "got %d with 0x%x {%d, %d, %d}\n",
489 res, errno, cb_called[0], cb_called[1], cb_called[2]);
491 /* NULL pointer in the array are skipped */
492 table[1] = NULL;
493 table[2] = initterm_cb2;
494 memset(cb_called, 0, sizeof(cb_called));
495 errno = 0xdeadbeef;
496 res = p_initterm_e(table, &table[3]);
497 ok( (res == 2) && (cb_called[0] == 1) && !cb_called[1] && (cb_called[2] == 1),
498 "got %d with 0x%x {%d, %d, %d}\n",
499 res, errno, cb_called[0], cb_called[1], cb_called[2]);
503 /* Beware that _encode_pointer is a NOP before XP
504 (the parameter is returned unchanged) */
505 static void test__encode_pointer(void)
507 void *ptr, *res;
509 ptr = (void*)0xdeadbeef;
510 res = p_encode_pointer(ptr);
511 res = p_decode_pointer(res);
512 ok(res == ptr, "Pointers are different after encoding and decoding\n");
514 ok(p_encoded_null() == p_encode_pointer(NULL), "Error encoding null\n");
516 ptr = p_encode_pointer(p_encode_pointer);
517 ok(p_decode_pointer(ptr) == p_encode_pointer, "Error decoding pointer\n");
519 /* Not present before XP */
520 if (!pEncodePointer) {
521 win_skip("EncodePointer not found\n");
522 return;
525 res = pEncodePointer(p_encode_pointer);
526 ok(ptr == res, "_encode_pointer produced different result than EncodePointer\n");
530 static void test_error_messages(void)
532 int *size, size_copy;
534 size = p__sys_nerr();
535 size_copy = *size;
536 ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
538 *size = 20;
539 ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
541 *size = size_copy;
543 ok(*p_sys_errlist == *(p__sys_errlist()), "p_sys_errlist != p__sys_errlist()\n");
546 static void test__strtoi64(void)
548 __int64 res;
549 unsigned __int64 ures;
551 SET_EXPECT(invalid_parameter_handler);
552 res = p_strtoi64(NULL, NULL, 10);
553 ok(res == 0, "res != 0\n");
554 CHECK_CALLED(invalid_parameter_handler, EINVAL);
556 SET_EXPECT(invalid_parameter_handler);
557 res = p_strtoi64("123", NULL, 1);
558 ok(res == 0, "res != 0\n");
559 CHECK_CALLED(invalid_parameter_handler, EINVAL);
561 SET_EXPECT(invalid_parameter_handler);
562 res = p_strtoi64("123", NULL, 37);
563 ok(res == 0, "res != 0\n");
564 CHECK_CALLED(invalid_parameter_handler, EINVAL);
566 SET_EXPECT(invalid_parameter_handler);
567 ures = p_strtoui64(NULL, NULL, 10);
568 ok(ures == 0, "res = %d\n", (int)ures);
569 CHECK_CALLED(invalid_parameter_handler, EINVAL);
571 SET_EXPECT(invalid_parameter_handler);
572 ures = p_strtoui64("123", NULL, 1);
573 ok(ures == 0, "res = %d\n", (int)ures);
574 CHECK_CALLED(invalid_parameter_handler, EINVAL);
576 SET_EXPECT(invalid_parameter_handler);
577 ures = p_strtoui64("123", NULL, 37);
578 ok(ures == 0, "res = %d\n", (int)ures);
579 CHECK_CALLED(invalid_parameter_handler, EINVAL);
582 static void test__itoa_s(void)
584 errno_t ret;
585 char buffer[33];
587 SET_EXPECT(invalid_parameter_handler);
588 ret = p_itoa_s(0, NULL, 0, 0);
589 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
590 CHECK_CALLED(invalid_parameter_handler, EINVAL);
592 memset(buffer, 'X', sizeof(buffer));
593 SET_EXPECT(invalid_parameter_handler);
594 ret = p_itoa_s(0, buffer, 0, 0);
595 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
596 ok(buffer[0] == 'X', "Expected the output buffer to be untouched\n");
597 CHECK_CALLED(invalid_parameter_handler, EINVAL);
599 memset(buffer, 'X', sizeof(buffer));
600 SET_EXPECT(invalid_parameter_handler);
601 ret = p_itoa_s(0, buffer, sizeof(buffer), 0);
602 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
603 ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
604 CHECK_CALLED(invalid_parameter_handler, EINVAL);
606 memset(buffer, 'X', sizeof(buffer));
607 SET_EXPECT(invalid_parameter_handler);
608 ret = p_itoa_s(0, buffer, sizeof(buffer), 64);
609 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
610 ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
611 CHECK_CALLED(invalid_parameter_handler, EINVAL);
613 memset(buffer, 'X', sizeof(buffer));
614 SET_EXPECT(invalid_parameter_handler);
615 ret = p_itoa_s(12345678, buffer, 4, 10);
616 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
617 ok(!memcmp(buffer, "\000765", 4),
618 "Expected the output buffer to be null terminated with truncated output\n");
619 CHECK_CALLED(invalid_parameter_handler, ERANGE);
621 memset(buffer, 'X', sizeof(buffer));
622 SET_EXPECT(invalid_parameter_handler);
623 ret = p_itoa_s(12345678, buffer, 8, 10);
624 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
625 ok(!memcmp(buffer, "\0007654321", 8),
626 "Expected the output buffer to be null terminated with truncated output\n");
627 CHECK_CALLED(invalid_parameter_handler, ERANGE);
629 memset(buffer, 'X', sizeof(buffer));
630 SET_EXPECT(invalid_parameter_handler);
631 ret = p_itoa_s(-12345678, buffer, 9, 10);
632 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
633 ok(!memcmp(buffer, "\00087654321", 9),
634 "Expected the output buffer to be null terminated with truncated output\n");
635 CHECK_CALLED(invalid_parameter_handler, ERANGE);
637 ret = p_itoa_s(12345678, buffer, 9, 10);
638 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
639 ok(!strcmp(buffer, "12345678"),
640 "Expected output buffer string to be \"12345678\", got \"%s\"\n",
641 buffer);
643 ret = p_itoa_s(43690, buffer, sizeof(buffer), 2);
644 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
645 ok(!strcmp(buffer, "1010101010101010"),
646 "Expected output buffer string to be \"1010101010101010\", got \"%s\"\n",
647 buffer);
649 ret = p_itoa_s(1092009, buffer, sizeof(buffer), 36);
650 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
651 ok(!strcmp(buffer, "nell"),
652 "Expected output buffer string to be \"nell\", got \"%s\"\n",
653 buffer);
655 ret = p_itoa_s(5704, buffer, sizeof(buffer), 18);
656 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
657 ok(!strcmp(buffer, "hag"),
658 "Expected output buffer string to be \"hag\", got \"%s\"\n",
659 buffer);
661 ret = p_itoa_s(-12345678, buffer, sizeof(buffer), 10);
662 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
663 ok(!strcmp(buffer, "-12345678"),
664 "Expected output buffer string to be \"-12345678\", got \"%s\"\n",
665 buffer);
668 static void test_wcsncat_s(void)
670 static wchar_t abcW[] = {'a','b','c',0};
671 int ret;
672 wchar_t dst[4];
673 wchar_t src[4];
675 memcpy(src, abcW, sizeof(abcW));
676 dst[0] = 0;
677 SET_EXPECT(invalid_parameter_handler);
678 ret = p_wcsncat_s(NULL, 4, src, 4);
679 ok(ret == EINVAL, "err = %d\n", ret);
680 CHECK_CALLED(invalid_parameter_handler, EINVAL);
682 SET_EXPECT(invalid_parameter_handler);
683 ret = p_wcsncat_s(dst, 0, src, 4);
684 ok(ret == EINVAL, "err = %d\n", ret);
685 CHECK_CALLED(invalid_parameter_handler, EINVAL);
687 SET_EXPECT(invalid_parameter_handler);
688 ret = p_wcsncat_s(dst, 0, src, _TRUNCATE);
689 ok(ret == EINVAL, "err = %d\n", ret);
690 CHECK_CALLED(invalid_parameter_handler, EINVAL);
692 ret = p_wcsncat_s(dst, 4, NULL, 0);
693 ok(ret == 0, "err = %d\n", ret);
695 dst[0] = 0;
696 SET_EXPECT(invalid_parameter_handler);
697 ret = p_wcsncat_s(dst, 2, src, 4);
698 ok(ret == ERANGE, "err = %d\n", ret);
699 CHECK_CALLED(invalid_parameter_handler, ERANGE);
701 dst[0] = 0;
702 ret = p_wcsncat_s(dst, 2, src, _TRUNCATE);
703 ok(ret == STRUNCATE, "err = %d\n", ret);
704 ok(dst[0] == 'a' && dst[1] == 0, "dst is %s\n", wine_dbgstr_w(dst));
706 memcpy(dst, abcW, sizeof(abcW));
707 dst[3] = 'd';
708 SET_EXPECT(invalid_parameter_handler);
709 ret = p_wcsncat_s(dst, 4, src, 4);
710 ok(ret == EINVAL, "err = %d\n", ret);
711 CHECK_CALLED(invalid_parameter_handler, EINVAL);
714 /* Based on dlls/ntdll/tests/string.c */
715 static __cdecl int intcomparefunc(void *context, const void *a, const void *b)
717 const int *p = a, *q = b;
719 ok (a != b, "must never get the same pointer\n");
720 ++*(int *) context;
722 return *p - *q;
725 static __cdecl int charcomparefunc(void *context, const void *a, const void *b)
727 const char *p = a, *q = b;
729 ok (a != b, "must never get the same pointer\n");
730 ++*(int *) context;
732 return *p - *q;
735 static __cdecl int strcomparefunc(void *context, const void *a, const void *b)
737 const char * const *p = a;
738 const char * const *q = b;
740 ok (a != b, "must never get the same pointer\n");
741 ++*(int *) context;
743 return lstrcmpA(*p, *q);
746 static void test_qsort_s(void)
748 int arr[5] = { 23, 42, 8, 4, 16 };
749 int arr2[5] = { 23, 42, 8, 4, 16 };
750 char carr[5] = { 42, 23, 4, 8, 16 };
751 const char *strarr[7] = {
752 "Hello",
753 "Wine",
754 "World",
755 "!",
756 "Hopefully",
757 "Sorted",
761 SET_EXPECT(invalid_parameter_handler);
762 p_qsort_s(NULL, 0, 0, NULL, NULL);
763 CHECK_CALLED(invalid_parameter_handler, EINVAL);
765 SET_EXPECT(invalid_parameter_handler);
766 p_qsort_s(NULL, 0, 0, intcomparefunc, NULL);
767 CHECK_CALLED(invalid_parameter_handler, EINVAL);
769 SET_EXPECT(invalid_parameter_handler);
770 p_qsort_s(NULL, 0, sizeof(int), NULL, NULL);
771 CHECK_CALLED(invalid_parameter_handler, EINVAL);
773 SET_EXPECT(invalid_parameter_handler);
774 p_qsort_s(NULL, 1, sizeof(int), intcomparefunc, NULL);
775 CHECK_CALLED(invalid_parameter_handler, EINVAL);
777 errno = 0xdeadbeef;
778 g_qsort_s_context_counter = 0;
779 p_qsort_s(NULL, 0, sizeof(int), intcomparefunc, NULL);
780 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
781 ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
783 /* overflow without side effects, other overflow values crash */
784 errno = 0xdeadbeef;
785 g_qsort_s_context_counter = 0;
786 p_qsort_s((void*)arr2, (((size_t)1) << (8*sizeof(size_t) - 1)) + 1, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
787 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
788 ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
789 ok(arr2[0] == 23, "should remain unsorted, arr2[0] is %d\n", arr2[0]);
790 ok(arr2[1] == 42, "should remain unsorted, arr2[1] is %d\n", arr2[1]);
791 ok(arr2[2] == 8, "should remain unsorted, arr2[2] is %d\n", arr2[2]);
792 ok(arr2[3] == 4, "should remain unsorted, arr2[3] is %d\n", arr2[3]);
794 errno = 0xdeadbeef;
795 g_qsort_s_context_counter = 0;
796 p_qsort_s((void*)arr, 0, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
797 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
798 ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
799 ok(arr[0] == 23, "badly sorted, nmemb=0, arr[0] is %d\n", arr[0]);
800 ok(arr[1] == 42, "badly sorted, nmemb=0, arr[1] is %d\n", arr[1]);
801 ok(arr[2] == 8, "badly sorted, nmemb=0, arr[2] is %d\n", arr[2]);
802 ok(arr[3] == 4, "badly sorted, nmemb=0, arr[3] is %d\n", arr[3]);
803 ok(arr[4] == 16, "badly sorted, nmemb=0, arr[4] is %d\n", arr[4]);
805 errno = 0xdeadbeef;
806 g_qsort_s_context_counter = 0;
807 p_qsort_s((void*)arr, 1, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
808 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
809 ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
810 ok(arr[0] == 23, "badly sorted, nmemb=1, arr[0] is %d\n", arr[0]);
811 ok(arr[1] == 42, "badly sorted, nmemb=1, arr[1] is %d\n", arr[1]);
812 ok(arr[2] == 8, "badly sorted, nmemb=1, arr[2] is %d\n", arr[2]);
813 ok(arr[3] == 4, "badly sorted, nmemb=1, arr[3] is %d\n", arr[3]);
814 ok(arr[4] == 16, "badly sorted, nmemb=1, arr[4] is %d\n", arr[4]);
816 SET_EXPECT(invalid_parameter_handler);
817 g_qsort_s_context_counter = 0;
818 p_qsort_s((void*)arr, 5, 0, intcomparefunc, &g_qsort_s_context_counter);
819 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
820 ok(arr[0] == 23, "badly sorted, size=0, arr[0] is %d\n", arr[0]);
821 ok(arr[1] == 42, "badly sorted, size=0, arr[1] is %d\n", arr[1]);
822 ok(arr[2] == 8, "badly sorted, size=0, arr[2] is %d\n", arr[2]);
823 ok(arr[3] == 4, "badly sorted, size=0, arr[3] is %d\n", arr[3]);
824 ok(arr[4] == 16, "badly sorted, size=0, arr[4] is %d\n", arr[4]);
825 CHECK_CALLED(invalid_parameter_handler, EINVAL);
827 g_qsort_s_context_counter = 0;
828 p_qsort_s((void*)arr, 5, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
829 ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
830 ok(arr[0] == 4, "badly sorted, arr[0] is %d\n", arr[0]);
831 ok(arr[1] == 8, "badly sorted, arr[1] is %d\n", arr[1]);
832 ok(arr[2] == 16, "badly sorted, arr[2] is %d\n", arr[2]);
833 ok(arr[3] == 23, "badly sorted, arr[3] is %d\n", arr[3]);
834 ok(arr[4] == 42, "badly sorted, arr[4] is %d\n", arr[4]);
836 g_qsort_s_context_counter = 0;
837 p_qsort_s((void*)carr, 5, sizeof(char), charcomparefunc, &g_qsort_s_context_counter);
838 ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
839 ok(carr[0] == 4, "badly sorted, carr[0] is %d\n", carr[0]);
840 ok(carr[1] == 8, "badly sorted, carr[1] is %d\n", carr[1]);
841 ok(carr[2] == 16, "badly sorted, carr[2] is %d\n", carr[2]);
842 ok(carr[3] == 23, "badly sorted, carr[3] is %d\n", carr[3]);
843 ok(carr[4] == 42, "badly sorted, carr[4] is %d\n", carr[4]);
845 g_qsort_s_context_counter = 0;
846 p_qsort_s((void*)strarr, 7, sizeof(char*), strcomparefunc, &g_qsort_s_context_counter);
847 ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
848 ok(!strcmp(strarr[0],"!"), "badly sorted, strarr[0] is %s\n", strarr[0]);
849 ok(!strcmp(strarr[1],"."), "badly sorted, strarr[1] is %s\n", strarr[1]);
850 ok(!strcmp(strarr[2],"Hello"), "badly sorted, strarr[2] is %s\n", strarr[2]);
851 ok(!strcmp(strarr[3],"Hopefully"), "badly sorted, strarr[3] is %s\n", strarr[3]);
852 ok(!strcmp(strarr[4],"Sorted"), "badly sorted, strarr[4] is %s\n", strarr[4]);
853 ok(!strcmp(strarr[5],"Wine"), "badly sorted, strarr[5] is %s\n", strarr[5]);
854 ok(!strcmp(strarr[6],"World"), "badly sorted, strarr[6] is %s\n", strarr[6]);
857 static void test_bsearch_s(void)
859 int arr[7] = { 1, 3, 4, 8, 16, 23, 42 };
860 int *x, l, i, j = 1;
862 SET_EXPECT(invalid_parameter_handler);
863 x = p_bsearch_s(NULL, NULL, 0, 0, NULL, NULL);
864 ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
865 CHECK_CALLED(invalid_parameter_handler, EINVAL);
867 g_bsearch_s_context_counter = 0;
868 SET_EXPECT(invalid_parameter_handler);
869 x = p_bsearch_s(&l, arr, j, 0, intcomparefunc, &g_bsearch_s_context_counter);
870 ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
871 ok(g_bsearch_s_context_counter == 0, "callback shouldn't have been called\n");
872 CHECK_CALLED(invalid_parameter_handler, EINVAL);
874 g_bsearch_s_context_counter = 0;
875 SET_EXPECT(invalid_parameter_handler);
876 x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), NULL, &g_bsearch_s_context_counter);
877 ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
878 ok(g_bsearch_s_context_counter == 0, "callback shouldn't have been called\n");
879 CHECK_CALLED(invalid_parameter_handler, EINVAL);
881 /* just try all array sizes */
882 for (j=1;j<sizeof(arr)/sizeof(arr[0]);j++) {
883 for (i=0;i<j;i++) {
884 l = arr[i];
885 g_bsearch_s_context_counter = 0;
886 x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), intcomparefunc, &g_bsearch_s_context_counter);
887 ok (x == &arr[i], "bsearch_s did not find %d entry in loopsize %d.\n", i, j);
888 ok(g_bsearch_s_context_counter > 0, "callback wasn't called\n");
890 l = 4242;
891 g_bsearch_s_context_counter = 0;
892 x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), intcomparefunc, &g_bsearch_s_context_counter);
893 ok (x == NULL, "bsearch_s did find 4242 entry in loopsize %d.\n", j);
894 ok(g_bsearch_s_context_counter > 0, "callback wasn't called\n");
898 static void test_controlfp_s(void)
900 unsigned int cur;
901 int ret;
903 SET_EXPECT(invalid_parameter_handler);
904 ret = p_controlfp_s( NULL, ~0, ~0 );
905 ok( ret == EINVAL, "wrong result %d\n", ret );
906 CHECK_CALLED(invalid_parameter_handler, EINVAL);
908 cur = 0xdeadbeef;
909 SET_EXPECT(invalid_parameter_handler);
910 ret = p_controlfp_s( &cur, ~0, ~0 );
911 ok( ret == EINVAL, "wrong result %d\n", ret );
912 ok( cur != 0xdeadbeef, "value not set\n" );
913 CHECK_CALLED(invalid_parameter_handler, EINVAL);
915 cur = 0xdeadbeef;
916 ret = p_controlfp_s( &cur, 0, 0 );
917 ok( !ret, "wrong result %d\n", ret );
918 ok( cur != 0xdeadbeef, "value not set\n" );
920 SET_EXPECT(invalid_parameter_handler);
921 cur = 0xdeadbeef;
922 ret = p_controlfp_s( &cur, 0x80000000, 0x80000000 );
923 ok( ret == EINVAL, "wrong result %d\n", ret );
924 ok( cur != 0xdeadbeef, "value not set\n" );
925 CHECK_CALLED(invalid_parameter_handler, EINVAL);
927 cur = 0xdeadbeef;
928 /* mask is only checked when setting invalid bits */
929 ret = p_controlfp_s( &cur, 0, 0x80000000 );
930 ok( !ret, "wrong result %d\n", ret );
931 ok( cur != 0xdeadbeef, "value not set\n" );
934 static void test_tmpfile_s( void )
936 int ret;
938 SET_EXPECT(invalid_parameter_handler);
939 ret = p_tmpfile_s(NULL);
940 ok(ret == EINVAL, "Expected tmpfile_s to return EINVAL, got %i\n", ret);
941 CHECK_CALLED(invalid_parameter_handler, EINVAL);
944 typedef struct
946 const char *str;
947 float flt;
948 int ret;
949 } _atoflt_test;
951 static const _atoflt_test _atoflt_testdata[] = {
952 { "12.1", 12.1, 0 },
953 { "-13.721", -13.721, 0 },
954 { "INF", 0.0, 0 },
955 { ".21e12", 0.21e12, 0 },
956 { "214353e-3", 214.353, 0 },
957 { "1d9999999999999999999", 0.0, _OVERFLOW },
958 { " d10", 0.0, 0 },
959 /* more significant digits */
960 { "1.23456789", 1.23456789, 0 },
961 { "1.23456789e1", 12.3456789, 0 },
962 { "1e39", 0.0, _OVERFLOW },
963 { "1e-39", 0.0, _UNDERFLOW },
964 { NULL }
967 static void test__atoflt(void)
969 _CRT_FLOAT flt;
970 int ret, i = 0;
972 if (0)
974 /* crashes on native */
975 p_atoflt(NULL, NULL);
976 p_atoflt(NULL, (char*)_atoflt_testdata[0].str);
977 p_atoflt(&flt, NULL);
980 while (_atoflt_testdata[i].str)
982 ret = p_atoflt(&flt, (char*)_atoflt_testdata[i].str);
983 ok(ret == _atoflt_testdata[i].ret, "got ret %d, expected ret %d, for %s\n", ret,
984 _atoflt_testdata[i].ret, _atoflt_testdata[i].str);
986 if (ret == 0)
987 ok(almost_equal_f(flt.f, _atoflt_testdata[i].flt), "got %f, expected %f, for %s\n", flt.f,
988 _atoflt_testdata[i].flt, _atoflt_testdata[i].str);
990 i++;
994 static void test__set_abort_behavior(void)
996 unsigned int res;
998 /* default is _WRITE_ABORT_MSG | _CALL_REPORTFAULT */
999 res = p_set_abort_behavior(0, 0);
1000 ok (res == (_WRITE_ABORT_MSG | _CALL_REPORTFAULT),
1001 "got 0x%x (expected 0x%x)\n", res, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
1003 /* no internal mask */
1004 p_set_abort_behavior(0xffffffff, 0xffffffff);
1005 res = p_set_abort_behavior(0, 0);
1006 ok (res == 0xffffffff, "got 0x%x (expected 0x%x)\n", res, 0xffffffff);
1008 /* set to default value */
1009 p_set_abort_behavior(_WRITE_ABORT_MSG | _CALL_REPORTFAULT, 0xffffffff);
1012 static void test__sopen_s(void)
1014 int ret, fd;
1016 SET_EXPECT(invalid_parameter_handler);
1017 ret = p_sopen_s(NULL, "test", _O_RDONLY, _SH_DENYNO, _S_IREAD);
1018 ok(ret == EINVAL, "got %d, expected EINVAL\n", ret);
1019 CHECK_CALLED(invalid_parameter_handler, EINVAL);
1021 fd = 0xdead;
1022 ret = p_sopen_s(&fd, "test", _O_RDONLY, _SH_DENYNO, _S_IREAD);
1023 ok(ret == ENOENT, "got %d, expected ENOENT\n", ret);
1024 ok(fd == -1, "got %d\n", fd);
1027 static void test__wsopen_s(void)
1029 wchar_t testW[] = {'t','e','s','t',0};
1030 int ret, fd;
1032 SET_EXPECT(invalid_parameter_handler);
1033 ret = p_wsopen_s(NULL, testW, _O_RDONLY, _SH_DENYNO, _S_IREAD);
1034 ok(ret == EINVAL, "got %d, expected EINVAL\n", ret);
1035 CHECK_CALLED(invalid_parameter_handler, EINVAL);
1037 fd = 0xdead;
1038 ret = p_wsopen_s(&fd, testW, _O_RDONLY, _SH_DENYNO, _S_IREAD);
1039 ok(ret == ENOENT, "got %d, expected ENOENT\n", ret);
1040 ok(fd == -1, "got %d\n", fd);
1043 static void test__realloc_crt(void)
1045 void *mem;
1047 if (0)
1049 /* crashes on some systems starting Vista */
1050 p_realloc_crt(NULL, 10);
1053 mem = p_malloc(10);
1054 ok(mem != NULL, "memory not allocated\n");
1056 mem = p_realloc_crt(mem, 20);
1057 ok(mem != NULL, "memory not reallocated\n");
1059 mem = p_realloc_crt(mem, 0);
1060 ok(mem == NULL, "memory not freed\n");
1062 mem = p_realloc_crt(NULL, 0);
1063 ok(mem != NULL, "memory not (re)allocated for size 0\n");
1064 p_free(mem);
1067 static void test_typeinfo(void)
1069 static type_info t1 = { NULL, NULL,{'.','?','A','V','t','e','s','t','1','@','@',0,0,0,0,0 } };
1070 struct __type_info_node node;
1071 char *name;
1073 /* name */
1074 t1.name = NULL;
1075 node.memPtr = NULL;
1076 node.next = NULL;
1077 name = call_func2(p_type_info_name_internal_method, &t1, &node);
1078 ok(name != NULL, "got %p\n", name);
1079 ok(name && t1.name && !strcmp(name, t1.name), "bad name '%s' for t1\n", name);
1081 ok(t1.name && !strcmp(t1.name, "class test1"), "demangled to '%s' for t1\n", t1.name);
1082 call_func1(ptype_info_dtor, &t1);
1085 /* Keep in sync with msvcrt/msvcrt.h */
1086 struct __thread_data {
1087 DWORD tid;
1088 HANDLE handle;
1089 int thread_errno;
1090 __msvcrt_ulong thread_doserrno;
1091 int unk1;
1092 unsigned int random_seed;
1093 char *strtok_next;
1094 wchar_t *wcstok_next;
1095 unsigned char *mbstok_next;
1096 char *strerror_buffer;
1097 wchar_t *wcserror_buffer;
1098 char *tmpnam_buffer;
1099 wchar_t *wtmpnam_buffer;
1100 void *unk2[2];
1101 char *asctime_buffer;
1102 wchar_t *wasctime_buffer;
1103 struct tm *time_buffer;
1104 char *efcvt_buffer;
1105 int unk3[2];
1106 void *unk4[3];
1107 EXCEPTION_POINTERS *xcptinfo;
1108 int fpecode;
1109 pthreadmbcinfo mbcinfo;
1110 pthreadlocinfo locinfo;
1111 BOOL have_locale;
1112 int unk5[1];
1113 void* terminate_handler;
1114 void* unexpected_handler;
1115 void* se_translator;
1116 void *unk6[3];
1117 int unk7;
1118 EXCEPTION_RECORD *exc_record;
1121 static void test_getptd(void)
1123 struct __thread_data *ptd = p_getptd();
1124 DWORD tid = GetCurrentThreadId();
1125 wchar_t testW[] = {'t','e','s','t',0}, tW[] = {'t',0}, *wp;
1126 char test[] = "test", *p;
1127 unsigned char mbstok_test[] = "test", *up;
1128 struct tm time;
1129 __time64_t secs = 0;
1130 int dec, sign;
1131 void *mbcinfo, *locinfo;
1133 ok(ptd->tid == tid, "ptd->tid = %x, expected %x\n", ptd->tid, tid);
1134 ok(ptd->handle == INVALID_HANDLE_VALUE, "ptd->handle = %p\n", ptd->handle);
1135 ok(p_errno() == &ptd->thread_errno, "ptd->thread_errno is different then _errno()\n");
1136 ok(p_doserrno() == &ptd->thread_doserrno, "ptd->thread_doserrno is different then __doserrno()\n");
1137 p_srand(1234);
1138 ok(ptd->random_seed == 1234, "ptd->random_seed = %d\n", ptd->random_seed);
1139 p = p_strtok(test, "t");
1140 ok(ptd->strtok_next == p+3, "ptd->strtok_next is incorrect\n");
1141 wp = p_wcstok(testW, tW);
1142 ok(ptd->wcstok_next == wp+3, "ptd->wcstok_next is incorrect\n");
1143 up = p__mbstok(mbstok_test, (unsigned char*)"t");
1144 ok(ptd->mbstok_next == up+3, "ptd->mbstok_next is incorrect\n");
1145 ok(p_strerror(0) == ptd->strerror_buffer, "ptd->strerror_buffer is incorrect\n");
1146 ok(p_wcserror(0) == ptd->wcserror_buffer, "ptd->wcserror_buffer is incorrect\n");
1147 ok(p_tmpnam(NULL) == ptd->tmpnam_buffer, "ptd->tmpnam_buffer is incorrect\n");
1148 ok(p_wtmpnam(NULL) == ptd->wtmpnam_buffer, "ptd->wtmpnam_buffer is incorrect\n");
1149 memset(&time, 0, sizeof(time));
1150 time.tm_mday = 1;
1151 ok(p_asctime(&time) == ptd->asctime_buffer, "ptd->asctime_buffer is incorrect\n");
1152 ok(p_wasctime(&time) == ptd->wasctime_buffer, "ptd->wasctime_buffer is incorrect\n");
1153 ok(p_localtime64(&secs) == ptd->time_buffer, "ptd->time_buffer is incorrect\n");
1154 ok(p_ecvt(3.12, 1, &dec, &sign) == ptd->efcvt_buffer, "ptd->efcvt_buffer is incorrect\n");
1155 ok(p__pxcptinfoptrs() == (void**)&ptd->xcptinfo, "ptd->xcptinfo is incorrect\n");
1156 ok(p_fpecode() == &ptd->fpecode, "ptd->fpecode is incorrect\n");
1157 mbcinfo = ptd->mbcinfo;
1158 locinfo = ptd->locinfo;
1159 todo_wine ok(ptd->have_locale == 1, "ptd->have_locale = %x\n", ptd->have_locale);
1160 p_configthreadlocale(1);
1161 todo_wine ok(mbcinfo == ptd->mbcinfo, "ptd->mbcinfo != mbcinfo\n");
1162 todo_wine ok(locinfo == ptd->locinfo, "ptd->locinfo != locinfo\n");
1163 todo_wine ok(ptd->have_locale == 3, "ptd->have_locale = %x\n", ptd->have_locale);
1164 ok(p_get_terminate() == ptd->terminate_handler, "ptd->terminate_handler != _get_terminate()\n");
1165 ok(p_get_unexpected() == ptd->unexpected_handler, "ptd->unexpected_handler != _get_unexpected()\n");
1168 static int __cdecl __vswprintf_l_wrapper(wchar_t *buf,
1169 const wchar_t *format, _locale_t locale, ...)
1171 int ret;
1172 __ms_va_list valist;
1173 __ms_va_start(valist, locale);
1174 ret = p__vswprintf_l(buf, format, locale, valist);
1175 __ms_va_end(valist);
1176 return ret;
1179 static int __cdecl _vswprintf_l_wrapper(wchar_t *buf,
1180 const wchar_t *format, _locale_t locale, ...)
1182 int ret;
1183 __ms_va_list valist;
1184 __ms_va_start(valist, locale);
1185 ret = p_vswprintf_l(buf, format, locale, valist);
1186 __ms_va_end(valist);
1187 return ret;
1190 static void test__vswprintf_l(void)
1192 static const wchar_t format[] = {'t','e','s','t',0};
1194 wchar_t buf[32];
1195 int ret;
1197 ret = __vswprintf_l_wrapper(buf, format, NULL);
1198 ok(ret == 4, "ret = %d\n", ret);
1199 ok(!memcmp(buf, format, sizeof(format)), "buf = %s, expected %s\n",
1200 wine_dbgstr_w(buf), wine_dbgstr_w(format));
1202 ret = _vswprintf_l_wrapper(buf, format, NULL);
1203 ok(ret == 4, "ret = %d\n", ret);
1204 ok(!memcmp(buf, format, sizeof(format)), "buf = %s, expected %s\n",
1205 wine_dbgstr_w(buf), wine_dbgstr_w(format));
1208 struct block_file_arg
1210 FILE *read;
1211 FILE *write;
1212 HANDLE init;
1213 HANDLE finish;
1214 int deadlock_test;
1217 static DWORD WINAPI block_file(void *arg)
1219 struct block_file_arg *files = arg;
1220 int deadlock_test;
1222 p_lock_file(files->read);
1223 p_lock_file(files->write);
1224 SetEvent(files->init);
1226 WaitForSingleObject(files->finish, INFINITE);
1227 Sleep(200);
1228 deadlock_test = InterlockedIncrement(&files->deadlock_test);
1229 ok(deadlock_test == 1, "deadlock_test = %d\n", deadlock_test);
1230 p_unlock_file(files->read);
1231 p_unlock_file(files->write);
1232 return 0;
1235 static void test_nonblocking_file_access(void)
1237 HANDLE thread;
1238 struct block_file_arg arg;
1239 FILE *filer, *filew;
1240 int ret;
1242 if(!p_lock_file || !p_unlock_file) {
1243 win_skip("_lock_file not available\n");
1244 return;
1247 filew = p_fopen("test_file", "w");
1248 ok(filew != NULL, "unable to create test file\n");
1249 if(!filew)
1250 return;
1251 filer = p_fopen("test_file", "r");
1252 ok(filer != NULL, "unable to open test file\n");
1253 if(!filer) {
1254 p_fclose(filew);
1255 p_unlink("test_file");
1256 return;
1259 arg.read = filer;
1260 arg.write = filew;
1261 arg.init = CreateEventW(NULL, FALSE, FALSE, NULL);
1262 arg.finish = CreateEventW(NULL, FALSE, FALSE, NULL);
1263 arg.deadlock_test = 0;
1264 ok(arg.init != NULL, "CreateEventW failed\n");
1265 ok(arg.finish != NULL, "CreateEventW failed\n");
1266 thread = CreateThread(NULL, 0, block_file, (void*)&arg, 0, NULL);
1267 ok(thread != NULL, "CreateThread failed\n");
1268 WaitForSingleObject(arg.init, INFINITE);
1270 ret = p_fileno(filer);
1271 ok(ret, "_fileno(filer) returned %d\n", ret);
1272 ret = p_fileno(filew);
1273 ok(ret, "_fileno(filew) returned %d\n", ret);
1275 ret = p_feof(filer);
1276 ok(ret==0, "feof(filer) returned %d\n", ret);
1277 ret = p_feof(filew);
1278 ok(ret==0, "feof(filew) returned %d\n", ret);
1280 ret = p_ferror(filer);
1281 ok(ret==0, "ferror(filer) returned %d\n", ret);
1282 ret = p_ferror(filew);
1283 ok(ret==0, "ferror(filew) returned %d\n", ret);
1285 ret = p_flsbuf('a', filer);
1286 ok(ret==-1, "_flsbuf(filer) returned %d\n", ret);
1287 ret = p_flsbuf('a', filew);
1288 ok(ret=='a', "_flsbuf(filew) returned %d\n", ret);
1290 ret = p_filbuf(filer);
1291 ok(ret==-1, "_filbuf(filer) returned %d\n", ret);
1292 ret = p_filbuf(filew);
1293 ok(ret==-1, "_filbuf(filew) returned %d\n", ret);
1295 ret = p_fflush_nolock(filer);
1296 ok(ret==0, "_fflush_nolock(filer) returned %d\n", ret);
1297 ret = p_fflush_nolock(filew);
1298 ok(ret==0, "_fflush_nolock(filew) returned %d\n", ret);
1300 SetEvent(arg.finish);
1302 ret = p_fflush_nolock(NULL);
1303 ok(ret==0, "_fflush_nolock(NULL) returned %d\n", ret);
1304 ret = InterlockedIncrement(&arg.deadlock_test);
1305 ok(ret==2, "InterlockedIncrement returned %d\n", ret);
1307 WaitForSingleObject(thread, INFINITE);
1308 CloseHandle(arg.init);
1309 CloseHandle(arg.finish);
1310 CloseHandle(thread);
1311 p_fclose(filer);
1312 p_fclose(filew);
1313 p_unlink("test_file");
1316 static void test_byteswap(void)
1318 unsigned long ret;
1320 ret = p_byteswap_ulong(0x12345678);
1321 ok(ret == 0x78563412, "ret = %lx\n", ret);
1323 ret = p_byteswap_ulong(0);
1324 ok(ret == 0, "ret = %lx\n", ret);
1327 static void test_access_s(void)
1329 FILE *f;
1330 int res;
1332 f = p_fopen("test_file", "w");
1333 ok(f != NULL, "unable to create test file\n");
1334 if(!f)
1335 return;
1337 p_fclose(f);
1339 errno = 0xdeadbeef;
1340 res = p_access_s("test_file", 0);
1341 ok(res == 0, "got %x\n", res);
1342 ok(errno == 0xdeadbeef, "got %x\n", res);
1344 errno = 0xdeadbeef;
1345 res = p_access_s("test_file", 2);
1346 ok(res == 0, "got %x\n", res);
1347 ok(errno == 0xdeadbeef, "got %x\n", res);
1349 errno = 0xdeadbeef;
1350 res = p_access_s("test_file", 4);
1351 ok(res == 0, "got %x\n", res);
1352 ok(errno == 0xdeadbeef, "got %x\n", res);
1354 errno = 0xdeadbeef;
1355 res = p_access_s("test_file", 6);
1356 ok(res == 0, "got %x\n", res);
1357 ok(errno == 0xdeadbeef, "got %x\n", res);
1359 SetFileAttributesA("test_file", FILE_ATTRIBUTE_READONLY);
1361 errno = 0xdeadbeef;
1362 res = p_access_s("test_file", 0);
1363 ok(res == 0, "got %x\n", res);
1364 ok(errno == 0xdeadbeef, "got %x\n", res);
1366 errno = 0xdeadbeef;
1367 res = p_access_s("test_file", 2);
1368 ok(res == EACCES, "got %x\n", res);
1369 ok(errno == EACCES, "got %x\n", res);
1371 errno = 0xdeadbeef;
1372 res = p_access_s("test_file", 4);
1373 ok(res == 0, "got %x\n", res);
1374 ok(errno == 0xdeadbeef, "got %x\n", res);
1376 errno = 0xdeadbeef;
1377 res = p_access_s("test_file", 6);
1378 ok(res == EACCES, "got %x\n", res);
1379 ok(errno == EACCES, "got %x\n", res);
1381 SetFileAttributesA("test_file", FILE_ATTRIBUTE_NORMAL);
1383 p_unlink("test_file");
1385 errno = 0xdeadbeef;
1386 res = p_access_s("test_file", 0);
1387 ok(res == ENOENT, "got %x\n", res);
1388 ok(errno == ENOENT, "got %x\n", res);
1390 errno = 0xdeadbeef;
1391 res = p_access_s("test_file", 2);
1392 ok(res == ENOENT, "got %x\n", res);
1393 ok(errno == ENOENT, "got %x\n", res);
1395 errno = 0xdeadbeef;
1396 res = p_access_s("test_file", 4);
1397 ok(res == ENOENT, "got %x\n", res);
1398 ok(errno == ENOENT, "got %x\n", res);
1400 errno = 0xdeadbeef;
1401 res = p_access_s("test_file", 6);
1402 ok(res == ENOENT, "got %x\n", res);
1403 ok(errno == ENOENT, "got %x\n", res);
1406 #ifndef __x86_64__
1407 #define EXCEPTION_REF(instance, name) &instance.name
1408 #else
1409 #define EXCEPTION_REF(instance, name) FIELD_OFFSET(struct _exception_data, name)
1410 #endif
1411 static void test_is_exception_typeof(void)
1413 const type_info ti1 = {NULL, NULL, {'.','?','A','V','t','e','s','t','1','@','@',0}};
1414 const type_info ti2 = {NULL, NULL, {'.','?','A','V','t','e','s','t','2','@','@',0}};
1415 const type_info ti3 = {NULL, NULL, {'.','?','A','V','t','e','s','t','3','@','@',0}};
1417 const struct _exception_data {
1418 type_info ti1;
1419 type_info ti2;
1420 cxx_type_info cti1;
1421 cxx_type_info cti2;
1422 cxx_type_info_table tit;
1423 cxx_exception_type et;
1424 } exception_data = {
1425 {NULL, NULL, {'.','?','A','V','t','e','s','t','1','@','@',0}},
1426 {NULL, NULL, {'.','?','A','V','t','e','s','t','2','@','@',0}},
1427 {0, EXCEPTION_REF(exception_data, ti1)},
1428 {0, EXCEPTION_REF(exception_data, ti2)},
1429 {2, {EXCEPTION_REF(exception_data, cti1), EXCEPTION_REF(exception_data, cti2)}},
1430 {0, 0, 0, EXCEPTION_REF(exception_data, tit)}
1433 EXCEPTION_RECORD rec = {CXX_EXCEPTION, 0, NULL, NULL, 3, {CXX_FRAME_MAGIC_VC6, 0, (ULONG_PTR)&exception_data.et}};
1434 EXCEPTION_POINTERS except_ptrs = {&rec, NULL};
1436 int ret;
1438 #ifdef __x86_64__
1439 rec.NumberParameters = 4;
1440 rec.ExceptionInformation[3] = (ULONG_PTR)&exception_data;
1441 #endif
1443 ret = p_is_exception_typeof(&ti1, &except_ptrs);
1444 ok(ret == 1, "_is_exception_typeof returned %d\n", ret);
1445 ret = p_is_exception_typeof(&ti2, &except_ptrs);
1446 ok(ret == 1, "_is_exception_typeof returned %d\n", ret);
1447 ret = p_is_exception_typeof(&ti3, &except_ptrs);
1448 ok(ret == 0, "_is_exception_typeof returned %d\n", ret);
1451 static void test__AdjustPointer(void)
1453 int off = 0xf0;
1454 void *obj1 = &off;
1455 void *obj2 = (char*)&off - 2;
1456 struct test_data {
1457 void *ptr;
1458 void *ret;
1459 struct {
1460 int this_offset;
1461 int vbase_descr;
1462 int vbase_offset;
1463 } this_ptr_offsets;
1464 } data[] = {
1465 {NULL, NULL, {0, -1, 0}},
1466 {(void*)0xbeef, (void*)0xbef0, {1, -1, 1}},
1467 {(void*)0xbeef, (void*)0xbeee, {-1, -1, 0}},
1468 {&obj1, (char*)&obj1 + off, {0, 0, 0}},
1469 {(char*)&obj1 - 5, (char*)&obj1 + off, {0, 5, 0}},
1470 {(char*)&obj1 - 3, (char*)&obj1 + off + 24, {24, 3, 0}},
1471 {(char*)&obj2 - 17, (char*)&obj2 + off + 4, {4, 17, 2}}
1473 void *ret;
1474 int i;
1476 for(i=0; i<sizeof(data)/sizeof(data[0]); i++) {
1477 ret = p__AdjustPointer(data[i].ptr, &data[i].this_ptr_offsets);
1478 ok(ret == data[i].ret, "%d) __AdjustPointer returned %p, expected %p\n", i, ret, data[i].ret);
1482 START_TEST(msvcr90)
1484 if(!init())
1485 return;
1487 test__initterm_e();
1488 test__encode_pointer();
1489 test_error_messages();
1490 test__strtoi64();
1491 test__itoa_s();
1492 test_wcsncat_s();
1493 test_qsort_s();
1494 test_bsearch_s();
1495 test_controlfp_s();
1496 test_tmpfile_s();
1497 test__atoflt();
1498 test__set_abort_behavior();
1499 test__sopen_s();
1500 test__wsopen_s();
1501 test__realloc_crt();
1502 test_typeinfo();
1503 test_getptd();
1504 test__vswprintf_l();
1505 test_nonblocking_file_access();
1506 test_byteswap();
1507 test_access_s();
1508 test_is_exception_typeof();
1509 test__AdjustPointer();