225 lines
6.1 KiB
C
225 lines
6.1 KiB
C
//+-------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1991 - 1992.
|
|
//
|
|
// File: dllentry.c
|
|
//
|
|
// Contents: Dll Entry point code. Calls the appropriate run-time
|
|
// init/term code and then defers to LibMain for further
|
|
// processing.
|
|
//
|
|
// Classes: <none>
|
|
//
|
|
// Functions: DllEntryPoint - Called by loader
|
|
//
|
|
// History: 10-May-92 BryanT Created
|
|
// 22-Jul-92 BryanT Switch to calling _cexit/_mtdeletelocks
|
|
// on cleanup.
|
|
// 06-Oct-92 BryanT Call RegisterWithCommnot on entry
|
|
// and DeRegisterWithCommnot on exit.
|
|
// This should fix the heap dump code.
|
|
// 12-23-93 TerryRu Replace LockExit, and UnLockExit
|
|
// with critial sections for Daytona.
|
|
// 12-28-93 TerryRu Place Regiter/DeRegister WinCommnot apis
|
|
// Inside WIN32 endifs for Daytona builds.
|
|
//
|
|
//--------------------------------------------------------------------
|
|
#include <windows.h>
|
|
//#include <win4p.h>
|
|
#include <process.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <malloc.h>
|
|
|
|
|
|
BOOL WINAPI _CRT_INIT (HANDLE hDll, DWORD dwReason, LPVOID lpReserved);
|
|
|
|
BOOL __stdcall DllEntryPoint (HANDLE hDll, DWORD dwReason, LPVOID lpReserved);
|
|
|
|
BOOL __cdecl LibMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved);
|
|
|
|
void __cdecl _mtdeletelocks(void);
|
|
|
|
DWORD WINAPI
|
|
GetModuleFileNameCtC(
|
|
HMODULE hModule,
|
|
LPWSTR pwszFilename,
|
|
DWORD nSize);
|
|
|
|
#ifdef USE_CRTDLL
|
|
|
|
#define _RT_ONEXIT 24
|
|
|
|
/*
|
|
* routine in DLL to do initialization (in this case, C++ constructors)
|
|
*/
|
|
|
|
typedef void (__cdecl *PF)(void);
|
|
|
|
/*
|
|
* pointers to initialization sections
|
|
*/
|
|
|
|
PF *__onexitbegin;
|
|
PF *__onexitend;
|
|
|
|
/*
|
|
* Define increment (in entries) for growing the _onexit/atexit table
|
|
*/
|
|
#define ONEXITTBLINCR 4
|
|
|
|
static void __cdecl _onexitinit ( void );
|
|
extern void __cdecl _initterm(PF *, PF *);
|
|
extern void __cdecl _amsg_exit(int);
|
|
extern void __cdecl _lockexit(void);
|
|
extern void __cdecl _unlockexit(void);
|
|
|
|
#endif
|
|
|
|
// BUGBUG: defined in $(COMMON)\src\except\memory.cxx
|
|
|
|
void RegisterWithCommnot(void);
|
|
void DeRegisterWithCommnot(void);
|
|
|
|
CRITICAL_SECTION __gCriticalSection;
|
|
|
|
BOOL __stdcall DllEntryPoint (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
|
{
|
|
BOOL fRc = FALSE;
|
|
|
|
switch (dwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
#ifdef USE_CRTDLL
|
|
//
|
|
// Assumption: The run-time is sufficiantly up and running to
|
|
// support malloc that _onexitinit will perform.
|
|
//
|
|
_onexitinit();
|
|
InitializeCriticalSection(&__gCriticalSection );
|
|
#endif
|
|
|
|
_CRT_INIT(hDll, dwReason, lpReserved);
|
|
#if WIN32==300
|
|
RegisterWithCommnot();
|
|
#endif
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
fRc = LibMain (hDll, dwReason, lpReserved);
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
fRc = LibMain (hDll, dwReason, lpReserved);
|
|
|
|
//
|
|
// BUGBUG: What a hack. In order to make sure we don't kill
|
|
// commnot's objects while still in use (_cexit will do
|
|
// the atexit list processing where the compiler stores
|
|
// pointers to all the static destructors), test the
|
|
// module name. If not commnot, call _cexit().
|
|
// DeRegisterWithCommnot will call it for commnot...
|
|
//
|
|
|
|
#ifdef USE_CRTDLL
|
|
|
|
{
|
|
wchar_t pwszModName[512];
|
|
GetModuleFileName(hDll, pwszModName, 512);
|
|
|
|
if (!wcswcs(wcsupr(pwszModName), L"COMMNOT"))
|
|
if (__onexitbegin)
|
|
_initterm(__onexitbegin, __onexitend);
|
|
}
|
|
|
|
DeleteCriticalSection( & __gCriticalSection );
|
|
#else
|
|
|
|
{
|
|
wchar_t pwszModName[512];
|
|
GetModuleFileName(hDll, pwszModName, 512);
|
|
|
|
if (!wcswcs(wcsupr(pwszModName), L"COMMNOT"))
|
|
_cexit();
|
|
}
|
|
|
|
_mtdeletelocks();
|
|
#endif
|
|
#if WIN32==300
|
|
DeRegisterWithCommnot();
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
return(fRc);
|
|
}
|
|
|
|
#ifdef USE_CRTDLL
|
|
|
|
_onexit_t __cdecl _onexit ( _onexit_t func )
|
|
{
|
|
PF *p;
|
|
|
|
EnterCriticalSection( &__gCriticalSection ); /* lock the exit code */
|
|
|
|
/*
|
|
* First, make sure the table has room for a new entry
|
|
*/
|
|
if ( _msize(__onexitbegin) <= (unsigned)((char *)__onexitend -
|
|
(char *)__onexitbegin) ) {
|
|
/*
|
|
* not enough room, try to grow the table
|
|
*/
|
|
if ( (p = (PF *) realloc(__onexitbegin, _msize(__onexitbegin) +
|
|
ONEXITTBLINCR * sizeof(PF))) == NULL ) {
|
|
/*
|
|
* didn't work. don't do anything rash, just fail
|
|
*/
|
|
LeaveCriticalSection(&__gCriticalSection );
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* update __onexitend and __onexitbegin
|
|
*/
|
|
|
|
__onexitend = p + (__onexitend - __onexitbegin);
|
|
__onexitbegin = p;
|
|
}
|
|
|
|
/*
|
|
* Put the new entry into the table and update the end-of-table
|
|
* pointer.
|
|
*/
|
|
|
|
*(__onexitend++) = (PF)func;
|
|
|
|
LeaveCriticalSection( &__gCriticalSection );
|
|
|
|
return func;
|
|
|
|
}
|
|
|
|
int __cdecl atexit ( PF func )
|
|
{
|
|
return (_onexit((_onexit_t)func) == NULL) ? -1 : 0;
|
|
}
|
|
|
|
static void __cdecl _onexitinit ( void )
|
|
{
|
|
if ( (__onexitbegin = (PF *)malloc(32 * sizeof(PF))) == NULL )
|
|
/*
|
|
* cannot allocate minimal required size. generate
|
|
* fatal runtime error.
|
|
*/
|
|
_amsg_exit(_RT_ONEXIT);
|
|
|
|
*(__onexitbegin) = (PF) NULL;
|
|
__onexitend = __onexitbegin;
|
|
}
|
|
|
|
#endif // USE_CRTDLL
|