dllentry.cpp
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:9k
源码类别:

P2P编程

开发平台:

Visual C++

  1. //------------------------------------------------------------------------------
  2. // File: DllEntry.cpp
  3. //
  4. // Desc: DirectShow base classes - implements classes used to support dll
  5. //       entry points for COM objects.
  6. //
  7. // Copyright (c) Microsoft Corporation.  All rights reserved.
  8. //------------------------------------------------------------------------------
  9. #include <streams.h>
  10. #include <initguid.h>
  11. #ifdef DEBUG
  12. #ifdef UNICODE
  13. #ifndef _UNICODE
  14. #define _UNICODE
  15. #endif // _UNICODE
  16. #endif // UNICODE
  17. #endif // DEBUG
  18. extern CFactoryTemplate g_Templates[];
  19. extern int g_cTemplates;
  20. HINSTANCE g_hInst;
  21. DWORD   g_amPlatform; // VER_PLATFORM_WIN32_WINDOWS etc... (from GetVersionEx)
  22. OSVERSIONINFO g_osInfo;
  23. //
  24. // an instance of this is created by the DLLGetClassObject entrypoint
  25. // it uses the CFactoryTemplate object it is given to support the
  26. // IClassFactory interface
  27. class CClassFactory : public IClassFactory, public CBaseObject
  28. {
  29. private:
  30.     const CFactoryTemplate *const m_pTemplate;
  31.     ULONG m_cRef;
  32.     static int m_cLocked;
  33. public:
  34.     CClassFactory(const CFactoryTemplate *);
  35.     // IUnknown
  36.     STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);
  37.     STDMETHODIMP_(ULONG)AddRef();
  38.     STDMETHODIMP_(ULONG)Release();
  39.     // IClassFactory
  40.     STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void **pv);
  41.     STDMETHODIMP LockServer(BOOL fLock);
  42.     // allow DLLGetClassObject to know about global server lock status
  43.     static BOOL IsLocked() {
  44.         return (m_cLocked > 0);
  45.     };
  46. };
  47. // process-wide dll locked state
  48. int CClassFactory::m_cLocked = 0;
  49. CClassFactory::CClassFactory(const CFactoryTemplate *pTemplate)
  50. : CBaseObject(NAME("Class Factory"))
  51. , m_cRef(0)
  52. , m_pTemplate(pTemplate)
  53. {
  54. }
  55. STDMETHODIMP
  56. CClassFactory::QueryInterface(REFIID riid,void **ppv)
  57. {
  58.     CheckPointer(ppv,E_POINTER)
  59.     ValidateReadWritePtr(ppv,sizeof(PVOID));
  60.     *ppv = NULL;
  61.     // any interface on this object is the object pointer.
  62.     if ((riid == IID_IUnknown) || (riid == IID_IClassFactory)) {
  63.         *ppv = (LPVOID) this;
  64. // AddRef returned interface pointer
  65.         ((LPUNKNOWN) *ppv)->AddRef();
  66.         return NOERROR;
  67.     }
  68.     return ResultFromScode(E_NOINTERFACE);
  69. }
  70. STDMETHODIMP_(ULONG)
  71. CClassFactory::AddRef()
  72. {
  73.     return ++m_cRef;
  74. }
  75. STDMETHODIMP_(ULONG)
  76. CClassFactory::Release()
  77. {
  78.     if (--m_cRef == 0) {
  79.         delete this;
  80.         return 0;
  81.     } else {
  82.         return m_cRef;
  83.     }
  84. }
  85. STDMETHODIMP
  86. CClassFactory::CreateInstance(
  87.     LPUNKNOWN pUnkOuter,
  88.     REFIID riid,
  89.     void **pv)
  90. {
  91.     CheckPointer(pv,E_POINTER)
  92.     ValidateReadWritePtr(pv,sizeof(void *));
  93.     /* Enforce the normal OLE rules regarding interfaces and delegation */
  94.     if (pUnkOuter != NULL) {
  95.         if (IsEqualIID(riid,IID_IUnknown) == FALSE) {
  96.             return ResultFromScode(E_NOINTERFACE);
  97.         }
  98.     }
  99.     /* Create the new object through the derived class's create function */
  100.     HRESULT hr = NOERROR;
  101.     CUnknown *pObj = m_pTemplate->CreateInstance(pUnkOuter, &hr);
  102.     if (pObj == NULL) {
  103. if (SUCCEEDED(hr)) {
  104.     hr = E_OUTOFMEMORY;
  105. }
  106. return hr;
  107.     }
  108.     /* Delete the object if we got a construction error */
  109.     if (FAILED(hr)) {
  110.         delete pObj;
  111.         return hr;
  112.     }
  113.     /* Get a reference counted interface on the object */
  114.     /* We wrap the non-delegating QI with NDAddRef & NDRelease. */
  115.     /* This protects any outer object from being prematurely    */
  116.     /* released by an inner object that may have to be created  */
  117.     /* in order to supply the requested interface.              */
  118.     pObj->NonDelegatingAddRef();
  119.     hr = pObj->NonDelegatingQueryInterface(riid, pv);
  120.     pObj->NonDelegatingRelease();
  121.     /* Note that if NonDelegatingQueryInterface fails, it will  */
  122.     /* not increment the ref count, so the NonDelegatingRelease */
  123.     /* will drop the ref back to zero and the object will "self-*/
  124.     /* destruct".  Hence we don't need additional tidy-up code  */
  125.     /* to cope with NonDelegatingQueryInterface failing.        */
  126.     if (SUCCEEDED(hr)) {
  127.         ASSERT(*pv);
  128.     }
  129.     return hr;
  130. }
  131. STDMETHODIMP
  132. CClassFactory::LockServer(BOOL fLock)
  133. {
  134.     if (fLock) {
  135.         m_cLocked++;
  136.     } else {
  137.         m_cLocked--;
  138.     }
  139.     return NOERROR;
  140. }
  141. // --- COM entrypoints -----------------------------------------
  142. //called by COM to get the class factory object for a given class
  143. STDAPI
  144. DllGetClassObject(
  145.     REFCLSID rClsID,
  146.     REFIID riid,
  147.     void **pv)
  148. {
  149.     if (!(riid == IID_IUnknown) && !(riid == IID_IClassFactory)) {
  150.             return E_NOINTERFACE;
  151.     }
  152.     // traverse the array of templates looking for one with this
  153.     // class id
  154.     for (int i = 0; i < g_cTemplates; i++) {
  155.         const CFactoryTemplate * pT = &g_Templates[i];
  156.         if (pT->IsClassID(rClsID)) {
  157.             // found a template - make a class factory based on this
  158.             // template
  159.             *pv = (LPVOID) (LPUNKNOWN) new CClassFactory(pT);
  160.             if (*pv == NULL) {
  161.                 return E_OUTOFMEMORY;
  162.             }
  163.             ((LPUNKNOWN)*pv)->AddRef();
  164.             return NOERROR;
  165.         }
  166.     }
  167.     return CLASS_E_CLASSNOTAVAILABLE;
  168. }
  169. //
  170. //  Call any initialization routines
  171. //
  172. void
  173. DllInitClasses(BOOL bLoading)
  174. {
  175.     int i;
  176.     // traverse the array of templates calling the init routine
  177.     // if they have one
  178.     for (i = 0; i < g_cTemplates; i++) {
  179.         const CFactoryTemplate * pT = &g_Templates[i];
  180.         if (pT->m_lpfnInit != NULL) {
  181.             (*pT->m_lpfnInit)(bLoading, pT->m_ClsID);
  182.         }
  183.     }
  184. }
  185. // called by COM to determine if this dll can be unloaded
  186. // return ok unless there are outstanding objects or a lock requested
  187. // by IClassFactory::LockServer
  188. //
  189. // CClassFactory has a static function that can tell us about the locks,
  190. // and CCOMObject has a static function that can tell us about the active
  191. // object count
  192. STDAPI
  193. DllCanUnloadNow()
  194. {
  195.     DbgLog((LOG_MEMORY,2,TEXT("DLLCanUnloadNow called - IsLocked = %d, Active objects = %d"),
  196.         CClassFactory::IsLocked(),
  197.         CBaseObject::ObjectsActive()));
  198.     if (CClassFactory::IsLocked() || CBaseObject::ObjectsActive()) {
  199. return S_FALSE;
  200.     } else {
  201.         return S_OK;
  202.     }
  203. }
  204. // --- standard WIN32 entrypoints --------------------------------------
  205. extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
  206. BOOL WINAPI
  207. DllEntryPoint(HINSTANCE hInstance, ULONG ulReason, LPVOID pv)
  208. {
  209. #ifdef DEBUG
  210.     extern bool g_fDbgInDllEntryPoint;
  211.     g_fDbgInDllEntryPoint = true;
  212. #endif
  213.     switch (ulReason)
  214.     {
  215.     case DLL_PROCESS_ATTACH:
  216.         DisableThreadLibraryCalls(hInstance);
  217.         DbgInitialise(hInstance);
  218.      {
  219.          // The platform identifier is used to work out whether
  220.          // full unicode support is available or not.  Hence the
  221.          // default will be the lowest common denominator - i.e. N/A
  222.                 g_amPlatform = VER_PLATFORM_WIN32_WINDOWS; // win95 assumed in case GetVersionEx fails
  223.     
  224.                 g_osInfo.dwOSVersionInfoSize = sizeof(g_osInfo);
  225.                 if (GetVersionEx(&g_osInfo)) {
  226.              g_amPlatform = g_osInfo.dwPlatformId;
  227.          } else {
  228.      DbgLog((LOG_ERROR, 1, TEXT("Failed to get the OS platform, assuming Win95")));
  229.          }
  230.      }
  231.         g_hInst = hInstance;
  232.         DllInitClasses(TRUE);
  233.         break;
  234.     case DLL_PROCESS_DETACH:
  235.         DllInitClasses(FALSE);
  236. #ifdef DEBUG
  237.         if (CBaseObject::ObjectsActive()) {
  238.             DbgSetModuleLevel(LOG_MEMORY, 2);
  239.             TCHAR szInfo[512];
  240.             extern TCHAR m_ModuleName[];     // Cut down module name
  241.             TCHAR FullName[_MAX_PATH];      // Load the full path and module name
  242.             TCHAR *pName;                   // Searches from the end for a backslash
  243.             GetModuleFileName(NULL,FullName,_MAX_PATH);
  244.             pName = _tcsrchr(FullName,'\');
  245.             if (pName == NULL) {
  246.                 pName = FullName;
  247.             } else {
  248.                 pName++;
  249.             }
  250.             (void)StringCchPrintf(szInfo, NUMELMS(szInfo), TEXT("Executable: %s  Pid %x  Tid %x. "),
  251.                      pName, GetCurrentProcessId(), GetCurrentThreadId());
  252.             DWORD cch = lstrlen(szInfo);
  253.             (void)StringCchPrintf(szInfo+cch, NUMELMS(szInfo) - cch, TEXT("Module %s, %d objects left active!"),
  254.                      m_ModuleName, CBaseObject::ObjectsActive());
  255.             DbgAssert(szInfo, TEXT(__FILE__),__LINE__);
  256.     // If running remotely wait for the Assert to be acknowledged
  257.     // before dumping out the object register
  258.             DbgDumpObjectRegister();
  259.         }
  260.         DbgTerminate();
  261. #endif
  262.         break;
  263.     }
  264. #ifdef DEBUG
  265.     g_fDbgInDllEntryPoint = false;
  266. #endif
  267.     return TRUE;
  268. }