home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
vc98
/
crt
/
src
/
dllcrt0.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-17
|
11KB
|
371 lines
/***
*dllcrt0.c - C runtime initialization routine for a DLL with linked-in C R-T
*
* Copyright (c) 1989-1997, 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.
*
*******************************************************************************/
#ifdef _WIN32
#ifndef CRTDLL
#include <cruntime.h>
#include <dos.h>
#include <internal.h>
#include <mtdll.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>
#include <awint.h>
#include <tchar.h>
#include <dbgint.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 = NULL; /* points to environment block */
wchar_t *_wenvptr = NULL; /* points to wide environment block */
void (__cdecl * _aexit_rtn)(int) = _exit; /* RT message return procedure */
/*
* _error_mode and _apptype, together, determine how error messages are
* written out.
*/
int __error_mode = _OUT_TO_DEFAULT;
int __app_type = _UNKNOWN_APP;
/*
* User routine DllMain is called on all notifications
*/
extern BOOL WINAPI DllMain(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
) ;
/* _pRawDllMain MUST be a common variable, not extern nor initialized! */
BOOL (WINAPI *_pRawDllMain)(HANDLE, DWORD, LPVOID);
/***
*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 or termination.
* For the multi-threaded run-time library, it also cleans up the
* multi-threading locks on DLL termination.
*
*Entry:
*
*Exit:
*
*NOTES:
* This routine must be the entry point for the DLL.
*
*******************************************************************************/
BOOL WINAPI _CRT_INIT(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
)
{
/*
* Start-up code only gets executed when the process is initialized
*/
if ( dwReason == DLL_PROCESS_ATTACH )
{
/*
* Get the full Win32 version
*/
_osver = GetVersion();
#ifdef _MT
if ( !_heap_init(1) ) /* initialize heap */
#else /* _MT */
if ( !_heap_init(0) ) /* initialize heap */
#endif /* _MT */
return FALSE; /* fail to load DLL */
_winminor = (_osver >> 8) & 0x00FF ;
_winmajor = _osver & 0x00FF ;
_winver = (_winmajor << 8) + _winminor;
_osver = (_osver >> 16) & 0x00FFFF ;
#ifdef _MT
if(!_mtinit()) /* initialize multi-thread */
{
_heap_term(); /* heap is now invalid! */
return FALSE; /* fail to load DLL */
}
#endif /* _MT */
_acmdln = (char *)GetCommandLineA();
_aenvptr = (char *)__crtGetEnvironmentStringsA();
_ioinit(); /* initialize lowio */
_setargv(); /* get cmd line info */
_setenvp(); /* get environ info */
_cinit(); /* do C data initialize */
/*
* increment flag to indicate process attach notification
* has been received
*/
__proc_attached++;
}
else if ( dwReason == DLL_PROCESS_DETACH )
{
if ( __proc_attached > 0 )
{
__proc_attached--;
/*
* Any basic clean-up code that goes here must be duplicated
* below in _DllMainCRTStartup for the case where the user's
* DllMain() routine fails on a Process Attach notification.
* This does not include calling user C++ destructors, etc.
*/
if ( _C_Termination_Done == FALSE )
_cexit();
#ifdef _DEBUG
/* Dump all memory leaks */
if (_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) & _CRTDBG_LEAK_CHECK_DF)
_CrtDumpMemoryLeaks();
#endif /* _DEBUG */
/* Shut down lowio */
_ioterm();
#ifdef _MT
_mtterm();
#endif /* _MT */
/* This should be the last thing the C run-time does */
_heap_term(); /* heap is now invalid! */
}
else
/* no prior process attach, just return */
return FALSE;
}
#ifdef _MT
else if ( dwReason == DLL_THREAD_DETACH )
{
_freeptd(NULL); /* free up per-thread CRT data */
}
#endif /* _MT */
return TRUE ;
}
/***
*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 is the preferred entry point. _CRT_INIT may also be
* used, or the user may supply his/her own entry and call _CRT_INIT
* from within it, but this is not the preferred method.
*
*******************************************************************************/
BOOL WINAPI _DllMainCRTStartup(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
)
{
BOOL retcode = TRUE;
/*
* If this is a process detach notification, check that there has
* has been a prior process attach notification.
*/
if ( (dwReason == DLL_PROCESS_DETACH) && (__proc_attached == 0) )
/*
* no prior process attach notification. just return
* without doing anything.
*/
return FALSE;
if ( dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH )
{
if ( _pRawDllMain )
retcode = (*_pRawDllMain)(hDllHandle, dwReason, lpreserved);
if ( retcode )
retcode = _CRT_INIT(hDllHandle, dwReason, lpreserved);
if ( !retcode )
return FALSE;
}
retcode = DllMain(hDllHandle, dwReason, lpreserved);
if ( (dwReason == DLL_PROCESS_ATTACH) && !retcode )
/*
* The user's DllMain routine returned failure, the C runtime
* needs to be cleaned up. Do this by calling _CRT_INIT again,
* this time imitating DLL_PROCESS_DETACH. Note this will also
* clear the __proc_attached flag so the cleanup will not be
* repeated upon receiving the real process detach notification.
*/
_CRT_INIT(hDllHandle, DLL_PROCESS_DETACH, lpreserved);
if ( (dwReason == DLL_PROCESS_DETACH) ||
(dwReason == DLL_THREAD_DETACH) )
{
if ( _CRT_INIT(hDllHandle, dwReason, lpreserved) == FALSE )
retcode = FALSE ;
if ( retcode && _pRawDllMain )
retcode = (*_pRawDllMain)(hDllHandle, dwReason, lpreserved);
}
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 __cdecl _amsg_exit (
int rterrnum
)
{
if ( (__error_mode == _OUT_TO_STDERR) || ((__error_mode ==
_OUT_TO_DEFAULT) && (__app_type == _CONSOLE_APP)) )
_FF_MSGBANNER(); /* write run-time error banner */
_NMSG_WRITE(rterrnum); /* write message */
_aexit_rtn(255); /* normally _exit(255) */
}
#endif /* CRTDLL */
#else /* _WIN32 */
#include <cruntime.h>
#include <dos.h>
#include <internal.h>
#include <stdlib.h>
#include <string.h>
#include <dbgint.h>
#include <macos\fragload.h>
/*
* User routine DllMain is called on all notifications
*/
OSErr _DllInit(InitBlockPtr pinitBlk);
void _DllExit(void);
void _CALLTYPE1 _cexit (void);
/***
*OSErr _DllMainCRTStartup(void) -
* 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".
*
*Entry:
*
*Exit:
*
*NOTES:
* This routine is the preferred entry point.
*
*******************************************************************************/
OSErr _DllMainCRTStartup(InitBlockPtr pinitBlk)
{
OSErr ret;
__cinit();
//return the user routine value
ret = _DllInit(pinitBlk);
return ret ;
}
/***
*OSErr _DllMainCRTExit(void) -
* C Run-Time termination for a DLL linked with a C run-time library.
*
*Purpose:
* This routine does the C run-time termination
* and then calls the user code notification handler "DllExit".
*
*Entry:
*
*Exit:
*
*NOTES:
* This routine is the preferred entry point.
*
*******************************************************************************/
void _DllMainCRTExit()
{
//currently don't care the return value user routine returns
//we could return user returns if this is an issue
_DllExit();
_cexit();
}
#endif /* _WIN32 */