/*** *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 #include #include #include #include #include #include #include #include #include /* * 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 #include #include #include #include #include #include #include #include #include #include #include #include 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 */