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
32 #include "wine/test.h"
34 #define DEFINE_EXPECT(func) \
35 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
37 #define SET_EXPECT(func) \
39 expect_ ## func = TRUE; \
43 #define CHECK_EXPECT2(func) \
45 ok(expect_ ##func, "unexpected call " #func "\n"); \
46 called_ ## func = TRUE; \
49 #define CHECK_EXPECT(func) \
51 CHECK_EXPECT2(func); \
52 expect_ ## func = FALSE; \
55 #define CHECK_CALLED(func,error) \
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; \
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 */
129 #define errno (*p_errno())
132 typedef struct __type_info
139 struct __type_info_node
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 */
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 */
159 typedef void (*cxx_copy_ctor
)(void);
161 /* complete information about a C++ type */
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 */
172 typedef struct __cxx_type_info
175 unsigned int type_info
;
176 this_ptr_offsets offsets
;
178 unsigned int copy_ctor
;
182 /* table of C++ types that apply for a given object */
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
;
190 typedef struct __cxx_type_info_table
193 unsigned int info
[3];
194 } cxx_type_info_table
;
197 /* type information for an exception object */
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
;
210 unsigned int destructor
;
211 unsigned int custom_handler
;
212 unsigned int type_info_table
;
213 } cxx_exception_type
;
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;
231 /* thiscall emulation */
232 /* Emulate a __thiscall */
235 static inline void* do_call_func1(void *func
, void *_this
)
237 volatile void* retval
= 0;
246 return (void*)retval
;
249 static inline void* do_call_func2(void *func
, void *_this
, const void* arg
)
251 volatile void* retval
= 0;
261 return (void*)retval
;
264 static void* do_call_func1(void *func
, void *_this
)
267 __asm__
__volatile__ ("call *%2"
268 : "=a" (ret
), "=c" (dummy
)
269 : "g" (func
), "1" (_this
)
274 static void* do_call_func2(void *func
, void *_this
, const void* arg
)
277 __asm__
__volatile__ ("pushl %3\n\tcall *%2"
278 : "=a" (ret
), "=c" (dummy
)
279 : "r" (func
), "r" (arg
), "1" (_this
)
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)
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)
315 SetLastError(0xdeadbeef);
316 hcrt
= LoadLibraryA("msvcr90.dll");
318 win_skip("msvcr90.dll not installed (got %d)\n", GetLastError());
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");
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");
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");
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");
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");
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");
409 static int __cdecl
initterm_cb0(void)
415 static int __cdecl
initterm_cb1(void)
421 static int __cdecl
initterm_cb2(void)
428 static void test__initterm_e(void)
430 _INITTERM_E_FN table
[4];
433 memset(table
, 0, sizeof(table
));
435 memset(cb_called
, 0, sizeof(cb_called
));
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
));
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]);
450 /* this crash on Windows */
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
));
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
));
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
));
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
));
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 */
493 table
[2] = initterm_cb2
;
494 memset(cb_called
, 0, sizeof(cb_called
));
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)
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");
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();
536 ok(*p_sys_nerr
== *size
, "_sys_nerr = %u, size = %u\n", *p_sys_nerr
, *size
);
539 ok(*p_sys_nerr
== *size
, "_sys_nerr = %u, size = %u\n", *p_sys_nerr
, *size
);
543 ok(*p_sys_errlist
== *(p__sys_errlist()), "p_sys_errlist != p__sys_errlist()\n");
546 static void test__strtoi64(void)
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)
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",
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",
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",
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",
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",
668 static void test_wcsncat_s(void)
670 static wchar_t abcW
[] = {'a','b','c',0};
675 memcpy(src
, abcW
, sizeof(abcW
));
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
);
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
);
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
));
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");
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");
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");
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] = {
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
);
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 */
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]);
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]);
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 };
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
++) {
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");
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)
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
);
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
);
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
);
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
);
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 )
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
);
951 static const _atoflt_test _atoflt_testdata
[] = {
953 { "-13.721", -13.721, 0 },
955 { ".21e12", 0.21e12
, 0 },
956 { "214353e-3", 214.353, 0 },
957 { "1d9999999999999999999", 0.0, _OVERFLOW
},
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
},
967 static void test__atoflt(void)
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
);
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
);
994 static void test__set_abort_behavior(void)
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)
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
);
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};
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
);
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)
1049 /* crashes on some systems starting Vista */
1050 p_realloc_crt(NULL
, 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");
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
;
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
{
1090 __msvcrt_ulong thread_doserrno
;
1092 unsigned int random_seed
;
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
;
1101 char *asctime_buffer
;
1102 wchar_t *wasctime_buffer
;
1103 struct tm
*time_buffer
;
1107 EXCEPTION_POINTERS
*xcptinfo
;
1109 pthreadmbcinfo mbcinfo
;
1110 pthreadlocinfo locinfo
;
1113 void* terminate_handler
;
1114 void* unexpected_handler
;
1115 void* se_translator
;
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
;
1129 __time64_t secs
= 0;
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");
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
));
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
, ...)
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
);
1179 static int __cdecl
_vswprintf_l_wrapper(wchar_t *buf
,
1180 const wchar_t *format
, _locale_t locale
, ...)
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
);
1190 static void test__vswprintf_l(void)
1192 static const wchar_t format
[] = {'t','e','s','t',0};
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
1217 static DWORD WINAPI
block_file(void *arg
)
1219 struct block_file_arg
*files
= arg
;
1222 p_lock_file(files
->read
);
1223 p_lock_file(files
->write
);
1224 SetEvent(files
->init
);
1226 WaitForSingleObject(files
->finish
, INFINITE
);
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
);
1235 static void test_nonblocking_file_access(void)
1238 struct block_file_arg arg
;
1239 FILE *filer
, *filew
;
1242 if(!p_lock_file
|| !p_unlock_file
) {
1243 win_skip("_lock_file not available\n");
1247 filew
= p_fopen("test_file", "w");
1248 ok(filew
!= NULL
, "unable to create test file\n");
1251 filer
= p_fopen("test_file", "r");
1252 ok(filer
!= NULL
, "unable to open test file\n");
1255 p_unlink("test_file");
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
);
1313 p_unlink("test_file");
1316 static void test_byteswap(void)
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)
1332 f
= p_fopen("test_file", "w");
1333 ok(f
!= NULL
, "unable to create test file\n");
1340 res
= p_access_s("test_file", 0);
1341 ok(res
== 0, "got %x\n", res
);
1342 ok(errno
== 0xdeadbeef, "got %x\n", res
);
1345 res
= p_access_s("test_file", 2);
1346 ok(res
== 0, "got %x\n", res
);
1347 ok(errno
== 0xdeadbeef, "got %x\n", res
);
1350 res
= p_access_s("test_file", 4);
1351 ok(res
== 0, "got %x\n", res
);
1352 ok(errno
== 0xdeadbeef, "got %x\n", res
);
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
);
1362 res
= p_access_s("test_file", 0);
1363 ok(res
== 0, "got %x\n", res
);
1364 ok(errno
== 0xdeadbeef, "got %x\n", res
);
1367 res
= p_access_s("test_file", 2);
1368 ok(res
== EACCES
, "got %x\n", res
);
1369 ok(errno
== EACCES
, "got %x\n", res
);
1372 res
= p_access_s("test_file", 4);
1373 ok(res
== 0, "got %x\n", res
);
1374 ok(errno
== 0xdeadbeef, "got %x\n", res
);
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");
1386 res
= p_access_s("test_file", 0);
1387 ok(res
== ENOENT
, "got %x\n", res
);
1388 ok(errno
== ENOENT
, "got %x\n", res
);
1391 res
= p_access_s("test_file", 2);
1392 ok(res
== ENOENT
, "got %x\n", res
);
1393 ok(errno
== ENOENT
, "got %x\n", res
);
1396 res
= p_access_s("test_file", 4);
1397 ok(res
== ENOENT
, "got %x\n", res
);
1398 ok(errno
== ENOENT
, "got %x\n", res
);
1401 res
= p_access_s("test_file", 6);
1402 ok(res
== ENOENT
, "got %x\n", res
);
1403 ok(errno
== ENOENT
, "got %x\n", res
);
1407 #define EXCEPTION_REF(instance, name) &instance.name
1409 #define EXCEPTION_REF(instance, name) FIELD_OFFSET(struct _exception_data, name)
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
{
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
};
1439 rec
.NumberParameters
= 4;
1440 rec
.ExceptionInformation
[3] = (ULONG_PTR
)&exception_data
;
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)
1455 void *obj2
= (char*)&off
- 2;
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}}
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
);
1488 test__encode_pointer();
1489 test_error_messages();
1498 test__set_abort_behavior();
1501 test__realloc_crt();
1504 test__vswprintf_l();
1505 test_nonblocking_file_access();
1508 test_is_exception_typeof();
1509 test__AdjustPointer();