370 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			370 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								//------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// File: DlleEntry.cpp
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Desc: DirectShow base classes - implements classes used to support dll
							 | 
						||
| 
								 | 
							
								//       entry points for COM objects.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
							 | 
						||
| 
								 | 
							
								//------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <streams.h>
							 | 
						||
| 
								 | 
							
								#include <initguid.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG
							 | 
						||
| 
								 | 
							
								#ifdef UNICODE
							 | 
						||
| 
								 | 
							
								#ifndef _UNICODE
							 | 
						||
| 
								 | 
							
								#define _UNICODE
							 | 
						||
| 
								 | 
							
								#endif // _UNICODE
							 | 
						||
| 
								 | 
							
								#endif // UNICODE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <tchar.h>
							 | 
						||
| 
								 | 
							
								#endif // DEBUG
							 | 
						||
| 
								 | 
							
								#include <strsafe.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#pragma warning(disable: 4996)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								extern CFactoryTemplate g_Templates[];
							 | 
						||
| 
								 | 
							
								extern int g_cTemplates;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HINSTANCE g_hInst;
							 | 
						||
| 
								 | 
							
								DWORD	  g_amPlatform;		// VER_PLATFORM_WIN32_WINDOWS etc... (from GetVersionEx)
							 | 
						||
| 
								 | 
							
								OSVERSIONINFO g_osInfo;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// an instance of this is created by the DLLGetClassObject entrypoint
							 | 
						||
| 
								 | 
							
								// it uses the CFactoryTemplate object it is given to support the
							 | 
						||
| 
								 | 
							
								// IClassFactory interface
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class CClassFactory : public IClassFactory, public CBaseObject
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    const CFactoryTemplate *const m_pTemplate;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ULONG m_cRef;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    static int m_cLocked;
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    CClassFactory(const CFactoryTemplate *);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // IUnknown
							 | 
						||
| 
								 | 
							
								    STDMETHODIMP QueryInterface(REFIID riid, __deref_out void ** ppv);
							 | 
						||
| 
								 | 
							
								    STDMETHODIMP_(ULONG)AddRef();
							 | 
						||
| 
								 | 
							
								    STDMETHODIMP_(ULONG)Release();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // IClassFactory
							 | 
						||
| 
								 | 
							
								    STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, __deref_out void **pv);
							 | 
						||
| 
								 | 
							
								    STDMETHODIMP LockServer(BOOL fLock);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // allow DLLGetClassObject to know about global server lock status
							 | 
						||
