Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

715 lines
23 KiB

  1. /***
  2. *crt0.c - C runtime initialization routine
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * This is the actual startup routine for apps. It calls the user's main
  8. * routine [w]main() or [w]WinMain after performing C Run-Time Library
  9. * initialization.
  10. *
  11. * With ifdefs, this source file also provides the source code for:
  12. * wcrt0.c the startup routine for console apps with wide chars
  13. * wincrt0.c the startup routine for Windows apps
  14. * wwincrt0.c the startup routine for Windows apps with wide chars
  15. *
  16. *Revision History:
  17. * 06-27-89 PHG Module created, based on asm version
  18. * 11-02-89 JCR Added DOS32QUERYSYSINFO to get osversion
  19. * 04-09-90 GJF Added #include <cruntime.h>. Put in explicit calling
  20. * types (_CALLTYPE1 or _CALLTYPE4) for __crt0(),
  21. * inherit(), __amsg_exit() and _cintDIV(). Also, fixed
  22. * the copyright and cleaned up the formatting a bit.
  23. * 04-10-90 GJF Fixed compiler warnings (-W3).
  24. * 08-08-90 GJF Added exception handling stuff (needed to support
  25. * runtime errors and signal()).
  26. * 08-31-90 GJF Removed 32 from API names.
  27. * 10-08-90 GJF New-style function declarators.
  28. * 12-05-90 GJF Fixed off-by-one error in inherit().
  29. * 12-06-90 GJF Win32 version of inherit().
  30. * 12-06-90 SRW Added _osfile back for win32. Changed _osfinfo from
  31. * an array of structures to an array of 32-bit handles
  32. * (_osfhnd)
  33. * 01-21-91 GJF ANSI naming.
  34. * 01-25-91 SRW Changed Win32 Process Startup [_WIN32_]
  35. * 02-01-91 SRW Removed usage of PPEB type [_WIN32_]
  36. * 02-05-91 SRW Changed to pass _osfile and _osfhnd arrays as binary
  37. * data to child process. [_WIN32_]
  38. * 04-02-91 GJF Need to get version number sooner so it can be used in
  39. * _heap_init. Prefixed an '_' onto BaseProcessStartup.
  40. * Version info now stored in _os[version|major|minor] and
  41. * _base[version|major|minor] (_WIN32_).
  42. * 04-10-91 PNT Added _MAC_ conditional
  43. * 04-26-91 SRW Removed level 3 warnings
  44. * 05-14-91 GJF Turn on exception handling for Dosx32.
  45. * 05-22-91 GJF Fixed careless errors.
  46. * 07-12-91 GJF Fixed one more careless error.
  47. * 08-13-91 GJF Removed definitions of _confh and _coninpfh.
  48. * 09-13-91 GJF Incorporated Stevewo's startup variations.
  49. * 11-07-91 GJF Revised try-except, fixed outdated comments on file
  50. * handle inheritance [_WIN32_].
  51. * 12-02-91 SRW Fixed WinMain startup code to skip over first token
  52. * plus delimiters for the lpszCommandLine parameter.
  53. * 01-17-92 GJF Merge of NT and CRT version. Restored Stevewo's scheme
  54. * for unhandled exceptions.
  55. * 02-13-92 GJF For Win32, moved file inheritance stuff to ioinit.c.
  56. * Call to inherit() is replace by call to _ioinit().
  57. * 03-23-92 OLM Created MAC version
  58. * 04-01-92 XY Add cinit call (MAC)
  59. * 04-16-92 DJM POSIX support
  60. * 06-10-92 PLM Added putenv support (MAC)
  61. * 08-26-92 SKS Add _osver, _winver, _winmajor, _winminor
  62. * 08-26-92 GJF Deleted version number(s) fetch from POSIX startup (it
  63. * involved a Win32 API call).
  64. * 09-30-92 SRW Call _heap_init before _mtinit
  65. * 03-20-93 SKS Remove obsolete variables _osmode, _cpumode, etc.
  66. * 04-01-93 CFW Change try-except to __try-__except
  67. * 04-05-93 JWM GUI apps now call MessageBox() from _amsg_exit().
  68. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  69. * 04-19-93 SKS Remove obsolete variable _atopsp
  70. * 04-26-93 SKS Change _mtinit to return failure
  71. * remove a number of OS/2 (CRUISER) ifdefs
  72. * 04-26-93 GJF Made lpszCommandLine (unsigned char *) to deal with
  73. * chars > 127 in the command line.
  74. * 04-27-93 GJF Removed support for _RT_STACK, _RT_INTDIV,
  75. * _RT_INVALDISP and _RT_NONCONT.
  76. * 05-14-93 GJF Added support for quoted program names.
  77. * 09-08-93 CFW Added call to _initmbctable.
  78. * 09-15-93 CFW Use ANSI conformant "__" names.
  79. * 09-21-93 CFW Move _initmbctable call to _cinit().
  80. * 11-05-93 CFW Undefine GetEnviromentStrings.
  81. * 11-08-93 GJF Guard as much init. code as possible with the __try -
  82. * __except statement, especially _cinit(). Also,
  83. * restored the call to __initmbctable to this module.
  84. * 11-19-93 CFW Add _wcmdln variable, enable wide char command line
  85. * only.
  86. * 11-23-93 CFW GetEnviromentStrings undef moved to internal.h.
  87. * 11-29-93 CFW Wide environment.
  88. * 12-21-93 CFW Fix API failure error handling.
  89. * 01-04-94 CFW Pass copy of environment to main.
  90. * 01-28-94 CFW Move environment copying to setenv.c.
  91. * 02-07-94 CFW POSIXify.
  92. * 03-30-93 CFW Use __crtXXX calls for Unicode model.
  93. * 04-08-93 CFW cinit() should be later.
  94. * 04-12-94 GJF Moved declaration of _[w]initenv to internal.h.
  95. * 04-14-94 GJF Enclosed whole source in #ifndef CRTDLL - #endif.
  96. * 09-02-94 SKS Fix inaccurate description in file header comment
  97. * 09-06-94 CFW Remove _MBCS_OS switch.
  98. * 09-06-94 GJF Added definitions of __error_mode and __app_type.
  99. * 10-14-94 BWT try->__try / except->__except for POSIX
  100. * 01-16-95 CFW Set default debug output for console.
  101. * 02-11-95 CFW PPC -> _M_MPPC.
  102. * 02-16-95 JWM Spliced _WIN32 & Mac versions.
  103. * 03-28-95 BWT Fail if unable to retrieve cmdline or envptr (fixes
  104. * stress bug).
  105. * 04-06-95 CFW Set default debug output for Mac.
  106. * 04-06-95 CFW Use __crtGetEnvironmentStringsA.
  107. * 04-26-95 CFW Change default debug output for Mac to debugger.
  108. * 07-04-95 GJF Interface to __crtGetEnvironmentStrings and _setenvp
  109. * changes slightly.
  110. * 07-07-95 CFW Simplify default report mode scheme.
  111. * 04-22-96 GJF Check for error on _heap_init.
  112. * 01-17-97 GJF For _heap_init() or _mtinit() failure, exit the
  113. * process without going through _exit().
  114. * 07-24-97 GJF Moved building of lpszCommandLine to wincmdln.c. Also,
  115. * heap_init changed slightly to support option to use
  116. * heap running directly on Win32 API.
  117. * 08-06-97 GJF Moved __mbctype_initialized to crt0dat.c
  118. * 12-23-97 RKP Corrected posix use of _heap_init()
  119. * 02-27-98 RKP Added 64 bit support.
  120. * 10-02-98 GJF Use GetVersionEx instead of GetVersion and store OS ID
  121. * in _osplatform.
  122. * 11-13-98 KBF Moved RTC_Initialize from _cinit to just after
  123. * _heap_init
  124. * 05-11-99 KBF Wrap RTC support in #ifdef.
  125. * 05-17-99 PML Remove all Macintosh support.
  126. * 11-03-99 RDL Win64 POSIX warning fix.
  127. * 11-12-99 KBF Create 4 new COM+ specific entrypoints which return
  128. * instead of calling exit().
  129. * 11-16-99 PML ... and remove them - linker problems mean new
  130. * entrypoints don't work. Instead, look directly at the
  131. * COM Descriptor Image Directory entry in the optional
  132. * header to see if we are a COM+ app.
  133. * 02-15-00 GB Changed GetModuleHandle to GetModuleHandleA in
  134. * check_complus_app.
  135. * 03-06-00 PML Call __crtExitProcess instead of ExitProcess.
  136. * 08-04-00 PML check_complus_app -> check_managed_app (VS7#117746).
  137. * 12-09-00 PML Tighten up check_managed_app tests (VS7#167293).
  138. * 03-17-01 PML _alloca the OSVERSIONINFO so /GS can work (vs7#224261)
  139. * 03-26-01 PML Use GetVersionExA, not GetVersionEx (vs7#230286)
  140. * 03-27-01 PML Call to _amsg_exit on startup failure now pushed up to
  141. * this level (vs7#231220)
  142. * 04-29-01 BWT Fix posix build
  143. * 10-11-01 BWT Replace GetModuleHandle(NULL) with &__ImageBase
  144. * 11-21-01 BWT Wrap ansi GetStartupInfo with try/except (it can raise
  145. * exceptions on failure)
  146. * 02-20-02 BWT prefast fixes - don't use alloca
  147. *
  148. *******************************************************************************/
  149. #ifndef CRTDLL
  150. #include <cruntime.h>
  151. #include <dos.h>
  152. #include <internal.h>
  153. #include <process.h>
  154. #include <stdlib.h>
  155. #include <string.h>
  156. #ifndef _POSIX_
  157. #include <rterr.h>
  158. #include <rtcapi.h>
  159. #else
  160. #include <posix/sys/types.h>
  161. #include <posix/unistd.h>
  162. #include <posix/signal.h>
  163. #endif
  164. #include <windows.h>
  165. #include <awint.h>
  166. #include <tchar.h>
  167. #include <dbgint.h>
  168. /*
  169. * wWinMain is not yet defined in winbase.h. When it is, this should be
  170. * removed.
  171. */
  172. #if defined(_WIN64) && defined(_M_IA64)
  173. #pragma section(".base", long, read, write)
  174. __declspec(allocate(".base"))
  175. extern
  176. IMAGE_DOS_HEADER __ImageBase;
  177. #else
  178. extern
  179. IMAGE_DOS_HEADER __ImageBase;
  180. #endif
  181. int
  182. WINAPI
  183. wWinMain(
  184. HINSTANCE hInstance,
  185. HINSTANCE hPrevInstance,
  186. LPWSTR lpCmdLine,
  187. int nShowCmd
  188. );
  189. #ifdef WPRFLAG
  190. _TUCHAR * __cdecl _wwincmdln(void);
  191. #else
  192. _TUCHAR * __cdecl _wincmdln(void);
  193. #endif
  194. /*
  195. * command line, environment, and a few other globals
  196. */
  197. #ifdef WPRFLAG
  198. wchar_t *_wcmdln; /* points to wide command line */
  199. #else
  200. char *_acmdln; /* points to command line */
  201. #endif
  202. char *_aenvptr = NULL; /* points to environment block */
  203. #ifndef _POSIX_
  204. wchar_t *_wenvptr = NULL; /* points to wide environment block */
  205. #endif
  206. #ifdef _POSIX_
  207. char *_cmdlin;
  208. #endif
  209. void (__cdecl * _aexit_rtn)(int) = _exit; /* RT message return procedure */
  210. static void __cdecl fast_error_exit(int); /* Error exit via ExitProcess */
  211. static int __cdecl check_managed_app(void); /* Determine if a managed app */
  212. /*
  213. * _error_mode and _apptype, together, determine how error messages are
  214. * written out.
  215. */
  216. int __error_mode = _OUT_TO_DEFAULT;
  217. #ifdef _WINMAIN_
  218. int __app_type = _GUI_APP;
  219. #else
  220. int __app_type = _CONSOLE_APP;
  221. #endif
  222. #ifdef _POSIX_
  223. /***
  224. *mainCRTStartup(void)
  225. *
  226. *Purpose:
  227. * This routine does the C runtime initialization, calls main(), and
  228. * then exits. It never returns.
  229. *
  230. *Entry:
  231. *
  232. *Exit:
  233. * This function never returns.
  234. *
  235. *******************************************************************************/
  236. void
  237. mainCRTStartup(
  238. void
  239. )
  240. {
  241. int mainret;
  242. int initret;
  243. char **ppch;
  244. extern char **environ;
  245. extern char * __PdxGetCmdLine(void); /* an API in the Posix SS */
  246. extern main(int,char**);
  247. _cmdlin = __PdxGetCmdLine();
  248. ppch = (char **)_cmdlin;
  249. __argv = ppch;
  250. // normalize argv pointers
  251. __argc = 0;
  252. while (NULL != *ppch) {
  253. *ppch += (int)(intptr_t)_cmdlin;
  254. ++__argc;
  255. ++ppch;
  256. }
  257. // normalize environ pointers
  258. ++ppch;
  259. environ = ppch;
  260. while (NULL != *ppch) {
  261. *ppch = *ppch + (int)(intptr_t)_cmdlin;
  262. ++ppch;
  263. }
  264. /*
  265. * If POSIX runtime needs to fetch and store POSIX verion info,
  266. * it should be done here.
  267. *
  268. * Get_and_save_version_info;
  269. */
  270. #ifdef _MT
  271. _heap_init(1); /* initialize heap */
  272. #else
  273. _heap_init(0); /* initialize heap */
  274. #endif
  275. initret = _cinit(); /* do C data initialize */
  276. if (initret != 0)
  277. _amsg_exit(initret);
  278. __try {
  279. mainret = main(__argc, __argv);
  280. } __except (EXCEPTION_EXECUTE_HANDLER) {
  281. switch (GetExceptionCode()) {
  282. case STATUS_ACCESS_VIOLATION:
  283. kill(getpid(), SIGSEGV);
  284. break;
  285. case STATUS_ILLEGAL_INSTRUCTION:
  286. case STATUS_PRIVILEGED_INSTRUCTION:
  287. kill(getpid(), SIGILL);
  288. break;
  289. case STATUS_FLOAT_DENORMAL_OPERAND:
  290. case STATUS_FLOAT_DIVIDE_BY_ZERO:
  291. case STATUS_FLOAT_INEXACT_RESULT:
  292. case STATUS_FLOAT_OVERFLOW:
  293. case STATUS_FLOAT_STACK_CHECK:
  294. case STATUS_FLOAT_UNDERFLOW:
  295. kill(getpid(), SIGFPE);
  296. break;
  297. default:
  298. kill(getpid(), SIGKILL);
  299. }
  300. mainret = -1;
  301. }
  302. exit(mainret);
  303. }
  304. #else /* ndef _POSIX_ */
  305. /***
  306. *mainCRTStartup(void)
  307. *wmainCRTStartup(void)
  308. *WinMainCRTStartup(void)
  309. *wWinMainCRTStartup(void)
  310. *
  311. *Purpose:
  312. * These routines do the C runtime initialization, call the appropriate
  313. * user entry function, and handle termination cleanup. For a managed
  314. * app, they then return the exit code back to the calling routine, which
  315. * is the managed startup code. For an unmanaged app, they call exit and
  316. * never return.
  317. *
  318. * Function: User entry called:
  319. * mainCRTStartup main
  320. * wmainCRTStartup wmain
  321. * WinMainCRTStartup WinMain
  322. * wWinMainCRTStartup wWinMain
  323. *
  324. *Entry:
  325. *
  326. *Exit:
  327. * Managed app: return value from main() et al, or the exception code if
  328. * execution was terminated by the __except guarding the call
  329. * to main().
  330. * Unmanaged app: never return.
  331. *
  332. *******************************************************************************/
  333. #ifdef _WINMAIN_
  334. #ifdef WPRFLAG
  335. int wWinMainCRTStartup(
  336. #else
  337. int WinMainCRTStartup(
  338. #endif
  339. #else /* ndef _WINMAIN_ */
  340. #ifdef WPRFLAG
  341. int wmainCRTStartup(
  342. #else
  343. int mainCRTStartup(
  344. #endif
  345. #endif /* _WINMAIN_ */
  346. void
  347. )
  348. {
  349. int initret;
  350. int mainret;
  351. OSVERSIONINFOA *posvi;
  352. int managedapp;
  353. #ifdef _WINMAIN_
  354. _TUCHAR *lpszCommandLine;
  355. STARTUPINFO StartupInfo;
  356. #ifdef WPRFLAG
  357. GetStartupInfo(&StartupInfo);
  358. #else
  359. __try {
  360. GetStartupInfo( &StartupInfo );
  361. } __except(EXCEPTION_EXECUTE_HANDLER) {
  362. return 255;
  363. }
  364. #endif
  365. #endif
  366. /*
  367. * Dynamically allocate the OSVERSIONINFOA buffer, so we avoid
  368. * triggering the /GS buffer overrun detection. That can't be
  369. * used here, since the guard cookie isn't available until we
  370. * initialize it from here!
  371. */
  372. posvi = (OSVERSIONINFOA *)HeapAlloc(GetProcessHeap(), 0, sizeof(OSVERSIONINFOA));
  373. if (!posvi) {
  374. return 255;
  375. }
  376. /*
  377. * Get the full Win32 version
  378. */
  379. posvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
  380. if ( !GetVersionExA(posvi) ) {
  381. HeapFree(GetProcessHeap(), 0, posvi);
  382. return 255;
  383. }
  384. _osplatform = posvi->dwPlatformId;
  385. _winmajor = posvi->dwMajorVersion;
  386. _winminor = posvi->dwMinorVersion;
  387. /*
  388. * The somewhat bizarre calculations of _osver and _winver are
  389. * required for backward compatibility (used to use GetVersion)
  390. */
  391. _osver = (posvi->dwBuildNumber) & 0x07fff;
  392. HeapFree(GetProcessHeap(), 0, posvi);
  393. if ( _osplatform != VER_PLATFORM_WIN32_NT )
  394. _osver |= 0x08000;
  395. _winver = (_winmajor << 8) + _winminor;
  396. /*
  397. * Determine if this is a managed application
  398. */
  399. managedapp = check_managed_app();
  400. #ifdef _MT
  401. if ( !_heap_init(1) ) /* initialize heap */
  402. #else
  403. if ( !_heap_init(0) ) /* initialize heap */
  404. #endif
  405. fast_error_exit(_RT_HEAPINIT); /* write message and die */
  406. #ifdef _MT
  407. if( !_mtinit() ) /* initialize multi-thread */
  408. fast_error_exit(_RT_THREAD); /* write message and die */
  409. #endif
  410. /*
  411. * Initialize the Runtime Checks stuff
  412. */
  413. #ifdef _RTC
  414. _RTC_Initialize();
  415. #endif
  416. /*
  417. * Guard the remainder of the initialization code and the call
  418. * to user's main, or WinMain, function in a __try/__except
  419. * statement.
  420. */
  421. __try {
  422. if ( _ioinit() < 0 ) /* initialize lowio */
  423. _amsg_exit(_RT_LOWIOINIT);
  424. #ifdef WPRFLAG
  425. /* get wide cmd line info */
  426. _wcmdln = (wchar_t *)__crtGetCommandLineW();
  427. /* get wide environ info */
  428. _wenvptr = (wchar_t *)__crtGetEnvironmentStringsW();
  429. if ( _wsetargv() < 0 )
  430. _amsg_exit(_RT_SPACEARG);
  431. if ( _wsetenvp() < 0 )
  432. _amsg_exit(_RT_SPACEENV);
  433. #else
  434. /* get cmd line info */
  435. _acmdln = (char *)GetCommandLineA();
  436. /* get environ info */
  437. _aenvptr = (char *)__crtGetEnvironmentStringsA();
  438. if ( _setargv() < 0 )
  439. _amsg_exit(_RT_SPACEARG);
  440. if ( _setenvp() < 0 )
  441. _amsg_exit(_RT_SPACEENV);
  442. #endif
  443. initret = _cinit(); /* do C data initialize */
  444. if (initret != 0)
  445. _amsg_exit(initret);
  446. #ifdef _WINMAIN_
  447. #ifdef WPRFLAG
  448. lpszCommandLine = _wwincmdln();
  449. mainret = wWinMain(
  450. #else
  451. lpszCommandLine = _wincmdln();
  452. mainret = WinMain(
  453. #endif
  454. (HINSTANCE)&__ImageBase,
  455. NULL,
  456. lpszCommandLine,
  457. StartupInfo.dwFlags & STARTF_USESHOWWINDOW
  458. ? StartupInfo.wShowWindow
  459. : SW_SHOWDEFAULT
  460. );
  461. #else /* _WINMAIN_ */
  462. #ifdef WPRFLAG
  463. __winitenv = _wenviron;
  464. mainret = wmain(__argc, __wargv, _wenviron);
  465. #else
  466. __initenv = _environ;
  467. mainret = main(__argc, __argv, _environ);
  468. #endif
  469. #endif /* _WINMAIN_ */
  470. if ( !managedapp )
  471. exit(mainret);
  472. _cexit();
  473. }
  474. __except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
  475. {
  476. /*
  477. * Should never reach here
  478. */
  479. mainret = GetExceptionCode();
  480. if ( !managedapp )
  481. _exit(mainret);
  482. _c_exit();
  483. } /* end of try - except */
  484. return mainret;
  485. }
  486. #endif /* _POSIX_ */
  487. /***
  488. *_amsg_exit(rterrnum) - Fast exit fatal errors
  489. *
  490. *Purpose:
  491. * Exit the program with error code of 255 and appropriate error
  492. * message.
  493. *
  494. *Entry:
  495. * int rterrnum - error message number (amsg_exit only).
  496. *
  497. *Exit:
  498. * Calls exit() (for integer divide-by-0) or _exit() indirectly
  499. * through _aexit_rtn [amsg_exit].
  500. * For multi-thread: calls _exit() function
  501. *
  502. *Exceptions:
  503. *
  504. *******************************************************************************/
  505. void __cdecl _amsg_exit (
  506. int rterrnum
  507. )
  508. {
  509. #ifdef _WINMAIN_
  510. if ( __error_mode == _OUT_TO_STDERR )
  511. #else
  512. if ( __error_mode != _OUT_TO_MSGBOX )
  513. #endif
  514. _FF_MSGBANNER(); /* write run-time error banner */
  515. _NMSG_WRITE(rterrnum); /* write message */
  516. _aexit_rtn(255); /* normally _exit(255) */
  517. }
  518. /***
  519. *fast_error_exit(rterrnum) - Faster exit fatal errors
  520. *
  521. *Purpose:
  522. * Exit the process with error code of 255 and appropriate error
  523. * message.
  524. *
  525. *Entry:
  526. * int rterrnum - error message number (amsg_exit only).
  527. *
  528. *Exit:
  529. * Calls ExitProcess (through __crtExitProcess).
  530. *
  531. *Exceptions:
  532. *
  533. *******************************************************************************/
  534. static void __cdecl fast_error_exit (
  535. int rterrnum
  536. )
  537. {
  538. #ifdef _WINMAIN_
  539. if ( __error_mode == _OUT_TO_STDERR )
  540. #else
  541. if ( __error_mode != _OUT_TO_MSGBOX )
  542. #endif
  543. _FF_MSGBANNER(); /* write run-time error banner */
  544. _NMSG_WRITE(rterrnum); /* write message */
  545. __crtExitProcess(255); /* normally _exit(255) */
  546. }
  547. /***
  548. *check_managed_app() - Check for a managed executable
  549. *
  550. *Purpose:
  551. * Determine if the EXE the startup code is linked into is a managed app
  552. * by looking for the COM Runtime Descriptor in the Image Data Directory
  553. * of the PE or PE+ header.
  554. *
  555. *Entry:
  556. * None
  557. *
  558. *Exit:
  559. * 1 if managed app, 0 if not.
  560. *
  561. *Exceptions:
  562. *
  563. *******************************************************************************/
  564. static int __cdecl check_managed_app (
  565. void
  566. )
  567. {
  568. PIMAGE_DOS_HEADER pDOSHeader;
  569. PIMAGE_NT_HEADERS pPEHeader;
  570. PIMAGE_OPTIONAL_HEADER32 pNTHeader32;
  571. PIMAGE_OPTIONAL_HEADER64 pNTHeader64;
  572. pDOSHeader = (PIMAGE_DOS_HEADER)&__ImageBase;
  573. if ( pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE )
  574. return 0;
  575. pPEHeader = (PIMAGE_NT_HEADERS)((char *)pDOSHeader +
  576. pDOSHeader->e_lfanew);
  577. if ( pPEHeader->Signature != IMAGE_NT_SIGNATURE )
  578. return 0;
  579. pNTHeader32 = (PIMAGE_OPTIONAL_HEADER32)&pPEHeader->OptionalHeader;
  580. switch ( pNTHeader32->Magic ) {
  581. case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
  582. /* PE header */
  583. if ( pNTHeader32->NumberOfRvaAndSizes <=
  584. IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR )
  585. return 0;
  586. return !! pNTHeader32 ->
  587. DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR] .
  588. VirtualAddress;
  589. case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
  590. /* PE+ header */
  591. pNTHeader64 = (PIMAGE_OPTIONAL_HEADER64)pNTHeader32;
  592. if ( pNTHeader64->NumberOfRvaAndSizes <=
  593. IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR )
  594. return 0;
  595. return !! pNTHeader64 ->
  596. DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR] .
  597. VirtualAddress;
  598. }
  599. /* Not PE or PE+, so not managed */
  600. return 0;
  601. }
  602. #ifndef WPRFLAG
  603. #ifdef _POSIX_
  604. /***
  605. *RaiseException() - stub for posix FP routines
  606. *
  607. *Purpose:
  608. * Stub of a Win32 API that posix can't call
  609. *
  610. *Entry:
  611. *
  612. *Exit:
  613. *
  614. *Exceptions:
  615. *
  616. *******************************************************************************/
  617. VOID
  618. WINAPI
  619. RaiseException(
  620. DWORD dwExceptionCode,
  621. DWORD dwExceptionFlags,
  622. DWORD nNumberOfArguments,
  623. const ULONG_PTR * lpArguments
  624. )
  625. {
  626. }
  627. #endif /* _POSIX_ */
  628. #endif /* WPRFLAG */
  629. #endif /* CRTDLL */