home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / crt0.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  12KB  |  471 lines

  1. /***
  2. *crt0.c - C runtime initialization routine
  3. *
  4. *       Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       This 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 ifdef's, this source file also provides the source code for
  12. *       wcrt0.c, the startup routine for console apps with wide characters,
  13. *       wincrt0.c, the startup routine for Windows apps, and wwincrt0.c,
  14. *       the startup routine for Windows apps with wide characters.)
  15. *
  16. *******************************************************************************/
  17.  
  18. #ifdef _WIN32
  19.  
  20. #ifndef CRTDLL
  21.  
  22. #include <cruntime.h>
  23. #include <dos.h>
  24. #include <internal.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <rterr.h>
  28. #include <windows.h>
  29. #include <awint.h>
  30. #include <tchar.h>
  31. #include <dbgint.h>
  32.  
  33. /*
  34.  * wWinMain is not yet defined in winbase.h. When it is, this should be
  35.  * removed.
  36.  */
  37.  
  38. int
  39. WINAPI
  40. wWinMain(
  41.     HINSTANCE hInstance,
  42.     HINSTANCE hPrevInstance,
  43.     LPWSTR lpCmdLine,
  44.     int nShowCmd
  45.     );
  46.  
  47. #ifdef WPRFLAG
  48. _TUCHAR * __cdecl _wwincmdln(void);
  49. #else  /* WPRFLAG */
  50. _TUCHAR * __cdecl _wincmdln(void);
  51. #endif  /* WPRFLAG */
  52.  
  53. /*
  54.  * command line, environment, and a few other globals
  55.  */
  56.  
  57. #ifdef WPRFLAG
  58. wchar_t *_wcmdln;           /* points to wide command line */
  59. #else  /* WPRFLAG */
  60. char *_acmdln;              /* points to command line */
  61. #endif  /* WPRFLAG */
  62.  
  63. char *_aenvptr = NULL;      /* points to environment block */
  64. wchar_t *_wenvptr = NULL;   /* points to wide environment block */
  65.  
  66.  
  67. void (__cdecl * _aexit_rtn)(int) = _exit;   /* RT message return procedure */
  68.  
  69. static void __cdecl fast_error_exit(int);   /* Error exit via ExitProcess */
  70.  
  71. /*
  72.  * _error_mode and _apptype, together, determine how error messages are
  73.  * written out.
  74.  */
  75. int __error_mode = _OUT_TO_DEFAULT;
  76. #ifdef _WINMAIN_
  77. int __app_type = _GUI_APP;
  78. #else  /* _WINMAIN_ */
  79. int __app_type = _CONSOLE_APP;
  80. #endif  /* _WINMAIN_ */
  81.  
  82.  
  83. /***
  84. *BaseProcessStartup(PVOID Peb)
  85. *
  86. *Purpose:
  87. *       This routine does the C runtime initialization, calls main(), and
  88. *       then exits.  It never returns.
  89. *
  90. *Entry:
  91. *       PVOID Peb - pointer to Win32 Process Environment Block (not used)
  92. *
  93. *Exit:
  94. *       This function never returns.
  95. *
  96. *******************************************************************************/
  97.  
  98. #ifdef _WINMAIN_
  99.  
  100. #ifdef WPRFLAG
  101. void wWinMainCRTStartup(
  102. #else  /* WPRFLAG */
  103. void WinMainCRTStartup(
  104. #endif  /* WPRFLAG */
  105.  
  106. #else  /* _WINMAIN_ */
  107.  
  108. #ifdef WPRFLAG
  109. void wmainCRTStartup(
  110. #else  /* WPRFLAG */
  111. void mainCRTStartup(
  112. #endif  /* WPRFLAG */
  113.  
  114. #endif  /* _WINMAIN_ */
  115.         void
  116.         )
  117.  
  118. {
  119.         int mainret;
  120.  
  121. #ifdef _WINMAIN_
  122.         _TUCHAR *lpszCommandLine;
  123.         STARTUPINFO StartupInfo;
  124. #endif  /* _WINMAIN_ */
  125.  
  126.         /*
  127.          * Get the full Win32 version
  128.          */
  129.         _osver = GetVersion();
  130.  
  131.         _winminor = (_osver >> 8) & 0x00FF ;
  132.         _winmajor = _osver & 0x00FF ;
  133.         _winver = (_winmajor << 8) + _winminor;
  134.         _osver = (_osver >> 16) & 0x00FFFF ;
  135.  
  136. #ifdef _MT
  137.         if ( !_heap_init(1) )               /* initialize heap */
  138. #else  /* _MT */
  139.         if ( !_heap_init(0) )               /* initialize heap */
  140. #endif  /* _MT */
  141.             fast_error_exit(_RT_HEAPINIT);  /* write message and die */
  142.  
  143. #ifdef _MT
  144.         if( !_mtinit() )                    /* initialize multi-thread */
  145.             fast_error_exit(_RT_THREAD);    /* write message and die */
  146. #endif  /* _MT */
  147.  
  148.         /*
  149.          * Guard the remainder of the initialization code and the call
  150.          * to user's main, or WinMain, function in a __try/__except
  151.          * statement.
  152.          */
  153.  
  154.         __try {
  155.  
  156.             _ioinit();                      /* initialize lowio */
  157.  
  158. #ifdef WPRFLAG
  159.             /* get wide cmd line info */
  160.             _wcmdln = (wchar_t *)__crtGetCommandLineW();
  161.  
  162.             /* get wide environ info */
  163.             _wenvptr = (wchar_t *)__crtGetEnvironmentStringsW();
  164.  
  165.             _wsetargv();
  166.             _wsetenvp();
  167. #else  /* WPRFLAG */
  168.             /* get cmd line info */
  169.             _acmdln = (char *)GetCommandLineA();
  170.  
  171.             /* get environ info */
  172.             _aenvptr = (char *)__crtGetEnvironmentStringsA();
  173.  
  174.             _setargv();
  175.             _setenvp();
  176. #endif  /* WPRFLAG */
  177.  
  178.             _cinit();                       /* do C data initialize */
  179.  
  180. #ifdef _WINMAIN_
  181.  
  182.             StartupInfo.dwFlags = 0;
  183.             GetStartupInfo( &StartupInfo );
  184.  
  185. #ifdef WPRFLAG
  186.             lpszCommandLine = _wwincmdln();
  187.             mainret = wWinMain(
  188. #else  /* WPRFLAG */
  189.             lpszCommandLine = _wincmdln();
  190.             mainret = WinMain(
  191. #endif  /* WPRFLAG */
  192.                                GetModuleHandleA(NULL),
  193.                                NULL,
  194.                                lpszCommandLine,
  195.                                StartupInfo.dwFlags & STARTF_USESHOWWINDOW
  196.                                     ? StartupInfo.wShowWindow
  197.                                     : SW_SHOWDEFAULT
  198.                              );
  199. #else  /* _WINMAIN_ */
  200.  
  201. #ifdef WPRFLAG
  202.             __winitenv = _wenviron;
  203.             mainret = wmain(__argc, __wargv, _wenviron);
  204. #else  /* WPRFLAG */
  205.             __initenv = _environ;
  206.             mainret = main(__argc, __argv, _environ);
  207. #endif  /* WPRFLAG */
  208.  
  209. #endif  /* _WINMAIN_ */
  210.             exit(mainret);
  211.         }
  212.         __except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
  213.         {
  214.             /*
  215.              * Should never reach here
  216.              */
  217.             _exit( GetExceptionCode() );
  218.  
  219.         } /* end of try - except */
  220.  
  221. }
  222.  
  223.  
  224.  
  225. /***
  226. *_amsg_exit(rterrnum) - Fast exit fatal errors
  227. *
  228. *Purpose:
  229. *       Exit the program with error code of 255 and appropriate error
  230. *       message.
  231. *
  232. *Entry:
  233. *       int rterrnum - error message number (amsg_exit only).
  234. *
  235. *Exit:
  236. *       Calls exit() (for integer divide-by-0) or _exit() indirectly
  237. *       through _aexit_rtn [amsg_exit].
  238. *       For multi-thread: calls _exit() function
  239. *
  240. *Exceptions:
  241. *
  242. *******************************************************************************/
  243.  
  244. void __cdecl _amsg_exit (
  245.         int rterrnum
  246.         )
  247. {
  248. #ifdef _WINMAIN_
  249.         if ( __error_mode == _OUT_TO_STDERR )
  250. #else  /* _WINMAIN_ */
  251.         if ( __error_mode != _OUT_TO_MSGBOX )
  252. #endif  /* _WINMAIN_ */
  253.             _FF_MSGBANNER();    /* write run-time error banner */
  254.  
  255.         _NMSG_WRITE(rterrnum);  /* write message */
  256.         _aexit_rtn(255);        /* normally _exit(255) */
  257. }
  258.  
  259. /***
  260. *fast_error_exit(rterrnum) - Faster exit fatal errors
  261. *
  262. *Purpose:
  263. *       Exit the process with error code of 255 and appropriate error
  264. *       message.
  265. *
  266. *Entry:
  267. *       int rterrnum - error message number (amsg_exit only).
  268. *
  269. *Exit:
  270. *       Calls ExitProcess.
  271. *
  272. *Exceptions:
  273. *
  274. *******************************************************************************/
  275.  
  276. static void __cdecl fast_error_exit (
  277.         int rterrnum
  278.         )
  279. {
  280. #ifdef _WINMAIN_
  281.         if ( __error_mode == _OUT_TO_STDERR )
  282. #else  /* _WINMAIN_ */
  283.         if ( __error_mode != _OUT_TO_MSGBOX )
  284. #endif  /* _WINMAIN_ */
  285.             _FF_MSGBANNER();    /* write run-time error banner */
  286.  
  287.         _NMSG_WRITE(rterrnum);  /* write message */
  288.         ExitProcess(255);       /* normally _exit(255) */
  289. }
  290.  
  291. #ifndef WPRFLAG
  292.  
  293.  
  294. #endif  /* WPRFLAG */
  295.  
  296. #endif  /* CRTDLL */
  297.  
  298. #else  /* _WIN32 */
  299.  
  300. #include <cruntime.h>
  301. #include <internal.h>
  302. #include <stdlib.h>
  303. #include <msdos.h>
  304. #include <string.h>
  305. #include <setjmp.h>
  306. #include <dbgint.h>
  307. #include <macos\types.h>
  308. #include <macos\segload.h>
  309. #include <macos\gestalte.h>
  310. #include <macos\osutils.h>
  311. #include <macos\traps.h>
  312. #include <mpw.h>
  313.  
  314. static void __cdecl Inherit(void);  /* local function */
  315.  
  316. int __cdecl main(int, char **, char **);             /*generated by compiler*/
  317.  
  318. unsigned long _GetShellStack(void);
  319.  
  320. static char * __cdecl _p2cstr_internal ( unsigned char * str );
  321.  
  322. extern MPWBLOCK * _pMPWBlock;
  323. extern int __argc;
  324. extern char **__argv;
  325.  
  326. /***
  327. *__crt0()
  328. *
  329. *Purpose:
  330. *       This routine does the C runtime initialization, calls main(), and
  331. *       then exits.  It never returns.
  332. *
  333. *Entry:
  334. *
  335. *Exit:
  336. *       This function never returns.
  337. *
  338. *******************************************************************************/
  339.  
  340. void __cdecl __crt0 (
  341.         )
  342. {
  343.         int mainret;
  344.         char szPgmName[32];
  345.         char *pArg;
  346.         char *argv[2];
  347.  
  348. #ifndef _M_MPPC
  349.         void *pv;
  350.  
  351.         /* This is the magic stuff that MPW tools do to get info from MPW*/
  352.  
  353.         pv = (void *)*(int *)0x316;
  354.         if (pv != NULL && !((int)pv & 1) && *(int *)pv == 'MPGM') {
  355.             pv = (void *)*++(int *)pv;
  356.             if (pv != NULL && *(short *)pv == 'SH') {
  357.                 _pMPWBlock = (MPWBLOCK *)pv;
  358.             }
  359.         }
  360.  
  361. #endif  /* _M_MPPC */
  362.  
  363.         _environ = NULL;
  364.         if (_pMPWBlock == NULL) {
  365.             __argc = 1;
  366.             memcpy(szPgmName, (char *)0x910, sizeof(szPgmName));
  367.             pArg = _p2cstr_internal(szPgmName);
  368.             argv[0] = pArg;
  369.             argv[1] = NULL;
  370.             __argv = argv;
  371.  
  372. #ifndef _M_MPPC
  373.             _shellStack = 0;                        /* force ExitToShell */
  374. #endif  /* _M_MPPC */
  375.         }
  376. #ifndef _M_MPPC
  377.         else {
  378.             _shellStack = _GetShellStack();        //return current a6, or first a6
  379.             _shellStack += 4;                      //a6 + 4 is the stack pointer we want
  380.             __argc = _pMPWBlock->argc;
  381.             __argv = _pMPWBlock->argv;
  382.  
  383.             Inherit();       /* Inherit file handles - env is set up by _envinit if needed */
  384.         }
  385. #endif  /* _M_MPPC */
  386.  
  387.         /*
  388.          * call run time initializer
  389.          */
  390.         __cinit();
  391.  
  392.         mainret = main(__argc, __argv, _environ);
  393.         exit(mainret);
  394. }
  395.  
  396.  
  397. #ifndef _M_MPPC
  398. /***
  399. *Inherit() - obtain and process info on inherited file handles.
  400. *
  401. *Purpose:
  402. *
  403. *       Locates and interprets MPW std files.  For files we just save the
  404. *       file handles.   For the console we save the device table address so
  405. *       we can do console I/O.  In the latter case, FDEV is set in the _osfile
  406. *       array.
  407. *
  408. *Entry:
  409. *       Address of MPW param table
  410. *
  411. *Exit:
  412. *       No return value.
  413. *
  414. *Exceptions:
  415. *
  416. *******************************************************************************/
  417.  
  418. static void __cdecl Inherit (
  419.         void
  420.         )
  421. {
  422.         MPWFILE *pFile;
  423.         int i;
  424.         pFile = _pMPWBlock->pFile;
  425.         if (pFile == NULL) {
  426.             return;
  427.         }
  428.         for (i = 0; i < 3; i++) {
  429.             switch ((pFile->pDevice)->name) {
  430.                 case 'ECON':
  431.                     _osfile[i] |= FDEV | FOPEN;
  432.                     _osfhnd[i] = (int)pFile;
  433.                     break;
  434.  
  435.                 case 'FSYS':
  436.                     _osfile[i] |= FOPEN;
  437.                     _osfhnd[i] = (*(pFile->ppFInfo))->ioRefNum;
  438.                     break;
  439.             }
  440.             pFile++;
  441.         }
  442. }
  443.  
  444. #endif  /* _M_MPPC */
  445.  
  446.  
  447.  
  448. static char * __cdecl _p2cstr_internal (
  449.         unsigned char * str
  450.         )
  451. {
  452.         unsigned char *pchSrc;
  453.         unsigned char *pchDst;
  454.         int  cch;
  455.  
  456.         if ( str && *str ) {
  457.             pchDst = str;
  458.             pchSrc = str + 1;
  459.  
  460.             for ( cch=*pchDst; cch; --cch ) {
  461.                 *pchDst++ = *pchSrc++;
  462.             }
  463.  
  464.             *pchDst = '\0';
  465.         }
  466.  
  467.         return( str );
  468. }
  469.  
  470. #endif  /* _WIN32 */
  471.