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
34 #include "wine/test.h"
36 #define DEFINE_EXPECT(func) \
37 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
39 #define SET_EXPECT(func) \
41 expect_ ## func = TRUE; \
45 #define CHECK_EXPECT2(func) \
47 ok(expect_ ##func, "unexpected call " #func "\n"); \
48 called_ ## func = TRUE; \
51 #define CHECK_EXPECT(func) \
53 CHECK_EXPECT2(func); \
54 expect_ ## func = FALSE; \
57 #define CHECK_CALLED(func,error) \
59 ok(called_ ## func, "expected " #func "\n"); \
60 ok( errno == (error), "got errno %u instead of %u\n", errno, (error) ); \
61 expect_ ## func = called_ ## func = FALSE; \
64 DEFINE_EXPECT(invalid_parameter_handler
);
66 static _invalid_parameter_handler (__cdecl
*p_set_invalid_parameter_handler
)(_invalid_parameter_handler
);
67 typedef int (__cdecl
*_INITTERM_E_FN
)(void);
68 static int (__cdecl
*p_initterm_e
)(_INITTERM_E_FN
*table
, _INITTERM_E_FN
*end
);
69 static void* (__cdecl
*p_encode_pointer
)(void *);
70 static void* (__cdecl
*p_decode_pointer
)(void *);
71 static void* (__cdecl
*p_encoded_null
)(void);
72 static int *p_sys_nerr
;
73 static int* (__cdecl
*p__sys_nerr
)(void);
74 static char **p_sys_errlist
;
75 static char** (__cdecl
*p__sys_errlist
)(void);
76 static __int64 (__cdecl
*p_strtoi64
)(const char *, char **, int);
77 static unsigned __int64 (__cdecl
*p_strtoui64
)(const char *, char **, int);
78 static errno_t (__cdecl
*p_itoa_s
)(int,char*,size_t,int);
79 static int (__cdecl
*p_wcsncat_s
)(wchar_t *dst
, size_t elem
, const wchar_t *src
, size_t count
);
80 static void (__cdecl
*p_qsort_s
)(void *, size_t, size_t, int (__cdecl
*)(void *, const void *, const void *), void *);
81 static void* (__cdecl
*p_bsearch_s
)(const void *, const void *, size_t, size_t,
82 int (__cdecl
*compare
)(void *, const void *, const void *), void *);
83 static int (__cdecl
*p_controlfp_s
)(unsigned int *, unsigned int, unsigned int);
84 static int (__cdecl
*p_tmpfile_s
)(FILE**);
85 static int (__cdecl
*p_atoflt
)(_CRT_FLOAT
*, char *);
86 static unsigned int (__cdecl
*p_set_abort_behavior
)(unsigned int, unsigned int);
87 static int (__cdecl
*p_sopen_s
)(int*, const char*, int, int, int);
88 static int (__cdecl
*p_wsopen_s
)(int*, const wchar_t*, int, int, int);
89 static void* (__cdecl
*p_realloc_crt
)(void*, size_t);
90 static void* (__cdecl
*p_malloc
)(size_t);
91 static void (__cdecl
*p_free
)(void*);
92 static void* (__cdecl
*p_getptd
)(void);
93 static int* (__cdecl
*p_errno
)(void);
94 static __msvcrt_ulong
* (__cdecl
*p_doserrno
)(void);
95 static void (__cdecl
*p_srand
)(unsigned int);
96 static char* (__cdecl
*p_strtok
)(char*, const char*);
97 static char* (__cdecl
*p_strtok_s
)(char*, const char*, char**);
98 static wchar_t* (__cdecl
*p_wcstok
)(wchar_t*, const wchar_t*);
99 static unsigned char* (__cdecl
*p__mbstok
)(unsigned char*, const unsigned char*);
100 static unsigned char* (__cdecl
*p__mbstok_s
)(unsigned char*, const unsigned char*, unsigned char**);
101 static char* (__cdecl
*p_strerror
)(int);
102 static wchar_t* (__cdecl
*p_wcserror
)(int);
103 static char* (__cdecl
*p_tmpnam
)(char*);
104 static wchar_t* (__cdecl
*p_wtmpnam
)(wchar_t*);
105 static char* (__cdecl
*p_asctime
)(struct tm
*);
106 static wchar_t* (__cdecl
*p_wasctime
)(struct tm
*);
107 static struct tm
* (__cdecl
*p_localtime64
)(__time64_t
*);
108 static char* (__cdecl
*p_ecvt
)(double, int, int*, int*);
109 static int* (__cdecl
*p_fpecode
)(void);
110 static int (__cdecl
*p_configthreadlocale
)(int);
111 static void* (__cdecl
*p_get_terminate
)(void);
112 static void* (__cdecl
*p_get_unexpected
)(void);
113 static int (__cdecl
*p__vswprintf_l
)(wchar_t*, const wchar_t*, _locale_t
, __ms_va_list
);
114 static int (__cdecl
*p_vswprintf_l
)(wchar_t*, const wchar_t*, _locale_t
, __ms_va_list
);
115 static FILE* (__cdecl
*p_fopen
)(const char*, const char*);
116 static int (__cdecl
*p_fclose
)(FILE*);
117 static int (__cdecl
*p_unlink
)(const char*);
118 static int (__cdecl
*p_access_s
)(const char*, int);
119 static void (__cdecl
*p_lock_file
)(FILE*);
120 static void (__cdecl
*p_unlock_file
)(FILE*);
121 static int (__cdecl
*p_fileno
)(FILE*);
122 static int (__cdecl
*p_feof
)(FILE*);
123 static int (__cdecl
*p_ferror
)(FILE*);
124 static int (__cdecl
*p_flsbuf
)(int, FILE*);
125 static int (__cdecl
*p_filbuf
)(FILE*);
126 static unsigned long (__cdecl
*p_byteswap_ulong
)(unsigned long);
127 static void** (__cdecl
*p__pxcptinfoptrs
)(void);
128 static void* (__cdecl
*p__AdjustPointer
)(void*, const void*);
129 static int (__cdecl
*p_fflush_nolock
)(FILE*);
130 static size_t (__cdecl
*p_mbstowcs
)(wchar_t*, const char*, size_t);
131 static size_t (__cdecl
*p_wcstombs
)(char*, const wchar_t*, size_t);
132 static char* (__cdecl
*p_setlocale
)(int, const char*);
133 static int (__cdecl
*p__fpieee_flt
)(ULONG
, EXCEPTION_POINTERS
*, int (__cdecl
*handler
)(_FPIEEE_RECORD
*));
134 static int (__cdecl
*p__memicmp
)(const char*, const char*, size_t);
135 static int (__cdecl
*p__memicmp_l
)(const char*, const char*, size_t, _locale_t
);
136 static int (__cdecl
*p__vsnwprintf
)(wchar_t *buffer
,size_t count
, const wchar_t *format
, __ms_va_list valist
);
137 static size_t (__cdecl
*p___strncnt
)(const char *str
, size_t count
);
138 static int (__cdecl
*p_swscanf
)(const wchar_t *str
, const wchar_t* format
, ...);
140 /* make sure we use the correct errno */
142 #define errno (*p_errno())
145 typedef struct __type_info
152 struct __type_info_node
155 struct __type_info_node
* next
;
158 static char* (WINAPI
*p_type_info_name_internal_method
)(type_info
*, struct __type_info_node
*);
159 static void (WINAPI
*ptype_info_dtor
)(type_info
*);
161 #define CXX_FRAME_MAGIC_VC6 0x19930520
162 #define CXX_EXCEPTION 0xe06d7363
164 /* offsets for computing the this pointer */
167 int this_offset
; /* offset of base class this pointer from start of object */
168 int vbase_descr
; /* offset of virtual base class descriptor */
169 int vbase_offset
; /* offset of this pointer offset in virtual base class descriptor */
172 typedef void (*cxx_copy_ctor
)(void);
174 /* complete information about a C++ type */
176 typedef struct __cxx_type_info
178 UINT flags
; /* flags (see CLASS_* flags below) */
179 const type_info
*type_info
; /* C++ type info */
180 this_ptr_offsets offsets
; /* offsets for computing the this pointer */
181 unsigned int size
; /* object size */
182 cxx_copy_ctor copy_ctor
; /* copy constructor */
185 typedef struct __cxx_type_info
188 unsigned int type_info
;
189 this_ptr_offsets offsets
;
191 unsigned int copy_ctor
;
195 /* table of C++ types that apply for a given object */
197 typedef struct __cxx_type_info_table
199 UINT count
; /* number of types */
200 const cxx_type_info
*info
[3]; /* variable length, we declare it large enough for static RTTI */
201 } cxx_type_info_table
;
203 typedef struct __cxx_type_info_table
206 unsigned int info
[3];
207 } cxx_type_info_table
;
210 /* type information for an exception object */
212 typedef struct __cxx_exception_type
214 UINT flags
; /* TYPE_FLAG flags */
215 void (*destructor
)(void);/* exception object destructor */
216 void *custom_handler
; /* custom handler for this exception */
217 const cxx_type_info_table
*type_info_table
; /* list of types for this exception object */
218 } cxx_exception_type
;
223 unsigned int destructor
;
224 unsigned int custom_handler
;
225 unsigned int type_info_table
;
226 } cxx_exception_type
;
229 static int (__cdecl
*p_is_exception_typeof
)(const type_info
*, EXCEPTION_POINTERS
*);
231 static void* (WINAPI
*pEncodePointer
)(void *);
233 static int cb_called
[4];
234 static int g_qsort_s_context_counter
;
235 static int g_bsearch_s_context_counter
;
237 static inline int almost_equal_f(float f1
, float f2
)
239 return f1
-f2
> -1e-30 && f1
-f2
< 1e-30;
244 /* thiscall emulation */
245 /* Emulate a __thiscall */
248 static inline void* do_call_func1(void *func
, void *_this
)
250 volatile void* retval
= 0;
259 return (void*)retval
;
262 static inline void* do_call_func2(void *func
, void *_this
, const void* arg
)
264 volatile void* retval
= 0;
274 return (void*)retval
;
277 static void* do_call_func1(void *func
, void *_this
)
280 __asm__
__volatile__ ("call *%2"
281 : "=a" (ret
), "=c" (dummy
)
282 : "g" (func
), "1" (_this
)
287 static void* do_call_func2(void *func
, void *_this
, const void* arg
)
290 __asm__
__volatile__ ("pushl %3\n\tcall *%2"
291 : "=a" (ret
), "=c" (dummy
)
292 : "r" (func
), "r" (arg
), "1" (_this
)
298 #define call_func1(func,_this) do_call_func1(func,_this)
299 #define call_func2(func,_this,a) do_call_func2(func,_this,(const void*)(a))
303 #define call_func1(func,_this) func(_this)
304 #define call_func2(func,_this,a) func(_this,a)
306 #endif /* __i386__ */
308 static void __cdecl
test_invalid_parameter_handler(const wchar_t *expression
,
309 const wchar_t *function
, const wchar_t *file
,
310 unsigned line
, uintptr_t arg
)
312 CHECK_EXPECT(invalid_parameter_handler
);
313 ok(expression
== NULL
, "expression is not NULL\n");
314 ok(function
== NULL
, "function is not NULL\n");
315 ok(file
== NULL
, "file is not NULL\n");
316 ok(line
== 0, "line = %u\n", line
);
317 ok(arg
== 0, "arg = %lx\n", (UINT_PTR
)arg
);
318 ok(errno
!= 0xdeadbeef, "errno not set\n");
321 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hcrt,y)
322 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
323 static BOOL
init(void)
328 SetLastError(0xdeadbeef);
329 hcrt
= LoadLibraryA("msvcr90.dll");
331 win_skip("msvcr90.dll not installed (got %d)\n", GetLastError());
335 SET(p_set_invalid_parameter_handler
, "_set_invalid_parameter_handler");
336 if(p_set_invalid_parameter_handler
)
337 ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler
) == NULL
,
338 "Invalid parameter handler was already set\n");
340 SET(p_initterm_e
, "_initterm_e");
341 SET(p_encode_pointer
, "_encode_pointer");
342 SET(p_decode_pointer
, "_decode_pointer");
343 SET(p_encoded_null
, "_encoded_null");
344 SET(p_sys_nerr
, "_sys_nerr");
345 SET(p__sys_nerr
, "__sys_nerr");
346 SET(p_sys_errlist
, "_sys_errlist");
347 SET(p__sys_errlist
, "__sys_errlist");
348 SET(p_strtoi64
, "_strtoi64");
349 SET(p_strtoui64
, "_strtoui64");
350 SET(p_itoa_s
, "_itoa_s");
351 SET(p_wcsncat_s
,"wcsncat_s" );
352 SET(p_qsort_s
, "qsort_s");
353 SET(p_bsearch_s
, "bsearch_s");
354 SET(p_controlfp_s
, "_controlfp_s");
355 SET(p_tmpfile_s
, "tmpfile_s");
356 SET(p_atoflt
, "_atoflt");
357 SET(p_set_abort_behavior
, "_set_abort_behavior");
358 SET(p_sopen_s
, "_sopen_s");
359 SET(p_wsopen_s
, "_wsopen_s");
360 SET(p_realloc_crt
, "_realloc_crt");
361 SET(p_malloc
, "malloc");
363 SET(p_getptd
, "_getptd");
364 SET(p_errno
, "_errno");
365 SET(p_doserrno
, "__doserrno");
366 SET(p_srand
, "srand");
367 SET(p_strtok
, "strtok");
368 SET(p_strtok_s
, "strtok_s");
369 SET(p_wcstok
, "wcstok");
370 SET(p__mbstok
, "_mbstok");
371 SET(p__mbstok_s
, "_mbstok_s");
372 SET(p_strerror
, "strerror");
373 SET(p_wcserror
, "_wcserror");
374 SET(p_tmpnam
, "tmpnam");
375 SET(p_wtmpnam
, "_wtmpnam");
376 SET(p_asctime
, "asctime");
377 SET(p_wasctime
, "_wasctime");
378 SET(p_localtime64
, "_localtime64");
379 SET(p_ecvt
, "_ecvt");
380 SET(p_fpecode
, "__fpecode");
381 SET(p_configthreadlocale
, "_configthreadlocale");
382 SET(p_get_terminate
, "_get_terminate");
383 SET(p_get_unexpected
, "_get_unexpected");
384 SET(p__vswprintf_l
, "__vswprintf_l");
385 SET(p_vswprintf_l
, "_vswprintf_l");
386 SET(p_fopen
, "fopen");
387 SET(p_fclose
, "fclose");
388 SET(p_unlink
, "_unlink");
389 SET(p_access_s
, "_access_s");
390 SET(p_lock_file
, "_lock_file");
391 SET(p_unlock_file
, "_unlock_file");
392 SET(p_fileno
, "_fileno");
394 SET(p_ferror
, "ferror");
395 SET(p_flsbuf
, "_flsbuf");
396 SET(p_filbuf
, "_filbuf");
397 SET(p_byteswap_ulong
, "_byteswap_ulong");
398 SET(p__pxcptinfoptrs
, "__pxcptinfoptrs");
399 SET(p__AdjustPointer
, "__AdjustPointer");
400 SET(p_fflush_nolock
, "_fflush_nolock");
401 SET(p_mbstowcs
, "mbstowcs");
402 SET(p_wcstombs
, "wcstombs");
403 SET(p_setlocale
, "setlocale");
404 SET(p__fpieee_flt
, "_fpieee_flt");
405 SET(p__memicmp
, "_memicmp");
406 SET(p__memicmp_l
, "_memicmp_l");
407 SET(p__vsnwprintf
, "_vsnwprintf");
408 SET(p___strncnt
, "__strncnt");
409 SET(p_swscanf
, "swscanf");
411 if (sizeof(void *) == 8)
413 SET(p_type_info_name_internal_method
, "?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z");
414 SET(ptype_info_dtor
, "??1type_info@@UEAA@XZ");
415 SET(p_is_exception_typeof
, "?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z");
420 SET(p_type_info_name_internal_method
, "?_name_internal_method@type_info@@QBAPBDPAU__type_info_node@@@Z");
421 SET(ptype_info_dtor
, "??1type_info@@UAA@XZ");
423 SET(p_type_info_name_internal_method
, "?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z");
424 SET(ptype_info_dtor
, "??1type_info@@UAE@XZ");
426 SET(p_is_exception_typeof
, "?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z");
429 hkernel32
= GetModuleHandleA("kernel32.dll");
430 pEncodePointer
= (void *) GetProcAddress(hkernel32
, "EncodePointer");
434 static int __cdecl
initterm_cb0(void)
440 static int __cdecl
initterm_cb1(void)
446 static int __cdecl
initterm_cb2(void)
453 static void test__initterm_e(void)
455 _INITTERM_E_FN table
[4];
458 memset(table
, 0, sizeof(table
));
460 memset(cb_called
, 0, sizeof(cb_called
));
462 res
= p_initterm_e(table
, table
);
463 ok( !res
&& !cb_called
[0] && !cb_called
[1] && !cb_called
[2],
464 "got %d with 0x%x {%d, %d, %d}\n",
465 res
, errno
, cb_called
[0], cb_called
[1], cb_called
[2]);
467 memset(cb_called
, 0, sizeof(cb_called
));
469 res
= p_initterm_e(table
, NULL
);
470 ok( !res
&& !cb_called
[0] && !cb_called
[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]);
475 /* this crash on Windows */
477 res
= p_initterm_e(NULL
, table
);
478 trace("got %d with 0x%x\n", res
, errno
);
481 table
[0] = initterm_cb0
;
482 memset(cb_called
, 0, sizeof(cb_called
));
484 res
= p_initterm_e(table
, &table
[1]);
485 ok( !res
&& (cb_called
[0] == 1) && !cb_called
[1] && !cb_called
[2],
486 "got %d with 0x%x {%d, %d, %d}\n",
487 res
, errno
, cb_called
[0], cb_called
[1], cb_called
[2]);
490 /* init-function returning failure */
491 table
[1] = initterm_cb1
;
492 memset(cb_called
, 0, sizeof(cb_called
));
494 res
= p_initterm_e(table
, &table
[3]);
495 ok( (res
== 1) && (cb_called
[0] == 1) && (cb_called
[1] == 1) && !cb_called
[2],
496 "got %d with 0x%x {%d, %d, %d}\n",
497 res
, errno
, cb_called
[0], cb_called
[1], cb_called
[2]);
499 /* init-function not called, when end < start */
500 memset(cb_called
, 0, sizeof(cb_called
));
502 res
= p_initterm_e(&table
[3], table
);
503 ok( !res
&& !cb_called
[0] && !cb_called
[1] && !cb_called
[2],
504 "got %d with 0x%x {%d, %d, %d}\n",
505 res
, errno
, cb_called
[0], cb_called
[1], cb_called
[2]);
507 /* initialization stop after first non-zero result */
508 table
[2] = initterm_cb0
;
509 memset(cb_called
, 0, sizeof(cb_called
));
511 res
= p_initterm_e(table
, &table
[3]);
512 ok( (res
== 1) && (cb_called
[0] == 1) && (cb_called
[1] == 1) && !cb_called
[2],
513 "got %d with 0x%x {%d, %d, %d}\n",
514 res
, errno
, cb_called
[0], cb_called
[1], cb_called
[2]);
516 /* NULL pointer in the array are skipped */
518 table
[2] = initterm_cb2
;
519 memset(cb_called
, 0, sizeof(cb_called
));
521 res
= p_initterm_e(table
, &table
[3]);
522 ok( (res
== 2) && (cb_called
[0] == 1) && !cb_called
[1] && (cb_called
[2] == 1),
523 "got %d with 0x%x {%d, %d, %d}\n",
524 res
, errno
, cb_called
[0], cb_called
[1], cb_called
[2]);
528 /* Beware that _encode_pointer is a NOP before XP
529 (the parameter is returned unchanged) */
530 static void test__encode_pointer(void)
534 ptr
= (void*)0xdeadbeef;
535 res
= p_encode_pointer(ptr
);
536 res
= p_decode_pointer(res
);
537 ok(res
== ptr
, "Pointers are different after encoding and decoding\n");
539 ok(p_encoded_null() == p_encode_pointer(NULL
), "Error encoding null\n");
541 ptr
= p_encode_pointer(p_encode_pointer
);
542 ok(p_decode_pointer(ptr
) == p_encode_pointer
, "Error decoding pointer\n");
544 /* Not present before XP */
545 if (!pEncodePointer
) {
546 win_skip("EncodePointer not found\n");
550 res
= pEncodePointer(p_encode_pointer
);
551 ok(ptr
== res
, "_encode_pointer produced different result than EncodePointer\n");
555 static void test_error_messages(void)
557 int *size
, size_copy
;
559 size
= p__sys_nerr();
561 ok(*p_sys_nerr
== *size
, "_sys_nerr = %u, size = %u\n", *p_sys_nerr
, *size
);
564 ok(*p_sys_nerr
== *size
, "_sys_nerr = %u, size = %u\n", *p_sys_nerr
, *size
);
568 ok(*p_sys_errlist
== *(p__sys_errlist()), "p_sys_errlist != p__sys_errlist()\n");
571 static void test__strtoi64(void)
574 unsigned __int64 ures
;
576 SET_EXPECT(invalid_parameter_handler
);
577 res
= p_strtoi64(NULL
, NULL
, 10);
578 ok(res
== 0, "res != 0\n");
579 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
581 SET_EXPECT(invalid_parameter_handler
);
582 res
= p_strtoi64("123", NULL
, 1);
583 ok(res
== 0, "res != 0\n");
584 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
586 SET_EXPECT(invalid_parameter_handler
);
587 res
= p_strtoi64("123", NULL
, 37);
588 ok(res
== 0, "res != 0\n");
589 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
591 SET_EXPECT(invalid_parameter_handler
);
592 ures
= p_strtoui64(NULL
, NULL
, 10);
593 ok(ures
== 0, "res = %d\n", (int)ures
);
594 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
596 SET_EXPECT(invalid_parameter_handler
);
597 ures
= p_strtoui64("123", NULL
, 1);
598 ok(ures
== 0, "res = %d\n", (int)ures
);
599 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
601 SET_EXPECT(invalid_parameter_handler
);
602 ures
= p_strtoui64("123", NULL
, 37);
603 ok(ures
== 0, "res = %d\n", (int)ures
);
604 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
607 static void test__itoa_s(void)
612 SET_EXPECT(invalid_parameter_handler
);
613 ret
= p_itoa_s(0, NULL
, 0, 0);
614 ok(ret
== EINVAL
, "Expected _itoa_s to return EINVAL, got %d\n", ret
);
615 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
617 memset(buffer
, 'X', sizeof(buffer
));
618 SET_EXPECT(invalid_parameter_handler
);
619 ret
= p_itoa_s(0, buffer
, 0, 0);
620 ok(ret
== EINVAL
, "Expected _itoa_s to return EINVAL, got %d\n", ret
);
621 ok(buffer
[0] == 'X', "Expected the output buffer to be untouched\n");
622 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
624 memset(buffer
, 'X', sizeof(buffer
));
625 SET_EXPECT(invalid_parameter_handler
);
626 ret
= p_itoa_s(0, buffer
, sizeof(buffer
), 0);
627 ok(ret
== EINVAL
, "Expected _itoa_s to return EINVAL, got %d\n", ret
);
628 ok(buffer
[0] == '\0', "Expected the output buffer to be null terminated\n");
629 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
631 memset(buffer
, 'X', sizeof(buffer
));
632 SET_EXPECT(invalid_parameter_handler
);
633 ret
= p_itoa_s(0, buffer
, sizeof(buffer
), 64);
634 ok(ret
== EINVAL
, "Expected _itoa_s to return EINVAL, got %d\n", ret
);
635 ok(buffer
[0] == '\0', "Expected the output buffer to be null terminated\n");
636 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
638 memset(buffer
, 'X', sizeof(buffer
));
639 SET_EXPECT(invalid_parameter_handler
);
640 ret
= p_itoa_s(12345678, buffer
, 4, 10);
641 ok(ret
== ERANGE
, "Expected _itoa_s to return ERANGE, got %d\n", ret
);
642 ok(!memcmp(buffer
, "\000765", 4),
643 "Expected the output buffer to be null terminated with truncated output\n");
644 CHECK_CALLED(invalid_parameter_handler
, ERANGE
);
646 memset(buffer
, 'X', sizeof(buffer
));
647 SET_EXPECT(invalid_parameter_handler
);
648 ret
= p_itoa_s(12345678, buffer
, 8, 10);
649 ok(ret
== ERANGE
, "Expected _itoa_s to return ERANGE, got %d\n", ret
);
650 ok(!memcmp(buffer
, "\0007654321", 8),
651 "Expected the output buffer to be null terminated with truncated output\n");
652 CHECK_CALLED(invalid_parameter_handler
, ERANGE
);
654 memset(buffer
, 'X', sizeof(buffer
));
655 SET_EXPECT(invalid_parameter_handler
);
656 ret
= p_itoa_s(-12345678, buffer
, 9, 10);
657 ok(ret
== ERANGE
, "Expected _itoa_s to return ERANGE, got %d\n", ret
);
658 ok(!memcmp(buffer
, "\00087654321", 9),
659 "Expected the output buffer to be null terminated with truncated output\n");
660 CHECK_CALLED(invalid_parameter_handler
, ERANGE
);
662 ret
= p_itoa_s(12345678, buffer
, 9, 10);
663 ok(ret
== 0, "Expected _itoa_s to return 0, got %d\n", ret
);
664 ok(!strcmp(buffer
, "12345678"),
665 "Expected output buffer string to be \"12345678\", got \"%s\"\n",
668 ret
= p_itoa_s(43690, buffer
, sizeof(buffer
), 2);
669 ok(ret
== 0, "Expected _itoa_s to return 0, got %d\n", ret
);
670 ok(!strcmp(buffer
, "1010101010101010"),
671 "Expected output buffer string to be \"1010101010101010\", got \"%s\"\n",
674 ret
= p_itoa_s(1092009, buffer
, sizeof(buffer
), 36);
675 ok(ret
== 0, "Expected _itoa_s to return 0, got %d\n", ret
);
676 ok(!strcmp(buffer
, "nell"),
677 "Expected output buffer string to be \"nell\", got \"%s\"\n",
680 ret
= p_itoa_s(5704, buffer
, sizeof(buffer
), 18);
681 ok(ret
== 0, "Expected _itoa_s to return 0, got %d\n", ret
);
682 ok(!strcmp(buffer
, "hag"),
683 "Expected output buffer string to be \"hag\", got \"%s\"\n",
686 ret
= p_itoa_s(-12345678, buffer
, sizeof(buffer
), 10);
687 ok(ret
== 0, "Expected _itoa_s to return 0, got %d\n", ret
);
688 ok(!strcmp(buffer
, "-12345678"),
689 "Expected output buffer string to be \"-12345678\", got \"%s\"\n",
693 static void test_wcsncat_s(void)
695 static wchar_t abcW
[] = {'a','b','c',0};
700 memcpy(src
, abcW
, sizeof(abcW
));
702 SET_EXPECT(invalid_parameter_handler
);
703 ret
= p_wcsncat_s(NULL
, 4, src
, 4);
704 ok(ret
== EINVAL
, "err = %d\n", ret
);
705 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
707 SET_EXPECT(invalid_parameter_handler
);
708 ret
= p_wcsncat_s(dst
, 0, src
, 4);
709 ok(ret
== EINVAL
, "err = %d\n", ret
);
710 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
712 SET_EXPECT(invalid_parameter_handler
);
713 ret
= p_wcsncat_s(dst
, 0, src
, _TRUNCATE
);
714 ok(ret
== EINVAL
, "err = %d\n", ret
);
715 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
717 ret
= p_wcsncat_s(dst
, 4, NULL
, 0);
718 ok(ret
== 0, "err = %d\n", ret
);
721 SET_EXPECT(invalid_parameter_handler
);
722 ret
= p_wcsncat_s(dst
, 2, src
, 4);
723 ok(ret
== ERANGE
, "err = %d\n", ret
);
724 CHECK_CALLED(invalid_parameter_handler
, ERANGE
);
727 ret
= p_wcsncat_s(dst
, 2, src
, _TRUNCATE
);
728 ok(ret
== STRUNCATE
, "err = %d\n", ret
);
729 ok(dst
[0] == 'a' && dst
[1] == 0, "dst is %s\n", wine_dbgstr_w(dst
));
731 memcpy(dst
, abcW
, sizeof(abcW
));
733 SET_EXPECT(invalid_parameter_handler
);
734 ret
= p_wcsncat_s(dst
, 4, src
, 4);
735 ok(ret
== EINVAL
, "err = %d\n", ret
);
736 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
739 /* Based on dlls/ntdll/tests/string.c */
740 static __cdecl
int intcomparefunc(void *context
, const void *a
, const void *b
)
742 const int *p
= a
, *q
= b
;
744 ok (a
!= b
, "must never get the same pointer\n");
750 static __cdecl
int charcomparefunc(void *context
, const void *a
, const void *b
)
752 const char *p
= a
, *q
= b
;
754 ok (a
!= b
, "must never get the same pointer\n");
760 static __cdecl
int strcomparefunc(void *context
, const void *a
, const void *b
)
762 const char * const *p
= a
;
763 const char * const *q
= b
;
765 ok (a
!= b
, "must never get the same pointer\n");
768 return lstrcmpA(*p
, *q
);
771 static void test_qsort_s(void)
773 int arr
[5] = { 23, 42, 8, 4, 16 };
774 int arr2
[5] = { 23, 42, 8, 4, 16 };
775 char carr
[5] = { 42, 23, 4, 8, 16 };
776 const char *strarr
[7] = {
786 SET_EXPECT(invalid_parameter_handler
);
787 p_qsort_s(NULL
, 0, 0, NULL
, NULL
);
788 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
790 SET_EXPECT(invalid_parameter_handler
);
791 p_qsort_s(NULL
, 0, 0, intcomparefunc
, NULL
);
792 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
794 SET_EXPECT(invalid_parameter_handler
);
795 p_qsort_s(NULL
, 0, sizeof(int), NULL
, NULL
);
796 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
798 SET_EXPECT(invalid_parameter_handler
);
799 p_qsort_s(NULL
, 1, sizeof(int), intcomparefunc
, NULL
);
800 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
803 g_qsort_s_context_counter
= 0;
804 p_qsort_s(NULL
, 0, sizeof(int), intcomparefunc
, NULL
);
805 ok(g_qsort_s_context_counter
== 0, "callback shouldn't have been called\n");
806 ok( errno
== 0xdeadbeef, "wrong errno %u\n", errno
);
808 /* overflow without side effects, other overflow values crash */
810 g_qsort_s_context_counter
= 0;
811 p_qsort_s((void*)arr2
, (((size_t)1) << (8*sizeof(size_t) - 1)) + 1, sizeof(int), intcomparefunc
, &g_qsort_s_context_counter
);
812 ok(g_qsort_s_context_counter
== 0, "callback shouldn't have been called\n");
813 ok( errno
== 0xdeadbeef, "wrong errno %u\n", errno
);
814 ok(arr2
[0] == 23, "should remain unsorted, arr2[0] is %d\n", arr2
[0]);
815 ok(arr2
[1] == 42, "should remain unsorted, arr2[1] is %d\n", arr2
[1]);
816 ok(arr2
[2] == 8, "should remain unsorted, arr2[2] is %d\n", arr2
[2]);
817 ok(arr2
[3] == 4, "should remain unsorted, arr2[3] is %d\n", arr2
[3]);
820 g_qsort_s_context_counter
= 0;
821 p_qsort_s((void*)arr
, 0, sizeof(int), intcomparefunc
, &g_qsort_s_context_counter
);
822 ok(g_qsort_s_context_counter
== 0, "callback shouldn't have been called\n");
823 ok( errno
== 0xdeadbeef, "wrong errno %u\n", errno
);
824 ok(arr
[0] == 23, "badly sorted, nmemb=0, arr[0] is %d\n", arr
[0]);
825 ok(arr
[1] == 42, "badly sorted, nmemb=0, arr[1] is %d\n", arr
[1]);
826 ok(arr
[2] == 8, "badly sorted, nmemb=0, arr[2] is %d\n", arr
[2]);
827 ok(arr
[3] == 4, "badly sorted, nmemb=0, arr[3] is %d\n", arr
[3]);
828 ok(arr
[4] == 16, "badly sorted, nmemb=0, arr[4] is %d\n", arr
[4]);
831 g_qsort_s_context_counter
= 0;
832 p_qsort_s((void*)arr
, 1, sizeof(int), intcomparefunc
, &g_qsort_s_context_counter
);
833 ok(g_qsort_s_context_counter
== 0, "callback shouldn't have been called\n");
834 ok( errno
== 0xdeadbeef, "wrong errno %u\n", errno
);
835 ok(arr
[0] == 23, "badly sorted, nmemb=1, arr[0] is %d\n", arr
[0]);
836 ok(arr
[1] == 42, "badly sorted, nmemb=1, arr[1] is %d\n", arr
[1]);
837 ok(arr
[2] == 8, "badly sorted, nmemb=1, arr[2] is %d\n", arr
[2]);
838 ok(arr
[3] == 4, "badly sorted, nmemb=1, arr[3] is %d\n", arr
[3]);
839 ok(arr
[4] == 16, "badly sorted, nmemb=1, arr[4] is %d\n", arr
[4]);
841 SET_EXPECT(invalid_parameter_handler
);
842 g_qsort_s_context_counter
= 0;
843 p_qsort_s((void*)arr
, 5, 0, intcomparefunc
, &g_qsort_s_context_counter
);
844 ok(g_qsort_s_context_counter
== 0, "callback shouldn't have been called\n");
845 ok(arr
[0] == 23, "badly sorted, size=0, arr[0] is %d\n", arr
[0]);
846 ok(arr
[1] == 42, "badly sorted, size=0, arr[1] is %d\n", arr
[1]);
847 ok(arr
[2] == 8, "badly sorted, size=0, arr[2] is %d\n", arr
[2]);
848 ok(arr
[3] == 4, "badly sorted, size=0, arr[3] is %d\n", arr
[3]);
849 ok(arr
[4] == 16, "badly sorted, size=0, arr[4] is %d\n", arr
[4]);
850 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
852 g_qsort_s_context_counter
= 0;
853 p_qsort_s((void*)arr
, 5, sizeof(int), intcomparefunc
, &g_qsort_s_context_counter
);
854 ok(g_qsort_s_context_counter
> 0, "callback wasn't called\n");
855 ok(arr
[0] == 4, "badly sorted, arr[0] is %d\n", arr
[0]);
856 ok(arr
[1] == 8, "badly sorted, arr[1] is %d\n", arr
[1]);
857 ok(arr
[2] == 16, "badly sorted, arr[2] is %d\n", arr
[2]);
858 ok(arr
[3] == 23, "badly sorted, arr[3] is %d\n", arr
[3]);
859 ok(arr
[4] == 42, "badly sorted, arr[4] is %d\n", arr
[4]);
861 g_qsort_s_context_counter
= 0;
862 p_qsort_s((void*)carr
, 5, sizeof(char), charcomparefunc
, &g_qsort_s_context_counter
);
863 ok(g_qsort_s_context_counter
> 0, "callback wasn't called\n");
864 ok(carr
[0] == 4, "badly sorted, carr[0] is %d\n", carr
[0]);
865 ok(carr
[1] == 8, "badly sorted, carr[1] is %d\n", carr
[1]);
866 ok(carr
[2] == 16, "badly sorted, carr[2] is %d\n", carr
[2]);
867 ok(carr
[3] == 23, "badly sorted, carr[3] is %d\n", carr
[3]);
868 ok(carr
[4] == 42, "badly sorted, carr[4] is %d\n", carr
[4]);
870 g_qsort_s_context_counter
= 0;
871 p_qsort_s((void*)strarr
, 7, sizeof(char*), strcomparefunc
, &g_qsort_s_context_counter
);
872 ok(g_qsort_s_context_counter
> 0, "callback wasn't called\n");
873 ok(!strcmp(strarr
[0],"!"), "badly sorted, strarr[0] is %s\n", strarr
[0]);
874 ok(!strcmp(strarr
[1],"."), "badly sorted, strarr[1] is %s\n", strarr
[1]);
875 ok(!strcmp(strarr
[2],"Hello"), "badly sorted, strarr[2] is %s\n", strarr
[2]);
876 ok(!strcmp(strarr
[3],"Hopefully"), "badly sorted, strarr[3] is %s\n", strarr
[3]);
877 ok(!strcmp(strarr
[4],"Sorted"), "badly sorted, strarr[4] is %s\n", strarr
[4]);
878 ok(!strcmp(strarr
[5],"Wine"), "badly sorted, strarr[5] is %s\n", strarr
[5]);
879 ok(!strcmp(strarr
[6],"World"), "badly sorted, strarr[6] is %s\n", strarr
[6]);
882 static void test_bsearch_s(void)
884 int arr
[7] = { 1, 3, 4, 8, 16, 23, 42 };
887 SET_EXPECT(invalid_parameter_handler
);
888 x
= p_bsearch_s(NULL
, NULL
, 0, 0, NULL
, NULL
);
889 ok(x
== NULL
, "Expected bsearch_s to return NULL, got %p\n", x
);
890 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
892 g_bsearch_s_context_counter
= 0;
893 SET_EXPECT(invalid_parameter_handler
);
894 x
= p_bsearch_s(&l
, arr
, j
, 0, intcomparefunc
, &g_bsearch_s_context_counter
);
895 ok(x
== NULL
, "Expected bsearch_s to return NULL, got %p\n", x
);
896 ok(g_bsearch_s_context_counter
== 0, "callback shouldn't have been called\n");
897 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
899 g_bsearch_s_context_counter
= 0;
900 SET_EXPECT(invalid_parameter_handler
);
901 x
= p_bsearch_s(&l
, arr
, j
, sizeof(arr
[0]), NULL
, &g_bsearch_s_context_counter
);
902 ok(x
== NULL
, "Expected bsearch_s to return NULL, got %p\n", x
);
903 ok(g_bsearch_s_context_counter
== 0, "callback shouldn't have been called\n");
904 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
906 /* just try all array sizes */
907 for (j
=1; j
<ARRAY_SIZE(arr
); j
++) {
910 g_bsearch_s_context_counter
= 0;
911 x
= p_bsearch_s(&l
, arr
, j
, sizeof(arr
[0]), intcomparefunc
, &g_bsearch_s_context_counter
);
912 ok (x
== &arr
[i
], "bsearch_s did not find %d entry in loopsize %d.\n", i
, j
);
913 ok(g_bsearch_s_context_counter
> 0, "callback wasn't called\n");
916 g_bsearch_s_context_counter
= 0;
917 x
= p_bsearch_s(&l
, arr
, j
, sizeof(arr
[0]), intcomparefunc
, &g_bsearch_s_context_counter
);
918 ok (x
== NULL
, "bsearch_s did find 4242 entry in loopsize %d.\n", j
);
919 ok(g_bsearch_s_context_counter
> 0, "callback wasn't called\n");
923 static void test_controlfp_s(void)
928 SET_EXPECT(invalid_parameter_handler
);
929 ret
= p_controlfp_s( NULL
, ~0, ~0 );
930 ok( ret
== EINVAL
, "wrong result %d\n", ret
);
931 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
934 SET_EXPECT(invalid_parameter_handler
);
935 ret
= p_controlfp_s( &cur
, ~0, ~0 );
936 ok( ret
== EINVAL
, "wrong result %d\n", ret
);
937 ok( cur
!= 0xdeadbeef, "value not set\n" );
938 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
941 ret
= p_controlfp_s( &cur
, 0, 0 );
942 ok( !ret
, "wrong result %d\n", ret
);
943 ok( cur
!= 0xdeadbeef, "value not set\n" );
945 SET_EXPECT(invalid_parameter_handler
);
947 ret
= p_controlfp_s( &cur
, 0x80000000, 0x80000000 );
948 ok( ret
== EINVAL
, "wrong result %d\n", ret
);
949 ok( cur
!= 0xdeadbeef, "value not set\n" );
950 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
953 /* mask is only checked when setting invalid bits */
954 ret
= p_controlfp_s( &cur
, 0, 0x80000000 );
955 ok( !ret
, "wrong result %d\n", ret
);
956 ok( cur
!= 0xdeadbeef, "value not set\n" );
959 static void test_tmpfile_s( void )
963 SET_EXPECT(invalid_parameter_handler
);
964 ret
= p_tmpfile_s(NULL
);
965 ok(ret
== EINVAL
, "Expected tmpfile_s to return EINVAL, got %i\n", ret
);
966 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
976 static const _atoflt_test _atoflt_testdata
[] = {
978 { "-13.721", -13.721, 0 },
980 { ".21e12", 0.21e12
, 0 },
981 { "214353e-3", 214.353, 0 },
982 { "1d9999999999999999999", 0.0, _OVERFLOW
},
984 /* more significant digits */
985 { "1.23456789", 1.23456789, 0 },
986 { "1.23456789e1", 12.3456789, 0 },
987 { "1e39", 0.0, _OVERFLOW
},
988 { "1e-39", 0.0, _UNDERFLOW
},
992 static void test__atoflt(void)
999 /* crashes on native */
1000 p_atoflt(NULL
, NULL
);
1001 p_atoflt(NULL
, (char*)_atoflt_testdata
[0].str
);
1002 p_atoflt(&flt
, NULL
);
1005 while (_atoflt_testdata
[i
].str
)
1007 ret
= p_atoflt(&flt
, (char*)_atoflt_testdata
[i
].str
);
1008 ok(ret
== _atoflt_testdata
[i
].ret
, "got ret %d, expected ret %d, for %s\n", ret
,
1009 _atoflt_testdata
[i
].ret
, _atoflt_testdata
[i
].str
);
1012 ok(almost_equal_f(flt
.f
, _atoflt_testdata
[i
].flt
), "got %f, expected %f, for %s\n", flt
.f
,
1013 _atoflt_testdata
[i
].flt
, _atoflt_testdata
[i
].str
);
1019 static void test__set_abort_behavior(void)
1023 /* default is _WRITE_ABORT_MSG | _CALL_REPORTFAULT */
1024 res
= p_set_abort_behavior(0, 0);
1025 ok (res
== (_WRITE_ABORT_MSG
| _CALL_REPORTFAULT
),
1026 "got 0x%x (expected 0x%x)\n", res
, _WRITE_ABORT_MSG
| _CALL_REPORTFAULT
);
1028 /* no internal mask */
1029 p_set_abort_behavior(0xffffffff, 0xffffffff);
1030 res
= p_set_abort_behavior(0, 0);
1031 ok (res
== 0xffffffff, "got 0x%x (expected 0x%x)\n", res
, 0xffffffff);
1033 /* set to default value */
1034 p_set_abort_behavior(_WRITE_ABORT_MSG
| _CALL_REPORTFAULT
, 0xffffffff);
1037 static void test__sopen_s(void)
1041 SET_EXPECT(invalid_parameter_handler
);
1042 ret
= p_sopen_s(NULL
, "test", _O_RDONLY
, _SH_DENYNO
, _S_IREAD
);
1043 ok(ret
== EINVAL
, "got %d, expected EINVAL\n", ret
);
1044 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
1047 ret
= p_sopen_s(&fd
, "test", _O_RDONLY
, _SH_DENYNO
, _S_IREAD
);
1048 ok(ret
== ENOENT
, "got %d, expected ENOENT\n", ret
);
1049 ok(fd
== -1, "got %d\n", fd
);
1052 static void test__wsopen_s(void)
1054 wchar_t testW
[] = {'t','e','s','t',0};
1057 SET_EXPECT(invalid_parameter_handler
);
1058 ret
= p_wsopen_s(NULL
, testW
, _O_RDONLY
, _SH_DENYNO
, _S_IREAD
);
1059 ok(ret
== EINVAL
, "got %d, expected EINVAL\n", ret
);
1060 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
1063 ret
= p_wsopen_s(&fd
, testW
, _O_RDONLY
, _SH_DENYNO
, _S_IREAD
);
1064 ok(ret
== ENOENT
, "got %d, expected ENOENT\n", ret
);
1065 ok(fd
== -1, "got %d\n", fd
);
1068 static void test__realloc_crt(void)
1074 /* crashes on some systems starting Vista */
1075 p_realloc_crt(NULL
, 10);
1079 ok(mem
!= NULL
, "memory not allocated\n");
1081 mem
= p_realloc_crt(mem
, 20);
1082 ok(mem
!= NULL
, "memory not reallocated\n");
1084 mem
= p_realloc_crt(mem
, 0);
1085 ok(mem
== NULL
, "memory not freed\n");
1087 mem
= p_realloc_crt(NULL
, 0);
1088 ok(mem
!= NULL
, "memory not (re)allocated for size 0\n");
1092 static void test_typeinfo(void)
1094 static type_info t1
= { NULL
, NULL
,{'.','?','A','V','t','e','s','t','1','@','@',0,0,0,0,0 } };
1095 struct __type_info_node node
;
1102 name
= call_func2(p_type_info_name_internal_method
, &t1
, &node
);
1103 ok(name
!= NULL
, "got %p\n", name
);
1104 ok(name
&& t1
.name
&& !strcmp(name
, t1
.name
), "bad name '%s' for t1\n", name
);
1106 ok(t1
.name
&& !strcmp(t1
.name
, "class test1"), "demangled to '%s' for t1\n", t1
.name
);
1107 call_func1(ptype_info_dtor
, &t1
);
1110 /* Keep in sync with msvcrt/msvcrt.h */
1111 struct __thread_data
{
1115 __msvcrt_ulong thread_doserrno
;
1117 unsigned int random_seed
;
1119 wchar_t *wcstok_next
;
1120 unsigned char *mbstok_next
;
1121 char *strerror_buffer
;
1122 wchar_t *wcserror_buffer
;
1123 char *tmpnam_buffer
;
1124 wchar_t *wtmpnam_buffer
;
1126 char *asctime_buffer
;
1127 wchar_t *wasctime_buffer
;
1128 struct tm
*time_buffer
;
1132 EXCEPTION_POINTERS
*xcptinfo
;
1134 pthreadmbcinfo mbcinfo
;
1135 pthreadlocinfo locinfo
;
1138 void* terminate_handler
;
1139 void* unexpected_handler
;
1140 void* se_translator
;
1143 EXCEPTION_RECORD
*exc_record
;
1146 static void test_getptd(void)
1148 struct __thread_data
*ptd
= p_getptd();
1149 DWORD tid
= GetCurrentThreadId();
1150 wchar_t testW
[] = {'t','e','s','t',0}, tW
[] = {'t',0}, *wp
;
1151 char test
[] = "test", *p
;
1152 unsigned char mbstok_test
[] = "test", *up
;
1154 __time64_t secs
= 0;
1156 void *mbcinfo
, *locinfo
;
1158 ok(ptd
->tid
== tid
, "ptd->tid = %x, expected %x\n", ptd
->tid
, tid
);
1159 ok(ptd
->handle
== INVALID_HANDLE_VALUE
, "ptd->handle = %p\n", ptd
->handle
);
1160 ok(p_errno() == &ptd
->thread_errno
, "ptd->thread_errno is different then _errno()\n");
1161 ok(p_doserrno() == &ptd
->thread_doserrno
, "ptd->thread_doserrno is different then __doserrno()\n");
1163 ok(ptd
->random_seed
== 1234, "ptd->random_seed = %d\n", ptd
->random_seed
);
1164 p
= p_strtok(test
, "t");
1165 ok(ptd
->strtok_next
== p
+3, "ptd->strtok_next is incorrect\n");
1166 wp
= p_wcstok(testW
, tW
);
1167 ok(ptd
->wcstok_next
== wp
+3, "ptd->wcstok_next is incorrect\n");
1168 up
= p__mbstok(mbstok_test
, (unsigned char*)"t");
1169 ok(ptd
->mbstok_next
== up
+3, "ptd->mbstok_next is incorrect\n");
1170 ok(p_strerror(0) == ptd
->strerror_buffer
, "ptd->strerror_buffer is incorrect\n");
1171 ok(p_wcserror(0) == ptd
->wcserror_buffer
, "ptd->wcserror_buffer is incorrect\n");
1172 ok(p_tmpnam(NULL
) == ptd
->tmpnam_buffer
, "ptd->tmpnam_buffer is incorrect\n");
1173 ok(p_wtmpnam(NULL
) == ptd
->wtmpnam_buffer
, "ptd->wtmpnam_buffer is incorrect\n");
1174 memset(&time
, 0, sizeof(time
));
1176 ok(p_asctime(&time
) == ptd
->asctime_buffer
, "ptd->asctime_buffer is incorrect\n");
1177 ok(p_wasctime(&time
) == ptd
->wasctime_buffer
, "ptd->wasctime_buffer is incorrect\n");
1178 ok(p_localtime64(&secs
) == ptd
->time_buffer
, "ptd->time_buffer is incorrect\n");
1179 ok(p_ecvt(3.12, 1, &dec
, &sign
) == ptd
->efcvt_buffer
, "ptd->efcvt_buffer is incorrect\n");
1180 ok(p__pxcptinfoptrs() == (void**)&ptd
->xcptinfo
, "ptd->xcptinfo is incorrect\n");
1181 ok(p_fpecode() == &ptd
->fpecode
, "ptd->fpecode is incorrect\n");
1182 mbcinfo
= ptd
->mbcinfo
;
1183 locinfo
= ptd
->locinfo
;
1184 todo_wine
ok(ptd
->have_locale
== 1, "ptd->have_locale = %x\n", ptd
->have_locale
);
1185 p_configthreadlocale(1);
1186 todo_wine
ok(mbcinfo
== ptd
->mbcinfo
, "ptd->mbcinfo != mbcinfo\n");
1187 todo_wine
ok(locinfo
== ptd
->locinfo
, "ptd->locinfo != locinfo\n");
1188 todo_wine
ok(ptd
->have_locale
== 3, "ptd->have_locale = %x\n", ptd
->have_locale
);
1189 ok(p_get_terminate() == ptd
->terminate_handler
, "ptd->terminate_handler != _get_terminate()\n");
1190 ok(p_get_unexpected() == ptd
->unexpected_handler
, "ptd->unexpected_handler != _get_unexpected()\n");
1193 static int WINAPIV
__vswprintf_l_wrapper(wchar_t *buf
,
1194 const wchar_t *format
, _locale_t locale
, ...)
1197 __ms_va_list valist
;
1198 __ms_va_start(valist
, locale
);
1199 ret
= p__vswprintf_l(buf
, format
, locale
, valist
);
1200 __ms_va_end(valist
);
1204 static int WINAPIV
_vswprintf_l_wrapper(wchar_t *buf
,
1205 const wchar_t *format
, _locale_t locale
, ...)
1208 __ms_va_list valist
;
1209 __ms_va_start(valist
, locale
);
1210 ret
= p_vswprintf_l(buf
, format
, locale
, valist
);
1211 __ms_va_end(valist
);
1215 static void test__vswprintf_l(void)
1217 static const wchar_t format
[] = {'t','e','s','t',0};
1222 ret
= __vswprintf_l_wrapper(buf
, format
, NULL
);
1223 ok(ret
== 4, "ret = %d\n", ret
);
1224 ok(!memcmp(buf
, format
, sizeof(format
)), "buf = %s, expected %s\n",
1225 wine_dbgstr_w(buf
), wine_dbgstr_w(format
));
1227 ret
= _vswprintf_l_wrapper(buf
, format
, NULL
);
1228 ok(ret
== 4, "ret = %d\n", ret
);
1229 ok(!memcmp(buf
, format
, sizeof(format
)), "buf = %s, expected %s\n",
1230 wine_dbgstr_w(buf
), wine_dbgstr_w(format
));
1233 struct block_file_arg
1242 static DWORD WINAPI
block_file(void *arg
)
1244 struct block_file_arg
*files
= arg
;
1247 p_lock_file(files
->read
);
1248 p_lock_file(files
->write
);
1249 SetEvent(files
->init
);
1251 WaitForSingleObject(files
->finish
, INFINITE
);
1253 deadlock_test
= InterlockedIncrement(&files
->deadlock_test
);
1254 ok(deadlock_test
== 1, "deadlock_test = %d\n", deadlock_test
);
1255 p_unlock_file(files
->read
);
1256 p_unlock_file(files
->write
);
1260 static void test_nonblocking_file_access(void)
1263 struct block_file_arg arg
;
1264 FILE *filer
, *filew
;
1267 if(!p_lock_file
|| !p_unlock_file
) {
1268 win_skip("_lock_file not available\n");
1272 filew
= p_fopen("test_file", "w");
1273 ok(filew
!= NULL
, "unable to create test file\n");
1276 filer
= p_fopen("test_file", "r");
1277 ok(filer
!= NULL
, "unable to open test file\n");
1280 p_unlink("test_file");
1286 arg
.init
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1287 arg
.finish
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1288 arg
.deadlock_test
= 0;
1289 ok(arg
.init
!= NULL
, "CreateEventW failed\n");
1290 ok(arg
.finish
!= NULL
, "CreateEventW failed\n");
1291 thread
= CreateThread(NULL
, 0, block_file
, (void*)&arg
, 0, NULL
);
1292 ok(thread
!= NULL
, "CreateThread failed\n");
1293 WaitForSingleObject(arg
.init
, INFINITE
);
1295 ret
= p_fileno(filer
);
1296 ok(ret
, "_fileno(filer) returned %d\n", ret
);
1297 ret
= p_fileno(filew
);
1298 ok(ret
, "_fileno(filew) returned %d\n", ret
);
1300 ret
= p_feof(filer
);
1301 ok(ret
==0, "feof(filer) returned %d\n", ret
);
1302 ret
= p_feof(filew
);
1303 ok(ret
==0, "feof(filew) returned %d\n", ret
);
1305 ret
= p_ferror(filer
);
1306 ok(ret
==0, "ferror(filer) returned %d\n", ret
);
1307 ret
= p_ferror(filew
);
1308 ok(ret
==0, "ferror(filew) returned %d\n", ret
);
1310 ret
= p_flsbuf('a', filer
);
1311 ok(ret
==-1, "_flsbuf(filer) returned %d\n", ret
);
1312 ret
= p_flsbuf('a', filew
);
1313 ok(ret
=='a', "_flsbuf(filew) returned %d\n", ret
);
1315 ret
= p_filbuf(filer
);
1316 ok(ret
==-1, "_filbuf(filer) returned %d\n", ret
);
1317 ret
= p_filbuf(filew
);
1318 ok(ret
==-1, "_filbuf(filew) returned %d\n", ret
);
1320 ret
= p_fflush_nolock(filer
);
1321 ok(ret
==0, "_fflush_nolock(filer) returned %d\n", ret
);
1322 ret
= p_fflush_nolock(filew
);
1323 ok(ret
==0, "_fflush_nolock(filew) returned %d\n", ret
);
1325 SetEvent(arg
.finish
);
1327 ret
= p_fflush_nolock(NULL
);
1328 ok(ret
==0, "_fflush_nolock(NULL) returned %d\n", ret
);
1329 ret
= InterlockedIncrement(&arg
.deadlock_test
);
1330 ok(ret
==2, "InterlockedIncrement returned %d\n", ret
);
1332 WaitForSingleObject(thread
, INFINITE
);
1333 CloseHandle(arg
.init
);
1334 CloseHandle(arg
.finish
);
1335 CloseHandle(thread
);
1338 p_unlink("test_file");
1341 static void test_byteswap(void)
1345 ret
= p_byteswap_ulong(0x12345678);
1346 ok(ret
== 0x78563412, "ret = %lx\n", ret
);
1348 ret
= p_byteswap_ulong(0);
1349 ok(ret
== 0, "ret = %lx\n", ret
);
1352 static void test_access_s(void)
1357 f
= p_fopen("test_file", "w");
1358 ok(f
!= NULL
, "unable to create test file\n");
1365 res
= p_access_s("test_file", 0);
1366 ok(res
== 0, "got %x\n", res
);
1367 ok(errno
== 0xdeadbeef, "got %x\n", res
);
1370 res
= p_access_s("test_file", 2);
1371 ok(res
== 0, "got %x\n", res
);
1372 ok(errno
== 0xdeadbeef, "got %x\n", res
);
1375 res
= p_access_s("test_file", 4);
1376 ok(res
== 0, "got %x\n", res
);
1377 ok(errno
== 0xdeadbeef, "got %x\n", res
);
1380 res
= p_access_s("test_file", 6);
1381 ok(res
== 0, "got %x\n", res
);
1382 ok(errno
== 0xdeadbeef, "got %x\n", res
);
1384 SetFileAttributesA("test_file", FILE_ATTRIBUTE_READONLY
);
1387 res
= p_access_s("test_file", 0);
1388 ok(res
== 0, "got %x\n", res
);
1389 ok(errno
== 0xdeadbeef, "got %x\n", res
);
1392 res
= p_access_s("test_file", 2);
1393 ok(res
== EACCES
, "got %x\n", res
);
1394 ok(errno
== EACCES
, "got %x\n", res
);
1397 res
= p_access_s("test_file", 4);
1398 ok(res
== 0, "got %x\n", res
);
1399 ok(errno
== 0xdeadbeef, "got %x\n", res
);
1402 res
= p_access_s("test_file", 6);
1403 ok(res
== EACCES
, "got %x\n", res
);
1404 ok(errno
== EACCES
, "got %x\n", res
);
1406 SetFileAttributesA("test_file", FILE_ATTRIBUTE_NORMAL
);
1408 p_unlink("test_file");
1411 res
= p_access_s("test_file", 0);
1412 ok(res
== ENOENT
, "got %x\n", res
);
1413 ok(errno
== ENOENT
, "got %x\n", res
);
1416 res
= p_access_s("test_file", 2);
1417 ok(res
== ENOENT
, "got %x\n", res
);
1418 ok(errno
== ENOENT
, "got %x\n", res
);
1421 res
= p_access_s("test_file", 4);
1422 ok(res
== ENOENT
, "got %x\n", res
);
1423 ok(errno
== ENOENT
, "got %x\n", res
);
1426 res
= p_access_s("test_file", 6);
1427 ok(res
== ENOENT
, "got %x\n", res
);
1428 ok(errno
== ENOENT
, "got %x\n", res
);
1432 #define EXCEPTION_REF(instance, name) &instance.name
1434 #define EXCEPTION_REF(instance, name) FIELD_OFFSET(struct _exception_data, name)
1436 static void test_is_exception_typeof(void)
1438 const type_info ti1
= {NULL
, NULL
, {'.','?','A','V','t','e','s','t','1','@','@',0}};
1439 const type_info ti2
= {NULL
, NULL
, {'.','?','A','V','t','e','s','t','2','@','@',0}};
1440 const type_info ti3
= {NULL
, NULL
, {'.','?','A','V','t','e','s','t','3','@','@',0}};
1442 const struct _exception_data
{
1447 cxx_type_info_table tit
;
1448 cxx_exception_type et
;
1449 } exception_data
= {
1450 {NULL
, NULL
, {'.','?','A','V','t','e','s','t','1','@','@',0}},
1451 {NULL
, NULL
, {'.','?','A','V','t','e','s','t','2','@','@',0}},
1452 {0, EXCEPTION_REF(exception_data
, ti1
)},
1453 {0, EXCEPTION_REF(exception_data
, ti2
)},
1454 {2, {EXCEPTION_REF(exception_data
, cti1
), EXCEPTION_REF(exception_data
, cti2
)}},
1455 {0, 0, 0, EXCEPTION_REF(exception_data
, tit
)}
1458 EXCEPTION_RECORD rec
= {CXX_EXCEPTION
, 0, NULL
, NULL
, 3, {CXX_FRAME_MAGIC_VC6
, 0, (ULONG_PTR
)&exception_data
.et
}};
1459 EXCEPTION_POINTERS except_ptrs
= {&rec
, NULL
};
1464 rec
.NumberParameters
= 4;
1465 rec
.ExceptionInformation
[3] = (ULONG_PTR
)&exception_data
;
1468 ret
= p_is_exception_typeof(&ti1
, &except_ptrs
);
1469 ok(ret
== 1, "_is_exception_typeof returned %d\n", ret
);
1470 ret
= p_is_exception_typeof(&ti2
, &except_ptrs
);
1471 ok(ret
== 1, "_is_exception_typeof returned %d\n", ret
);
1472 ret
= p_is_exception_typeof(&ti3
, &except_ptrs
);
1473 ok(ret
== 0, "_is_exception_typeof returned %d\n", ret
);
1476 static void test__AdjustPointer(void)
1480 void *obj2
= (char*)&off
- 2;
1490 {NULL
, NULL
, {0, -1, 0}},
1491 {(void*)0xbeef, (void*)0xbef0, {1, -1, 1}},
1492 {(void*)0xbeef, (void*)0xbeee, {-1, -1, 0}},
1493 {&obj1
, (char*)&obj1
+ off
, {0, 0, 0}},
1494 {(char*)&obj1
- 5, (char*)&obj1
+ off
, {0, 5, 0}},
1495 {(char*)&obj1
- 3, (char*)&obj1
+ off
+ 24, {24, 3, 0}},
1496 {(char*)&obj2
- 17, (char*)&obj2
+ off
+ 4, {4, 17, 2}}
1501 for(i
=0; i
<ARRAY_SIZE(data
); i
++) {
1502 ret
= p__AdjustPointer(data
[i
].ptr
, &data
[i
].this_ptr_offsets
);
1503 ok(ret
== data
[i
].ret
, "%d) __AdjustPointer returned %p, expected %p\n", i
, ret
, data
[i
].ret
);
1507 static void test_mbstowcs(void)
1515 memset(bufw
, 'x', sizeof(bufw
));
1516 ret
= p_mbstowcs(bufw
, buf
, -1);
1517 ok(ret
== 1, "ret = %d\n", (int)ret
);
1518 ok(bufw
[0] == 'a', "bufw[0] = '%c'\n", bufw
[0]);
1519 ok(bufw
[1] == 0, "bufw[1] = '%c'\n", bufw
[1]);
1521 memset(bufw
, 'x', sizeof(bufw
));
1522 ret
= p_mbstowcs(bufw
, buf
, -1000);
1523 ok(ret
== 1, "ret = %d\n", (int)ret
);
1524 ok(bufw
[0] == 'a', "bufw[0] = '%c'\n", bufw
[0]);
1525 ok(bufw
[1] == 0, "bufw[1] = '%c'\n", bufw
[1]);
1527 memset(buf
, 'x', sizeof(buf
));
1528 ret
= p_wcstombs(buf
, bufw
, -1);
1529 ok(ret
== 1, "ret = %d\n", (int)ret
);
1530 ok(buf
[0] == 'a', "buf[0] = '%c'\n", buf
[0]);
1531 ok(buf
[1] == 0, "buf[1] = '%c'\n", buf
[1]);
1533 memset(buf
, 'x', sizeof(buf
));
1534 ret
= p_wcstombs(buf
, bufw
, -1000);
1535 ok(ret
== 1, "ret = %d\n", (int)ret
);
1536 ok(buf
[0] == 'a', "buf[0] = '%c'\n", buf
[0]);
1537 ok(buf
[1] == 0, "buf[1] = '%c'\n", buf
[1]);
1539 if(!p_setlocale(LC_ALL
, "English")) {
1540 win_skip("English locale not available\n");
1546 memset(bufw
, 'x', sizeof(bufw
));
1547 ret
= p_mbstowcs(bufw
, buf
, -1);
1548 ok(ret
== -1, "ret = %d\n", (int)ret
);
1549 ok(bufw
[0] == 0, "bufw[0] = '%c'\n", bufw
[0]);
1551 memset(bufw
, 'x', sizeof(bufw
));
1552 ret
= p_mbstowcs(bufw
, buf
, -1000);
1553 ok(ret
== -1, "ret = %d\n", (int)ret
);
1554 ok(bufw
[0] == 0, "bufw[0] = '%c'\n", bufw
[0]);
1556 memset(buf
, 'x', sizeof(buf
));
1557 ret
= p_wcstombs(buf
, bufw
, -1);
1558 ok(ret
== 0, "ret = %d\n", (int)ret
);
1559 ok(buf
[0] == 0, "buf[0] = '%c'\n", buf
[0]);
1561 memset(buf
, 'x', sizeof(buf
));
1562 ret
= p_wcstombs(buf
, bufw
, -1000);
1563 ok(ret
== 0, "ret = %d\n", (int)ret
);
1564 ok(buf
[0] == 0, "buf[0] = '%c'\n", buf
[0]);
1566 p_setlocale(LC_ALL
, "C");
1569 static void test_strtok_s(void)
1571 char test
[] = "a/b";
1578 context
= (char*)0xdeadbeef;
1579 strret
= p_strtok_s( test
, delim
, &context
);
1580 ok(strret
== test
, "Expected test, got %p.\n", strret
);
1581 ok(context
== test
+2, "Expected test+2, got %p.\n", context
);
1583 strret
= p_strtok_s( NULL
, delim
, &context
);
1584 ok(strret
== test
+2, "Expected test+2, got %p.\n", strret
);
1585 ok(context
== test
+3, "Expected test+3, got %p.\n", context
);
1587 strret
= p_strtok_s( NULL
, delim
, &context
);
1588 ok(strret
== NULL
, "Expected NULL, got %p.\n", strret
);
1589 ok(context
== test
+3, "Expected test+3, got %p.\n", context
);
1592 strret
= p_strtok_s( empty
, delim
, &context
);
1593 ok(strret
== NULL
, "Expected NULL, got %p.\n", strret
);
1594 ok(context
== empty
, "Expected empty, got %p.\n", context
);
1596 strret
= p_strtok_s( NULL
, delim
, &context
);
1597 ok(strret
== NULL
, "Expected NULL, got %p.\n", strret
);
1598 ok(context
== empty
, "Expected empty, got %p.\n", context
);
1601 strret
= p_strtok_s( space
, delim
, &context
);
1602 ok(strret
== space
, "Expected space, got %p.\n", strret
);
1603 ok(context
== space
+1, "Expected space+1, got %p.\n", context
);
1605 strret
= p_strtok_s( NULL
, delim
, &context
);
1606 ok(strret
== NULL
, "Expected NULL, got %p.\n", strret
);
1607 ok(context
== space
+1, "Expected space+1, got %p.\n", context
);
1610 static void test__mbstok_s(void)
1612 unsigned char test
[] = "a/b";
1613 unsigned char empty
[] = "";
1614 unsigned char space
[] = " ";
1615 unsigned char delim
[] = "/";
1616 unsigned char *strret
;
1617 unsigned char *context
;
1619 context
= (unsigned char*)0xdeadbeef;
1620 strret
= p__mbstok_s( test
, delim
, &context
);
1621 ok(strret
== test
, "Expected test, got %p.\n", strret
);
1622 ok(context
== test
+2, "Expected test+2, got %p.\n", context
);
1624 strret
= p__mbstok_s( NULL
, delim
, &context
);
1625 ok(strret
== test
+2, "Expected test+2, got %p.\n", strret
);
1626 ok(context
== test
+3, "Expected test+3, got %p.\n", context
);
1628 strret
= p__mbstok_s( NULL
, delim
, &context
);
1629 ok(strret
== NULL
, "Expected NULL, got %p.\n", strret
);
1630 ok(context
== test
+3, "Expected test+3, got %p.\n", context
);
1633 strret
= p__mbstok_s( empty
, delim
, &context
);
1634 ok(strret
== NULL
, "Expected NULL, got %p.\n", strret
);
1635 ok(context
== empty
, "Expected empty, got %p.\n", context
);
1637 strret
= p__mbstok_s( NULL
, delim
, &context
);
1638 ok(strret
== NULL
, "Expected NULL, got %p.\n", strret
);
1639 ok(context
== empty
, "Expected empty, got %p.\n", context
);
1642 strret
= p__mbstok_s( space
, delim
, &context
);
1643 ok(strret
== space
, "Expected space, got %p.\n", strret
);
1644 ok(context
== space
+1, "Expected space+1, got %p.\n", context
);
1646 strret
= p__mbstok_s( NULL
, delim
, &context
);
1647 ok(strret
== NULL
, "Expected NULL, got %p.\n", strret
);
1648 ok(context
== space
+1, "Expected space+1, got %p.\n", context
);
1652 static _FPIEEE_RECORD fpieee_record
;
1653 static int handler_called
;
1654 static int __cdecl
fpieee_handler(_FPIEEE_RECORD
*rec
)
1657 fpieee_record
= *rec
;
1658 return EXCEPTION_CONTINUE_EXECUTION
;
1661 static void test__fpieee_flt(void)
1665 DWORD exception_code
;
1673 { STATUS_FLOAT_DIVIDE_BY_ZERO
, 0x35dc, (DWORD
)&argd
, 0, 0,
1674 {0, 2, _FpCodeDivide
,
1675 {0}, {1, 1, 1, 1, 1}, {0},
1676 {{0}, 1, _FpFormatFp80
},
1677 {{0}, 1, _FpFormatFp64
},
1678 {{0}, 0, _FpFormatFp80
}},
1679 EXCEPTION_CONTINUE_EXECUTION
},
1680 { STATUS_FLOAT_INEXACT_RESULT
, 0x35dc, (DWORD
)&argd
, 0, 0,
1681 {0, 2, _FpCodeDivide
,
1682 {0}, {1, 1, 1, 1, 1}, {0},
1683 {{0}, 0, _FpFormatFp80
},
1684 {{0}, 1, _FpFormatFp64
},
1685 {{0}, 1, _FpFormatFp80
}},
1686 EXCEPTION_CONTINUE_EXECUTION
},
1687 { STATUS_FLOAT_INVALID_OPERATION
, 0x35dc, (DWORD
)&argd
, 0, 0,
1688 {0, 2, _FpCodeDivide
,
1689 {0}, {1, 1, 1, 1, 1}, {0},
1690 {{0}, 1, _FpFormatFp80
},
1691 {{0}, 1, _FpFormatFp64
},
1692 {{0}, 0, _FpFormatFp80
}},
1693 EXCEPTION_CONTINUE_EXECUTION
},
1694 { STATUS_FLOAT_OVERFLOW
, 0x35dc, (DWORD
)&argd
, 0, 0,
1695 {0, 2, _FpCodeDivide
,
1696 {0}, {1, 1, 1, 1, 1}, {0},
1697 {{0}, 0, _FpFormatFp80
},
1698 {{0}, 1, _FpFormatFp64
},
1699 {{0}, 1, _FpFormatFp80
}},
1700 EXCEPTION_CONTINUE_EXECUTION
},
1701 { STATUS_FLOAT_UNDERFLOW
, 0x35dc, (DWORD
)&argd
, 0, 0,
1702 {0, 2, _FpCodeDivide
,
1703 {0}, {1, 1, 1, 1, 1}, {0},
1704 {{0}, 0, _FpFormatFp80
},
1705 {{0}, 1, _FpFormatFp64
},
1706 {{0}, 1, _FpFormatFp80
}},
1707 EXCEPTION_CONTINUE_EXECUTION
},
1708 { STATUS_FLOAT_DIVIDE_BY_ZERO
, 0x35dc, (DWORD
)&argd
, 0, 0xffffffff,
1709 {0, 2, _FpCodeDivide
,
1710 {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1},
1711 {{0}, 1, _FpFormatFp80
},
1712 {{0}, 1, _FpFormatFp64
},
1713 {{0}, 0, _FpFormatFp80
}},
1714 EXCEPTION_CONTINUE_EXECUTION
},
1715 { STATUS_FLOAT_DIVIDE_BY_ZERO
, 0x35dc, (DWORD
)&argd
, 0xffffffff, 0xffffffff,
1716 {3, 0, _FpCodeDivide
,
1717 {0}, {0}, {1, 1, 1, 1, 1},
1718 {{0}, 1, _FpFormatFp80
},
1719 {{0}, 1, _FpFormatFp64
},
1720 {{0}, 0, _FpFormatFp80
}},
1721 EXCEPTION_CONTINUE_EXECUTION
},
1723 EXCEPTION_POINTERS ep
;
1724 EXCEPTION_RECORD rec
;
1728 if(!p__fpieee_flt
) {
1729 win_skip("_fpieee_flt not available\n");
1733 ep
.ExceptionRecord
= &rec
;
1734 ep
.ContextRecord
= &ctx
;
1735 memset(&rec
, 0, sizeof(rec
));
1736 memset(&ctx
, 0, sizeof(ctx
));
1737 ret
= p__fpieee_flt(1, &ep
, fpieee_handler
);
1738 ok(ret
== EXCEPTION_CONTINUE_SEARCH
, "_fpieee_flt returned %d\n", ret
);
1739 ok(handler_called
== 0, "handler_called = %d\n", handler_called
);
1741 for(i
=0; i
<ARRAY_SIZE(test_data
); i
++) {
1742 ep
.ExceptionRecord
= &rec
;
1743 ep
.ContextRecord
= &ctx
;
1744 memset(&rec
, 0, sizeof(rec
));
1745 memset(&ctx
, 0, sizeof(ctx
));
1747 ctx
.FloatSave
.ErrorOffset
= (DWORD
)&test_data
[i
].opcode
;
1748 ctx
.FloatSave
.DataOffset
= test_data
[i
].data_offset
;
1749 ctx
.FloatSave
.ControlWord
= test_data
[i
].control_word
;
1750 ctx
.FloatSave
.StatusWord
= test_data
[i
].status_word
;
1753 ret
= p__fpieee_flt(test_data
[i
].exception_code
, &ep
, fpieee_handler
);
1754 ok(ret
== test_data
[i
].ret
, "%d) _fpieee_flt returned %d\n", i
, ret
);
1755 ok(handler_called
== 1, "%d) handler_called = %d\n", i
, handler_called
);
1757 ok(fpieee_record
.RoundingMode
== test_data
[i
].rec
.RoundingMode
,
1758 "%d) RoundingMode = %x\n", i
, fpieee_record
.RoundingMode
);
1759 ok(fpieee_record
.Precision
== test_data
[i
].rec
.Precision
,
1760 "%d) Precision = %x\n", i
, fpieee_record
.Precision
);
1761 ok(fpieee_record
.Operation
== test_data
[i
].rec
.Operation
,
1762 "%d) Operation = %x\n", i
, fpieee_record
.Operation
);
1763 ok(fpieee_record
.Cause
.Inexact
== test_data
[i
].rec
.Cause
.Inexact
,
1764 "%d) Cause.Inexact = %x\n", i
, fpieee_record
.Cause
.Inexact
);
1765 ok(fpieee_record
.Cause
.Underflow
== test_data
[i
].rec
.Cause
.Underflow
,
1766 "%d) Cause.Underflow = %x\n", i
, fpieee_record
.Cause
.Underflow
);
1767 ok(fpieee_record
.Cause
.Overflow
== test_data
[i
].rec
.Cause
.Overflow
,
1768 "%d) Cause.Overflow = %x\n", i
, fpieee_record
.Cause
.Overflow
);
1769 ok(fpieee_record
.Cause
.ZeroDivide
== test_data
[i
].rec
.Cause
.ZeroDivide
,
1770 "%d) Cause.ZeroDivide = %x\n", i
, fpieee_record
.Cause
.ZeroDivide
);
1771 ok(fpieee_record
.Cause
.InvalidOperation
== test_data
[i
].rec
.Cause
.InvalidOperation
,
1772 "%d) Cause.InvalidOperation = %x\n", i
, fpieee_record
.Cause
.InvalidOperation
);
1773 ok(fpieee_record
.Enable
.Inexact
== test_data
[i
].rec
.Enable
.Inexact
,
1774 "%d) Enable.Inexact = %x\n", i
, fpieee_record
.Enable
.Inexact
);
1775 ok(fpieee_record
.Enable
.Underflow
== test_data
[i
].rec
.Enable
.Underflow
,
1776 "%d) Enable.Underflow = %x\n", i
, fpieee_record
.Enable
.Underflow
);
1777 ok(fpieee_record
.Enable
.Overflow
== test_data
[i
].rec
.Enable
.Overflow
,
1778 "%d) Enable.Overflow = %x\n", i
, fpieee_record
.Enable
.Overflow
);
1779 ok(fpieee_record
.Enable
.ZeroDivide
== test_data
[i
].rec
.Enable
.ZeroDivide
,
1780 "%d) Enable.ZeroDivide = %x\n", i
, fpieee_record
.Enable
.ZeroDivide
);
1781 ok(fpieee_record
.Enable
.InvalidOperation
== test_data
[i
].rec
.Enable
.InvalidOperation
,
1782 "%d) Enable.InvalidOperation = %x\n", i
, fpieee_record
.Enable
.InvalidOperation
);
1783 ok(fpieee_record
.Status
.Inexact
== test_data
[i
].rec
.Status
.Inexact
,
1784 "%d) Status.Inexact = %x\n", i
, fpieee_record
.Status
.Inexact
);
1785 ok(fpieee_record
.Status
.Underflow
== test_data
[i
].rec
.Status
.Underflow
,
1786 "%d) Status.Underflow = %x\n", i
, fpieee_record
.Status
.Underflow
);
1787 ok(fpieee_record
.Status
.Overflow
== test_data
[i
].rec
.Status
.Overflow
,
1788 "%d) Status.Overflow = %x\n", i
, fpieee_record
.Status
.Overflow
);
1789 ok(fpieee_record
.Status
.ZeroDivide
== test_data
[i
].rec
.Status
.ZeroDivide
,
1790 "%d) Status.ZeroDivide = %x\n", i
, fpieee_record
.Status
.ZeroDivide
);
1791 ok(fpieee_record
.Status
.InvalidOperation
== test_data
[i
].rec
.Status
.InvalidOperation
,
1792 "%d) Status.InvalidOperation = %x\n", i
, fpieee_record
.Status
.InvalidOperation
);
1793 ok(fpieee_record
.Operand1
.OperandValid
== test_data
[i
].rec
.Operand1
.OperandValid
,
1794 "%d) Operand1.OperandValid = %x\n", i
, fpieee_record
.Operand1
.OperandValid
);
1795 if(fpieee_record
.Operand1
.OperandValid
) {
1796 ok(fpieee_record
.Operand1
.Format
== test_data
[i
].rec
.Operand1
.Format
,
1797 "%d) Operand1.Format = %x\n", i
, fpieee_record
.Operand1
.Format
);
1799 ok(fpieee_record
.Operand2
.OperandValid
== test_data
[i
].rec
.Operand2
.OperandValid
,
1800 "%d) Operand2.OperandValid = %x\n", i
, fpieee_record
.Operand2
.OperandValid
);
1801 ok(fpieee_record
.Operand2
.Format
== test_data
[i
].rec
.Operand2
.Format
,
1802 "%d) Operand2.Format = %x\n", i
, fpieee_record
.Operand2
.Format
);
1803 ok(fpieee_record
.Result
.OperandValid
== test_data
[i
].rec
.Result
.OperandValid
,
1804 "%d) Result.OperandValid = %x\n", i
, fpieee_record
.Result
.OperandValid
);
1805 ok(fpieee_record
.Result
.Format
== test_data
[i
].rec
.Result
.Format
,
1806 "%d) Result.Format = %x\n", i
, fpieee_record
.Result
.Format
);
1811 static void test__memicmp(void)
1813 static const char *s1
= "abc";
1814 static const char *s2
= "aBd";
1817 ret
= p__memicmp(NULL
, NULL
, 0);
1818 ok(!ret
, "got %d\n", ret
);
1820 SET_EXPECT(invalid_parameter_handler
);
1821 ret
= p__memicmp(NULL
, NULL
, 1);
1822 ok(ret
== _NLSCMPERROR
, "got %d\n", ret
);
1823 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
1825 SET_EXPECT(invalid_parameter_handler
);
1826 ret
= p__memicmp(s1
, NULL
, 1);
1827 ok(ret
== _NLSCMPERROR
, "got %d\n", ret
);
1828 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
1830 SET_EXPECT(invalid_parameter_handler
);
1831 ret
= p__memicmp(NULL
, s2
, 1);
1832 ok(ret
== _NLSCMPERROR
, "got %d\n", ret
);
1833 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
1835 ret
= p__memicmp(s1
, s2
, 2);
1836 ok(!ret
, "got %d\n", ret
);
1838 ret
= p__memicmp(s1
, s2
, 3);
1839 ok(ret
== -1, "got %d\n", ret
);
1842 static void test__memicmp_l(void)
1844 static const char *s1
= "abc";
1845 static const char *s2
= "aBd";
1848 ret
= p__memicmp_l(NULL
, NULL
, 0, NULL
);
1849 ok(!ret
, "got %d\n", ret
);
1851 SET_EXPECT(invalid_parameter_handler
);
1852 ret
= p__memicmp_l(NULL
, NULL
, 1, NULL
);
1853 ok(ret
== _NLSCMPERROR
, "got %d\n", ret
);
1854 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
1856 SET_EXPECT(invalid_parameter_handler
);
1857 ret
= p__memicmp_l(s1
, NULL
, 1, NULL
);
1858 ok(ret
== _NLSCMPERROR
, "got %d\n", ret
);
1859 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
1861 SET_EXPECT(invalid_parameter_handler
);
1862 ret
= p__memicmp_l(NULL
, s2
, 1, NULL
);
1863 ok(ret
== _NLSCMPERROR
, "got %d\n", ret
);
1864 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
1866 ret
= p__memicmp_l(s1
, s2
, 2, NULL
);
1867 ok(!ret
, "got %d\n", ret
);
1869 ret
= p__memicmp_l(s1
, s2
, 3, NULL
);
1870 ok(ret
== -1, "got %d\n", ret
);
1873 static int WINAPIV
_vsnwprintf_wrapper(wchar_t *str
, size_t len
, const wchar_t *format
, ...)
1876 __ms_va_list valist
;
1877 __ms_va_start(valist
, format
);
1878 ret
= p__vsnwprintf(str
, len
, format
, valist
);
1879 __ms_va_end(valist
);
1883 static void test__vsnwprintf(void)
1888 _invalid_parameter_handler old_handler
= p_set_invalid_parameter_handler(test_invalid_parameter_handler
);
1890 SET_EXPECT(invalid_parameter_handler
);
1893 ret
= _vsnwprintf_wrapper(str
, 0, NULL
);
1894 ok(ret
== -1, "got %d, expected -1\n", ret
);
1895 ok(str
[0] == 'x', "Expected string to be unchanged.\n");
1896 CHECK_CALLED(invalid_parameter_handler
, EINVAL
);
1898 ok(p_set_invalid_parameter_handler(old_handler
) == test_invalid_parameter_handler
, "Cannot reset invalid parameter handler\n");
1901 static void test___strncnt(void)
1921 ret
= p___strncnt(NULL
, 1);
1923 for (i
= 0; i
< ARRAY_SIZE(strncnt_tests
); ++i
)
1925 ret
= p___strncnt(strncnt_tests
[i
].str
, strncnt_tests
[i
].size
);
1926 ok(ret
== strncnt_tests
[i
].ret
, "%u: unexpected return value %u.\n", i
, (int)ret
);
1930 static void test_swscanf(void)
1933 wchar_t buffer
[100];
1937 ret
= p_swscanf(L
" \t\n\n", L
"%s", buffer
);
1938 ok( ret
== (short)WEOF
, "ret = %d\n", ret
);
1947 test__encode_pointer();
1948 test_error_messages();
1957 test__set_abort_behavior();
1960 test__realloc_crt();
1963 test__vswprintf_l();
1964 test_nonblocking_file_access();
1967 test_is_exception_typeof();
1968 test__AdjustPointer();