mmdevapi/tests: Add tests for IAudioClient::GetCurrentPadding.
[wine] / dlls / msvcr90 / tests / msvcr90.c
1 /*
2  * Copyright 2010 Detlef Riekenberg
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <fcntl.h>
24 #include <share.h>
25 #include <sys/stat.h>
26
27 #include <windef.h>
28 #include <winbase.h>
29 #include <errno.h>
30 #include "wine/test.h"
31
32 #define DEFINE_EXPECT(func) \
33     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
34
35 #define SET_EXPECT(func) \
36     expect_ ## func = TRUE
37
38 #define CHECK_EXPECT2(func) \
39     do { \
40         ok(expect_ ##func, "unexpected call " #func "\n"); \
41         called_ ## func = TRUE; \
42     }while(0)
43
44 #define CHECK_EXPECT(func) \
45     do { \
46         CHECK_EXPECT2(func); \
47         expect_ ## func = FALSE; \
48     }while(0)
49
50 #define CHECK_CALLED(func) \
51     do { \
52         ok(called_ ## func, "expected " #func "\n"); \
53         expect_ ## func = called_ ## func = FALSE; \
54     }while(0)
55
56 DEFINE_EXPECT(invalid_parameter_handler);
57
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*);
81
82 /* type info */
83 typedef struct __type_info
84 {
85   void *vtable;
86   char *name;
87   char  mangled[16];
88 } type_info;
89
90
91 struct __type_info_node
92 {
93     void *memPtr;
94     struct __type_info_node* next;
95 };
96
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*);
99
100 static void* (WINAPI *pEncodePointer)(void *);
101
102 static int cb_called[4];
103 static int g_qsort_s_context_counter;
104
105 static inline int almost_equal_f(float f1, float f2)
106 {
107     return f1-f2 > -1e-30 && f1-f2 < 1e-30;
108 }
109
110 /* ########## */
111
112 /* thiscall emulation */
113 /* Emulate a __thiscall */
114 #ifdef __i386__
115 #ifdef _MSC_VER
116 static inline void* do_call_func1(void *func, void *_this)
117 {
118   volatile void* retval = 0;
119   __asm
120   {
121     push ecx
122     mov ecx, _this
123     call func
124     mov retval, eax
125     pop ecx
126   }
127   return (void*)retval;
128 }
129
130 static inline void* do_call_func2(void *func, void *_this, const void* arg)
131 {
132   volatile void* retval = 0;
133   __asm
134   {
135     push ecx
136     push arg
137     mov ecx, _this
138     call func
139     mov retval, eax
140     pop ecx
141   }
142   return (void*)retval;
143 }
144 #else
145 static void* do_call_func1(void *func, void *_this)
146 {
147   void *ret, *dummy;
148   __asm__ __volatile__ ("call *%2"
149                         : "=a" (ret), "=c" (dummy)
150                         : "g" (func), "1" (_this)
151                         : "edx", "memory" );
152   return ret;
153 }
154
155 static void* do_call_func2(void *func, void *_this, const void* arg)
156 {
157   void *ret, *dummy;
158   __asm__ __volatile__ ("pushl %3\n\tcall *%2"
159                         : "=a" (ret), "=c" (dummy)
160                         : "r" (func), "r" (arg), "1" (_this)
161                         : "edx", "memory" );
162   return ret;
163 }
164 #endif
165
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)
168
169 #else
170
171 #define call_func1(func,_this) func(_this)
172 #define call_func2(func,_this,a) func(_this,a)
173
174 #endif /* __i386__ */
175
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)
179 {
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);
186 }
187
188 static int __cdecl initterm_cb0(void)
189 {
190     cb_called[0]++;
191     return 0;
192 }
193
194 static int __cdecl initterm_cb1(void)
195 {
196     cb_called[1]++;
197     return 1;
198 }
199
200 static int __cdecl initterm_cb2(void)
201 {
202     cb_called[2]++;
203     return 2;
204 }
205
206
207 static void test__initterm_e(void)
208 {
209     _INITTERM_E_FN table[4];
210     int res;
211
212     if (!p_initterm_e) {
213         skip("_initterm_e not found\n");
214         return;
215     }
216
217     memset(table, 0, sizeof(table));
218
219     memset(cb_called, 0, sizeof(cb_called));
220     errno = 0xdeadbeef;
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]);
225
226     memset(cb_called, 0, sizeof(cb_called));
227     errno = 0xdeadbeef;
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]);
232
233     if (0) {
234         /* this crash on Windows */
235         errno = 0xdeadbeef;
236         res = p_initterm_e(NULL, table);
237         trace("got %d with 0x%x\n", res, errno);
238     }
239
240     table[0] = initterm_cb0;
241     memset(cb_called, 0, sizeof(cb_called));
242     errno = 0xdeadbeef;
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]);
247
248
249     /* init-function returning failure */
250     table[1] = initterm_cb1;
251     memset(cb_called, 0, sizeof(cb_called));
252     errno = 0xdeadbeef;
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]);
257
258     /* init-function not called, when end < start */
259     memset(cb_called, 0, sizeof(cb_called));
260     errno = 0xdeadbeef;
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]);
265
266     /* initialization stop after first non-zero result */
267     table[2] = initterm_cb0;
268     memset(cb_called, 0, sizeof(cb_called));
269     errno = 0xdeadbeef;
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]);
274
275     /* NULL pointer in the array are skipped */
276     table[1] = NULL;
277     table[2] = initterm_cb2;
278     memset(cb_called, 0, sizeof(cb_called));
279     errno = 0xdeadbeef;
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]);
284
285 }
286
287 /* Beware that _encode_pointer is a NOP before XP
288    (the parameter is returned unchanged) */
289 static void test__encode_pointer(void)
290 {
291     void *ptr, *res;
292
293     if(!p_encode_pointer || !p_decode_pointer || !p_encoded_null) {
294         win_skip("_encode_pointer, _decode_pointer or _encoded_null not found\n");
295         return;
296     }
297
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");
302
303     ok(p_encoded_null() == p_encode_pointer(NULL), "Error encoding null\n");
304
305     ptr = p_encode_pointer(p_encode_pointer);
306     ok(p_decode_pointer(ptr) == p_encode_pointer, "Error decoding pointer\n");
307
308     /* Not present before XP */
309     if (!pEncodePointer) {
310         win_skip("EncodePointer not found\n");
311         return;
312     }
313
314     res = pEncodePointer(p_encode_pointer);
315     ok(ptr == res, "_encode_pointer produced different result than EncodePointer\n");
316
317 }
318
319 static void test_error_messages(void)
320 {
321     int *size, size_copy;
322
323     if(!p_sys_nerr || !p__sys_nerr || !p_sys_errlist || !p__sys_errlist) {
324         win_skip("Skipping test_error_messages tests\n");
325         return;
326     }
327
328     size = p__sys_nerr();
329     size_copy = *size;
330     ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
331
332     *size = 20;
333     ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
334
335     *size = size_copy;
336
337     ok(*p_sys_errlist == *(p__sys_errlist()), "p_sys_errlist != p__sys_errlist()\n");
338 }
339
340 static void test__strtoi64(void)
341 {
342     __int64 res;
343     unsigned __int64 ures;
344
345     if(!p_strtoi64 || !p_strtoui64) {
346         win_skip("_strtoi64 or _strtoui64 not found\n");
347         return;
348     }
349
350     if(!p_set_invalid_parameter_handler) {
351         win_skip("_set_invalid_parameter_handler not found\n");
352         return;
353     }
354
355     errno = 0xdeadbeef;
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);
360
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);
365
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);
370
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);
375
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);
380
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);
386 }
387
388 static void test__itoa_s(void)
389 {
390     errno_t ret;
391     char buffer[33];
392
393     if (!p_itoa_s)
394     {
395         win_skip("Skipping _itoa_s tests\n");
396         return;
397     }
398
399     if(!p_set_invalid_parameter_handler) {
400         win_skip("_set_invalid_parameter_handler not found\n");
401         return;
402     }
403
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
406      * isn't changed
407      */
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);
412
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);
419
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);
426
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);
433
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);
441
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);
449
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);
457
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",
462        buffer);
463
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",
468        buffer);
469
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",
474        buffer);
475
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",
480        buffer);
481
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",
486        buffer);
487 }
488
489 static void test_wcsncat_s(void)
490 {
491     static wchar_t abcW[] = {'a','b','c',0};
492     int ret;
493     wchar_t dst[4];
494     wchar_t src[4];
495
496     if (!p_wcsncat_s)
497     {
498         win_skip("skipping wcsncat_s tests\n");
499         return;
500     }
501
502     if(!p_set_invalid_parameter_handler) {
503         win_skip("_set_invalid_parameter_handler not found\n");
504         return;
505     }
506
507     memcpy(src, abcW, sizeof(abcW));
508     dst[0] = 0;
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);
513
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);
518
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);
523
524     ret = p_wcsncat_s(dst, 4, NULL, 0);
525     ok(ret == 0, "err = %d\n", ret);
526
527     dst[0] = 0;
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);
532
533     dst[0] = 0;
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));
537
538     memcpy(dst, abcW, sizeof(abcW));
539     dst[3] = 'd';
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);
544 }
545
546 /* Based on dlls/ntdll/tests/string.c */
547 static __cdecl int intcomparefunc(void *context, const void *a, const void *b)
548 {
549     const int *p = a, *q = b;
550
551     ok (a != b, "must never get the same pointer\n");
552     ++*(int *) context;
553
554     return *p - *q;
555 }
556
557 static __cdecl int charcomparefunc(void *context, const void *a, const void *b)
558 {
559     const char *p = a, *q = b;
560
561     ok (a != b, "must never get the same pointer\n");
562     ++*(int *) context;
563
564     return *p - *q;
565 }
566
567 static __cdecl int strcomparefunc(void *context, const void *a, const void *b)
568 {
569     const char * const *p = a;
570     const char * const *q = b;
571
572     ok (a != b, "must never get the same pointer\n");
573     ++*(int *) context;
574
575     return lstrcmpA(*p, *q);
576 }
577
578 static void test_qsort_s(void)
579 {
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] = {
584     "Hello",
585     "Wine",
586     "World",
587     "!",
588     "Hopefully",
589     "Sorted",
590     "."
591     };
592
593     if(!p_qsort_s) {
594         win_skip("qsort_s not found\n");
595         return;
596     }
597
598     SET_EXPECT(invalid_parameter_handler);
599     p_qsort_s(NULL, 0, 0, NULL, NULL);
600     CHECK_CALLED(invalid_parameter_handler);
601
602     SET_EXPECT(invalid_parameter_handler);
603     p_qsort_s(NULL, 0, 0, intcomparefunc, NULL);
604     CHECK_CALLED(invalid_parameter_handler);
605
606     SET_EXPECT(invalid_parameter_handler);
607     p_qsort_s(NULL, 0, sizeof(int), NULL, NULL);
608     CHECK_CALLED(invalid_parameter_handler);
609
610     SET_EXPECT(invalid_parameter_handler);
611     p_qsort_s(NULL, 1, sizeof(int), intcomparefunc, NULL);
612     CHECK_CALLED(invalid_parameter_handler);
613
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");
617
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]);
626
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]);
635
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]);
644
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);
655
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]);
664
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]);
673
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]);
684 }
685
686 static void test_controlfp_s(void)
687 {
688     unsigned int cur;
689     int ret;
690
691     if (!p_controlfp_s)
692     {
693         win_skip("_controlfp_s not found\n");
694         return;
695     }
696
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);
701
702     cur = 0xdeadbeef;
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);
708
709     cur = 0xdeadbeef;
710     ret = p_controlfp_s( &cur, 0, 0 );
711     ok( !ret, "wrong result %d\n", ret );
712     ok( cur != 0xdeadbeef, "value not set\n" );
713
714     SET_EXPECT(invalid_parameter_handler);
715     cur = 0xdeadbeef;
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);
720
721     cur = 0xdeadbeef;
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" );
726 }
727
728 typedef struct
729 {
730     const char *str;
731     float flt;
732     int ret;
733 } _atoflt_test;
734
735 static const _atoflt_test _atoflt_testdata[] = {
736     { "12.1", 12.1, 0 },
737     { "-13.721", -13.721, 0 },
738     { "INF", 0.0, 0 },
739     { ".21e12", 0.21e12, 0 },
740     { "214353e-3", 214.353, 0 },
741     { "1d9999999999999999999", 0.0, _OVERFLOW },
742     { "  d10", 0.0, 0 },
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 },
748     { NULL }
749 };
750
751 static void test__atoflt(void)
752 {
753     _CRT_FLOAT flt;
754     int ret, i = 0;
755
756     if (!p_atoflt)
757     {
758         win_skip("_atoflt not found\n");
759         return;
760     }
761
762 if (0)
763 {
764     /* crashes on native */
765     p_atoflt(NULL, NULL);
766     p_atoflt(NULL, (char*)_atoflt_testdata[0].str);
767     p_atoflt(&flt, NULL);
768 }
769
770     while (_atoflt_testdata[i].str)
771     {
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);
775
776         if (ret == 0)
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);
779
780         i++;
781     }
782 }
783
784 static void test__set_abort_behavior(void)
785 {
786     unsigned int res;
787
788     if (!p_set_abort_behavior)
789     {
790         win_skip("_set_abort_behavior not found\n");
791         return;
792     }
793
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);
798
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);
803
804     /* set to default value */
805     p_set_abort_behavior(_WRITE_ABORT_MSG | _CALL_REPORTFAULT, 0xffffffff);
806 }
807
808 static void test__sopen_s(void)
809 {
810     int ret, fd;
811
812     if(!p_sopen_s)
813     {
814         win_skip("_sopen_s not found\n");
815         return;
816     }
817
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);
822
823     fd = 0xdead;
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);
827 }
828
829 static void test__wsopen_s(void)
830 {
831     wchar_t testW[] = {'t','e','s','t',0};
832     int ret, fd;
833
834     if(!p_wsopen_s)
835     {
836         win_skip("_wsopen_s not found\n");
837         return;
838     }
839
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);
844
845     fd = 0xdead;
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);
849 }
850
851 static void test__realloc_crt(void)
852 {
853     void *mem;
854
855     if(!p_realloc_crt)
856     {
857         win_skip("_realloc_crt not found\n");
858         return;
859     }
860
861 if (0)
862 {
863     /* crashes on some systems starting Vista */
864     p_realloc_crt(NULL, 10);
865 }
866
867     mem = p_malloc(10);
868     ok(mem != NULL, "memory not allocated\n");
869
870     mem = p_realloc_crt(mem, 20);
871     ok(mem != NULL, "memory not reallocated\n");
872
873     mem = p_realloc_crt(mem, 0);
874     ok(mem == NULL, "memory not freed\n");
875
876     mem = p_realloc_crt(NULL, 0);
877     ok(mem != NULL, "memory not (re)allocated for size 0\n");
878     p_free(mem);
879 }
880
881 static void test_typeinfo(void)
882 {
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;
885     char *name;
886
887     if (!p_type_info_name_internal_method)
888     {
889         win_skip("public: char const * __thiscall type_info::_name_internal_method(struct \
890                   __type_info_node *)const not supported\n");
891         return;
892     }
893
894     /* name */
895     t1.name = NULL;
896     node.memPtr = NULL;
897     node.next = NULL;
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);
901
902     ok(t1.name && !strcmp(t1.name, "class test1"), "demangled to '%s' for t1\n", t1.name);
903     call_func1(ptype_info_dtor, &t1);
904 }
905
906 START_TEST(msvcr90)
907 {
908     HMODULE hcrt;
909     HMODULE hkernel32;
910
911     SetLastError(0xdeadbeef);
912     hcrt = LoadLibraryA("msvcr90.dll");
913     if (!hcrt) {
914         win_skip("msvcr90.dll not installed (got %d)\n", GetLastError());
915         return;
916     }
917
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");
922
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)
945     {
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");
949     }
950     else
951     {
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");
955     }
956
957     hkernel32 = GetModuleHandleA("kernel32.dll");
958     pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
959
960     test__initterm_e();
961     test__encode_pointer();
962     test_error_messages();
963     test__strtoi64();
964     test__itoa_s();
965     test_wcsncat_s();
966     test_qsort_s();
967     test_controlfp_s();
968     test__atoflt();
969     test__set_abort_behavior();
970     test__sopen_s();
971     test__wsopen_s();
972     test__realloc_crt();
973     test_typeinfo();
974 }