home *** CD-ROM | disk | FTP | other *** search
- /***
- *crt0.c - C runtime initialization routine
- *
- * Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.
- *
- *Purpose:
- * This the actual startup routine for apps. It calls the user's main
- * routine [w]main() or [w]WinMain after performing C Run-Time Library
- * initialization.
- *
- * (With ifdef's, this source file also provides the source code for
- * wcrt0.c, the startup routine for console apps with wide characters,
- * wincrt0.c, the startup routine for Windows apps, and wwincrt0.c,
- * the startup routine for Windows apps with wide characters.)
- *
- *******************************************************************************/
-
- #ifdef _WIN32
-
- #ifndef CRTDLL
-
- #include <cruntime.h>
- #include <dos.h>
- #include <internal.h>
- #include <stdlib.h>
- #include <string.h>
- #include <rterr.h>
- #include <windows.h>
- #include <awint.h>
- #include <tchar.h>
- #include <dbgint.h>
-
- /*
- * wWinMain is not yet defined in winbase.h. When it is, this should be
- * removed.
- */
-
- int
- WINAPI
- wWinMain(
- HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPWSTR lpCmdLine,
- int nShowCmd
- );
-
- #ifdef WPRFLAG
- _TUCHAR * __cdecl _wwincmdln(void);
- #else /* WPRFLAG */
- _TUCHAR * __cdecl _wincmdln(void);
- #endif /* WPRFLAG */
-
- /*
- * command line, environment, and a few other globals
- */
-
- #ifdef WPRFLAG
- wchar_t *_wcmdln; /* points to wide command line */
- #else /* WPRFLAG */
- char *_acmdln; /* points to command line */
- #endif /* WPRFLAG */
-
- char *_aenvptr = NULL; /* points to environment block */
- wchar_t *_wenvptr = NULL; /* points to wide environment block */
-
-
- void (__cdecl * _aexit_rtn)(int) = _exit; /* RT message return procedure */
-
- static void __cdecl fast_error_exit(int); /* Error exit via ExitProcess */
-
- /*
- * _error_mode and _apptype, together, determine how error messages are
- * written out.
- */
- int __error_mode = _OUT_TO_DEFAULT;
- #ifdef _WINMAIN_
- int __app_type = _GUI_APP;
- #else /* _WINMAIN_ */
- int __app_type = _CONSOLE_APP;
- #endif /* _WINMAIN_ */
-
-
- /***
- *BaseProcessStartup(PVOID Peb)
- *
- *Purpose:
- * This routine does the C runtime initialization, calls main(), and
- * then exits. It never returns.
- *
- *Entry:
- * PVOID Peb - pointer to Win32 Process Environment Block (not used)
- *
- *Exit:
- * This function never returns.
- *
- *******************************************************************************/
-
- #ifdef _WINMAIN_
-
- #ifdef WPRFLAG
- void wWinMainCRTStartup(
- #else /* WPRFLAG */
- void WinMainCRTStartup(
- #endif /* WPRFLAG */
-
- #else /* _WINMAIN_ */
-
- #ifdef WPRFLAG
- void wmainCRTStartup(
- #else /* WPRFLAG */
- void mainCRTStartup(
- #endif /* WPRFLAG */
-
- #endif /* _WINMAIN_ */
- void
- )
-
- {
- int mainret;
-
- #ifdef _WINMAIN_
- _TUCHAR *lpszCommandLine;
- STARTUPINFO StartupInfo;
- #endif /* _WINMAIN_ */
-
- /*
- * Get the full Win32 version
- */
- _osver = GetVersion();
-
- _winminor = (_osver >> 8) & 0x00FF ;
- _winmajor = _osver & 0x00FF ;
- _winver = (_winmajor << 8) + _winminor;
- _osver = (_osver >> 16) & 0x00FFFF ;
-
- #ifdef _MT
- if ( !_heap_init(1) ) /* initialize heap */
- #else /* _MT */
- if ( !_heap_init(0) ) /* initialize heap */
- #endif /* _MT */
- fast_error_exit(_RT_HEAPINIT); /* write message and die */
-
- #ifdef _MT
- if( !_mtinit() ) /* initialize multi-thread */
- fast_error_exit(_RT_THREAD); /* write message and die */
- #endif /* _MT */
-
- /*
- * Guard the remainder of the initialization code and the call
- * to user's main, or WinMain, function in a __try/__except
- * statement.
- */
-
- __try {
-
- _ioinit(); /* initialize lowio */
-
- #ifdef WPRFLAG
- /* get wide cmd line info */
- _wcmdln = (wchar_t *)__crtGetCommandLineW();
-
- /* get wide environ info */
- _wenvptr = (wchar_t *)__crtGetEnvironmentStringsW();
-
- _wsetargv();
- _wsetenvp();
- #else /* WPRFLAG */
- /* get cmd line info */
- _acmdln = (char *)GetCommandLineA();
-
- /* get environ info */
- _aenvptr = (char *)__crtGetEnvironmentStringsA();
-
- _setargv();
- _setenvp();
- #endif /* WPRFLAG */
-
- _cinit(); /* do C data initialize */
-
- #ifdef _WINMAIN_
-
- StartupInfo.dwFlags = 0;
- GetStartupInfo( &StartupInfo );
-
- #ifdef WPRFLAG
- lpszCommandLine = _wwincmdln();
- mainret = wWinMain(
- #else /* WPRFLAG */
- lpszCommandLine = _wincmdln();
- mainret = WinMain(
- #endif /* WPRFLAG */
- GetModuleHandleA(NULL),
- NULL,
- lpszCommandLine,
- StartupInfo.dwFlags & STARTF_USESHOWWINDOW
- ? StartupInfo.wShowWindow
- : SW_SHOWDEFAULT
- );
- #else /* _WINMAIN_ */
-
- #ifdef WPRFLAG
- __winitenv = _wenviron;
- mainret = wmain(__argc, __wargv, _wenviron);
- #else /* WPRFLAG */
- __initenv = _environ;
- mainret = main(__argc, __argv, _environ);
- #endif /* WPRFLAG */
-
- #endif /* _WINMAIN_ */
- exit(mainret);
- }
- __except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
- {
- /*
- * Should never reach here
- */
- _exit( GetExceptionCode() );
-
- } /* end of try - except */
-
- }
-
-
-
- /***
- *_amsg_exit(rterrnum) - Fast exit fatal errors
- *
- *Purpose:
- * Exit the program with error code of 255 and appropriate error
- * message.
- *
- *Entry:
- * int rterrnum - error message number (amsg_exit only).
- *
- *Exit:
- * Calls exit() (for integer divide-by-0) or _exit() indirectly
- * through _aexit_rtn [amsg_exit].
- * For multi-thread: calls _exit() function
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- void __cdecl _amsg_exit (
- int rterrnum
- )
- {
- #ifdef _WINMAIN_
- if ( __error_mode == _OUT_TO_STDERR )
- #else /* _WINMAIN_ */
- if ( __error_mode != _OUT_TO_MSGBOX )
- #endif /* _WINMAIN_ */
- _FF_MSGBANNER(); /* write run-time error banner */
-
- _NMSG_WRITE(rterrnum); /* write message */
- _aexit_rtn(255); /* normally _exit(255) */
- }
-
- /***
- *fast_error_exit(rterrnum) - Faster exit fatal errors
- *
- *Purpose:
- * Exit the process with error code of 255 and appropriate error
- * message.
- *
- *Entry:
- * int rterrnum - error message number (amsg_exit only).
- *
- *Exit:
- * Calls ExitProcess.
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- static void __cdecl fast_error_exit (
- int rterrnum
- )
- {
- #ifdef _WINMAIN_
- if ( __error_mode == _OUT_TO_STDERR )
- #else /* _WINMAIN_ */
- if ( __error_mode != _OUT_TO_MSGBOX )
- #endif /* _WINMAIN_ */
- _FF_MSGBANNER(); /* write run-time error banner */
-
- _NMSG_WRITE(rterrnum); /* write message */
- ExitProcess(255); /* normally _exit(255) */
- }
-
- #ifndef WPRFLAG
-
-
- #endif /* WPRFLAG */
-
- #endif /* CRTDLL */
-
- #else /* _WIN32 */
-
- #include <cruntime.h>
- #include <internal.h>
- #include <stdlib.h>
- #include <msdos.h>
- #include <string.h>
- #include <setjmp.h>
- #include <dbgint.h>
- #include <macos\types.h>
- #include <macos\segload.h>
- #include <macos\gestalte.h>
- #include <macos\osutils.h>
- #include <macos\traps.h>
- #include <mpw.h>
-
- static void __cdecl Inherit(void); /* local function */
-
- int __cdecl main(int, char **, char **); /*generated by compiler*/
-
- unsigned long _GetShellStack(void);
-
- static char * __cdecl _p2cstr_internal ( unsigned char * str );
-
- extern MPWBLOCK * _pMPWBlock;
- extern int __argc;
- extern char **__argv;
-
- /***
- *__crt0()
- *
- *Purpose:
- * This routine does the C runtime initialization, calls main(), and
- * then exits. It never returns.
- *
- *Entry:
- *
- *Exit:
- * This function never returns.
- *
- *******************************************************************************/
-
- void __cdecl __crt0 (
- )
- {
- int mainret;
- char szPgmName[32];
- char *pArg;
- char *argv[2];
-
- #ifndef _M_MPPC
- void *pv;
-
- /* This is the magic stuff that MPW tools do to get info from MPW*/
-
- pv = (void *)*(int *)0x316;
- if (pv != NULL && !((int)pv & 1) && *(int *)pv == 'MPGM') {
- pv = (void *)*++(int *)pv;
- if (pv != NULL && *(short *)pv == 'SH') {
- _pMPWBlock = (MPWBLOCK *)pv;
- }
- }
-
- #endif /* _M_MPPC */
-
- _environ = NULL;
- if (_pMPWBlock == NULL) {
- __argc = 1;
- memcpy(szPgmName, (char *)0x910, sizeof(szPgmName));
- pArg = _p2cstr_internal(szPgmName);
- argv[0] = pArg;
- argv[1] = NULL;
- __argv = argv;
-
- #ifndef _M_MPPC
- _shellStack = 0; /* force ExitToShell */
- #endif /* _M_MPPC */
- }
- #ifndef _M_MPPC
- else {
- _shellStack = _GetShellStack(); //return current a6, or first a6
- _shellStack += 4; //a6 + 4 is the stack pointer we want
- __argc = _pMPWBlock->argc;
- __argv = _pMPWBlock->argv;
-
- Inherit(); /* Inherit file handles - env is set up by _envinit if needed */
- }
- #endif /* _M_MPPC */
-
- /*
- * call run time initializer
- */
- __cinit();
-
- mainret = main(__argc, __argv, _environ);
- exit(mainret);
- }
-
-
- #ifndef _M_MPPC
- /***
- *Inherit() - obtain and process info on inherited file handles.
- *
- *Purpose:
- *
- * Locates and interprets MPW std files. For files we just save the
- * file handles. For the console we save the device table address so
- * we can do console I/O. In the latter case, FDEV is set in the _osfile
- * array.
- *
- *Entry:
- * Address of MPW param table
- *
- *Exit:
- * No return value.
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- static void __cdecl Inherit (
- void
- )
- {
- MPWFILE *pFile;
- int i;
- pFile = _pMPWBlock->pFile;
- if (pFile == NULL) {
- return;
- }
- for (i = 0; i < 3; i++) {
- switch ((pFile->pDevice)->name) {
- case 'ECON':
- _osfile[i] |= FDEV | FOPEN;
- _osfhnd[i] = (int)pFile;
- break;
-
- case 'FSYS':
- _osfile[i] |= FOPEN;
- _osfhnd[i] = (*(pFile->ppFInfo))->ioRefNum;
- break;
- }
- pFile++;
- }
- }
-
- #endif /* _M_MPPC */
-
-
-
- static char * __cdecl _p2cstr_internal (
- unsigned char * str
- )
- {
- unsigned char *pchSrc;
- unsigned char *pchDst;
- int cch;
-
- if ( str && *str ) {
- pchDst = str;
- pchSrc = str + 1;
-
- for ( cch=*pchDst; cch; --cch ) {
- *pchDst++ = *pchSrc++;
- }
-
- *pchDst = '\0';
- }
-
- return( str );
- }
-
- #endif /* _WIN32 */
-