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 } 641