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 + -
显示快捷键?