#ifdef CRTDLL /*** *crtlib.c - CRT DLL initialization and termination routine (Win32, Dosx32) * * Copyright (c) 1991-1993, Microsoft Corporation. All rights reserved. * *Purpose: * This module contains initialization entry point for the CRT DLL in * Win32 and Dosx32 environments. It also contains some of the supporting * initialization and termination code. * *Revision History: * 08-12-91 GJF Module created. Sort of. * 01-17-92 GJF Return exception code value for RTEs corresponding * to exceptions. * 01-29-92 GJF Support for wildcard expansion in filenames on the * command line. * 02-14-92 GJF Moved file inheritance stuff to ioinit.c. Call to * inherit() is replace by call to _ioinit(). * 08-26-92 SKS Add _osver, _winver, _winmajor, _winminor * 09-04-92 GJF Replaced _CALLTYPE3 with WINAPI. * 09-30-92 SRW Call _heap_init before _mtinit * 10-19-92 SKS Add "dowildcard" parameter to GetMainArgs() * Prepend a second "_" to name since it is internal-only * 04-16-93 SKS Change call to _mtdeletelocks to _mtterm. _mtterm * calls _mtdeletelocks and also frees up the TLS index. * 04-27-93 GJF Removed support for _RT_STACK, _RT_INTDIV, * _RT_INVALDISP and _RT_NONCONT. * 05-11-93 SKS Change _CRTDLL_INIT to fail loading on failure to * initialize/clean up, rather than calling _amsg_exit(). * 06-03-93 GJF Added __proc_attached flag. * 06-07-93 GJF Incorporated SteveWo's code to call LoadLibrary, from * crtdll.c. * 12-14-93 SKS Add _freeptd(), which frees up the per-thread data * maintained by the C run-time library. * *******************************************************************************/ #include #include #include #include #include #include #include #include #include /* * flag set iff _CRTDLL_INIT was called with DLL_PROCESS_ATTACH */ static int __proc_attached = 0; /* * command line, environment, and a few other globals */ char *_acmdln; /* points to command line */ char *_aenvptr; /* points to environment block */ void (_CALLTYPE1 * _aexit_rtn)(int) = _exit; /* RT message return procedure */ static void _CALLTYPE4 inherit(void); /* local function */ /*** *void __GetMainArgs(pargc, pargv, penvp, dowildcard) - get values for args to main() * *Purpose: * This function invokes the command line parsing and copies the args * to main back through the passsed pointers. The reason for doing * this here, rather than having _CRTDLL_INIT do the work and exporting * the __argc and __argv, is to support the linked-in option to have * wildcard characters in filename arguments expanded. * *Entry: * int *pargc - pointer to argc * char ***pargv - pointer to argv * char ***penvp - pointer to envp * int dowildcard - flag (true means expand wildcards in cmd line) * *Exit: * No return value. Values for the arguments to main() are copied through * the passed pointers. * *******************************************************************************/ void _CALLTYPE1 __GetMainArgs ( int *pargc, char ***pargv, char ***penvp, int dowildcard) { if ( dowildcard ) __setargv(); /* do wildcard expansion after parsing args */ else _setargv(); /* NO wildcard expansion; just parse args */ *pargc = __argc; *pargv = __argv; *penvp = _environ; } /*** *BOOL _CRTDLL_INIT(hDllHandle, dwReason, lpreserved) - C DLL initialization. * *Purpose: * This routine does the C runtime initialization. * *Entry: * *Exit: * *******************************************************************************/ BOOL WINAPI _CRTDLL_INIT( HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved ) { char szDllName[ MAX_PATH ]; if ( dwReason == DLL_PROCESS_ATTACH ) { /* * Increment flag indicating process attach notification * has been received. */ __proc_attached++; /* * Pin ourselves in memory since we dont clean up if we * unload. */ if ( !GetModuleFileName( hDllHandle, szDllName, sizeof(szDllName)) ) { strcpy(szDllName, "CRTDLL"); } LoadLibrary(szDllName); } else if ( dwReason == DLL_PROCESS_DETACH ) { /* * if this is a process detach notification, make sure there * has been a prior process attach notification. */ if ( __proc_attached > 0 ) __proc_attached--; else /* no prior process attach, just return */ return FALSE; } else if ( dwReason == DLL_THREAD_DETACH ) { _freeptd(NULL); /* free up per-thread CRT data */ } /* * Only do initialization when a client process attaches to * the DLL. */ if ( dwReason != DLL_PROCESS_ATTACH ) { /* * if a client process is detaching, make sure minimal * runtime termination is performed and clean up our * 'locks' (i.e., delete critical sections). */ if ( dwReason == DLL_PROCESS_DETACH ) { if ( _C_Termination_Done == FALSE ) _c_exit(); #ifdef MTHREAD _mtterm(); /* free TLS index, call _mtdeletelocks() */ #endif } return TRUE; } _acmdln = (char *)GetCommandLine(); _aenvptr = (char *)GetEnvironmentStrings(); /* * Get the full Win32 version */ _osversion = /* OBSOLETE */ _osver = GetVersion(); _winminor = (_osver >> 8) & 0x00FF ; _winmajor = _osver & 0x00FF ; _winver = (_winmajor << 8) + _winminor; _osver = (_osver >> 16) & 0x00FFFF ; /* --------- The following block is OBSOLETE --------- */ /* * unpack base version info */ _baseversion = (_osversion & 0xFFFF0000) >> 16; _baseminor = _baseversion & 0x00FF; _basemajor = (_baseversion & 0xFF00) >> 8; /* * unpack top-level version info (Windows version) */ _osversion &= 0x0000FFFF; _osmajor = _osversion & 0x00FF; _osminor = (_osversion & 0xFF00) >> 8; /* --------- The preceding block is OBSOLETE --------- */ _heap_init(); /* initialize heap */ #ifdef MTHREAD if(!_mtinit()) /* initialize multi-thread */ return FALSE; /* fail DLL load on failure */ #endif _ioinit(); /* inherit file info */ _setenvp(); /* get environ info */ _cinit(); /* do C data initialize */ return TRUE; } /*** *_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 _CALLTYPE1 _amsg_exit ( int rterrnum ) { _FF_MSGBANNER(); /* write run-time error banner */ _NMSG_WRITE(rterrnum); /* write message */ _aexit_rtn(255); /* normally _exit(255) */ } #endif /* CRTDLL */