dllentry.cpp.svn-base

来自「ffshow源码」· SVN-BASE 代码 · 共 336 行

SVN-BASE
336
字号
//------------------------------------------------------------------------------// File: DllEntry.cpp//// Desc: DirectShow base classes - implements classes used to support dll//       entry points for COM objects.//// Copyright (c) 1992-2002 Microsoft Corporation.  All rights reserved.//------------------------------------------------------------------------------#include "stdafx.h"#include <initguid.h>#ifdef DEBUG#ifdef UNICODE#ifndef _UNICODE#define _UNICODE#endif // _UNICODE#endif // UNICODE#include <tchar.h>#endif // DEBUGextern 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 interfaceclass 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, void ** ppv);    STDMETHODIMP_(ULONG)AddRef();    STDMETHODIMP_(ULONG)Release();    // IClassFactory    STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, 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 stateint CClassFactory::m_cLocked = 0;CClassFactory::CClassFactory(const CFactoryTemplate *pTemplate): CBaseObject(NAME("Class Factory")), m_cRef(0), m_pTemplate(pTemplate){}STDMETHODIMPCClassFactory::QueryInterface(REFIID riid,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(){    if (--m_cRef == 0) {        delete this;        return 0;    } else {        return m_cRef;    }}STDMETHODIMPCClassFactory::CreateInstance(    LPUNKNOWN pUnkOuter,    REFIID riid,    void **pv){    CheckPointer(pv,E_POINTER)    ValidateReadWritePtr(pv,sizeof(void *));    /* Enforce the normal OLE rules regarding interfaces and delegation */    if (pUnkOuter != NULL) {        if (IsEqualIID(riid,IID_IUnknown) == FALSE) {            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) {	if (SUCCEEDED(hr)) {	    hr = E_OUTOFMEMORY;	}	return hr;    }    /* Delete the object if we got a construction error */    if (FAILED(hr)) {        delete pObj;        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;}STDMETHODIMPCClassFactory::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 classSTDAPIDllGetClassObject(    REFCLSID rClsID,    REFIID riid,    void **pv){    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//voidDllInitClasses(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 countSTDAPIDllCanUnloadNow(){    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" BOOL WINAPI DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pv);BOOL WINAPI DllMain(HINSTANCE hInstance, ULONG ulReason, 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);        #if _MSC_VER>=1400 && !defined(WIN64)         _set_printf_count_output(1);        #endif        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++;            }	    DWORD cch = wsprintf(szInfo, TEXT("Executable: %s  Pid %x  Tid %x. "),			    pName, GetCurrentProcessId(), GetCurrentThreadId());            wsprintf(szInfo+cch, 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;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?