diff options
Diffstat (limited to 'private/crt32/startup/dllcrt0.c')
-rw-r--r-- | private/crt32/startup/dllcrt0.c | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/private/crt32/startup/dllcrt0.c b/private/crt32/startup/dllcrt0.c new file mode 100644 index 000000000..9f3b7003a --- /dev/null +++ b/private/crt32/startup/dllcrt0.c @@ -0,0 +1,306 @@ +#ifndef _POSIX_ /* not built for POSIX */ +#ifndef CRTDLL /* not built for CRTDLL */ + +/*** +*dllcrt0.c - C runtime initialization routine for a DLL with linked-in C R-T +* +* Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This the startup routine for a DLL which is linked with its own +* C run-time code. It is similar to the routine _mainCRTStartup() +* in the file CRT0.C, except that there is no main() in a DLL. +* +*Revision History: +* 05-04-92 SKS Based on CRT0.C (start-up code for EXE's) +* 08-26-92 SKS Add _osver, _winver, _winmajor, _winminor +* 09-16-92 SKS This module used to be enabled only in LIBCMT.LIB, +* but it is now enabled for LIBC.LIB as well! +* 09-29-92 SKS _CRT_INIT needs to be WINAPI, not cdecl +* 10-16-92 SKS Call _heap_init before _mtinit (fix copied from CRT0.C) +* 10-24-92 SKS Call to _mtdeletelocks() must be under #ifdef MTHREAD! +* 04-16-93 SKS Call _mtterm instead of _mtdeletelocks on +* PROCESS_DETACH to do all multi-thread cleanup +* It will call _mtdeletelocks and free up the TLS index. +* 04-27-93 GJF Removed support for _RT_STACK, _RT_INTDIV, +* _RT_INVALDISP and _RT_NONCONT. +* 05-11-93 SKS Add _DllMainCRTStartup to co-exist with _CRT_INIT +* _mtinit now returns 0 or 1, no longer calls _amsg_exit +* Delete obsolete variable _atopsp +* 06-03-93 GJF Added __proc_attached flag. +* 06-08-93 SKS Clean up failure handling in _CRT_INIT +* 12-13-93 SKS Free up per-thread CRT data on DLL_THREAD_DETACH +* using a call to _freeptd() in _CRT_INIT() +* +*******************************************************************************/ + +#include <cruntime.h> +#include <dos.h> +#include <internal.h> +#include <stdlib.h> +#include <string.h> +#include <rterr.h> +#include <oscalls.h> +#define _DECL_DLLMAIN /* enable prototypes for DllMain and _CRT_INIT */ +#include <process.h> + + +/* + * 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 */ + + +/* + * User routine DllMain is called on all notifications + */ + +extern BOOL WINAPI DllMain( + HANDLE hDllHandle, + DWORD dwReason, + LPVOID lpreserved + ) ; + + +/*** +*BOOL WINAPI _CRT_INIT(hDllHandle, dwReason, lpreserved) - C Run-Time +* initialization for a DLL linked with a C run-time library. +* +*Purpose: +* This routine does the C run-time initialization. +* For the multi-threaded run-time library, it also cleans up the +* multi-threading locks on DLL termination. +* +*Entry: +* +*Exit: +* +*NOTES: +* This routine should either be the entry-point for the DLL +* or else be called by the entry-point routine for the DLL. +* +*******************************************************************************/ + +BOOL WINAPI +_CRT_INIT( + HANDLE hDllHandle, + DWORD dwReason, + LPVOID lpreserved + ) +{ + switch (dwReason) { + case DLL_PROCESS_DETACH: + /* + * make sure there has been prior process attach + * notification! + */ + if ( __proc_attached > 0 ) { + __proc_attached--; + + if ( _C_Termination_Done == FALSE ) { + /* do exit() time clean-up */ + _cexit(); + } + +#ifdef MTHREAD + /* delete MT locks, free TLS index, etc. */ + _mtterm(); +#endif + if (_aenvptr) { + FreeEnvironmentStrings(_aenvptr); + _aenvptr=NULL; + } + + return TRUE; + + } else { + /* no prior process attach, just return */ + return FALSE; + } + +#ifdef MTHREAD + case DLL_THREAD_DETACH: + _freeptd(NULL); /* free up per-thread CRT data */ + + case DLL_THREAD_ATTACH: + return TRUE; +#endif + + case DLL_PROCESS_ATTACH: + + /* + * increment flag to indicate process attach notification has been + * received + */ + __proc_attached++; + + _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 */ + FreeEnvironmentStrings(_aenvptr); + return FALSE; /* fail to load DLL */ + } +#endif + _ioinit(); /* initialize lowio */ + _setargv(); /* get cmd line info */ + _setenvp(); /* get environ info */ + + _cinit(); /* do C data initialize */ + + return TRUE; /* initialization succeeded */ + } +} + + +/*** +*BOOL WINAPI _DllMainCRTStartup(hDllHandle, dwReason, lpreserved) - +* C Run-Time initialization for a DLL linked with a C run-time library. +* +*Purpose: +* This routine does the C run-time initialization or termination +* and then calls the user code notification handler "DllMain". +* For the multi-threaded run-time library, it also cleans up the +* multi-threading locks on DLL termination. +* +*Entry: +* +*Exit: +* +*NOTES: +* This routine should be the entry point for the DLL if +* the user is not supplying one and calling _CRT_INIT. +* +*******************************************************************************/ +BOOL WINAPI _DllMainCRTStartup( + HANDLE hDllHandle, + DWORD dwReason, + LPVOID lpreserved + ) +{ + BOOL retcode = TRUE; + + /* + * If this is a process attach notification, increment the process + * attached flag. If this is a process detach notification, check + * that there has been a prior process attach notification. + */ + if ( dwReason == DLL_PROCESS_ATTACH ) + __proc_attached++; + else if ( dwReason == DLL_PROCESS_DETACH ) { + if ( __proc_attached > 0 ) + __proc_attached--; + else + /* + * no prior process attach notification. just return + * without doing anything. + */ + return FALSE; + } + + if ( dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH ) + retcode = _CRT_INIT(hDllHandle, dwReason, lpreserved); + + if ( retcode ) + retcode = DllMain(hDllHandle, dwReason, lpreserved); + + /* + * If _CRT_INIT successfully handles a Process Attach notification + * but the user's DllMain routine returns failure, we need to do + * clean-up of the C run-time similar to what _CRT_INIT does on a + * Process Detach Notification. + */ + + if ( retcode == FALSE && dwReason == DLL_PROCESS_ATTACH ) + { + /* Failure to attach DLL - must clean up C run-time */ +#ifdef MTHREAD + _mtterm(); +#endif + if (_aenvptr) { + FreeEnvironmentStrings(_aenvptr); + _aenvptr=NULL; + } + } + + if ( dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH ) + { + if ( _CRT_INIT(hDllHandle, dwReason, lpreserved) == FALSE ) + retcode = FALSE ; + } + + return retcode ; +} + + +/*** +*_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 */ +#endif /* _POSIX_ */ |