AJA NTV2 SDK  17.6.0.2675
NTV2 SDK 17.6.0.2675
combase.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 // File: ComBase.cpp
3 //
4 // Desc: DirectShow base classes - implements class hierarchy for creating
5 // COM objects.
6 //
7 // Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
8 //------------------------------------------------------------------------------
9 
10 
11 #include <streams.h>
12 #pragma warning( disable : 4514 ) // Disable warnings re unused inline functions
13 
14 
15 /* Define the static member variable */
16 
17 LONG CBaseObject::m_cObjects = 0;
18 
19 
20 /* Constructor */
21 
22 CBaseObject::CBaseObject(__in_opt LPCTSTR pName)
23 {
24  /* Increment the number of active objects */
25  InterlockedIncrement(&m_cObjects);
26 
27 #ifdef DEBUG
28 
29 #ifdef UNICODE
30  m_dwCookie = DbgRegisterObjectCreation(0, pName);
31 #else
32  m_dwCookie = DbgRegisterObjectCreation(pName, 0);
33 #endif
34 
35 #endif
36 }
37 
38 #ifdef UNICODE
39 CBaseObject::CBaseObject(const char *pName)
40 {
41  /* Increment the number of active objects */
42  InterlockedIncrement(&m_cObjects);
43 
44 #ifdef DEBUG
45  m_dwCookie = DbgRegisterObjectCreation(pName, 0);
46 #endif
47 }
48 #endif
49 
50 HINSTANCE hlibOLEAut32;
51 
52 /* Destructor */
53 
55 {
56  /* Decrement the number of objects active */
57  if (InterlockedDecrement(&m_cObjects) == 0) {
58  if (hlibOLEAut32) {
59  FreeLibrary(hlibOLEAut32);
60 
61  hlibOLEAut32 = 0;
62  }
63  };
64 
65 
66 #ifdef DEBUG
67  DbgRegisterObjectDestruction(m_dwCookie);
68 #endif
69 }
70 
71 static const TCHAR szOle32Aut[] = TEXT("OleAut32.dll");
72 
73 HINSTANCE LoadOLEAut32()
74 {
75  if (hlibOLEAut32 == 0) {
76 
77  hlibOLEAut32 = LoadLibrary(szOle32Aut);
78  }
79 
80  return hlibOLEAut32;
81 }
82 
83 
84 /* Constructor */
85 
86 // We know we use "this" in the initialization list, we also know we don't modify *phr.
87 #pragma warning( disable : 4355 4100 )
88 CUnknown::CUnknown(__in_opt LPCTSTR pName, __in_opt LPUNKNOWN pUnk)
90 /* Start the object with a reference count of zero - when the */
91 /* object is queried for it's first interface this may be */
92 /* incremented depending on whether or not this object is */
93 /* currently being aggregated upon */
94 , m_cRef(0)
95 /* Set our pointer to our IUnknown interface. */
96 /* If we have an outer, use its, otherwise use ours. */
97 /* This pointer effectivly points to the owner of */
98 /* this object and can be accessed by the GetOwner() method. */
99 , m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
100  /* Why the double cast? Well, the inner cast is a type-safe cast */
101  /* to pointer to a type from which we inherit. The second is */
102  /* type-unsafe but works because INonDelegatingUnknown "behaves */
103  /* like" IUnknown. (Only the names on the methods change.) */
104 {
105  // Everything we need to do has been done in the initializer list
106 }
107 
108 // This does the same as above except it has a useless HRESULT argument
109 // use the previous constructor, this is just left for compatibility...
110 CUnknown::CUnknown(__in_opt LPCTSTR pName, __in_opt LPUNKNOWN pUnk, __inout_opt HRESULT *phr) :
112  m_cRef(0),
113  m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
114 {
115 }
116 
117 #ifdef UNICODE
118 CUnknown::CUnknown(__in_opt LPCSTR pName, __in_opt LPUNKNOWN pUnk)
119 : CBaseObject(pName), m_cRef(0),
120  m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
121 { }
122 
123 CUnknown::CUnknown(__in_opt LPCSTR pName, __in_opt LPUNKNOWN pUnk, __inout_opt HRESULT *phr) :
124  CBaseObject(pName), m_cRef(0),
125  m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
126 { }
127 
128 #endif
129 
130 #pragma warning( default : 4355 4100 )
131 
132 
133 /* QueryInterface */
134 
135 STDMETHODIMP CUnknown::NonDelegatingQueryInterface(REFIID riid, __deref_out void ** ppv)
136 {
137  CheckPointer(ppv,E_POINTER);
138  ValidateReadWritePtr(ppv,sizeof(PVOID));
139 
140  /* We know only about IUnknown */
141 
142  if (riid == IID_IUnknown) {
143  GetInterface((LPUNKNOWN) (PNDUNKNOWN) this, ppv);
144  return NOERROR;
145  } else {
146  *ppv = NULL;
147  return E_NOINTERFACE;
148  }
149 }
150 
151 /* We have to ensure that we DON'T use a max macro, since these will typically */
152 /* lead to one of the parameters being evaluated twice. Since we are worried */
153 /* about concurrency, we can't afford to access the m_cRef twice since we can't */
154 /* afford to run the risk that its value having changed between accesses. */
155 
156 template<class T> inline static T ourmax( const T & a, const T & b )
157 {
158  return a > b ? a : b;
159 }
160 
161 /* AddRef */
162 
163 STDMETHODIMP_(ULONG) CUnknown::NonDelegatingAddRef()
164 {
165  LONG lRef = InterlockedIncrement( &m_cRef );
166  ASSERT(lRef > 0);
167  DbgLog((LOG_MEMORY,3,TEXT(" Obj %d ref++ = %d"),
168  m_dwCookie, m_cRef));
169  return ourmax(ULONG(m_cRef), 1ul);
170 }
171 
172 
173 /* Release */
174 
175 STDMETHODIMP_(ULONG) CUnknown::NonDelegatingRelease()
176 {
177  /* If the reference count drops to zero delete ourselves */
178 
179  LONG lRef = InterlockedDecrement( &m_cRef );
180  ASSERT(lRef >= 0);
181 
182  DbgLog((LOG_MEMORY,3,TEXT(" Object %d ref-- = %d"),
183  m_dwCookie, m_cRef));
184  if (lRef == 0) {
185 
186  // COM rules say we must protect against re-entrancy.
187  // If we are an aggregator and we hold our own interfaces
188  // on the aggregatee, the QI for these interfaces will
189  // addref ourselves. So after doing the QI we must release
190  // a ref count on ourselves. Then, before releasing the
191  // private interface, we must addref ourselves. When we do
192  // this from the destructor here it will result in the ref
193  // count going to 1 and then back to 0 causing us to
194  // re-enter the destructor. Hence we add an extra refcount here
195  // once we know we will delete the object.
196  // for an example aggregator see filgraph\distrib.cpp.
197 
198  m_cRef++;
199 
200  delete this;
201  return ULONG(0);
202  } else {
203  // Don't touch m_cRef again even in this leg as the object
204  // may have just been released on another thread too
205  return ourmax(ULONG(lRef), 1ul);
206  }
207 }
208 
209 
210 /* Return an interface pointer to a requesting client
211  performing a thread safe AddRef as necessary */
212 
213 STDAPI GetInterface(LPUNKNOWN pUnk, __out void **ppv)
214 {
215  CheckPointer(ppv, E_POINTER);
216  *ppv = pUnk;
217  pUnk->AddRef();
218  return NOERROR;
219 }
220 
221 
222 /* Compares two interfaces and returns TRUE if they are on the same object */
223 
224 BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond)
225 {
226  /* Different objects can't have the same interface pointer for
227  any interface
228  */
229  if (pFirst == pSecond) {
230  return TRUE;
231  }
232  /* OK - do it the hard way - check if they have the same
233  IUnknown pointers - a single object can only have one of these
234  */
235  LPUNKNOWN pUnknown1; // Retrieve the IUnknown interface
236  LPUNKNOWN pUnknown2; // Retrieve the other IUnknown interface
237  HRESULT hr; // General OLE return code
238 
239  ASSERT(pFirst);
240  ASSERT(pSecond);
241 
242  /* See if the IUnknown pointers match */
243 
244  hr = pFirst->QueryInterface(IID_IUnknown,(void **) &pUnknown1);
245  if (FAILED(hr)) {
246  return FALSE;
247  }
248  ASSERT(pUnknown1);
249 
250  /* Release the extra interface we hold */
251 
252  pUnknown1->Release();
253 
254  hr = pSecond->QueryInterface(IID_IUnknown,(void **) &pUnknown2);
255  if (FAILED(hr)) {
256  return FALSE;
257  }
258  ASSERT(pUnknown2);
259 
260  /* Release the extra interface we hold */
261 
262  pUnknown2->Release();
263  return (pUnknown1 == pUnknown2);
264 }
265 
CBaseObject::~CBaseObject
~CBaseObject()
Definition: combase.cpp:54
DbgRegisterObjectCreation
#define DbgRegisterObjectCreation(pObjectName)
Definition: wxdebug.h:187
DbgRegisterObjectDestruction
#define DbgRegisterObjectDestruction(dwCookie)
Definition: wxdebug.h:188
streams.h
NULL
#define NULL
Definition: ntv2caption608types.h:19
CUnknown::NonDelegatingQueryInterface
STDMETHODIMP NonDelegatingQueryInterface(REFIID, __deref_out void **)
Definition: combase.cpp:135
PNDUNKNOWN
INonDelegatingUnknown * PNDUNKNOWN
Definition: combase.h:148
STDMETHODIMP_
STDMETHODIMP_(ULONG) CUnknown
Definition: combase.cpp:163
ValidateReadWritePtr
#define ValidateReadWritePtr(p, cb)
Definition: wxdebug.h:241
szOle32Aut
static const TCHAR szOle32Aut[]
Definition: combase.cpp:71
CUnknown::m_cRef
volatile LONG m_cRef
Definition: combase.h:207
pName
CHAR * pName
Definition: amvideo.cpp:26
DbgLog
#define DbgLog(_x_)
Definition: wxdebug.h:183
LoadOLEAut32
HINSTANCE LoadOLEAut32()
Definition: combase.cpp:73
riid
__in REFIID riid
Definition: dllentry.cpp:192
PVOID
void * PVOID
Definition: ajatypes.h:319
LOG_MEMORY
@ LOG_MEMORY
Definition: wxdebug.h:46
IsEqualObject
BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond)
Definition: combase.cpp:224
hlibOLEAut32
HINSTANCE hlibOLEAut32
Definition: combase.cpp:50
ULONG
ULONG(__stdcall *_RegisterTraceGuids)(__in IN WMIDPREQUEST RequestAddress
ourmax
static T ourmax(const T &a, const T &b)
Definition: combase.cpp:156
CheckPointer
#define CheckPointer(p, ret)
Definition: wxdebug.h:225
CUnknown::CUnknown
CUnknown(__in_opt LPCTSTR pName, __in_opt LPUNKNOWN pUnk)
Definition: combase.cpp:88
ASSERT
#define ASSERT(_x_)
Definition: wxdebug.h:205
GetInterface
STDAPI GetInterface(LPUNKNOWN pUnk, __out void **ppv)
Definition: combase.cpp:213
hr
__out HRESULT & hr
Definition: pstream.cpp:145
CBaseObject
Definition: combase.h:158