combase.cpp
资源名称:p2p_vod.rar [点击查看]
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:7k
源码类别:
P2P编程
开发平台:
Visual C++
- //------------------------------------------------------------------------------
- // File: ComBase.cpp
- //
- // Desc: DirectShow base classes - implements class hierarchy for creating
- // COM objects.
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------------------------
- #include <streams.h>
- #pragma warning( disable : 4514 ) // Disable warnings re unused inline functions
- /* Define the static member variable */
- LONG CBaseObject::m_cObjects = 0;
- /* Constructor */
- CBaseObject::CBaseObject(const TCHAR *pName)
- {
- /* Increment the number of active objects */
- InterlockedIncrement(&m_cObjects);
- #ifdef DEBUG
- #ifdef UNICODE
- m_dwCookie = DbgRegisterObjectCreation(0, pName);
- #else
- m_dwCookie = DbgRegisterObjectCreation(pName, 0);
- #endif
- #endif
- }
- #ifdef UNICODE
- CBaseObject::CBaseObject(const char *pName)
- {
- /* Increment the number of active objects */
- InterlockedIncrement(&m_cObjects);
- #ifdef DEBUG
- m_dwCookie = DbgRegisterObjectCreation(pName, 0);
- #endif
- }
- #endif
- HINSTANCE hlibOLEAut32;
- /* Destructor */
- CBaseObject::~CBaseObject()
- {
- /* Decrement the number of objects active */
- if (InterlockedDecrement(&m_cObjects) == 0) {
- if (hlibOLEAut32) {
- FreeLibrary(hlibOLEAut32);
- hlibOLEAut32 = 0;
- }
- };
- #ifdef DEBUG
- DbgRegisterObjectDestruction(m_dwCookie);
- #endif
- }
- static const TCHAR szOle32Aut[] = TEXT("OleAut32.dll");
- HINSTANCE LoadOLEAut32()
- {
- if (hlibOLEAut32 == 0) {
- hlibOLEAut32 = LoadLibrary(szOle32Aut);
- }
- return hlibOLEAut32;
- }
- /* Constructor */
- // We know we use "this" in the initialization list, we also know we don't modify *phr.
- #pragma warning( disable : 4355 4100 )
- CUnknown::CUnknown(const TCHAR *pName, LPUNKNOWN pUnk)
- : CBaseObject(pName)
- /* Start the object with a reference count of zero - when the */
- /* object is queried for it's first interface this may be */
- /* incremented depending on whether or not this object is */
- /* currently being aggregated upon */
- , m_cRef(0)
- /* Set our pointer to our IUnknown interface. */
- /* If we have an outer, use its, otherwise use ours. */
- /* This pointer effectivly points to the owner of */
- /* this object and can be accessed by the GetOwner() method. */
- , m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
- /* Why the double cast? Well, the inner cast is a type-safe cast */
- /* to pointer to a type from which we inherit. The second is */
- /* type-unsafe but works because INonDelegatingUnknown "behaves */
- /* like" IUnknown. (Only the names on the methods change.) */
- {
- // Everything we need to do has been done in the initializer list
- }
- // This does the same as above except it has a useless HRESULT argument
- // use the previous constructor, this is just left for compatibility...
- CUnknown::CUnknown(TCHAR *pName, LPUNKNOWN pUnk,HRESULT *phr) :
- CBaseObject(pName),
- m_cRef(0),
- m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
- {
- }
- #ifdef UNICODE
- CUnknown::CUnknown(const CHAR *pName, LPUNKNOWN pUnk)
- : CBaseObject(pName), m_cRef(0),
- m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
- { }
- CUnknown::CUnknown(CHAR *pName, LPUNKNOWN pUnk,HRESULT *phr) :
- CBaseObject(pName), m_cRef(0),
- m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
- { }
- #endif
- #pragma warning( default : 4355 4100 )
- /* QueryInterface */
- STDMETHODIMP CUnknown::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
- {
- CheckPointer(ppv,E_POINTER);
- ValidateReadWritePtr(ppv,sizeof(PVOID));
- /* We know only about IUnknown */
- if (riid == IID_IUnknown) {
- GetInterface((LPUNKNOWN) (PNDUNKNOWN) this, ppv);
- return NOERROR;
- } else {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- }
- /* We have to ensure that we DON'T use a max macro, since these will typically */
- /* lead to one of the parameters being evaluated twice. Since we are worried */
- /* about concurrency, we can't afford to access the m_cRef twice since we can't */
- /* afford to run the risk that its value having changed between accesses. */
- template<class T> inline static T ourmax( const T & a, const T & b )
- {
- return a > b ? a : b;
- }
- /* AddRef */
- STDMETHODIMP_(ULONG) CUnknown::NonDelegatingAddRef()
- {
- LONG lRef = InterlockedIncrement( &m_cRef );
- ASSERT(lRef > 0);
- DbgLog((LOG_MEMORY,3,TEXT(" Obj %d ref++ = %d"),
- m_dwCookie, m_cRef));
- return ourmax(ULONG(m_cRef), 1ul);
- }
- /* Release */
- STDMETHODIMP_(ULONG) CUnknown::NonDelegatingRelease()
- {
- /* If the reference count drops to zero delete ourselves */
- LONG lRef = InterlockedDecrement( &m_cRef );
- ASSERT(lRef >= 0);
- DbgLog((LOG_MEMORY,3,TEXT(" Object %d ref-- = %d"),
- m_dwCookie, m_cRef));
- if (lRef == 0) {
- // COM rules say we must protect against re-entrancy.
- // If we are an aggregator and we hold our own interfaces
- // on the aggregatee, the QI for these interfaces will
- // addref ourselves. So after doing the QI we must release
- // a ref count on ourselves. Then, before releasing the
- // private interface, we must addref ourselves. When we do
- // this from the destructor here it will result in the ref
- // count going to 1 and then back to 0 causing us to
- // re-enter the destructor. Hence we add an extra refcount here
- // once we know we will delete the object.
- // for an example aggregator see filgraphdistrib.cpp.
- m_cRef++;
- delete this;
- return ULONG(0);
- } else {
- return ourmax(ULONG(m_cRef), 1ul);
- }
- }
- /* Return an interface pointer to a requesting client
- performing a thread safe AddRef as necessary */
- STDAPI GetInterface(LPUNKNOWN pUnk, void **ppv)
- {
- CheckPointer(ppv, E_POINTER);
- *ppv = pUnk;
- pUnk->AddRef();
- return NOERROR;
- }
- /* Compares two interfaces and returns TRUE if they are on the same object */
- BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond)
- {
- /* Different objects can't have the same interface pointer for
- any interface
- */
- if (pFirst == pSecond) {
- return TRUE;
- }
- /* OK - do it the hard way - check if they have the same
- IUnknown pointers - a single object can only have one of these
- */
- LPUNKNOWN pUnknown1; // Retrieve the IUnknown interface
- LPUNKNOWN pUnknown2; // Retrieve the other IUnknown interface
- HRESULT hr; // General OLE return code
- ASSERT(pFirst);
- ASSERT(pSecond);
- /* See if the IUnknown pointers match */
- hr = pFirst->QueryInterface(IID_IUnknown,(void **) &pUnknown1);
- ASSERT(SUCCEEDED(hr));
- ASSERT(pUnknown1);
- hr = pSecond->QueryInterface(IID_IUnknown,(void **) &pUnknown2);
- ASSERT(SUCCEEDED(hr));
- ASSERT(pUnknown2);
- /* Release the extra interfaces we hold */
- pUnknown1->Release();
- pUnknown2->Release();
- return (pUnknown1 == pUnknown2);
- }