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
30 #include "wine/test.h"
32 #define DEFINE_EXPECT(func) \
33 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
35 #define SET_EXPECT(func) \
36 expect_ ## func = TRUE
38 #define CHECK_EXPECT2(func) \
40 ok(expect_ ##func, "unexpected call " #func "\n"); \
41 called_ ## func = TRUE; \
44 #define CHECK_EXPECT(func) \
46 CHECK_EXPECT2(func); \
47 expect_ ## func = FALSE; \
50 #define CHECK_CALLED(func) \
52 ok(called_ ## func, "expected " #func "\n"); \
53 expect_ ## func = called_ ## func = FALSE; \
56 DEFINE_EXPECT(invalid_parameter_handler);
58 static _invalid_parameter_handler (__cdecl *p_set_invalid_parameter_handler)(_invalid_parameter_handler);
59 typedef int (__cdecl *_INITTERM_E_FN)(void);
60 static int (__cdecl *p_initterm_e)(_INITTERM_E_FN *table, _INITTERM_E_FN *end);
61 static void* (__cdecl *p_encode_pointer)(void *);
62 static void* (__cdecl *p_decode_pointer)(void *);
63 static void* (__cdecl *p_encoded_null)(void);
64 static int *p_sys_nerr;
65 static int* (__cdecl *p__sys_nerr)(void);
66 static char **p_sys_errlist;
67 static char** (__cdecl *p__sys_errlist)(void);
68 static __int64 (__cdecl *p_strtoi64)(const char *, char **, int);
69 static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int);
70 static errno_t (__cdecl *p_itoa_s)(int,char*,size_t,int);
71 static int (__cdecl *p_wcsncat_s)(wchar_t *dst, size_t elem, const wchar_t *src, size_t count);
72 static void (__cdecl *p_qsort_s)(void *, size_t, size_t, int (__cdecl *)(void *, const void *, const void *), void *);
73 static int (__cdecl *p_controlfp_s)(unsigned int *, unsigned int, unsigned int);
74 static int (__cdecl *p_atoflt)(_CRT_FLOAT *, char *);
75 static unsigned int (__cdecl *p_set_abort_behavior)(unsigned int, unsigned int);
76 static int (__cdecl *p_sopen_s)(int*, const char*, int, int, int);
77 static int (__cdecl *p_wsopen_s)(int*, const wchar_t*, int, int, int);
78 static void* (__cdecl *p_realloc_crt)(void*, size_t);
79 static void* (__cdecl *p_malloc)(size_t);
80 static void (__cdecl *p_free)(void*);
83 typedef struct __type_info
91 struct __type_info_node
94 struct __type_info_node* next;
97 static char* (WINAPI *p_type_info_name_internal_method)(type_info*, struct __type_info_node *);
98 static void (WINAPI *ptype_info_dtor)(type_info*);
100 static void* (WINAPI *pEncodePointer)(void *);
102 static int cb_called[4];
103 static int g_qsort_s_context_counter;
105 static inline int almost_equal_f(float f1, float f2)
107 return f1-f2 > -1e-30 && f1-f2 < 1e-30;
112 /* thiscall emulation */
113 /* Emulate a __thiscall */
116 static inline void* do_call_func1(void *func, void *_this)
118 volatile void* retval = 0;
127 return (void*)retval;
130 static inline void* do_call_func2(void *func, void *_this, const void* arg)
132 volatile void* retval = 0;
142 return (void*)retval;
145 static void* do_call_func1(void *func, void *_this)
148 __asm__ __volatile__ ("call *%2"
149 : "=a" (ret), "=c" (dummy)
150 : "g" (func), "1" (_this)
155 static void* do_call_func2(void *func, void *_this, const void* arg)
158 __asm__ __volatile__ ("pushl %3\n\tcall *%2"
159 : "=a" (ret), "=c" (dummy)
160 : "r" (func), "r" (arg), "1" (_this)
166 #define call_func1(func,_this) do_call_func1(func,_this)
167 #define call_func2(func,_this,a) do_call_func2(func,_this,(const void*)a)
171 #define call_func1(func,_this) func(_this)
172 #define call_func2(func,_this,a) func(_this,a)
174 #endif /* __i386__ */
176 static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
177 const wchar_t *function, const wchar_t *file,
178 unsigned line, uintptr_t arg)
180 CHECK_EXPECT(invalid_parameter_handler);
181 ok(expression == NULL, "expression is not NULL\n");
182 ok(function == NULL, "function is not NULL\n");
183 ok(file == NULL, "file is not NULL\n");
184 ok(line == 0, "line = %u\n", line);
185 ok(arg == 0, "arg = %lx\n", (UINT_PTR)arg);
188 static int __cdecl initterm_cb0(void)
194 static int __cdecl initterm_cb1(void)
200 static int __cdecl initterm_cb2(void)
207 static void test__initterm_e(void)
209 _INITTERM_E_FN table[4];
213 skip("_initterm_e not found\n");
217 memset(table, 0, sizeof(table));
219 memset(cb_called, 0, sizeof(cb_called));
221 res = p_initterm_e(table, table);
222 ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
223 "got %d with 0x%x {%d, %d, %d}\n",
224 res, errno, cb_called[0], cb_called[1], cb_called[2]);
226 memset(cb_called, 0, sizeof(cb_called));
228 res = p_initterm_e(table, NULL);
229 ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
230 "got %d with 0x%x {%d, %d, %d}\n",
231 res, errno, cb_called[0], cb_called[1], cb_called[2]);
234 /* this crash on Windows */
236 res = p_initterm_e(NULL, table);
237 trace("got %d with 0x%x\n", res, errno);
240 table[0] = initterm_cb0;
241 memset(cb_called, 0, sizeof(cb_called));
243 res = p_initterm_e(table, &table[1]);
244 ok( !res && (cb_called[0] == 1) && !cb_called[1] && !cb_called[2],
245 "got %d with 0x%x {%d, %d, %d}\n",
246 res, errno, cb_called[0], cb_called[1], cb_called[2]);
249 /* init-function returning failure */
250 table[1] = initterm_cb1;
251 memset(cb_called, 0, sizeof(cb_called));
253 res = p_initterm_e(table, &table[3]);
254 ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
255 "got %d with 0x%x {%d, %d, %d}\n",
256 res, errno, cb_called[0], cb_called[1], cb_called[2]);
258 /* init-function not called, when end < start */
259 memset(cb_called, 0, sizeof(cb_called));
261 res = p_initterm_e(&table[3], table);
262 ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
263 "got %d with 0x%x {%d, %d, %d}\n",
264 res, errno, cb_called[0], cb_called[1], cb_called[2]);
266 /* initialization stop after first non-zero result */
267 table[2] = initterm_cb0;
268 memset(cb_called, 0, sizeof(cb_called));
270 res = p_initterm_e(table, &table[3]);
271 ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
272 "got %d with 0x%x {%d, %d, %d}\n",
273 res, errno, cb_called[0], cb_called[1], cb_called[2]);
275 /* NULL pointer in the array are skipped */
277 table[2] = initterm_cb2;
278 memset(cb_called, 0, sizeof(cb_called));
280 res = p_initterm_e(table, &table[3]);
281 ok( (res == 2) && (cb_called[0] == 1) && !cb_called[1] && (cb_called[2] == 1),
282 "got %d with 0x%x {%d, %d, %d}\n",
283 res, errno, cb_called[0], cb_called[1], cb_called[2]);
287 /* Beware that _encode_pointer is a NOP before XP
288 (the parameter is returned unchanged) */
289 static void test__encode_pointer(void)
293 if(!p_encode_pointer || !p_decode_pointer || !p_encoded_null) {
294 win_skip("_encode_pointer, _decode_pointer or _encoded_null not found\n");
298 ptr = (void*)0xdeadbeef;
299 res = p_encode_pointer(ptr);
300 res = p_decode_pointer(res);
301 ok(res == ptr, "Pointers are different after encoding and decoding\n");
303 ok(p_encoded_null() == p_encode_pointer(NULL), "Error encoding null\n");
305 ptr = p_encode_pointer(p_encode_pointer);
306 ok(p_decode_pointer(ptr) == p_encode_pointer, "Error decoding pointer\n");
308 /* Not present before XP */
309 if (!pEncodePointer) {
310 win_skip("EncodePointer not found\n");
314 res = pEncodePointer(p_encode_pointer);
315 ok(ptr == res, "_encode_pointer produced different result than EncodePointer\n");
319 static void test_error_messages(void)
321 int *size, size_copy;
323 if(!p_sys_nerr || !p__sys_nerr || !p_sys_errlist || !p__sys_errlist) {
324 win_skip("Skipping test_error_messages tests\n");
328 size = p__sys_nerr();
330 ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
333 ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
337 ok(*p_sys_errlist == *(p__sys_errlist()), "p_sys_errlist != p__sys_errlist()\n");
340 static void test__strtoi64(void)
343 unsigned __int64 ures;
345 if(!p_strtoi64 || !p_strtoui64) {
346 win_skip("_strtoi64 or _strtoui64 not found\n");
350 if(!p_set_invalid_parameter_handler) {
351 win_skip("_set_invalid_parameter_handler not found\n");
356 SET_EXPECT(invalid_parameter_handler);
357 res = p_strtoi64(NULL, NULL, 10);
358 ok(res == 0, "res != 0\n");
359 CHECK_CALLED(invalid_parameter_handler);
361 SET_EXPECT(invalid_parameter_handler);
362 res = p_strtoi64("123", NULL, 1);
363 ok(res == 0, "res != 0\n");
364 CHECK_CALLED(invalid_parameter_handler);
366 SET_EXPECT(invalid_parameter_handler);
367 res = p_strtoi64("123", NULL, 37);
368 ok(res == 0, "res != 0\n");
369 CHECK_CALLED(invalid_parameter_handler);
371 SET_EXPECT(invalid_parameter_handler);
372 ures = p_strtoui64(NULL, NULL, 10);
373 ok(ures == 0, "res = %d\n", (int)ures);
374 CHECK_CALLED(invalid_parameter_handler);
376 SET_EXPECT(invalid_parameter_handler);
377 ures = p_strtoui64("123", NULL, 1);
378 ok(ures == 0, "res = %d\n", (int)ures);
379 CHECK_CALLED(invalid_parameter_handler);
381 SET_EXPECT(invalid_parameter_handler);
382 ures = p_strtoui64("123", NULL, 37);
383 ok(ures == 0, "res = %d\n", (int)ures);
384 CHECK_CALLED(invalid_parameter_handler);
385 ok(errno == 0xdeadbeef, "errno = %x\n", errno);
388 static void test__itoa_s(void)
395 win_skip("Skipping _itoa_s tests\n");
399 if(!p_set_invalid_parameter_handler) {
400 win_skip("_set_invalid_parameter_handler not found\n");
404 /* _itoa_s (on msvcr90) doesn't set errno (in case of errors) while msvcrt does
405 * as we always set errno in our msvcrt implementation, don't test here that errno
408 SET_EXPECT(invalid_parameter_handler);
409 ret = p_itoa_s(0, NULL, 0, 0);
410 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
411 CHECK_CALLED(invalid_parameter_handler);
413 memset(buffer, 'X', sizeof(buffer));
414 SET_EXPECT(invalid_parameter_handler);
415 ret = p_itoa_s(0, buffer, 0, 0);
416 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
417 ok(buffer[0] == 'X', "Expected the output buffer to be untouched\n");
418 CHECK_CALLED(invalid_parameter_handler);
420 memset(buffer, 'X', sizeof(buffer));
421 SET_EXPECT(invalid_parameter_handler);
422 ret = p_itoa_s(0, buffer, sizeof(buffer), 0);
423 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
424 ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
425 CHECK_CALLED(invalid_parameter_handler);
427 memset(buffer, 'X', sizeof(buffer));
428 SET_EXPECT(invalid_parameter_handler);
429 ret = p_itoa_s(0, buffer, sizeof(buffer), 64);
430 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
431 ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
432 CHECK_CALLED(invalid_parameter_handler);
434 memset(buffer, 'X', sizeof(buffer));
435 SET_EXPECT(invalid_parameter_handler);
436 ret = p_itoa_s(12345678, buffer, 4, 10);
437 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
438 ok(!memcmp(buffer, "\000765", 4),
439 "Expected the output buffer to be null terminated with truncated output\n");
440 CHECK_CALLED(invalid_parameter_handler);
442 memset(buffer, 'X', sizeof(buffer));
443 SET_EXPECT(invalid_parameter_handler);
444 ret = p_itoa_s(12345678, buffer, 8, 10);
445 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
446 ok(!memcmp(buffer, "\0007654321", 8),
447 "Expected the output buffer to be null terminated with truncated output\n");
448 CHECK_CALLED(invalid_parameter_handler);
450 memset(buffer, 'X', sizeof(buffer));
451 SET_EXPECT(invalid_parameter_handler);
452 ret = p_itoa_s(-12345678, buffer, 9, 10);
453 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
454 ok(!memcmp(buffer, "\00087654321", 9),
455 "Expected the output buffer to be null terminated with truncated output\n");
456 CHECK_CALLED(invalid_parameter_handler);
458 ret = p_itoa_s(12345678, buffer, 9, 10);
459 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
460 ok(!strcmp(buffer, "12345678"),
461 "Expected output buffer string to be \"12345678\", got \"%s\"\n",
464 ret = p_itoa_s(43690, buffer, sizeof(buffer), 2);
465 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
466 ok(!strcmp(buffer, "1010101010101010"),
467 "Expected output buffer string to be \"1010101010101010\", got \"%s\"\n",
470 ret = p_itoa_s(1092009, buffer, sizeof(buffer), 36);
471 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
472 ok(!strcmp(buffer, "nell"),
473 "Expected output buffer string to be \"nell\", got \"%s\"\n",
476 ret = p_itoa_s(5704, buffer, sizeof(buffer), 18);
477 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
478 ok(!strcmp(buffer, "hag"),
479 "Expected output buffer string to be \"hag\", got \"%s\"\n",
482 ret = p_itoa_s(-12345678, buffer, sizeof(buffer), 10);
483 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
484 ok(!strcmp(buffer, "-12345678"),
485 "Expected output buffer string to be \"-12345678\", got \"%s\"\n",
489 static void test_wcsncat_s(void)
491 static wchar_t abcW[] = {'a','b','c',0};
498 win_skip("skipping wcsncat_s tests\n");
502 if(!p_set_invalid_parameter_handler) {
503 win_skip("_set_invalid_parameter_handler not found\n");
507 memcpy(src, abcW, sizeof(abcW));
509 SET_EXPECT(invalid_parameter_handler);
510 ret = p_wcsncat_s(NULL, 4, src, 4);
511 ok(ret == EINVAL, "err = %d\n", ret);
512 CHECK_CALLED(invalid_parameter_handler);
514 SET_EXPECT(invalid_parameter_handler);
515 ret = p_wcsncat_s(dst, 0, src, 4);
516 ok(ret == EINVAL, "err = %d\n", ret);
517 CHECK_CALLED(invalid_parameter_handler);
519 SET_EXPECT(invalid_parameter_handler);
520 ret = p_wcsncat_s(dst, 0, src, _TRUNCATE);
521 ok(ret == EINVAL, "err = %d\n", ret);
522 CHECK_CALLED(invalid_parameter_handler);
524 ret = p_wcsncat_s(dst, 4, NULL, 0);
525 ok(ret == 0, "err = %d\n", ret);
528 SET_EXPECT(invalid_parameter_handler);
529 ret = p_wcsncat_s(dst, 2, src, 4);
530 ok(ret == ERANGE, "err = %d\n", ret);
531 CHECK_CALLED(invalid_parameter_handler);
534 ret = p_wcsncat_s(dst, 2, src, _TRUNCATE);
535 ok(ret == STRUNCATE, "err = %d\n", ret);
536 ok(dst[0] == 'a' && dst[1] == 0, "dst is %s\n", wine_dbgstr_w(dst));
538 memcpy(dst, abcW, sizeof(abcW));
540 SET_EXPECT(invalid_parameter_handler);
541 ret = p_wcsncat_s(dst, 4, src, 4);
542 ok(ret == EINVAL, "err = %d\n", ret);
543 CHECK_CALLED(invalid_parameter_handler);
546 /* Based on dlls/ntdll/tests/string.c */
547 static __cdecl int intcomparefunc(void *context, const void *a, const void *b)
549 const int *p = a, *q = b;
551 ok (a != b, "must never get the same pointer\n");
557 static __cdecl int charcomparefunc(void *context, const void *a, const void *b)
559 const char *p = a, *q = b;
561 ok (a != b, "must never get the same pointer\n");
567 static __cdecl int strcomparefunc(void *context, const void *a, const void *b)
569 const char * const *p = a;
570 const char * const *q = b;
572 ok (a != b, "must never get the same pointer\n");
575 return lstrcmpA(*p, *q);
578 static void test_qsort_s(void)
580 int arr[5] = { 23, 42, 8, 4, 16 };
581 int arr2[5] = { 23, 42, 8, 4, 16 };
582 char carr[5] = { 42, 23, 4, 8, 16 };
583 const char *strarr[7] = {
594 win_skip("qsort_s not found\n");
598 SET_EXPECT(invalid_parameter_handler);
599 p_qsort_s(NULL, 0, 0, NULL, NULL);
600 CHECK_CALLED(invalid_parameter_handler);
602 SET_EXPECT(invalid_parameter_handler);
603 p_qsort_s(NULL, 0, 0, intcomparefunc, NULL);
604 CHECK_CALLED(invalid_parameter_handler);
606 SET_EXPECT(invalid_parameter_handler);
607 p_qsort_s(NULL, 0, sizeof(int), NULL, NULL);
608 CHECK_CALLED(invalid_parameter_handler);
610 SET_EXPECT(invalid_parameter_handler);
611 p_qsort_s(NULL, 1, sizeof(int), intcomparefunc, NULL);
612 CHECK_CALLED(invalid_parameter_handler);
614 g_qsort_s_context_counter = 0;
615 p_qsort_s(NULL, 0, sizeof(int), intcomparefunc, NULL);
616 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
618 /* overflow without side effects, other overflow values crash */
619 g_qsort_s_context_counter = 0;
620 p_qsort_s((void*)arr2, (((size_t)1) << (8*sizeof(size_t) - 1)) + 1, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
621 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
622 ok(arr2[0] == 23, "should remain unsorted, arr2[0] is %d\n", arr2[0]);
623 ok(arr2[1] == 42, "should remain unsorted, arr2[1] is %d\n", arr2[1]);
624 ok(arr2[2] == 8, "should remain unsorted, arr2[2] is %d\n", arr2[2]);
625 ok(arr2[3] == 4, "should remain unsorted, arr2[3] is %d\n", arr2[3]);
627 g_qsort_s_context_counter = 0;
628 p_qsort_s((void*)arr, 0, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
629 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
630 ok(arr[0] == 23, "badly sorted, nmemb=0, arr[0] is %d\n", arr[0]);
631 ok(arr[1] == 42, "badly sorted, nmemb=0, arr[1] is %d\n", arr[1]);
632 ok(arr[2] == 8, "badly sorted, nmemb=0, arr[2] is %d\n", arr[2]);
633 ok(arr[3] == 4, "badly sorted, nmemb=0, arr[3] is %d\n", arr[3]);
634 ok(arr[4] == 16, "badly sorted, nmemb=0, arr[4] is %d\n", arr[4]);
636 g_qsort_s_context_counter = 0;
637 p_qsort_s((void*)arr, 1, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
638 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
639 ok(arr[0] == 23, "badly sorted, nmemb=1, arr[0] is %d\n", arr[0]);
640 ok(arr[1] == 42, "badly sorted, nmemb=1, arr[1] is %d\n", arr[1]);
641 ok(arr[2] == 8, "badly sorted, nmemb=1, arr[2] is %d\n", arr[2]);
642 ok(arr[3] == 4, "badly sorted, nmemb=1, arr[3] is %d\n", arr[3]);
643 ok(arr[4] == 16, "badly sorted, nmemb=1, arr[4] is %d\n", arr[4]);
645 SET_EXPECT(invalid_parameter_handler);
646 g_qsort_s_context_counter = 0;
647 p_qsort_s((void*)arr, 5, 0, intcomparefunc, &g_qsort_s_context_counter);
648 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
649 ok(arr[0] == 23, "badly sorted, size=0, arr[0] is %d\n", arr[0]);
650 ok(arr[1] == 42, "badly sorted, size=0, arr[1] is %d\n", arr[1]);
651 ok(arr[2] == 8, "badly sorted, size=0, arr[2] is %d\n", arr[2]);
652 ok(arr[3] == 4, "badly sorted, size=0, arr[3] is %d\n", arr[3]);
653 ok(arr[4] == 16, "badly sorted, size=0, arr[4] is %d\n", arr[4]);
654 CHECK_CALLED(invalid_parameter_handler);
656 g_qsort_s_context_counter = 0;
657 p_qsort_s((void*)arr, 5, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
658 ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
659 ok(arr[0] == 4, "badly sorted, arr[0] is %d\n", arr[0]);
660 ok(arr[1] == 8, "badly sorted, arr[1] is %d\n", arr[1]);
661 ok(arr[2] == 16, "badly sorted, arr[2] is %d\n", arr[2]);
662 ok(arr[3] == 23, "badly sorted, arr[3] is %d\n", arr[3]);
663 ok(arr[4] == 42, "badly sorted, arr[4] is %d\n", arr[4]);
665 g_qsort_s_context_counter = 0;
666 p_qsort_s((void*)carr, 5, sizeof(char), charcomparefunc, &g_qsort_s_context_counter);
667 ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
668 ok(carr[0] == 4, "badly sorted, carr[0] is %d\n", carr[0]);
669 ok(carr[1] == 8, "badly sorted, carr[1] is %d\n", carr[1]);
670 ok(carr[2] == 16, "badly sorted, carr[2] is %d\n", carr[2]);
671 ok(carr[3] == 23, "badly sorted, carr[3] is %d\n", carr[3]);
672 ok(carr[4] == 42, "badly sorted, carr[4] is %d\n", carr[4]);
674 g_qsort_s_context_counter = 0;
675 p_qsort_s((void*)strarr, 7, sizeof(char*), strcomparefunc, &g_qsort_s_context_counter);
676 ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
677 ok(!strcmp(strarr[0],"!"), "badly sorted, strarr[0] is %s\n", strarr[0]);
678 ok(!strcmp(strarr[1],"."), "badly sorted, strarr[1] is %s\n", strarr[1]);
679 ok(!strcmp(strarr[2],"Hello"), "badly sorted, strarr[2] is %s\n", strarr[2]);
680 ok(!strcmp(strarr[3],"Hopefully"), "badly sorted, strarr[3] is %s\n", strarr[3]);
681 ok(!strcmp(strarr[4],"Sorted"), "badly sorted, strarr[4] is %s\n", strarr[4]);
682 ok(!strcmp(strarr[5],"Wine"), "badly sorted, strarr[5] is %s\n", strarr[5]);
683 ok(!strcmp(strarr[6],"World"), "badly sorted, strarr[6] is %s\n", strarr[6]);
686 static void test_controlfp_s(void)
693 win_skip("_controlfp_s not found\n");
697 SET_EXPECT(invalid_parameter_handler);
698 ret = p_controlfp_s( NULL, ~0, ~0 );
699 ok( ret == EINVAL, "wrong result %d\n", ret );
700 CHECK_CALLED(invalid_parameter_handler);
703 SET_EXPECT(invalid_parameter_handler);
704 ret = p_controlfp_s( &cur, ~0, ~0 );
705 ok( ret == EINVAL, "wrong result %d\n", ret );
706 ok( cur != 0xdeadbeef, "value not set\n" );
707 CHECK_CALLED(invalid_parameter_handler);
710 ret = p_controlfp_s( &cur, 0, 0 );
711 ok( !ret, "wrong result %d\n", ret );
712 ok( cur != 0xdeadbeef, "value not set\n" );
714 SET_EXPECT(invalid_parameter_handler);
716 ret = p_controlfp_s( &cur, 0x80000000, 0x80000000 );
717 ok( ret == EINVAL, "wrong result %d\n", ret );
718 ok( cur != 0xdeadbeef, "value not set\n" );
719 CHECK_CALLED(invalid_parameter_handler);
722 /* mask is only checked when setting invalid bits */
723 ret = p_controlfp_s( &cur, 0, 0x80000000 );
724 ok( !ret, "wrong result %d\n", ret );
725 ok( cur != 0xdeadbeef, "value not set\n" );
735 static const _atoflt_test _atoflt_testdata[] = {
737 { "-13.721", -13.721, 0 },
739 { ".21e12", 0.21e12, 0 },
740 { "214353e-3", 214.353, 0 },
741 { "1d9999999999999999999", 0.0, _OVERFLOW },
743 /* more significant digits */
744 { "1.23456789", 1.23456789, 0 },
745 { "1.23456789e1", 12.3456789, 0 },
746 { "1e39", 0.0, _OVERFLOW },
747 { "1e-39", 0.0, _UNDERFLOW },
751 static void test__atoflt(void)
758 win_skip("_atoflt not found\n");
764 /* crashes on native */
765 p_atoflt(NULL, NULL);
766 p_atoflt(NULL, (char*)_atoflt_testdata[0].str);
767 p_atoflt(&flt, NULL);
770 while (_atoflt_testdata[i].str)
772 ret = p_atoflt(&flt, (char*)_atoflt_testdata[i].str);
773 ok(ret == _atoflt_testdata[i].ret, "got ret %d, expected ret %d, for %s\n", ret,
774 _atoflt_testdata[i].ret, _atoflt_testdata[i].str);
777 ok(almost_equal_f(flt.f, _atoflt_testdata[i].flt), "got %f, expected %f, for %s\n", flt.f,
778 _atoflt_testdata[i].flt, _atoflt_testdata[i].str);
784 static void test__set_abort_behavior(void)
788 if (!p_set_abort_behavior)
790 win_skip("_set_abort_behavior not found\n");
794 /* default is _WRITE_ABORT_MSG | _CALL_REPORTFAULT */
795 res = p_set_abort_behavior(0, 0);
796 ok (res == (_WRITE_ABORT_MSG | _CALL_REPORTFAULT),
797 "got 0x%x (expected 0x%x)\n", res, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
799 /* no internal mask */
800 p_set_abort_behavior(0xffffffff, 0xffffffff);
801 res = p_set_abort_behavior(0, 0);
802 ok (res == 0xffffffff, "got 0x%x (expected 0x%x)\n", res, 0xffffffff);
804 /* set to default value */
805 p_set_abort_behavior(_WRITE_ABORT_MSG | _CALL_REPORTFAULT, 0xffffffff);
808 static void test__sopen_s(void)
814 win_skip("_sopen_s not found\n");
818 SET_EXPECT(invalid_parameter_handler);
819 ret = p_sopen_s(NULL, "test", _O_RDONLY, _SH_DENYNO, _S_IREAD);
820 ok(ret == EINVAL, "got %d, expected EINVAL\n", ret);
821 CHECK_CALLED(invalid_parameter_handler);
824 ret = p_sopen_s(&fd, "test", _O_RDONLY, _SH_DENYNO, _S_IREAD);
825 ok(ret == ENOENT, "got %d, expected ENOENT\n", ret);
826 ok(fd == -1, "got %d\n", fd);
829 static void test__wsopen_s(void)
831 wchar_t testW[] = {'t','e','s','t',0};
836 win_skip("_wsopen_s not found\n");
840 SET_EXPECT(invalid_parameter_handler);
841 ret = p_wsopen_s(NULL, testW, _O_RDONLY, _SH_DENYNO, _S_IREAD);
842 ok(ret == EINVAL, "got %d, expected EINVAL\n", ret);
843 CHECK_CALLED(invalid_parameter_handler);
846 ret = p_wsopen_s(&fd, testW, _O_RDONLY, _SH_DENYNO, _S_IREAD);
847 ok(ret == ENOENT, "got %d, expected ENOENT\n", ret);
848 ok(fd == -1, "got %d\n", fd);
851 static void test__realloc_crt(void)
857 win_skip("_realloc_crt not found\n");
863 /* crashes on some systems starting Vista */
864 p_realloc_crt(NULL, 10);
868 ok(mem != NULL, "memory not allocated\n");
870 mem = p_realloc_crt(mem, 20);
871 ok(mem != NULL, "memory not reallocated\n");
873 mem = p_realloc_crt(mem, 0);
874 ok(mem == NULL, "memory not freed\n");
876 mem = p_realloc_crt(NULL, 0);
877 ok(mem != NULL, "memory not (re)allocated for size 0\n");
881 static void test_typeinfo(void)
883 static type_info t1 = { NULL, NULL,{'.','?','A','V','t','e','s','t','1','@','@',0,0,0,0,0 } };
884 struct __type_info_node node;
887 if (!p_type_info_name_internal_method)
889 win_skip("public: char const * __thiscall type_info::_name_internal_method(struct \
890 __type_info_node *)const not supported\n");
898 name = call_func2(p_type_info_name_internal_method, &t1, &node);
899 ok(name != NULL, "got %p\n", name);
900 ok(name && t1.name && !strcmp(name, t1.name), "bad name '%s' for t1\n", name);
902 ok(t1.name && !strcmp(t1.name, "class test1"), "demangled to '%s' for t1\n", t1.name);
903 call_func1(ptype_info_dtor, &t1);
911 SetLastError(0xdeadbeef);
912 hcrt = LoadLibraryA("msvcr90.dll");
914 win_skip("msvcr90.dll not installed (got %d)\n", GetLastError());
918 p_set_invalid_parameter_handler = (void *) GetProcAddress(hcrt, "_set_invalid_parameter_handler");
919 if(p_set_invalid_parameter_handler)
920 ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
921 "Invalid parameter handler was already set\n");
923 p_initterm_e = (void *) GetProcAddress(hcrt, "_initterm_e");
924 p_encode_pointer = (void *) GetProcAddress(hcrt, "_encode_pointer");
925 p_decode_pointer = (void *) GetProcAddress(hcrt, "_decode_pointer");
926 p_encoded_null = (void *) GetProcAddress(hcrt, "_encoded_null");
927 p_sys_nerr = (void *) GetProcAddress(hcrt, "_sys_nerr");
928 p__sys_nerr = (void *) GetProcAddress(hcrt, "__sys_nerr");
929 p_sys_errlist = (void *) GetProcAddress(hcrt, "_sys_errlist");
930 p__sys_errlist = (void *) GetProcAddress(hcrt, "__sys_errlist");
931 p_strtoi64 = (void *) GetProcAddress(hcrt, "_strtoi64");
932 p_strtoui64 = (void *) GetProcAddress(hcrt, "_strtoui64");
933 p_itoa_s = (void *)GetProcAddress(hcrt, "_itoa_s");
934 p_wcsncat_s = (void *)GetProcAddress( hcrt,"wcsncat_s" );
935 p_qsort_s = (void *) GetProcAddress(hcrt, "qsort_s");
936 p_controlfp_s = (void *) GetProcAddress(hcrt, "_controlfp_s");
937 p_atoflt = (void* )GetProcAddress(hcrt, "_atoflt");
938 p_set_abort_behavior = (void *) GetProcAddress(hcrt, "_set_abort_behavior");
939 p_sopen_s = (void*) GetProcAddress(hcrt, "_sopen_s");
940 p_wsopen_s = (void*) GetProcAddress(hcrt, "_wsopen_s");
941 p_realloc_crt = (void*) GetProcAddress(hcrt, "_realloc_crt");
942 p_malloc = (void*) GetProcAddress(hcrt, "malloc");
943 p_free = (void*)GetProcAddress(hcrt, "free");
944 if (sizeof(void *) == 8)
946 p_type_info_name_internal_method = (void*)GetProcAddress(hcrt,
947 "?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z");
948 ptype_info_dtor = (void*)GetProcAddress(hcrt, "??1type_info@@UEAA@XZ");
952 p_type_info_name_internal_method = (void*)GetProcAddress(hcrt,
953 "?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z");
954 ptype_info_dtor = (void*)GetProcAddress(hcrt, "??1type_info@@UAE@XZ");
957 hkernel32 = GetModuleHandleA("kernel32.dll");
958 pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
961 test__encode_pointer();
962 test_error_messages();
969 test__set_abort_behavior();