Add AppDefaults app selection to control panel
[wine/gsoc-2012-control.git] / dlls / msvcr90 / tests / msvcr90.c
blobce8fe693d69e5ebe254aa2cb26ef008e3f30d154
1 /*
2 * Copyright 2010 Detlef Riekenberg
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <fcntl.h>
24 #include <share.h>
25 #include <sys/stat.h>
26 #include <time.h>
27 #include <locale.h>
29 #include <windef.h>
30 #include <winbase.h>
31 #include <errno.h>
32 #include "wine/test.h"
34 #define DEFINE_EXPECT(func) \
35 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
37 #define SET_EXPECT(func) \
38 do { \
39 expect_ ## func = TRUE; \
40 errno = 0xdeadbeef; \
41 }while(0)
43 #define CHECK_EXPECT2(func) \
44 do { \
45 ok(expect_ ##func, "unexpected call " #func "\n"); \
46 called_ ## func = TRUE; \
47 }while(0)
49 #define CHECK_EXPECT(func) \
50 do { \
51 CHECK_EXPECT2(func); \
52 expect_ ## func = FALSE; \
53 }while(0)
55 #define CHECK_CALLED(func,error) \
56 do { \
57 ok(called_ ## func, "expected " #func "\n"); \
58 ok( errno == (error), "got errno %u instead of %u\n", errno, (error) ); \
59 expect_ ## func = called_ ## func = FALSE; \
60 }while(0)
62 DEFINE_EXPECT(invalid_parameter_handler);
64 static _invalid_parameter_handler (__cdecl *p_set_invalid_parameter_handler)(_invalid_parameter_handler);
65 typedef int (__cdecl *_INITTERM_E_FN)(void);
66 static int (__cdecl *p_initterm_e)(_INITTERM_E_FN *table, _INITTERM_E_FN *end);
67 static void* (__cdecl *p_encode_pointer)(void *);
68 static void* (__cdecl *p_decode_pointer)(void *);
69 static void* (__cdecl *p_encoded_null)(void);
70 static int *p_sys_nerr;
71 static int* (__cdecl *p__sys_nerr)(void);
72 static char **p_sys_errlist;
73 static char** (__cdecl *p__sys_errlist)(void);
74 static __int64 (__cdecl *p_strtoi64)(const char *, char **, int);
75 static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int);
76 static errno_t (__cdecl *p_itoa_s)(int,char*,size_t,int);
77 static int (__cdecl *p_wcsncat_s)(wchar_t *dst, size_t elem, const wchar_t *src, size_t count);
78 static void (__cdecl *p_qsort_s)(void *, size_t, size_t, int (__cdecl *)(void *, const void *, const void *), void *);
79 static void* (__cdecl *p_bsearch_s)(const void *, const void *, size_t, size_t,
80 int (__cdecl *compare)(void *, const void *, const void *), void *);
81 static int (__cdecl *p_controlfp_s)(unsigned int *, unsigned int, unsigned int);
82 static int (__cdecl *p_tmpfile_s)(FILE**);
83 static int (__cdecl *p_atoflt)(_CRT_FLOAT *, char *);
84 static unsigned int (__cdecl *p_set_abort_behavior)(unsigned int, unsigned int);
85 static int (__cdecl *p_sopen_s)(int*, const char*, int, int, int);
86 static int (__cdecl *p_wsopen_s)(int*, const wchar_t*, int, int, int);
87 static void* (__cdecl *p_realloc_crt)(void*, size_t);
88 static void* (__cdecl *p_malloc)(size_t);
89 static void (__cdecl *p_free)(void*);
90 static void* (__cdecl *p_getptd)(void);
91 static int* (__cdecl *p_errno)(void);
92 static __msvcrt_ulong* (__cdecl *p_doserrno)(void);
93 static void (__cdecl *p_srand)(unsigned int);
94 static char* (__cdecl *p_strtok)(char*, const char*);
95 static wchar_t* (__cdecl *p_wcstok)(wchar_t*, const wchar_t*);
96 static char* (__cdecl *p_strerror)(int);
97 static wchar_t* (__cdecl *p_wcserror)(int);
98 static char* (__cdecl *p_tmpnam)(char*);
99 static wchar_t* (__cdecl *p_wtmpnam)(wchar_t*);
100 static char* (__cdecl *p_asctime)(struct tm*);
101 static wchar_t* (__cdecl *p_wasctime)(struct tm*);
102 static struct tm* (__cdecl *p_localtime64)(__time64_t*);
103 static char* (__cdecl *p_ecvt)(double, int, int*, int*);
104 static int* (__cdecl *p_fpecode)(void);
105 static int (__cdecl *p_configthreadlocale)(int);
106 static void* (__cdecl *p_get_terminate)(void);
107 static void* (__cdecl *p_get_unexpected)(void);
108 static int (__cdecl *p__vswprintf_l)(wchar_t*, const wchar_t*, _locale_t, __ms_va_list);
109 static int (__cdecl *p_vswprintf_l)(wchar_t*, const wchar_t*, _locale_t, __ms_va_list);
110 static FILE* (__cdecl *p_fopen)(const char*, const char*);
111 static int (__cdecl *p_fclose)(FILE*);
112 static int (__cdecl *p_unlink)(const char*);
113 static void (__cdecl *p_lock_file)(FILE*);
114 static void (__cdecl *p_unlock_file)(FILE*);
115 static int (__cdecl *p_fileno)(FILE*);
116 static int (__cdecl *p_feof)(FILE*);
117 static int (__cdecl *p_ferror)(FILE*);
118 static int (__cdecl *p_flsbuf)(int, FILE*);
119 static unsigned long (__cdecl *p_byteswap_ulong)(unsigned long);
121 /* make sure we use the correct errno */
122 #undef errno
123 #define errno (*p_errno())
125 /* type info */
126 typedef struct __type_info
128 void *vtable;
129 char *name;
130 char mangled[16];
131 } type_info;
134 struct __type_info_node
136 void *memPtr;
137 struct __type_info_node* next;
140 static char* (WINAPI *p_type_info_name_internal_method)(type_info*, struct __type_info_node *);
141 static void (WINAPI *ptype_info_dtor)(type_info*);
143 static void* (WINAPI *pEncodePointer)(void *);
145 static int cb_called[4];
146 static int g_qsort_s_context_counter;
147 static int g_bsearch_s_context_counter;
149 static inline int almost_equal_f(float f1, float f2)
151 return f1-f2 > -1e-30 && f1-f2 < 1e-30;
154 /* ########## */
156 /* thiscall emulation */
157 /* Emulate a __thiscall */
158 #ifdef __i386__
159 #ifdef _MSC_VER
160 static inline void* do_call_func1(void *func, void *_this)
162 volatile void* retval = 0;
163 __asm
165 push ecx
166 mov ecx, _this
167 call func
168 mov retval, eax
169 pop ecx
171 return (void*)retval;
174 static inline void* do_call_func2(void *func, void *_this, const void* arg)
176 volatile void* retval = 0;
177 __asm
179 push ecx
180 push arg
181 mov ecx, _this
182 call func
183 mov retval, eax
184 pop ecx
186 return (void*)retval;
188 #else
189 static void* do_call_func1(void *func, void *_this)
191 void *ret, *dummy;
192 __asm__ __volatile__ ("call *%2"
193 : "=a" (ret), "=c" (dummy)
194 : "g" (func), "1" (_this)
195 : "edx", "memory" );
196 return ret;
199 static void* do_call_func2(void *func, void *_this, const void* arg)
201 void *ret, *dummy;
202 __asm__ __volatile__ ("pushl %3\n\tcall *%2"
203 : "=a" (ret), "=c" (dummy)
204 : "r" (func), "r" (arg), "1" (_this)
205 : "edx", "memory" );
206 return ret;
208 #endif
210 #define call_func1(func,_this) do_call_func1(func,_this)
211 #define call_func2(func,_this,a) do_call_func2(func,_this,(const void*)a)
213 #else
215 #define call_func1(func,_this) func(_this)
216 #define call_func2(func,_this,a) func(_this,a)
218 #endif /* __i386__ */
220 static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
221 const wchar_t *function, const wchar_t *file,
222 unsigned line, uintptr_t arg)
224 CHECK_EXPECT(invalid_parameter_handler);
225 ok(expression == NULL, "expression is not NULL\n");
226 ok(function == NULL, "function is not NULL\n");
227 ok(file == NULL, "file is not NULL\n");
228 ok(line == 0, "line = %u\n", line);
229 ok(arg == 0, "arg = %lx\n", (UINT_PTR)arg);
230 ok(errno != 0xdeadbeef, "errno not set\n");
233 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hcrt,y)
234 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
235 static BOOL init(void)
237 HMODULE hcrt;
238 HMODULE hkernel32;
240 SetLastError(0xdeadbeef);
241 hcrt = LoadLibraryA("msvcr90.dll");
242 if (!hcrt) {
243 win_skip("msvcr90.dll not installed (got %d)\n", GetLastError());
244 return FALSE;
247 SET(p_set_invalid_parameter_handler, "_set_invalid_parameter_handler");
248 if(p_set_invalid_parameter_handler)
249 ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
250 "Invalid parameter handler was already set\n");
252 SET(p_initterm_e, "_initterm_e");
253 SET(p_encode_pointer, "_encode_pointer");
254 SET(p_decode_pointer, "_decode_pointer");
255 SET(p_encoded_null, "_encoded_null");
256 SET(p_sys_nerr, "_sys_nerr");
257 SET(p__sys_nerr, "__sys_nerr");
258 SET(p_sys_errlist, "_sys_errlist");
259 SET(p__sys_errlist, "__sys_errlist");
260 SET(p_strtoi64, "_strtoi64");
261 SET(p_strtoui64, "_strtoui64");
262 SET(p_itoa_s, "_itoa_s");
263 SET(p_wcsncat_s,"wcsncat_s" );
264 SET(p_qsort_s, "qsort_s");
265 SET(p_bsearch_s, "bsearch_s");
266 SET(p_controlfp_s, "_controlfp_s");
267 SET(p_tmpfile_s, "tmpfile_s");
268 SET(p_atoflt, "_atoflt");
269 SET(p_set_abort_behavior, "_set_abort_behavior");
270 SET(p_sopen_s, "_sopen_s");
271 SET(p_wsopen_s, "_wsopen_s");
272 SET(p_realloc_crt, "_realloc_crt");
273 SET(p_malloc, "malloc");
274 SET(p_free, "free");
275 SET(p_getptd, "_getptd");
276 SET(p_errno, "_errno");
277 SET(p_doserrno, "__doserrno");
278 SET(p_srand, "srand");
279 SET(p_strtok, "strtok");
280 SET(p_wcstok, "wcstok");
281 SET(p_strerror, "strerror");
282 SET(p_wcserror, "_wcserror");
283 SET(p_tmpnam, "tmpnam");
284 SET(p_wtmpnam, "_wtmpnam");
285 SET(p_asctime, "asctime");
286 SET(p_wasctime, "_wasctime");
287 SET(p_localtime64, "_localtime64");
288 SET(p_ecvt, "_ecvt");
289 SET(p_fpecode, "__fpecode");
290 SET(p_configthreadlocale, "_configthreadlocale");
291 SET(p_get_terminate, "_get_terminate");
292 SET(p_get_unexpected, "_get_unexpected");
293 SET(p__vswprintf_l, "__vswprintf_l");
294 SET(p_vswprintf_l, "_vswprintf_l");
295 SET(p_fopen, "fopen");
296 SET(p_fclose, "fclose");
297 SET(p_unlink, "_unlink");
298 SET(p_lock_file, "_lock_file");
299 SET(p_unlock_file, "_unlock_file");
300 SET(p_fileno, "_fileno");
301 SET(p_feof, "feof");
302 SET(p_ferror, "ferror");
303 SET(p_flsbuf, "_flsbuf");
304 SET(p_byteswap_ulong, "_byteswap_ulong");
305 if (sizeof(void *) == 8)
307 SET(p_type_info_name_internal_method, "?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z");
308 SET(ptype_info_dtor, "??1type_info@@UEAA@XZ");
310 else
312 SET(p_type_info_name_internal_method, "?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z");
313 SET(ptype_info_dtor, "??1type_info@@UAE@XZ");
316 hkernel32 = GetModuleHandleA("kernel32.dll");
317 pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
318 return TRUE;
321 static int __cdecl initterm_cb0(void)
323 cb_called[0]++;
324 return 0;
327 static int __cdecl initterm_cb1(void)
329 cb_called[1]++;
330 return 1;
333 static int __cdecl initterm_cb2(void)
335 cb_called[2]++;
336 return 2;
340 static void test__initterm_e(void)
342 _INITTERM_E_FN table[4];
343 int res;
345 memset(table, 0, sizeof(table));
347 memset(cb_called, 0, sizeof(cb_called));
348 errno = 0xdeadbeef;
349 res = p_initterm_e(table, table);
350 ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
351 "got %d with 0x%x {%d, %d, %d}\n",
352 res, errno, cb_called[0], cb_called[1], cb_called[2]);
354 memset(cb_called, 0, sizeof(cb_called));
355 errno = 0xdeadbeef;
356 res = p_initterm_e(table, NULL);
357 ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
358 "got %d with 0x%x {%d, %d, %d}\n",
359 res, errno, cb_called[0], cb_called[1], cb_called[2]);
361 if (0) {
362 /* this crash on Windows */
363 errno = 0xdeadbeef;
364 res = p_initterm_e(NULL, table);
365 trace("got %d with 0x%x\n", res, errno);
368 table[0] = initterm_cb0;
369 memset(cb_called, 0, sizeof(cb_called));
370 errno = 0xdeadbeef;
371 res = p_initterm_e(table, &table[1]);
372 ok( !res && (cb_called[0] == 1) && !cb_called[1] && !cb_called[2],
373 "got %d with 0x%x {%d, %d, %d}\n",
374 res, errno, cb_called[0], cb_called[1], cb_called[2]);
377 /* init-function returning failure */
378 table[1] = initterm_cb1;
379 memset(cb_called, 0, sizeof(cb_called));
380 errno = 0xdeadbeef;
381 res = p_initterm_e(table, &table[3]);
382 ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
383 "got %d with 0x%x {%d, %d, %d}\n",
384 res, errno, cb_called[0], cb_called[1], cb_called[2]);
386 /* init-function not called, when end < start */
387 memset(cb_called, 0, sizeof(cb_called));
388 errno = 0xdeadbeef;
389 res = p_initterm_e(&table[3], table);
390 ok( !res && !cb_called[0] && !cb_called[1] && !cb_called[2],
391 "got %d with 0x%x {%d, %d, %d}\n",
392 res, errno, cb_called[0], cb_called[1], cb_called[2]);
394 /* initialization stop after first non-zero result */
395 table[2] = initterm_cb0;
396 memset(cb_called, 0, sizeof(cb_called));
397 errno = 0xdeadbeef;
398 res = p_initterm_e(table, &table[3]);
399 ok( (res == 1) && (cb_called[0] == 1) && (cb_called[1] == 1) && !cb_called[2],
400 "got %d with 0x%x {%d, %d, %d}\n",
401 res, errno, cb_called[0], cb_called[1], cb_called[2]);
403 /* NULL pointer in the array are skipped */
404 table[1] = NULL;
405 table[2] = initterm_cb2;
406 memset(cb_called, 0, sizeof(cb_called));
407 errno = 0xdeadbeef;
408 res = p_initterm_e(table, &table[3]);
409 ok( (res == 2) && (cb_called[0] == 1) && !cb_called[1] && (cb_called[2] == 1),
410 "got %d with 0x%x {%d, %d, %d}\n",
411 res, errno, cb_called[0], cb_called[1], cb_called[2]);
415 /* Beware that _encode_pointer is a NOP before XP
416 (the parameter is returned unchanged) */
417 static void test__encode_pointer(void)
419 void *ptr, *res;
421 ptr = (void*)0xdeadbeef;
422 res = p_encode_pointer(ptr);
423 res = p_decode_pointer(res);
424 ok(res == ptr, "Pointers are different after encoding and decoding\n");
426 ok(p_encoded_null() == p_encode_pointer(NULL), "Error encoding null\n");
428 ptr = p_encode_pointer(p_encode_pointer);
429 ok(p_decode_pointer(ptr) == p_encode_pointer, "Error decoding pointer\n");
431 /* Not present before XP */
432 if (!pEncodePointer) {
433 win_skip("EncodePointer not found\n");
434 return;
437 res = pEncodePointer(p_encode_pointer);
438 ok(ptr == res, "_encode_pointer produced different result than EncodePointer\n");
442 static void test_error_messages(void)
444 int *size, size_copy;
446 size = p__sys_nerr();
447 size_copy = *size;
448 ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
450 *size = 20;
451 ok(*p_sys_nerr == *size, "_sys_nerr = %u, size = %u\n", *p_sys_nerr, *size);
453 *size = size_copy;
455 ok(*p_sys_errlist == *(p__sys_errlist()), "p_sys_errlist != p__sys_errlist()\n");
458 static void test__strtoi64(void)
460 __int64 res;
461 unsigned __int64 ures;
463 SET_EXPECT(invalid_parameter_handler);
464 res = p_strtoi64(NULL, NULL, 10);
465 ok(res == 0, "res != 0\n");
466 CHECK_CALLED(invalid_parameter_handler, EINVAL);
468 SET_EXPECT(invalid_parameter_handler);
469 res = p_strtoi64("123", NULL, 1);
470 ok(res == 0, "res != 0\n");
471 CHECK_CALLED(invalid_parameter_handler, EINVAL);
473 SET_EXPECT(invalid_parameter_handler);
474 res = p_strtoi64("123", NULL, 37);
475 ok(res == 0, "res != 0\n");
476 CHECK_CALLED(invalid_parameter_handler, EINVAL);
478 SET_EXPECT(invalid_parameter_handler);
479 ures = p_strtoui64(NULL, NULL, 10);
480 ok(ures == 0, "res = %d\n", (int)ures);
481 CHECK_CALLED(invalid_parameter_handler, EINVAL);
483 SET_EXPECT(invalid_parameter_handler);
484 ures = p_strtoui64("123", NULL, 1);
485 ok(ures == 0, "res = %d\n", (int)ures);
486 CHECK_CALLED(invalid_parameter_handler, EINVAL);
488 SET_EXPECT(invalid_parameter_handler);
489 ures = p_strtoui64("123", NULL, 37);
490 ok(ures == 0, "res = %d\n", (int)ures);
491 CHECK_CALLED(invalid_parameter_handler, EINVAL);
494 static void test__itoa_s(void)
496 errno_t ret;
497 char buffer[33];
499 SET_EXPECT(invalid_parameter_handler);
500 ret = p_itoa_s(0, NULL, 0, 0);
501 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
502 CHECK_CALLED(invalid_parameter_handler, EINVAL);
504 memset(buffer, 'X', sizeof(buffer));
505 SET_EXPECT(invalid_parameter_handler);
506 ret = p_itoa_s(0, buffer, 0, 0);
507 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
508 ok(buffer[0] == 'X', "Expected the output buffer to be untouched\n");
509 CHECK_CALLED(invalid_parameter_handler, EINVAL);
511 memset(buffer, 'X', sizeof(buffer));
512 SET_EXPECT(invalid_parameter_handler);
513 ret = p_itoa_s(0, buffer, sizeof(buffer), 0);
514 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
515 ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
516 CHECK_CALLED(invalid_parameter_handler, EINVAL);
518 memset(buffer, 'X', sizeof(buffer));
519 SET_EXPECT(invalid_parameter_handler);
520 ret = p_itoa_s(0, buffer, sizeof(buffer), 64);
521 ok(ret == EINVAL, "Expected _itoa_s to return EINVAL, got %d\n", ret);
522 ok(buffer[0] == '\0', "Expected the output buffer to be null terminated\n");
523 CHECK_CALLED(invalid_parameter_handler, EINVAL);
525 memset(buffer, 'X', sizeof(buffer));
526 SET_EXPECT(invalid_parameter_handler);
527 ret = p_itoa_s(12345678, buffer, 4, 10);
528 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
529 ok(!memcmp(buffer, "\000765", 4),
530 "Expected the output buffer to be null terminated with truncated output\n");
531 CHECK_CALLED(invalid_parameter_handler, ERANGE);
533 memset(buffer, 'X', sizeof(buffer));
534 SET_EXPECT(invalid_parameter_handler);
535 ret = p_itoa_s(12345678, buffer, 8, 10);
536 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
537 ok(!memcmp(buffer, "\0007654321", 8),
538 "Expected the output buffer to be null terminated with truncated output\n");
539 CHECK_CALLED(invalid_parameter_handler, ERANGE);
541 memset(buffer, 'X', sizeof(buffer));
542 SET_EXPECT(invalid_parameter_handler);
543 ret = p_itoa_s(-12345678, buffer, 9, 10);
544 ok(ret == ERANGE, "Expected _itoa_s to return ERANGE, got %d\n", ret);
545 ok(!memcmp(buffer, "\00087654321", 9),
546 "Expected the output buffer to be null terminated with truncated output\n");
547 CHECK_CALLED(invalid_parameter_handler, ERANGE);
549 ret = p_itoa_s(12345678, buffer, 9, 10);
550 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
551 ok(!strcmp(buffer, "12345678"),
552 "Expected output buffer string to be \"12345678\", got \"%s\"\n",
553 buffer);
555 ret = p_itoa_s(43690, buffer, sizeof(buffer), 2);
556 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
557 ok(!strcmp(buffer, "1010101010101010"),
558 "Expected output buffer string to be \"1010101010101010\", got \"%s\"\n",
559 buffer);
561 ret = p_itoa_s(1092009, buffer, sizeof(buffer), 36);
562 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
563 ok(!strcmp(buffer, "nell"),
564 "Expected output buffer string to be \"nell\", got \"%s\"\n",
565 buffer);
567 ret = p_itoa_s(5704, buffer, sizeof(buffer), 18);
568 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
569 ok(!strcmp(buffer, "hag"),
570 "Expected output buffer string to be \"hag\", got \"%s\"\n",
571 buffer);
573 ret = p_itoa_s(-12345678, buffer, sizeof(buffer), 10);
574 ok(ret == 0, "Expected _itoa_s to return 0, got %d\n", ret);
575 ok(!strcmp(buffer, "-12345678"),
576 "Expected output buffer string to be \"-12345678\", got \"%s\"\n",
577 buffer);
580 static void test_wcsncat_s(void)
582 static wchar_t abcW[] = {'a','b','c',0};
583 int ret;
584 wchar_t dst[4];
585 wchar_t src[4];
587 memcpy(src, abcW, sizeof(abcW));
588 dst[0] = 0;
589 SET_EXPECT(invalid_parameter_handler);
590 ret = p_wcsncat_s(NULL, 4, src, 4);
591 ok(ret == EINVAL, "err = %d\n", ret);
592 CHECK_CALLED(invalid_parameter_handler, EINVAL);
594 SET_EXPECT(invalid_parameter_handler);
595 ret = p_wcsncat_s(dst, 0, src, 4);
596 ok(ret == EINVAL, "err = %d\n", ret);
597 CHECK_CALLED(invalid_parameter_handler, EINVAL);
599 SET_EXPECT(invalid_parameter_handler);
600 ret = p_wcsncat_s(dst, 0, src, _TRUNCATE);
601 ok(ret == EINVAL, "err = %d\n", ret);
602 CHECK_CALLED(invalid_parameter_handler, EINVAL);
604 ret = p_wcsncat_s(dst, 4, NULL, 0);
605 ok(ret == 0, "err = %d\n", ret);
607 dst[0] = 0;
608 SET_EXPECT(invalid_parameter_handler);
609 ret = p_wcsncat_s(dst, 2, src, 4);
610 ok(ret == ERANGE, "err = %d\n", ret);
611 CHECK_CALLED(invalid_parameter_handler, ERANGE);
613 dst[0] = 0;
614 ret = p_wcsncat_s(dst, 2, src, _TRUNCATE);
615 ok(ret == STRUNCATE, "err = %d\n", ret);
616 ok(dst[0] == 'a' && dst[1] == 0, "dst is %s\n", wine_dbgstr_w(dst));
618 memcpy(dst, abcW, sizeof(abcW));
619 dst[3] = 'd';
620 SET_EXPECT(invalid_parameter_handler);
621 ret = p_wcsncat_s(dst, 4, src, 4);
622 ok(ret == EINVAL, "err = %d\n", ret);
623 CHECK_CALLED(invalid_parameter_handler, EINVAL);
626 /* Based on dlls/ntdll/tests/string.c */
627 static __cdecl int intcomparefunc(void *context, const void *a, const void *b)
629 const int *p = a, *q = b;
631 ok (a != b, "must never get the same pointer\n");
632 ++*(int *) context;
634 return *p - *q;
637 static __cdecl int charcomparefunc(void *context, const void *a, const void *b)
639 const char *p = a, *q = b;
641 ok (a != b, "must never get the same pointer\n");
642 ++*(int *) context;
644 return *p - *q;
647 static __cdecl int strcomparefunc(void *context, const void *a, const void *b)
649 const char * const *p = a;
650 const char * const *q = b;
652 ok (a != b, "must never get the same pointer\n");
653 ++*(int *) context;
655 return lstrcmpA(*p, *q);
658 static void test_qsort_s(void)
660 int arr[5] = { 23, 42, 8, 4, 16 };
661 int arr2[5] = { 23, 42, 8, 4, 16 };
662 char carr[5] = { 42, 23, 4, 8, 16 };
663 const char *strarr[7] = {
664 "Hello",
665 "Wine",
666 "World",
667 "!",
668 "Hopefully",
669 "Sorted",
673 SET_EXPECT(invalid_parameter_handler);
674 p_qsort_s(NULL, 0, 0, NULL, NULL);
675 CHECK_CALLED(invalid_parameter_handler, EINVAL);
677 SET_EXPECT(invalid_parameter_handler);
678 p_qsort_s(NULL, 0, 0, intcomparefunc, NULL);
679 CHECK_CALLED(invalid_parameter_handler, EINVAL);
681 SET_EXPECT(invalid_parameter_handler);
682 p_qsort_s(NULL, 0, sizeof(int), NULL, NULL);
683 CHECK_CALLED(invalid_parameter_handler, EINVAL);
685 SET_EXPECT(invalid_parameter_handler);
686 p_qsort_s(NULL, 1, sizeof(int), intcomparefunc, NULL);
687 CHECK_CALLED(invalid_parameter_handler, EINVAL);
689 errno = 0xdeadbeef;
690 g_qsort_s_context_counter = 0;
691 p_qsort_s(NULL, 0, sizeof(int), intcomparefunc, NULL);
692 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
693 ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
695 /* overflow without side effects, other overflow values crash */
696 errno = 0xdeadbeef;
697 g_qsort_s_context_counter = 0;
698 p_qsort_s((void*)arr2, (((size_t)1) << (8*sizeof(size_t) - 1)) + 1, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
699 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
700 ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
701 ok(arr2[0] == 23, "should remain unsorted, arr2[0] is %d\n", arr2[0]);
702 ok(arr2[1] == 42, "should remain unsorted, arr2[1] is %d\n", arr2[1]);
703 ok(arr2[2] == 8, "should remain unsorted, arr2[2] is %d\n", arr2[2]);
704 ok(arr2[3] == 4, "should remain unsorted, arr2[3] is %d\n", arr2[3]);
706 errno = 0xdeadbeef;
707 g_qsort_s_context_counter = 0;
708 p_qsort_s((void*)arr, 0, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
709 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
710 ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
711 ok(arr[0] == 23, "badly sorted, nmemb=0, arr[0] is %d\n", arr[0]);
712 ok(arr[1] == 42, "badly sorted, nmemb=0, arr[1] is %d\n", arr[1]);
713 ok(arr[2] == 8, "badly sorted, nmemb=0, arr[2] is %d\n", arr[2]);
714 ok(arr[3] == 4, "badly sorted, nmemb=0, arr[3] is %d\n", arr[3]);
715 ok(arr[4] == 16, "badly sorted, nmemb=0, arr[4] is %d\n", arr[4]);
717 errno = 0xdeadbeef;
718 g_qsort_s_context_counter = 0;
719 p_qsort_s((void*)arr, 1, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
720 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
721 ok( errno == 0xdeadbeef, "wrong errno %u\n", errno );
722 ok(arr[0] == 23, "badly sorted, nmemb=1, arr[0] is %d\n", arr[0]);
723 ok(arr[1] == 42, "badly sorted, nmemb=1, arr[1] is %d\n", arr[1]);
724 ok(arr[2] == 8, "badly sorted, nmemb=1, arr[2] is %d\n", arr[2]);
725 ok(arr[3] == 4, "badly sorted, nmemb=1, arr[3] is %d\n", arr[3]);
726 ok(arr[4] == 16, "badly sorted, nmemb=1, arr[4] is %d\n", arr[4]);
728 SET_EXPECT(invalid_parameter_handler);
729 g_qsort_s_context_counter = 0;
730 p_qsort_s((void*)arr, 5, 0, intcomparefunc, &g_qsort_s_context_counter);
731 ok(g_qsort_s_context_counter == 0, "callback shouldn't have been called\n");
732 ok(arr[0] == 23, "badly sorted, size=0, arr[0] is %d\n", arr[0]);
733 ok(arr[1] == 42, "badly sorted, size=0, arr[1] is %d\n", arr[1]);
734 ok(arr[2] == 8, "badly sorted, size=0, arr[2] is %d\n", arr[2]);
735 ok(arr[3] == 4, "badly sorted, size=0, arr[3] is %d\n", arr[3]);
736 ok(arr[4] == 16, "badly sorted, size=0, arr[4] is %d\n", arr[4]);
737 CHECK_CALLED(invalid_parameter_handler, EINVAL);
739 g_qsort_s_context_counter = 0;
740 p_qsort_s((void*)arr, 5, sizeof(int), intcomparefunc, &g_qsort_s_context_counter);
741 ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
742 ok(arr[0] == 4, "badly sorted, arr[0] is %d\n", arr[0]);
743 ok(arr[1] == 8, "badly sorted, arr[1] is %d\n", arr[1]);
744 ok(arr[2] == 16, "badly sorted, arr[2] is %d\n", arr[2]);
745 ok(arr[3] == 23, "badly sorted, arr[3] is %d\n", arr[3]);
746 ok(arr[4] == 42, "badly sorted, arr[4] is %d\n", arr[4]);
748 g_qsort_s_context_counter = 0;
749 p_qsort_s((void*)carr, 5, sizeof(char), charcomparefunc, &g_qsort_s_context_counter);
750 ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
751 ok(carr[0] == 4, "badly sorted, carr[0] is %d\n", carr[0]);
752 ok(carr[1] == 8, "badly sorted, carr[1] is %d\n", carr[1]);
753 ok(carr[2] == 16, "badly sorted, carr[2] is %d\n", carr[2]);
754 ok(carr[3] == 23, "badly sorted, carr[3] is %d\n", carr[3]);
755 ok(carr[4] == 42, "badly sorted, carr[4] is %d\n", carr[4]);
757 g_qsort_s_context_counter = 0;
758 p_qsort_s((void*)strarr, 7, sizeof(char*), strcomparefunc, &g_qsort_s_context_counter);
759 ok(g_qsort_s_context_counter > 0, "callback wasn't called\n");
760 ok(!strcmp(strarr[0],"!"), "badly sorted, strarr[0] is %s\n", strarr[0]);
761 ok(!strcmp(strarr[1],"."), "badly sorted, strarr[1] is %s\n", strarr[1]);
762 ok(!strcmp(strarr[2],"Hello"), "badly sorted, strarr[2] is %s\n", strarr[2]);
763 ok(!strcmp(strarr[3],"Hopefully"), "badly sorted, strarr[3] is %s\n", strarr[3]);
764 ok(!strcmp(strarr[4],"Sorted"), "badly sorted, strarr[4] is %s\n", strarr[4]);
765 ok(!strcmp(strarr[5],"Wine"), "badly sorted, strarr[5] is %s\n", strarr[5]);
766 ok(!strcmp(strarr[6],"World"), "badly sorted, strarr[6] is %s\n", strarr[6]);
769 static void test_bsearch_s(void)
771 int arr[7] = { 1, 3, 4, 8, 16, 23, 42 };
772 int *x, l, i, j = 1;
774 SET_EXPECT(invalid_parameter_handler);
775 x = p_bsearch_s(NULL, NULL, 0, 0, NULL, NULL);
776 ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
777 CHECK_CALLED(invalid_parameter_handler, EINVAL);
779 g_bsearch_s_context_counter = 0;
780 SET_EXPECT(invalid_parameter_handler);
781 x = p_bsearch_s(&l, arr, j, 0, intcomparefunc, &g_bsearch_s_context_counter);
782 ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
783 ok(g_bsearch_s_context_counter == 0, "callback shouldn't have been called\n");
784 CHECK_CALLED(invalid_parameter_handler, EINVAL);
786 g_bsearch_s_context_counter = 0;
787 SET_EXPECT(invalid_parameter_handler);
788 x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), NULL, &g_bsearch_s_context_counter);
789 ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
790 ok(g_bsearch_s_context_counter == 0, "callback shouldn't have been called\n");
791 CHECK_CALLED(invalid_parameter_handler, EINVAL);
793 /* just try all array sizes */
794 for (j=1;j<sizeof(arr)/sizeof(arr[0]);j++) {
795 for (i=0;i<j;i++) {
796 l = arr[i];
797 g_bsearch_s_context_counter = 0;
798 x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), intcomparefunc, &g_bsearch_s_context_counter);
799 ok (x == &arr[i], "bsearch_s did not find %d entry in loopsize %d.\n", i, j);
800 ok(g_bsearch_s_context_counter > 0, "callback wasn't called\n");
802 l = 4242;
803 g_bsearch_s_context_counter = 0;
804 x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), intcomparefunc, &g_bsearch_s_context_counter);
805 ok (x == NULL, "bsearch_s did find 4242 entry in loopsize %d.\n", j);
806 ok(g_bsearch_s_context_counter > 0, "callback wasn't called\n");
810 static void test_controlfp_s(void)
812 unsigned int cur;
813 int ret;
815 SET_EXPECT(invalid_parameter_handler);
816 ret = p_controlfp_s( NULL, ~0, ~0 );
817 ok( ret == EINVAL, "wrong result %d\n", ret );
818 CHECK_CALLED(invalid_parameter_handler, EINVAL);
820 cur = 0xdeadbeef;
821 SET_EXPECT(invalid_parameter_handler);
822 ret = p_controlfp_s( &cur, ~0, ~0 );
823 ok( ret == EINVAL, "wrong result %d\n", ret );
824 ok( cur != 0xdeadbeef, "value not set\n" );
825 CHECK_CALLED(invalid_parameter_handler, EINVAL);
827 cur = 0xdeadbeef;
828 ret = p_controlfp_s( &cur, 0, 0 );
829 ok( !ret, "wrong result %d\n", ret );
830 ok( cur != 0xdeadbeef, "value not set\n" );
832 SET_EXPECT(invalid_parameter_handler);
833 cur = 0xdeadbeef;
834 ret = p_controlfp_s( &cur, 0x80000000, 0x80000000 );
835 ok( ret == EINVAL, "wrong result %d\n", ret );
836 ok( cur != 0xdeadbeef, "value not set\n" );
837 CHECK_CALLED(invalid_parameter_handler, EINVAL);
839 cur = 0xdeadbeef;
840 /* mask is only checked when setting invalid bits */
841 ret = p_controlfp_s( &cur, 0, 0x80000000 );
842 ok( !ret, "wrong result %d\n", ret );
843 ok( cur != 0xdeadbeef, "value not set\n" );
846 static void test_tmpfile_s( void )
848 int ret;
850 SET_EXPECT(invalid_parameter_handler);
851 ret = p_tmpfile_s(NULL);
852 ok(ret == EINVAL, "Expected tmpfile_s to return EINVAL, got %i\n", ret);
853 CHECK_CALLED(invalid_parameter_handler, EINVAL);
856 typedef struct
858 const char *str;
859 float flt;
860 int ret;
861 } _atoflt_test;
863 static const _atoflt_test _atoflt_testdata[] = {
864 { "12.1", 12.1, 0 },
865 { "-13.721", -13.721, 0 },
866 { "INF", 0.0, 0 },
867 { ".21e12", 0.21e12, 0 },
868 { "214353e-3", 214.353, 0 },
869 { "1d9999999999999999999", 0.0, _OVERFLOW },
870 { " d10", 0.0, 0 },
871 /* more significant digits */
872 { "1.23456789", 1.23456789, 0 },
873 { "1.23456789e1", 12.3456789, 0 },
874 { "1e39", 0.0, _OVERFLOW },
875 { "1e-39", 0.0, _UNDERFLOW },
876 { NULL }
879 static void test__atoflt(void)
881 _CRT_FLOAT flt;
882 int ret, i = 0;
884 if (0)
886 /* crashes on native */
887 p_atoflt(NULL, NULL);
888 p_atoflt(NULL, (char*)_atoflt_testdata[0].str);
889 p_atoflt(&flt, NULL);
892 while (_atoflt_testdata[i].str)
894 ret = p_atoflt(&flt, (char*)_atoflt_testdata[i].str);
895 ok(ret == _atoflt_testdata[i].ret, "got ret %d, expected ret %d, for %s\n", ret,
896 _atoflt_testdata[i].ret, _atoflt_testdata[i].str);
898 if (ret == 0)
899 ok(almost_equal_f(flt.f, _atoflt_testdata[i].flt), "got %f, expected %f, for %s\n", flt.f,
900 _atoflt_testdata[i].flt, _atoflt_testdata[i].str);
902 i++;
906 static void test__set_abort_behavior(void)
908 unsigned int res;
910 /* default is _WRITE_ABORT_MSG | _CALL_REPORTFAULT */
911 res = p_set_abort_behavior(0, 0);
912 ok (res == (_WRITE_ABORT_MSG | _CALL_REPORTFAULT),
913 "got 0x%x (expected 0x%x)\n", res, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
915 /* no internal mask */
916 p_set_abort_behavior(0xffffffff, 0xffffffff);
917 res = p_set_abort_behavior(0, 0);
918 ok (res == 0xffffffff, "got 0x%x (expected 0x%x)\n", res, 0xffffffff);
920 /* set to default value */
921 p_set_abort_behavior(_WRITE_ABORT_MSG | _CALL_REPORTFAULT, 0xffffffff);
924 static void test__sopen_s(void)
926 int ret, fd;
928 SET_EXPECT(invalid_parameter_handler);
929 ret = p_sopen_s(NULL, "test", _O_RDONLY, _SH_DENYNO, _S_IREAD);
930 ok(ret == EINVAL, "got %d, expected EINVAL\n", ret);
931 CHECK_CALLED(invalid_parameter_handler, EINVAL);
933 fd = 0xdead;
934 ret = p_sopen_s(&fd, "test", _O_RDONLY, _SH_DENYNO, _S_IREAD);
935 ok(ret == ENOENT, "got %d, expected ENOENT\n", ret);
936 ok(fd == -1, "got %d\n", fd);
939 static void test__wsopen_s(void)
941 wchar_t testW[] = {'t','e','s','t',0};
942 int ret, fd;
944 SET_EXPECT(invalid_parameter_handler);
945 ret = p_wsopen_s(NULL, testW, _O_RDONLY, _SH_DENYNO, _S_IREAD);
946 ok(ret == EINVAL, "got %d, expected EINVAL\n", ret);
947 CHECK_CALLED(invalid_parameter_handler, EINVAL);
949 fd = 0xdead;
950 ret = p_wsopen_s(&fd, testW, _O_RDONLY, _SH_DENYNO, _S_IREAD);
951 ok(ret == ENOENT, "got %d, expected ENOENT\n", ret);
952 ok(fd == -1, "got %d\n", fd);
955 static void test__realloc_crt(void)
957 void *mem;
959 if (0)
961 /* crashes on some systems starting Vista */
962 p_realloc_crt(NULL, 10);
965 mem = p_malloc(10);
966 ok(mem != NULL, "memory not allocated\n");
968 mem = p_realloc_crt(mem, 20);
969 ok(mem != NULL, "memory not reallocated\n");
971 mem = p_realloc_crt(mem, 0);
972 ok(mem == NULL, "memory not freed\n");
974 mem = p_realloc_crt(NULL, 0);
975 ok(mem != NULL, "memory not (re)allocated for size 0\n");
976 p_free(mem);
979 static void test_typeinfo(void)
981 static type_info t1 = { NULL, NULL,{'.','?','A','V','t','e','s','t','1','@','@',0,0,0,0,0 } };
982 struct __type_info_node node;
983 char *name;
985 /* name */
986 t1.name = NULL;
987 node.memPtr = NULL;
988 node.next = NULL;
989 name = call_func2(p_type_info_name_internal_method, &t1, &node);
990 ok(name != NULL, "got %p\n", name);
991 ok(name && t1.name && !strcmp(name, t1.name), "bad name '%s' for t1\n", name);
993 ok(t1.name && !strcmp(t1.name, "class test1"), "demangled to '%s' for t1\n", t1.name);
994 call_func1(ptype_info_dtor, &t1);
997 /* Keep in sync with msvcrt/msvcrt.h */
998 struct __thread_data {
999 DWORD tid;
1000 HANDLE handle;
1001 int thread_errno;
1002 __msvcrt_ulong thread_doserrno;
1003 int unk1;
1004 unsigned int random_seed;
1005 char *strtok_next;
1006 wchar_t *wcstok_next;
1007 unsigned char *mbstok_next;
1008 char *strerror_buffer;
1009 wchar_t *wcserror_buffer;
1010 char *tmpnam_buffer;
1011 wchar_t *wtmpnam_buffer;
1012 void *unk2[2];
1013 char *asctime_buffer;
1014 wchar_t *wasctime_buffer;
1015 struct tm *time_buffer;
1016 char *efcvt_buffer;
1017 int unk3[2];
1018 void *unk4[4];
1019 int fpecode;
1020 pthreadmbcinfo mbcinfo;
1021 pthreadlocinfo locinfo;
1022 BOOL have_locale;
1023 int unk5[1];
1024 void* terminate_handler;
1025 void* unexpected_handler;
1026 void* se_translator;
1027 void *unk6[3];
1028 int unk7;
1029 EXCEPTION_RECORD *exc_record;
1032 static void test_getptd(void)
1034 struct __thread_data *ptd = p_getptd();
1035 DWORD tid = GetCurrentThreadId();
1036 wchar_t testW[] = {'t','e','s','t',0}, tW[] = {'t',0}, *wp;
1037 char test[] = "test", *p;
1038 struct tm time;
1039 __time64_t secs = 0;
1040 int dec, sign;
1041 void *mbcinfo, *locinfo;
1043 ok(ptd->tid == tid, "ptd->tid = %x, expected %x\n", ptd->tid, tid);
1044 ok(ptd->handle == INVALID_HANDLE_VALUE, "ptd->handle = %p\n", ptd->handle);
1045 ok(p_errno() == &ptd->thread_errno, "ptd->thread_errno is different then _errno()\n");
1046 ok(p_doserrno() == &ptd->thread_doserrno, "ptd->thread_doserrno is different then __doserrno()\n");
1047 p_srand(1234);
1048 ok(ptd->random_seed == 1234, "ptd->random_seed = %d\n", ptd->random_seed);
1049 p = p_strtok(test, "t");
1050 ok(ptd->strtok_next == p+3, "ptd->strtok_next is incorrect\n");
1051 wp = p_wcstok(testW, tW);
1052 ok(ptd->wcstok_next == wp+3, "ptd->wcstok_next is incorrect\n");
1053 ok(p_strerror(0) == ptd->strerror_buffer, "ptd->strerror_buffer is incorrect\n");
1054 ok(p_wcserror(0) == ptd->wcserror_buffer, "ptd->wcserror_buffer is incorrect\n");
1055 ok(p_tmpnam(NULL) == ptd->tmpnam_buffer, "ptd->tmpnam_buffer is incorrect\n");
1056 ok(p_wtmpnam(NULL) == ptd->wtmpnam_buffer, "ptd->wtmpnam_buffer is incorrect\n");
1057 memset(&time, 0, sizeof(time));
1058 time.tm_mday = 1;
1059 ok(p_asctime(&time) == ptd->asctime_buffer, "ptd->asctime_buffer is incorrect\n");
1060 ok(p_wasctime(&time) == ptd->wasctime_buffer, "ptd->wasctime_buffer is incorrect\n");
1061 ok(p_localtime64(&secs) == ptd->time_buffer, "ptd->time_buffer is incorrect\n");
1062 ok(p_ecvt(3.12, 1, &dec, &sign) == ptd->efcvt_buffer, "ptd->efcvt_buffer is incorrect\n");
1063 ok(p_fpecode() == &ptd->fpecode, "ptd->fpecode is incorrect\n");
1064 mbcinfo = ptd->mbcinfo;
1065 locinfo = ptd->locinfo;
1066 todo_wine ok(ptd->have_locale == 1, "ptd->have_locale = %x\n", ptd->have_locale);
1067 p_configthreadlocale(1);
1068 todo_wine ok(mbcinfo == ptd->mbcinfo, "ptd->mbcinfo != mbcinfo\n");
1069 todo_wine ok(locinfo == ptd->locinfo, "ptd->locinfo != locinfo\n");
1070 todo_wine ok(ptd->have_locale == 3, "ptd->have_locale = %x\n", ptd->have_locale);
1071 ok(p_get_terminate() == ptd->terminate_handler, "ptd->terminate_handler != _get_terminate()\n");
1072 ok(p_get_unexpected() == ptd->unexpected_handler, "ptd->unexpected_handler != _get_unexpected()\n");
1075 static int __cdecl __vswprintf_l_wrapper(wchar_t *buf,
1076 const wchar_t *format, _locale_t locale, ...)
1078 int ret;
1079 __ms_va_list valist;
1080 __ms_va_start(valist, locale);
1081 ret = p__vswprintf_l(buf, format, locale, valist);
1082 __ms_va_end(valist);
1083 return ret;
1086 static int __cdecl _vswprintf_l_wrapper(wchar_t *buf,
1087 const wchar_t *format, _locale_t locale, ...)
1089 int ret;
1090 __ms_va_list valist;
1091 __ms_va_start(valist, locale);
1092 ret = p_vswprintf_l(buf, format, locale, valist);
1093 __ms_va_end(valist);
1094 return ret;
1097 static void test__vswprintf_l(void)
1099 static const wchar_t format[] = {'t','e','s','t',0};
1101 wchar_t buf[32];
1102 int ret;
1104 ret = __vswprintf_l_wrapper(buf, format, NULL);
1105 ok(ret == 4, "ret = %d\n", ret);
1106 ok(!memcmp(buf, format, sizeof(format)), "buf = %s, expected %s\n",
1107 wine_dbgstr_w(buf), wine_dbgstr_w(format));
1109 ret = _vswprintf_l_wrapper(buf, format, NULL);
1110 ok(ret == 4, "ret = %d\n", ret);
1111 ok(!memcmp(buf, format, sizeof(format)), "buf = %s, expected %s\n",
1112 wine_dbgstr_w(buf), wine_dbgstr_w(format));
1115 struct block_file_arg
1117 FILE *read;
1118 FILE *write;
1119 HANDLE blocked;
1122 static DWORD WINAPI block_file(void *arg)
1124 struct block_file_arg *files = arg;
1126 p_lock_file(files->read);
1127 p_lock_file(files->write);
1128 SetEvent(files->blocked);
1129 WaitForSingleObject(files->blocked, INFINITE);
1130 p_unlock_file(files->read);
1131 p_unlock_file(files->write);
1132 return 0;
1135 static void test_nonblocking_file_access(void)
1137 HANDLE thread;
1138 struct block_file_arg arg;
1139 FILE *filer, *filew;
1140 int ret;
1142 if(!p_lock_file || !p_unlock_file) {
1143 win_skip("_lock_file not available\n");
1144 return;
1147 filew = p_fopen("test_file", "w");
1148 ok(filew != NULL, "unable to create test file\n");
1149 if(!filew)
1150 return;
1151 filer = p_fopen("test_file", "r");
1152 ok(filer != NULL, "unable to open test file\n");
1153 if(!filer) {
1154 p_fclose(filew);
1155 p_unlink("test_file");
1156 return;
1159 arg.read = filer;
1160 arg.write = filew;
1161 arg.blocked = CreateEvent(NULL, FALSE, FALSE, NULL);
1162 ok(arg.blocked != NULL, "CreateEvent failed\n");
1163 if(!arg.blocked) {
1164 p_fclose(filer);
1165 p_fclose(filew);
1166 p_unlink("test_file");
1167 return;
1169 thread = CreateThread(NULL, 0, block_file, (void*)&arg, 0, NULL);
1170 ok(thread != NULL, "CreateThread failed\n");
1171 if(!thread) {
1172 CloseHandle(arg.blocked);
1173 p_fclose(filer);
1174 p_fclose(filew);
1175 p_unlink("test_file");
1176 return;
1178 WaitForSingleObject(arg.blocked, INFINITE);
1180 ret = p_fileno(filer);
1181 ok(ret, "_fileno(filer) returned %d\n", ret);
1182 ret = p_fileno(filew);
1183 ok(ret, "_fileno(filew) returned %d\n", ret);
1185 ret = p_feof(filer);
1186 ok(ret==0, "feof(filer) returned %d\n", ret);
1187 ret = p_feof(filew);
1188 ok(ret==0, "feof(filew) returned %d\n", ret);
1190 ret = p_ferror(filer);
1191 ok(ret==0, "ferror(filer) returned %d\n", ret);
1192 ret = p_ferror(filew);
1193 ok(ret==0, "ferror(filew) returned %d\n", ret);
1195 ret = p_flsbuf('a', filer);
1196 ok(ret==-1, "_flsbuf(filer) returned %d\n", ret);
1197 ret = p_flsbuf('a', filew);
1198 ok(ret=='a', "_flsbuf(filew) returned %d\n", ret);
1200 SetEvent(arg.blocked);
1201 WaitForSingleObject(thread, INFINITE);
1202 CloseHandle(arg.blocked);
1203 CloseHandle(thread);
1204 p_fclose(filer);
1205 p_fclose(filew);
1206 p_unlink("test_file");
1209 static void test_byteswap(void)
1211 unsigned long ret;
1213 ret = p_byteswap_ulong(0x12345678);
1214 ok(ret == 0x78563412, "ret = %lx\n", ret);
1216 ret = p_byteswap_ulong(0);
1217 ok(ret == 0, "ret = %lx\n", ret);
1220 START_TEST(msvcr90)
1222 if(!init())
1223 return;
1225 test__initterm_e();
1226 test__encode_pointer();
1227 test_error_messages();
1228 test__strtoi64();
1229 test__itoa_s();
1230 test_wcsncat_s();
1231 test_qsort_s();
1232 test_bsearch_s();
1233 test_controlfp_s();
1234 test_tmpfile_s();
1235 test__atoflt();
1236 test__set_abort_behavior();
1237 test__sopen_s();
1238 test__wsopen_s();
1239 test__realloc_crt();
1240 test_typeinfo();
1241 test_getptd();
1242 test__vswprintf_l();
1243 test_nonblocking_file_access();
1244 test_byteswap();