[CRT_APITEST] Add tests for data exports
[reactos.git] / modules / rostests / apitests / crt / crtdata.c
1 /*
2 * PROJECT: ReactOS CRT API tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Tests for crt data exports
5 * COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer@reactos.org>
6 */
7
8 #include <apitest.h>
9 #include <apitest_guard.h>
10
11 #define WIN32_NO_STATUS
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <time.h>
15 #include <locale.h>
16 #include <mbctype.h>
17
18 static OSVERSIONINFOW s_osvi;
19 extern char __ImageBase;
20 static void* s_ImageEnd;
21
22 int IsLocalSymbol(void* Address)
23 {
24 return ((Address >= (void*)&__ImageBase) && (Address <= s_ImageEnd));
25 }
26
27 #ifndef TEST_STATIC
28 #define test_is_local_symbol(addr, is) ok_int(IsLocalSymbol(addr), (is))
29 #else
30 #define test_is_local_symbol(addr, is)
31 #endif
32
33 void Test___argc(void)
34 {
35 void* p = &__argc;
36 test_is_local_symbol(p, FALSE);
37
38 #undef __argc
39 ok_ptr(&__argc, p);
40 #ifdef _M_IX86
41 ok_ptr(__p___argc(), p);
42 #endif
43 }
44
45 void Test___argv(void)
46 {
47 void* p = &__argv;
48 test_is_local_symbol(p, FALSE);
49
50 #undef __argv
51 ok_ptr(&__argv, p);
52 #ifdef _M_IX86
53 ok_ptr(__p___argv(), p);
54 #endif
55 }
56
57 void Test___badioinfo(void)
58 {
59 typedef struct _ioinfo ioinfo;
60 _CRTIMP extern ioinfo* __badioinfo[];
61 ok(__badioinfo != NULL, "__badioinfo is NULL\n");
62 ok(__badioinfo[0] != NULL, "__badioinfo is NULL\n");
63 }
64
65 void Test___initenv(void)
66 {
67 _CRTIMP extern char** __initenv;
68 ok(__initenv != NULL, "__initenv is NULL\n");
69 ok(*__initenv != NULL, "*__initenv is NULL\n");
70 #ifdef _M_IX86
71 _CRTIMP char*** __p___initenv(void);
72 ok_ptr(__p___initenv(), &__initenv);
73 #endif
74 }
75
76 void Test___lc_codepage(void)
77 {
78 _CRTIMP extern unsigned int __lc_codepage;
79 ok_int(__lc_codepage, 0);
80 ok_int(___lc_codepage_func(), 0);
81 __lc_codepage++;
82 todo_ros ok_int(___lc_codepage_func(), 0);
83 __lc_codepage--;
84 }
85
86 void Test___lc_collate_cp(void)
87 {
88 _CRTIMP extern int __lc_collate_cp;
89 test_is_local_symbol(&__lc_collate_cp, FALSE);
90 ok_int(__lc_collate_cp, 0);
91 ok_int(___lc_collate_cp_func(), 0);
92 __lc_collate_cp++;
93 ok_int(___lc_collate_cp_func(), 0);
94 __lc_collate_cp--;
95 }
96
97 void Test___lc_handle(void)
98 {
99 _CRTIMP int __lc_handle;
100 ok_int(__lc_handle, 0);
101 _CRTIMP int* ___lc_handle_func();
102 ok_int(*___lc_handle_func(), 0);
103 __lc_handle++;
104 todo_ros ok_int(*___lc_handle_func(), 0);
105 __lc_handle--;
106 }
107
108 void Test___mb_cur_max(void)
109 {
110 void* p = &__mb_cur_max;
111 test_is_local_symbol(&__mb_cur_max, FALSE);
112 ok_int(__mb_cur_max, 1);
113
114 #undef __mb_cur_max
115 _CRTIMP extern int __mb_cur_max;
116 ok_ptr(&__mb_cur_max, p);
117
118 ok_int(___mb_cur_max_func(), 1);
119 #ifdef _M_IX86
120 _CRTIMP int* __p___mb_cur_max(void);
121 ok_int(*__p___mb_cur_max(), 1);
122 #endif
123 __mb_cur_max++;
124 if (s_osvi.dwMajorVersion >= 6)
125 {
126 ok_int(___mb_cur_max_func(), 1);
127 #ifdef _M_IX86
128 ok_int(*__p___mb_cur_max(), 1);
129 #endif
130 }
131 else
132 {
133 todo_ros ok_int(___mb_cur_max_func(), 2);
134 #ifdef _M_IX86
135 todo_ros ok_ptr(__p___mb_cur_max(), p); // wine code handles it like on Vista+
136 todo_ros ok_int(*__p___mb_cur_max(), 2);
137 #endif
138 }
139
140 __mb_cur_max--;
141 }
142
143 void Test___pioinfo(void)
144 {
145
146 }
147
148 void Test___setlc_active(void)
149 {
150 _CRTIMP extern unsigned int __setlc_active;
151 ok_int(__setlc_active, 0);
152
153 _CRTIMP unsigned int ___setlc_active_func(void);
154 ok_int(___setlc_active_func(), __setlc_active);
155 __setlc_active++;
156 ok_int(___setlc_active_func(), __setlc_active);
157 __setlc_active--;
158 }
159
160 void Test___unguarded_readlc_active(void)
161 {
162 _CRTIMP extern unsigned int __unguarded_readlc_active;
163 void* p = &__unguarded_readlc_active;
164 ok_int(__unguarded_readlc_active, 0);
165
166 _CRTIMP unsigned int* ___unguarded_readlc_active_add_func(void);
167 ok_ptr(___unguarded_readlc_active_add_func(), p);
168 }
169
170 void Test___wargv(void)
171 {
172 void* p = &__wargv;
173 test_is_local_symbol(p, FALSE);
174
175 #undef __wargv
176 _CRTIMP extern wchar_t ** __wargv;
177 ok_ptr(&__wargv, p);
178 #ifdef _M_IX86
179 ok_ptr(__p___wargv(), p);
180 #endif
181 }
182
183 void Test___winitenv(void)
184 {
185 _CRTIMP extern wchar_t** __winitenv;
186 todo_ros ok(__winitenv == NULL, "__winitenv is not NULL\n");
187 #ifdef _M_IX86
188 _CRTIMP wchar_t*** __p___winitenv(void);
189 ok_ptr(__p___winitenv(), &__winitenv);
190 #endif
191 }
192
193 void Test__acmdln(void)
194 {
195 _CRTIMP extern char* _acmdln;
196 ok(_acmdln != NULL, "__winitenv is NULL\n");
197 #ifdef _M_IX86
198 _CRTIMP char** __p__acmdln(void);
199 ok_ptr(__p__acmdln(), &_acmdln);
200 #endif
201 }
202
203 #ifdef _M_IX86
204 void Test__adjust_fdiv(void)
205 {
206 _CRTIMP extern int _adjust_fdiv;
207 ok_int(_adjust_fdiv, 0);
208 }
209 #endif
210
211 void Test__aexit_rtn(void)
212 {
213 typedef void (*_exit_t)(int exitcode);
214 _CRTIMP extern _exit_t _aexit_rtn;
215 ok_ptr(_aexit_rtn, _exit);
216 }
217
218 void Test__commode(void)
219 {
220 void* p = &_commode;
221 test_is_local_symbol(&_commode, FALSE);
222 ok_int(_commode, 0);
223
224 #undef _commode
225 _CRTIMP extern int _commode;
226 ok_ptr(&_commode, p);
227 #ifdef _M_IX86
228 ok_ptr(__p__commode(), &_commode);
229 #endif
230 }
231
232 void Test__ctype(void)
233 {
234 _CRTIMP extern const unsigned short _ctype[];
235 ok_int(_ctype[0], 0);
236 ok_int(_ctype[1], _CONTROL);
237
238 #undef _pctype
239 _CRTIMP extern const unsigned short* _pctype;
240 ok(_pctype != &_ctype[0], "_pwctype should not match &_wctype[0]");
241 if (s_osvi.dwMajorVersion >= 6)
242 {
243 ok(_pctype != &_ctype[1], "_pwctype should not match &_wctype[1]");
244 }
245 else
246 {
247 ok(_pctype == &_ctype[1], "_pwctype should match &_wctype[1]");
248 }
249
250 ok(__pctype_func() != _ctype, "__pctype_func() should not match _ctype\n");
251 ok_int(__pctype_func()[0], _CONTROL);
252 ok_int(__pctype_func()[1], _CONTROL);
253 #ifdef _M_IX86
254 _CRTIMP const unsigned short** __cdecl __p__pctype(void);
255 ok_ptr(*__p__pctype(), __pctype_func());
256 #endif
257 }
258
259 void Test__wctype(void)
260 {
261 ok_int(_wctype[0], 0);
262 ok_int(_wctype[1], _CONTROL);
263
264 #undef _pwctype
265 _CRTIMP extern const unsigned short* _pwctype;
266 ok_ptr(_pwctype, &_wctype[1]);
267
268 ok(__pwctype_func() != _wctype, "__pwctype_func() == _wctype\n");
269 ok_int(__pctype_func()[0], _CONTROL);
270 ok_int(__pctype_func()[1], _CONTROL);
271 #ifdef _M_IX86
272 _CRTIMP const unsigned short** __cdecl __p__pwctype(void);
273 ok_ptr(*__p__pwctype(), __pwctype_func());
274 #endif
275 }
276
277 void Test__daylight(void)
278 {
279 void* p = &_daylight;
280 test_is_local_symbol(&_daylight, FALSE);
281
282 #undef _daylight
283 _CRTIMP extern int _daylight;
284 ok_ptr(&_daylight, p);
285
286 #ifdef _M_IX86
287 _CRTIMP void* __p__daylight(void);
288 ok_ptr(__p__daylight(), &_daylight);
289 #endif
290 #if (WINVER >= 0x600)
291 _CRTIMP int* __cdecl __daylight(void);
292 ok_ptr(&__daylight, &_daylight);
293 #endif
294 }
295
296 void Test__dstbias(void)
297 {
298 void* p = &_dstbias;
299 test_is_local_symbol(&_dstbias, FALSE);
300
301 #undef _dstbias
302 _CRTIMP extern long _dstbias;
303 ok_ptr(&_dstbias, p);
304 #ifdef _M_IX86
305 _CRTIMP long* __cdecl __p__dstbias(void);
306 ok_ptr(__p__dstbias(), &_dstbias);
307 #endif
308 #if (WINVER >= 0x600)
309 _CRTIMP long* __cdecl __dstbias(void);
310 ok_ptr(&__dstbias, &_dstbias);
311 #endif
312 }
313
314 void Test__environ(void)
315 {
316 void* p = &_environ;
317 ok(_environ != NULL, "_environ == NULL\n");
318
319 #undef _environ
320 _CRTIMP extern char** _environ;
321 ok_ptr(&_environ, p);
322 #ifdef _M_IX86
323 ok_ptr(__p__environ(), &_environ);
324 #endif
325 }
326
327 void Test__fileinfo(void)
328 {
329 _CRTIMP extern int _fileinfo;
330 ok_int(_fileinfo, -1);
331
332 #ifdef _M_IX86
333 _CRTIMP int* __p__fileinfo();
334 ok_ptr(__p__fileinfo(), &_fileinfo);
335 #endif
336 }
337
338 void Test__fmode(void)
339 {
340 void* p = &_fmode;
341 test_is_local_symbol(&_fmode, FALSE);
342 ok_int(_fmode, 0);
343
344 #undef _fmode
345 _CRTIMP extern int _fmode;
346 ok_ptr(&_fmode, p);
347
348 #ifdef _M_IX86
349 _CRTIMP int* __cdecl __p__fmode();
350 ok_ptr(__p__fmode(), p);
351 #endif
352
353 #if (_WIN32_WINNT >= 0x600)
354 _fmode = 1234;
355 _CRTIMP errno_t __cdecl _get_fmode(_Out_ int* _PMode);
356 int mode;
357 ok_int(_get_fmode(&mode), 0);
358 ok_int(mode, _fmode);
359 _fmode = 0;
360 #endif
361 }
362
363 void Test__iob(void)
364 {
365 void* p = &_iob;
366 test_is_local_symbol(&_iob, FALSE);
367 ok_ptr(&_iob[0], stdin);
368 ok_ptr(&_iob[1], stdout);
369 ok_ptr(&_iob[2], stderr);
370
371 #undef _iob
372 _CRTIMP extern FILE _iob[];
373 ok_ptr(&_iob, p);
374
375 ok_ptr(__iob_func(), &_iob);
376
377 #ifdef _M_IX86
378 _CRTIMP int* __cdecl __p__iob();
379 ok_ptr(__p__iob(), p);
380 #endif
381 }
382
383 void Test__mbcasemap(void)
384 {
385 void* p = &_mbcasemap;
386 ok_int(_mbcasemap[0], 0);
387
388 #undef _mbcasemap
389 ok_ptr(_mbcasemap, p);
390
391 #ifdef _M_IX86
392 _CRTIMP unsigned char* __cdecl __p__mbcasemap();
393 ok_ptr(__p__mbcasemap(), &_mbcasemap);
394 #endif
395 }
396
397 void Test__mbctype(void)
398 {
399 void* p = &_mbctype;
400 ok_int(_mbctype[0], 0);
401
402 #undef _mbctype
403 ok_ptr(&_mbctype, p);
404
405 #ifdef _M_IX86
406 _CRTIMP unsigned char* __cdecl __p__mbctype();
407 todo_ros ok_ptr(__p__mbctype(), &_mbctype); // wine implements thiss like on Vista
408 #endif
409 }
410
411 void Test__osplatform(void)
412 {
413 ok_int(_osplatform, s_osvi.dwPlatformId);
414 #if (WINVER >= 0x600)
415 _CRTIMP unsigned int __cdecl _get_osplatform(void);
416 ok_ptr(_get_osplatform(), _osplatform);
417 #endif
418 }
419
420 void Test__osver(void)
421 {
422 ok_int(_osver, s_osvi.dwBuildNumber);
423
424 #ifdef _M_IX86
425 _CRTIMP int* __cdecl __p__osver();
426 ok_ptr(__p__osver(), &_osver);
427 #endif
428 }
429
430 void Test__pgmptr(void)
431 {
432 void* p = &_pgmptr;
433 ok(_pgmptr != NULL, "_pgmptr should not be NULL\n");
434
435 #undef _pgmptr
436 _CRTIMP extern char* _pgmptr;
437 ok_ptr(&_pgmptr, p);
438 #ifdef _M_IX86
439 ok_ptr(__p__pgmptr(), &_pgmptr);
440 #endif
441 #if (WINVER >= 0x600)
442 _CRTIMP char* __cdecl _get_pgmptr(void);
443 ok_ptr(_get_pgmptr(), _pgmptr);
444 #endif
445 }
446
447 void Test__sys_errlist(void)
448 {
449 void* p = &_sys_errlist;
450 ok_int(strcmp(_sys_errlist[0], strerror(0)), 0);
451 ok_int(strcmp(_sys_errlist[42], strerror(42)), 0);
452
453 #undef _sys_errlist
454 _CRTIMP extern char* _sys_errlist[];
455 ok_ptr(&_sys_errlist, p);
456 }
457
458 void Test__sys_nerr(void)
459 {
460 void* p = &_sys_nerr;
461 ok_int(_sys_nerr, 43);
462
463 #undef _sys_nerr
464 _CRTIMP extern int _sys_nerr;
465 ok_ptr(&_sys_nerr, p);
466 }
467
468 void Test__timezone(void)
469 {
470 void* p = &_timezone;
471 test_is_local_symbol(&_timezone, FALSE);
472
473 #undef _timezone
474 _CRTIMP extern long _timezone;
475 ok_ptr(&_timezone, p);
476
477 #ifdef _M_IX86
478 _CRTIMP char** __p__timezone();
479 ok_ptr(__p__timezone(), &_timezone);
480 #endif
481 }
482
483 void Test__tzname(void)
484 {
485 void* p = &_tzname;
486 test_is_local_symbol(&_tzname, FALSE);
487 ok(_tzname[0] != NULL, "_tzname[0] == NULL\n");
488 ok(_tzname[0] != NULL, "_tzname[0] == NULL\n");
489
490 #undef _tzname
491 _CRTIMP extern char * _tzname[2];
492 ok_ptr(_tzname, p);
493
494 #ifdef _M_IX86
495 _CRTIMP char** __p__tzname();
496 ok_ptr(__p__tzname(), &_tzname);
497 #endif
498 #if (WINVER >= 0x600)
499 _CRTIMP char* __cdecl __tzname(void);
500 ok_ptr(__tzname(), _wenviron);
501 #endif
502 }
503
504 void Test__wcmdln(void)
505 {
506 _CRTIMP extern wchar_t* _wcmdln;
507 #ifdef _M_IX86
508 _CRTIMP wchar_t** __p__wcmdln(void);
509 ok_ptr(__p__wcmdln(), &_wcmdln);
510 #endif
511 }
512
513 void Test__wenviron(void)
514 {
515 void* p = &_wenviron;
516 todo_ros ok(_wenviron == NULL, "_wenviron is not NULL\n");
517
518 #undef _wenviron
519 _CRTIMP extern wchar_t** _wenviron;
520 ok_ptr(&_wenviron, p);
521 #ifdef _M_IX86
522 ok_ptr(__p__wenviron(), &_wenviron);
523 #endif
524 #if (WINVER >= 0x600)
525 _CRTIMP unsigned int __cdecl _get_wenviron(void);
526 ok_int(_get_wenviron(), _wenviron);
527 #endif
528 }
529
530 void Test__winmajor(void)
531 {
532 ok_int(_winmajor, s_osvi.dwMajorVersion);
533 #ifdef _M_IX86
534 _CRTIMP unsigned int* __cdecl __p__winmajor();
535 ok_ptr(__p__winmajor(), &_winmajor);
536 #endif
537 #if (WINVER >= 0x600)
538 _CRTIMP unsigned int __cdecl _get_winmajor(void);
539 ok_int(_get_winmajor(), _winmajor);
540 #endif
541 }
542
543 void Test__winminor(void)
544 {
545 ok_int(_winminor, s_osvi.dwMinorVersion);
546 #ifdef _M_IX86
547 _CRTIMP unsigned int* __cdecl __p__winminor();
548 ok_ptr(__p__winminor(), &_winminor);
549 #endif
550 #if (WINVER >= 0x600)
551 _CRTIMP unsigned int __cdecl _get_winminor(void);
552 ok_int(_get_winminor(), _winminor);
553 #endif
554 }
555
556 void Test__winver(void)
557 {
558 ok_int(_winver, (s_osvi.dwMajorVersion << 8) | s_osvi.dwMinorVersion);
559 #ifdef _M_IX86
560 _CRTIMP unsigned int* __cdecl __p__winver();
561 ok_ptr(__p__winver(), &_winver);
562 #endif
563 #if (WINVER >= 0x600)
564 _CRTIMP unsigned int __cdecl _get_winver(void);
565 ok_int(_get_winver(), _winver);
566 #endif
567 }
568
569 void Test__wpgmptr(void)
570 {
571 void* p = _wpgmptr;
572 ok_ptr(_wpgmptr, NULL);
573
574 #undef _wpgmptr
575 ok_ptr(_wpgmptr, p);
576
577 #ifdef _M_IX86
578 _CRTIMP wchar_t ** __cdecl __p__wpgmptr();
579 ok_ptr(__p__wpgmptr(), &_wpgmptr);
580 #endif
581 #if (WINVER >= 0x600)
582 _CRTIMP unsigned int __cdecl _get_wpgmptr(void);
583 ok_int(_get_wpgmptr(), _wpgmptr);
584 #endif
585 }
586
587 START_TEST(crtdata)
588 {
589 /* Initialize image size */
590 PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)&__ImageBase;
591 PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((PUCHAR)dosHeader + dosHeader->e_lfanew);
592 s_ImageEnd = (PUCHAR)dosHeader + ntHeaders->OptionalHeader.SizeOfImage;
593
594 /* initialize version info */
595 s_osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
596 GetVersionExW(&s_osvi);
597
598 Test___argc();
599 Test___argv();
600 Test___badioinfo();
601 Test___initenv();
602 Test___lc_codepage();
603 Test___lc_collate_cp();
604 Test___lc_handle();
605 Test___mb_cur_max();
606 Test___pioinfo();
607 Test___setlc_active();
608 Test___unguarded_readlc_active();
609 Test___wargv();
610 Test___winitenv();
611 Test__acmdln();
612 #ifdef _M_IX86
613 Test__adjust_fdiv();
614 #endif
615 Test__aexit_rtn();
616 Test__commode();
617 Test__ctype();
618 Test__daylight();
619 Test__dstbias();
620 Test__environ();
621 Test__fileinfo();
622 Test__fmode();
623 Test__iob();
624 Test__mbcasemap();
625 Test__mbctype();
626 Test__osplatform();
627 Test__osver();
628 Test__pgmptr();
629 Test__sys_errlist();
630 Test__sys_nerr();
631 Test__timezone();
632 Test__tzname();
633 Test__wcmdln();
634 Test__wctype();
635 Test__wenviron();
636 Test__winmajor();
637 Test__winminor();
638 Test__winver();
639 Test__wpgmptr();
640 }