home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / MFC / SRC / DLLINIT.CP_ / DLLINIT.CP
Encoding:
Text File  |  1993-02-08  |  13.8 KB  |  487 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and Microsoft
  7. // QuickHelp and/or WinHelp documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11.  
  12. #include "stdafx.h"
  13. #include "winhand_.h"       // for creation of CHandleMap
  14.  
  15. #include <stdarg.h>
  16.  
  17. #ifdef AFX_INIT_SEG
  18. #pragma code_seg(AFX_INIT_SEG)
  19. #endif
  20.  
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char BASED_CODE THIS_FILE[] = __FILE__;
  24. #endif
  25.  
  26. #ifndef _AFXDLL
  27. #error file must be compiled with _AFXDLL
  28. #endif
  29.  
  30. /////////////////////////////////////////////////////////////////////////////
  31. // _AFXDLL support
  32.  
  33. static AFX_EXTENSION_MODULE coreDLL = { NULL, NULL };
  34.  
  35. /////////////////////////////////////////////////////////////////////////////
  36. // Per-app initialization
  37.  
  38. BOOL WINAPI _AfxAppDataInit()
  39. {
  40.     ASSERT(coreDLL.hModule != NULL);
  41.  
  42.     ASSERT(sizeof(AFX_APPDATA) <= 128);     // hard coded limit in 'afxdll.asm'
  43. #ifdef _DEBUG
  44.     ASSERT(sizeof(AFX_APPDEBUG) <= 32);     // hard coded limit in 'afxdll.asm'
  45. #endif
  46.  
  47.     // called for each Application's instance run with the MFC200.DLL
  48.     if (_AfxGetAppData()->cbSize < sizeof(AFX_APPDATA) ||
  49.         (int)_AfxGetAppData()->cbSize < 0)
  50.     {
  51. #ifdef _DEBUG
  52.         OutputDebugString("FATAL ERROR: Illegal size for AFX_APPDATA\n\r");
  53.         OutputDebugString(" AFX_NULL segment must start at DGROUP:0010\n\r");
  54.         ASSERT(FALSE);
  55. #endif
  56.         return FALSE;
  57.     }
  58.     if (_AfxGetAppData()->wVersion != 0x200)
  59.     {
  60. #ifdef _DEBUG
  61.         OutputDebugString("FATAL ERROR: Illegal version for AFX_APPDATA\n\r");
  62. #endif
  63.         ASSERT(FALSE);
  64.         return FALSE;
  65.     }
  66.  
  67.     // make sure we have a routines for memory allocator, VBX and abort
  68.     ASSERT(_AfxGetAppData()->lpfnAppAlloc != NULL);
  69.     ASSERT(_AfxGetAppData()->lpfnAppFree != NULL);
  70.     ASSERT(_AfxGetAppData()->lpfnVBApiEntry != NULL);
  71.     ASSERT(_AfxGetAppData()->lpfnAppAbort != NULL);
  72.  
  73.     // other sanity asserts : AFX_APPDATA must be zero initialized !
  74.     ASSERT(afxExceptionContext.m_pCurrent == NULL);
  75.     ASSERT(afxExceptionContext.m_pLinkTop == NULL);
  76.  
  77. #ifdef _DEBUG
  78.     // check debug entries
  79.     ASSERT(_AfxGetAppDebug() != NULL);
  80.     ASSERT(_AfxGetAppDebug()->lpfnTraceV != NULL);
  81.     ASSERT(_AfxGetAppDebug()->lpszAllocFileName == NULL);
  82.     ASSERT(!_AfxGetAppDebug()->bMemoryTracking);    // tracking off
  83.         // internal App data memory is not tracked
  84. #endif //_DEBUG
  85.  
  86.     // allocate handle maps
  87.     ASSERT(_AfxGetAppData()->appMapHGDIOBJ == NULL);
  88.     _AfxGetAppData()->appMapHGDIOBJ = new CHandleMap(RUNTIME_CLASS(CGdiObject));
  89.     ASSERT(_AfxGetAppData()->appMapHDC == NULL);
  90.     _AfxGetAppData()->appMapHDC = new CHandleMap(RUNTIME_CLASS(CDC), 2);
  91.     ASSERT(_AfxGetAppData()->appMapHMENU == NULL);
  92.     _AfxGetAppData()->appMapHMENU = new CHandleMap(RUNTIME_CLASS(CMenu));
  93.     ASSERT(_AfxGetAppData()->appMapHWND == NULL);
  94.     _AfxGetAppData()->appMapHWND = new CHandleMap(RUNTIME_CLASS(CWnd));
  95.  
  96.     // allocate structures for sub-system state
  97.     ASSERT(_AfxGetAppData()->appVBState == NULL);
  98.     _AfxGetAppData()->appVBState = new AFX_VBSTATE;
  99.     ASSERT(_AfxGetAppData()->appLastFRState == NULL);
  100.     _AfxGetAppData()->appLastFRState = new AFX_FRSTATE;
  101.     ASSERT(_AfxGetAppData()->appOCState == NULL);
  102.     _AfxGetAppData()->appOCState = new AFX_OCSTATE;
  103.     _AfxGetAppData()->appOCState->cWaitForRelease = 0;  // extra init
  104.  
  105.     // any CRuntimeClasses registered between last DLL loaded and now must
  106.     //  be ours
  107.     ASSERT(_AfxGetAppData()->pFirstAppClass == NULL);
  108.     _AfxGetAppData()->pFirstAppClass = CRuntimeClass::pFirstClass;
  109.     CRuntimeClass::pFirstClass = NULL;  // clear for next DLL
  110.  
  111.     // there is a CDynLinkLibrary object for each DLL available for each app.
  112.     // hook in MFCDLL first (always last on the resource handler chain)
  113.     ASSERT(_AfxGetAppData()->pFirstDLL == NULL);    // must be first added
  114.     new CDynLinkLibrary(coreDLL);   // will add to list
  115.     ASSERT(_AfxGetAppData()->pFirstDLL != NULL);
  116.  
  117.     // other initialization
  118.     _AfxGetAppData()->appDlgTextClr = (COLORREF)-1; // use normal text
  119.  
  120. #ifdef _DEBUG
  121.     // turn on memory tracking from now on
  122.     _AfxGetAppDebug()->bMemoryTracking = TRUE;
  123. #endif
  124.     return TRUE;
  125. }
  126.  
  127. void WINAPI _AfxAppDataTerm()
  128. {
  129.     // free the DLL info blocks
  130.     CDynLinkLibrary* pDLL;
  131.     CDynLinkLibrary* pDLLNext;
  132.     for (pDLL = _AfxGetAppData()->pFirstDLL; pDLL != NULL; pDLL = pDLLNext)
  133.     {
  134.         pDLLNext = pDLL->m_pNextDLL;        // save next pointer before delete
  135.         delete pDLL;
  136.     }
  137.  
  138.     // free any MFC library implementation state
  139.     delete _AfxGetAppData()->appVBState;
  140.     delete _AfxGetAppData()->appLastFRState;
  141.     delete _AfxGetAppData()->appOCState;
  142. }
  143.  
  144. /////////////////////////////////////////////////////////////////////////////
  145. // CDynLinkLibrary class
  146.  
  147. IMPLEMENT_DYNAMIC(CDynLinkLibrary, CCmdTarget)
  148.  
  149. // Constructor - will wire into the current application's list
  150. CDynLinkLibrary::CDynLinkLibrary(AFX_EXTENSION_MODULE& state)
  151. {
  152.     ASSERT(state.hModule != NULL);
  153.     m_hResource = m_hModule = state.hModule;
  154.     m_pFirstSharedClass = state.pFirstSharedClass;
  155.  
  156.     // Insert at the head of the list (extensions will go in front of core DLL)
  157.     m_pNextDLL = _AfxGetAppData()->pFirstDLL;
  158.     _AfxGetAppData()->pFirstDLL = this;
  159. }
  160.  
  161. CDynLinkLibrary::~CDynLinkLibrary()
  162. {
  163. }
  164.  
  165. #ifdef _DEBUG
  166. void CDynLinkLibrary::AssertValid() const
  167. {
  168.     ASSERT(m_hModule != NULL);
  169. }
  170.  
  171. void CDynLinkLibrary::Dump(CDumpContext& dc) const
  172. {
  173.     CCmdTarget::Dump(dc);
  174.  
  175.     AFX_DUMP1(dc, "\nm_hModule = ", (UINT)m_hModule);
  176.     AFX_DUMP1(dc, "\nm_hResource = ", (UINT)m_hResource);
  177.     char szName[64];
  178.     GetModuleFileName(m_hModule, szName, sizeof(szName));
  179.     AFX_DUMP1(dc, "\nmodule name = ", szName);
  180. }
  181. #endif //_DEBUG
  182.  
  183. // This is called in an extension DLL's LibMain
  184. //  It makes a copy of the DLL's HMODULE as well as all the CRuntimeClass
  185. //   objects that have been registered as part of the normal C++ static
  186. //   constructors called before LibMain.
  187. void AFXAPI AfxInitExtensionModule(AFX_EXTENSION_MODULE& state, HMODULE hModule)
  188. {
  189.     ASSERT(hModule != NULL);
  190.     state.hModule = hModule;
  191.     state.pFirstSharedClass = CRuntimeClass::pFirstClass;
  192.     CRuntimeClass::pFirstClass = NULL;  // clear for next DLL or EXE
  193. }
  194.  
  195. /////////////////////////////////////////////////////////////////////////////
  196. // Resource helpers
  197.  
  198. HINSTANCE AFXAPI AfxFindResourceHandle(LPCSTR lpszName, LPCSTR lpszType)
  199. {
  200.     ASSERT(lpszName != NULL);
  201.     ASSERT(lpszType != NULL);
  202.  
  203.     // first check the app
  204.     HINSTANCE hInstApp = AfxGetResourceHandle();
  205.     if (::FindResource(hInstApp, lpszName, lpszType) != NULL)
  206.         return hInstApp;
  207.  
  208.     // check for DLLs in proper order
  209.     CDynLinkLibrary* pDLL;
  210.     for (pDLL = _AfxGetAppData()->pFirstDLL; pDLL != NULL;
  211.         pDLL = pDLL->m_pNextDLL)
  212.     {
  213.         if (pDLL->m_hResource != NULL &&
  214.             ::FindResource(pDLL->m_hResource, lpszName, lpszType) != NULL)
  215.         {
  216.             // found it in a DLL
  217.             return pDLL->m_hResource;
  218.         }
  219.     }
  220.  
  221.     // if failed to find resource, return application 
  222.     return hInstApp;
  223. }
  224.  
  225. // _AfxLoadString must not only check for the appropriate string segment
  226. //   in the resource file, but also that the string is non-zero
  227. int PASCAL _AfxLoadString(UINT nID, char* pszBuf)
  228. {
  229.     ASSERT(AfxIsValidAddress(pszBuf, 256)); // must be big enough for 256 bytes
  230.  
  231.     LPCSTR lpszName = MAKEINTRESOURCE((nID>>4)+1);
  232.     HINSTANCE hInst;
  233.     int nLen;
  234.  
  235.     // first check the app
  236.     hInst = AfxGetResourceHandle();
  237.     if (::FindResource(hInst, lpszName, RT_STRING) != NULL &&
  238.         (nLen = ::LoadString(hInst, nID, pszBuf, 255)) != 0)
  239.     {
  240.         // found a non-zero string in app
  241.         return nLen;
  242.     }
  243.  
  244.     // check for DLLs in proper order
  245.     CDynLinkLibrary* pDLL;
  246.     for (pDLL = _AfxGetAppData()->pFirstDLL; pDLL != NULL;
  247.         pDLL = pDLL->m_pNextDLL)
  248.     {
  249.         if ((hInst = pDLL->m_hResource) != NULL &&
  250.           ::FindResource(hInst, lpszName, RT_STRING) != NULL &&
  251.           (nLen = ::LoadString(hInst, nID, pszBuf, 255)) != 0)
  252.         {
  253.             return nLen;
  254.         }
  255.     }
  256.  
  257.     return 0;       // did not find it
  258. }
  259.  
  260. /////////////////////////////////////////////////////////////////////////////
  261. /////////////////////////////////////////////////////////////////////////////
  262. // Library init and WEP
  263.  
  264. extern "C"
  265. int CALLBACK LibMain(HINSTANCE hInstance, WORD, WORD, LPSTR)
  266. {
  267. #ifdef _DEBUG
  268.     OutputDebugString("MFCDLL Initializing!\n\r");
  269. #endif //_DEBUG
  270.     // Shared initialization
  271.     AfxInitExtensionModule(coreDLL, hInstance);
  272.  
  273.     return 1;   // ok
  274. }
  275.  
  276. void CWinApp::_ForceLinkage()
  277. {
  278.     ASSERT(FALSE);      // dummy routine for building DLL
  279. }
  280.  
  281. #ifdef AFX_CORE1_SEG
  282. #pragma code_seg("WEP_TEXT")
  283. #endif
  284.  
  285. extern "C" int CALLBACK _WEP(int)
  286. {
  287.     // subset of AfxWinTerm for when DLL terminates
  288.     ((CWnd&)CWnd::wndTop).m_hWnd = NULL;
  289.     ((CWnd&)CWnd::wndBottom).m_hWnd = NULL;
  290.     ((CWnd&)CWnd::wndTopMost).m_hWnd = NULL;
  291.     ((CWnd&)CWnd::wndNoTopMost).m_hWnd = NULL;
  292.     return TRUE;
  293. }
  294.  
  295. /////////////////////////////////////////////////////////////////////////////
  296. // Helper routines to delegate to app provided implementation
  297.  
  298. #ifdef AFX_CORE1_SEG
  299. #pragma code_seg(AFX_CORE1_SEG)
  300. #endif
  301.  
  302. #ifdef _DEBUG
  303.  
  304. extern "C" void CDECL 
  305. AfxTrace(LPCSTR pszFormat, ...)
  306. {
  307.     va_list args;
  308.     va_start(args, pszFormat);
  309.  
  310.     (_AfxGetAppDebug()->lpfnTraceV)(pszFormat, args);
  311. }
  312.  
  313. extern "C" void AFXAPI
  314. AfxAssertFailedLine(LPCSTR lpszFileName, int nLine)
  315. {
  316.     (_AfxGetAppDebug()->lpfnAssertFailed)(lpszFileName, nLine);
  317. }
  318.  
  319. BOOL AFXAPI AfxEnableMemoryTracking(BOOL bNewTrackingOn)
  320. {
  321.     BOOL bOldTrackingOn = _AfxGetAppDebug()->bMemoryTracking;
  322.     _AfxGetAppDebug()->bMemoryTracking = bNewTrackingOn;
  323.     return bOldTrackingOn;
  324. }
  325.  
  326. #endif //_DEBUG
  327.  
  328. void AFXAPI AfxAbort()
  329. {
  330. #ifdef _DEBUG
  331.     OutputDebugString("DLL's AfxAbort called\n\r");
  332.     OutputDebugString(" - calling app provided AbortProc\n\r");
  333. #endif //_DEBUG
  334.     (_AfxGetAppData()->lpfnAppAbort)();
  335.     ASSERT(FALSE);      // NOT REACHED !!
  336. }
  337.  
  338. void AFXAPI AfxTerminate()
  339. {
  340.     // hookability not provided
  341.     AfxAbort();
  342. }
  343.  
  344. /////////////////////////////////////////////////////////////////////////////
  345. // Memory allocation is done by app !
  346.  
  347. void* operator new(size_t nSize)
  348. {
  349. #ifdef _DEBUG
  350.     ASSERT(_AfxGetAppData()->lpfnAppAlloc != NULL);
  351.     ASSERT(_AfxGetAppDebug()->lpszAllocFileName == NULL);
  352.     _AfxGetAppDebug()->bAllocObj = FALSE;
  353. #endif //_DEBUG
  354.     void* p = (_AfxGetAppData()->lpfnAppAlloc)(nSize);
  355.     if (p == NULL)
  356.         AfxThrowMemoryException();
  357.     return p;
  358. }
  359.  
  360. void* operator new(size_t nSize, LPCSTR pFileName, int nLine)
  361. {
  362. #ifdef _DEBUG
  363.     ASSERT(_AfxGetAppData()->lpfnAppAlloc != NULL);
  364.     _AfxGetAppDebug()->lpszAllocFileName = pFileName;
  365.     _AfxGetAppDebug()->nAllocLine = nLine;
  366.     _AfxGetAppDebug()->bAllocObj = FALSE;
  367. #endif //_DEBUG
  368.  
  369.     void* p = (_AfxGetAppData()->lpfnAppAlloc)(nSize);
  370.  
  371. #ifdef _DEBUG
  372.     _AfxGetAppDebug()->lpszAllocFileName = NULL;
  373. #endif //_DEBUG
  374.  
  375.     if (p == NULL)
  376.         AfxThrowMemoryException();
  377.     return p;
  378. }
  379.  
  380. void operator delete(void* pbData)
  381. {
  382.     if (pbData == NULL)
  383.         return;
  384. #ifdef _DEBUG
  385.     ASSERT(_AfxGetAppData()->lpfnAppFree != NULL);
  386.     _AfxGetAppDebug()->bAllocObj = FALSE;
  387. #endif //_DEBUG
  388.     (*_AfxGetAppData()->lpfnAppFree)(pbData);
  389. }
  390.  
  391. /////////////////////////////////////////////////////////////////////////////
  392. // Additional CObject new/delete operators for memory tracking
  393.  
  394. #ifdef _DEBUG
  395. void* CObject::operator new(size_t nSize)
  396. {
  397.     ASSERT(_AfxGetAppData()->lpfnAppAlloc != NULL);
  398.     ASSERT(_AfxGetAppDebug()->lpszAllocFileName == NULL);
  399.     _AfxGetAppDebug()->bAllocObj = TRUE;
  400.     void* p = (_AfxGetAppData()->lpfnAppAlloc)(nSize);
  401.     if (p == NULL)
  402.         AfxThrowMemoryException();
  403.     return p;
  404. }
  405.  
  406. void* CObject::operator new(size_t nSize, LPCSTR pFileName, int nLine)
  407. {
  408.     ASSERT(_AfxGetAppData()->lpfnAppAlloc != NULL);
  409.     _AfxGetAppDebug()->lpszAllocFileName = pFileName;
  410.     _AfxGetAppDebug()->nAllocLine = nLine;
  411.     _AfxGetAppDebug()->bAllocObj = TRUE;
  412.  
  413.     void* p = (_AfxGetAppData()->lpfnAppAlloc)(nSize);
  414.     _AfxGetAppDebug()->lpszAllocFileName = NULL;
  415.     if (p == NULL)
  416.         AfxThrowMemoryException();
  417.     return p;
  418. }
  419.  
  420. void CObject::operator delete(void* pbData)
  421. {
  422.     if (pbData == NULL)
  423.         return;
  424.     ASSERT(_AfxGetAppData()->lpfnAppFree != NULL);
  425.     _AfxGetAppDebug()->bAllocObj = TRUE;
  426.     (*_AfxGetAppData()->lpfnAppFree)(pbData);
  427. }
  428.  
  429. #endif //_DEBUG
  430.  
  431. /////////////////////////////////////////////////////////////////////////////
  432. // we must also replace any direct calls to malloc/free
  433.  
  434. extern "C"
  435. void __far* __cdecl _fmalloc(size_t nSize)
  436. {
  437. #ifdef _DEBUG
  438.     ASSERT(_AfxGetAppData()->lpfnAppAlloc != NULL);
  439.     ASSERT(_AfxGetAppDebug()->lpszAllocFileName == NULL);
  440.     _AfxGetAppDebug()->bAllocObj = FALSE;
  441.     BOOL bOldTracking = _AfxGetAppDebug()->bMemoryTracking;
  442.     _AfxGetAppDebug()->bMemoryTracking = FALSE; // mallocs not tracked
  443. #endif //_DEBUG
  444.     void* p = (_AfxGetAppData()->lpfnAppAlloc)(nSize);
  445. #ifdef _DEBUG
  446.     _AfxGetAppDebug()->bMemoryTracking = bOldTracking;
  447. #endif //_DEBUG
  448.     if (p == NULL)
  449.         AfxThrowMemoryException();
  450.     return p;
  451. }
  452.  
  453. extern "C"
  454. void __cdecl _ffree(void __far* p)
  455. {
  456. #ifdef _DEBUG
  457.     ASSERT(_AfxGetAppData()->lpfnAppFree != NULL);
  458.     _AfxGetAppDebug()->bAllocObj = FALSE;
  459. #endif //_DEBUG
  460.     (*_AfxGetAppData()->lpfnAppFree)(p);
  461. }
  462.  
  463. extern "C"
  464. void __far* __cdecl _frealloc(void __far* pOld, size_t nSize)
  465. {
  466.     ASSERT(_AfxGetAppData()->lpfnAppReAlloc != NULL);
  467.     return (_AfxGetAppData()->lpfnAppReAlloc)(pOld, nSize);
  468. }
  469.  
  470. /////////////////////////////////////////////////////////////////////////////
  471. // and finally replace the _set_new_handler
  472.  
  473. _PNH AFXAPI _AfxSetNewHandler(_PNH pnh)
  474. {
  475.     ASSERT(_AfxGetAppData()->lpfnAppSetNewHandler != NULL);
  476.     return (_PNH)(_AfxGetAppData()->lpfnAppSetNewHandler)((FARPROC)pnh);
  477. }
  478.  
  479. /////////////////////////////////////////////////////////////////////////////
  480. // Also stub out the runtime init 'setenvp' routine to avoid malloc calls
  481.  
  482. extern "C" void _cdecl _setenvp()
  483. {
  484. }
  485.  
  486. /////////////////////////////////////////////////////////////////////////////
  487.