| 
								 | 
							
								    static BOOL IsLocked() {
							 | 
						||
| 
								 | 
							
								        return (m_cLocked > 0);
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// process-wide dll locked state
							 | 
						||
| 
								 | 
							
								int CClassFactory::m_cLocked = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								CClassFactory::CClassFactory(const CFactoryTemplate *pTemplate)
							 | 
						||
| 
								 | 
							
								: CBaseObject(NAME("Class Factory"))
							 | 
						||
| 
								 | 
							
								, m_cRef(0)
							 | 
						||
| 
								 | 
							
								, m_pTemplate(pTemplate)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP
							 | 
						||
| 
								 | 
							
								CClassFactory::QueryInterface(REFIID riid,__deref_out void **ppv)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CheckPointer(ppv,E_POINTER)
							 | 
						||
| 
								 | 
							
								    ValidateReadWritePtr(ppv,sizeof(PVOID));
							 | 
						||
| 
								 | 
							
								    *ppv = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // any interface on this object is the object pointer.
							 | 
						||
| 
								 | 
							
								    if ((riid == IID_IUnknown) || (riid == IID_IClassFactory)) {
							 | 
						||
| 
								 | 
							
								        *ppv = (LPVOID) this;
							 | 
						||
| 
								 | 
							
									// AddRef returned interface pointer
							 | 
						||
| 
								 | 
							
								        ((LPUNKNOWN) *ppv)->AddRef();
							 | 
						||
| 
								 | 
							
								        return NOERROR;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ResultFromScode(E_NOINTERFACE);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP_(ULONG)
							 | 
						||
| 
								 | 
							
								CClassFactory::AddRef()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return ++m_cRef;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP_(ULONG)
							 | 
						||
| 
								 | 
							
								CClassFactory::Release()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    LONG lRef = InterlockedDecrement((volatile LONG *)&m_cRef);
							 | 
						||
| 
								 | 
							
								    if (lRef == 0) {
							 | 
						||
| 
								 | 
							
								        delete this;
							 | 
						||
| 
								 | 
							
								        return 0;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        return lRef;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP
							 | 
						||
| 
								 | 
							
								CClassFactory::CreateInstance(
							 | 
						||
| 
								 | 
							
								    LPUNKNOWN pUnkOuter,
							 | 
						||
| 
								 | 
							
								    REFIID riid,
							 | 
						||
| 
								 | 
							
								    __deref_out void **pv)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    CheckPointer(pv,E_POINTER)
							 | 
						||
| 
								 | 
							
								    ValidateReadWritePtr(pv,sizeof(void *));
							 | 
						||
| 
								 | 
							
								    *pv = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Enforce the normal OLE rules regarding interfaces and delegation */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (pUnkOuter != NULL) {
							 | 
						||
| 
								 | 
							
								        if (IsEqualIID(riid,IID_IUnknown) == FALSE) {
							 | 
						||
| 
								 | 
							
								            *pv = NULL;
							 | 
						||
| 
								 | 
							
								            return ResultFromScode(E_NOINTERFACE);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Create the new object through the derived class's create function */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    HRESULT hr = NOERROR;
							 | 
						||
| 
								 | 
							
								    CUnknown *pObj = m_pTemplate->CreateInstance(pUnkOuter, &hr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (pObj == NULL) {
							 | 
						||
| 
								 | 
							
								        *pv = NULL;
							 | 
						||
| 
								 | 
							
									if (SUCCEEDED(hr)) {
							 | 
						||
| 
								 | 
							
									    hr = E_OUTOFMEMORY;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return hr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Delete the object if we got a construction error */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (FAILED(hr)) {
							 | 
						||
| 
								 | 
							
								        delete pObj;
							 | 
						||
| 
								 | 
							
								        *pv = NULL;
							 | 
						||
| 
								 | 
							
								        return hr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Get a reference counted interface on the object */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* We wrap the non-delegating QI with NDAddRef & NDRelease. */
							 | 
						||
| 
								 | 
							
								    /* This protects any outer object from being prematurely    */
							 | 
						||
| 
								 | 
							
								    /* released by an inner object that may have to be created  */
							 | 
						||
| 
								 | 
							
								    /* in order to supply the requested interface.              */
							 | 
						||
| 
								 | 
							
								    pObj->NonDelegatingAddRef();
							 | 
						||
| 
								 | 
							
								    hr = pObj->NonDelegatingQueryInterface(riid, pv);
							 | 
						||
| 
								 | 
							
								    pObj->NonDelegatingRelease();
							 | 
						||
| 
								 | 
							
								    /* Note that if NonDelegatingQueryInterface fails, it will  */
							 | 
						||
| 
								 | 
							
								    /* not increment the ref count, so the NonDelegatingRelease */
							 | 
						||
| 
								 | 
							
								    /* will drop the ref back to zero and the object will "self-*/
							 | 
						||
| 
								 | 
							
								    /* destruct".  Hence we don't need additional tidy-up code  */
							 | 
						||
| 
								 | 
							
								    /* to cope with NonDelegatingQueryInterface failing.        */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (SUCCEEDED(hr)) {
							 | 
						||
| 
								 | 
							
								        ASSERT(*pv);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return hr;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								STDMETHODIMP
							 | 
						||
| 
								 | 
							
								CClassFactory::LockServer(BOOL fLock)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (fLock) {
							 | 
						||
| 
								 | 
							
								        m_cLocked++;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        m_cLocked--;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return NOERROR;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// --- COM entrypoints -----------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//called by COM to get the class factory object for a given class
							 | 
						||
| 
								 | 
							
								__control_entrypoint(DllExport) STDAPI
							 | 
						||
| 
								 | 
							
								DllGetClassObject(
							 | 
						||
| 
								 | 
							
								    __in REFCLSID rClsID,
							 | 
						||
| 
								 | 
							
								    __in REFIID riid,
							 | 
						||
| 
								 | 
							
								    __deref_out void **pv)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    *pv = NULL;
							 | 
						||
| 
								 | 
							
								    if (!(riid == IID_IUnknown) && !(riid == IID_IClassFactory)) {
							 | 
						||
| 
								 | 
							
								            return E_NOINTERFACE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // traverse the array of templates looking for one with this
							 | 
						||
| 
								 | 
							
								    // class id
							 | 
						||
| 
								 | 
							
								    for (int i = 0; i < g_cTemplates; i++) {
							 | 
						||
| 
								 | 
							
								        const CFactoryTemplate * pT = &g_Templates[i];
							 | 
						||
| 
								 | 
							
								        if (pT->IsClassID(rClsID)) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // found a template - make a class factory based on this
							 | 
						||
| 
								 | 
							
								            // template
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            *pv = (LPVOID) (LPUNKNOWN) new CClassFactory(pT);
							 | 
						||
| 
								 | 
							
								            if (*pv == NULL) {
							 | 
						||
| 
								 | 
							
								                return E_OUTOFMEMORY;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            ((LPUNKNOWN)*pv)->AddRef();
							 | 
						||
| 
								 | 
							
								            return NOERROR;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return CLASS_E_CLASSNOTAVAILABLE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  Call any initialization routines
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								void
							 | 
						||
| 
								 | 
							
								DllInitClasses(BOOL bLoading)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // traverse the array of templates calling the init routine
							 | 
						||
| 
								 | 
							
								    // if they have one
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < g_cTemplates; i++) {
							 | 
						||
| 
								 | 
							
								        const CFactoryTemplate * pT = &g_Templates[i];
							 | 
						||
| 
								 | 
							
								        if (pT->m_lpfnInit != NULL) {
							 | 
						||
| 
								 | 
							
								            (*pT->m_lpfnInit)(bLoading, pT->m_ClsID);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// called by COM to determine if this dll can be unloaded
							 | 
						||
| 
								 | 
							
								// return ok unless there are outstanding objects or a lock requested
							 | 
						||
| 
								 | 
							
								// by IClassFactory::LockServer
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// CClassFactory has a static function that can tell us about the locks,
							 | 
						||
| 
								 | 
							
								// and CCOMObject has a static function that can tell us about the active
							 | 
						||
| 
								 | 
							
								// object count
							 | 
						||
| 
								 | 
							
								STDAPI
							 | 
						||
| 
								 | 
							
								DllCanUnloadNow()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    DbgLog((LOG_MEMORY,2,TEXT("DLLCanUnloadNow called - IsLocked = %d, Active objects = %d"),
							 | 
						||
| 
								 | 
							
								        CClassFactory::IsLocked(),
							 | 
						||
| 
								 | 
							
								        CBaseObject::ObjectsActive()));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (CClassFactory::IsLocked() || CBaseObject::ObjectsActive()) {
							 | 
						||
| 
								 | 
							
									return S_FALSE;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        return S_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// --- standard WIN32 entrypoints --------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								extern "C" void __cdecl __security_init_cookie(void);
							 | 
						||
| 
								 | 
							
								extern "C" BOOL WINAPI _DllEntryPoint(HINSTANCE, ULONG, __inout_opt LPVOID);
							 | 
						||
| 
								 | 
							
								#pragma comment(linker, "/merge:.CRT=.rdata")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								extern "C"
							 | 
						||
| 
								 | 
							
								DECLSPEC_NOINLINE
							 | 
						||
| 
								 | 
							
								BOOL 
							 | 
						||
| 
								 | 
							
								WINAPI
							 | 
						||
| 
								 | 
							
								DllEntryPoint(
							 | 
						||
| 
								 | 
							
								    HINSTANCE hInstance, 
							 | 
						||
| 
								 | 
							
								    ULONG ulReason, 
							 | 
						||
| 
								 | 
							
								    __inout_opt LPVOID pv
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if ( ulReason == DLL_PROCESS_ATTACH ) {
							 | 
						||
| 
								 | 
							
								        // Must happen before any other code is executed.  Thankfully - it's re-entrant
							 | 
						||
| 
								 | 
							
								        __security_init_cookie();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return _DllEntryPoint(hInstance, ulReason, pv);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DECLSPEC_NOINLINE
							 | 
						||
| 
								 | 
							
								BOOL 
							 | 
						||
| 
								 | 
							
								WINAPI
							 | 
						||
| 
								 | 
							
								_DllEntryPoint(
							 | 
						||
| 
								 | 
							
								    HINSTANCE hInstance, 
							 | 
						||
| 
								 | 
							
								    ULONG ulReason, 
							 | 
						||
| 
								 | 
							
								    __inout_opt LPVOID pv
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG
							 | 
						||
| 
								 | 
							
								    extern bool g_fDbgInDllEntryPoint;
							 | 
						||
| 
								 | 
							
								    g_fDbgInDllEntryPoint = true;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (ulReason)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case DLL_PROCESS_ATTACH:
							 | 
						||
| 
								 | 
							
								        DisableThreadLibraryCalls(hInstance);
							 | 
						||
| 
								 | 
							
								        DbgInitialise(hInstance);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    	{
							 | 
						||
| 
								 | 
							
								    	    // The platform identifier is used to work out whether
							 | 
						||
| 
								 | 
							
								    	    // full unicode support is available or not.  Hence the
							 | 
						||
| 
								 | 
							
								    	    // default will be the lowest common denominator - i.e. N/A
							 | 
						||
| 
								 | 
							
								                g_amPlatform = VER_PLATFORM_WIN32_WINDOWS; // win95 assumed in case GetVersionEx fails
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								                g_osInfo.dwOSVersionInfoSize = sizeof(g_osInfo);
							 | 
						||
| 
								 | 
							
								                if (GetVersionEx(&g_osInfo)) {
							 | 
						||
| 
								 | 
							
								            	g_amPlatform = g_osInfo.dwPlatformId;
							 | 
						||
| 
								 | 
							
								    	    } else {
							 | 
						||
| 
								 | 
							
								    		DbgLog((LOG_ERROR, 1, TEXT("Failed to get the OS platform, assuming Win95")));
							 | 
						||
| 
								 | 
							
								    	    }
							 | 
						||
| 
								 | 
							
								    	}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        g_hInst = hInstance;
							 | 
						||
| 
								 | 
							
								        DllInitClasses(TRUE);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case DLL_PROCESS_DETACH:
							 | 
						||
| 
								 | 
							
								        DllInitClasses(FALSE);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG
							 | 
						||
| 
								 | 
							
								        if (CBaseObject::ObjectsActive()) {
							 | 
						||
| 
								 | 
							
								            DbgSetModuleLevel(LOG_MEMORY, 2);
							 | 
						||
| 
								 | 
							
								            TCHAR szInfo[512];
							 | 
						||
| 
								 | 
							
								            extern TCHAR m_ModuleName[];     // Cut down module name
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            TCHAR FullName[_MAX_PATH];      // Load the full path and module name
							 | 
						||
| 
								 | 
							
								            TCHAR *pName;                   // Searches from the end for a backslash
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            GetModuleFileName(NULL,FullName,_MAX_PATH);
							 | 
						||
| 
								 | 
							
								            pName = _tcsrchr(FullName,'\\');
							 | 
						||
| 
								 | 
							
								            if (pName == NULL) {
							 | 
						||
| 
								 | 
							
								                pName = FullName;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                pName++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            (void)StringCchPrintf(szInfo, NUMELMS(szInfo), TEXT("Executable: %s  Pid %x  Tid %x. "),
							 | 
						||
| 
								 | 
							
											    pName, GetCurrentProcessId(), GetCurrentThreadId());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            (void)StringCchPrintf(szInfo+lstrlen(szInfo), NUMELMS(szInfo) - lstrlen(szInfo), TEXT("Module %s, %d objects left active!"),
							 | 
						||
| 
								 | 
							
								                     m_ModuleName, CBaseObject::ObjectsActive());
							 | 
						||
| 
								 | 
							
								            DbgAssert(szInfo, TEXT(__FILE__),__LINE__);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									    // If running remotely wait for the Assert to be acknowledged
							 | 
						||
| 
								 | 
							
									    // before dumping out the object register
							 | 
						||
| 
								 | 
							
								            DbgDumpObjectRegister();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        DbgTerminate();
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef DEBUG
							 | 
						||
| 
								 | 
							
								    g_fDbgInDllEntryPoint = false;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |