AJA NTV2 SDK  17.6.0.2675
NTV2 SDK 17.6.0.2675
dllentry.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 // File: DlleEntry.cpp
3 //
4 // Desc: DirectShow base classes - implements classes used to support dll
5 // entry points for COM objects.
6 //
7 // Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
8 //------------------------------------------------------------------------------
9 
10 
11 #include <streams.h>
12 #include <initguid.h>
13 
14 #ifdef DEBUG
15 #ifdef UNICODE
16 #ifndef _UNICODE
17 #define _UNICODE
18 #endif // _UNICODE
19 #endif // UNICODE
20 
21 #include <tchar.h>
22 #endif // DEBUG
23 #include <strsafe.h>
24 
26 extern int g_cTemplates;
27 
28 HINSTANCE g_hInst;
29 DWORD g_amPlatform; // VER_PLATFORM_WIN32_WINDOWS etc... (from GetVersionEx)
30 OSVERSIONINFO g_osInfo;
31 
32 //
33 // an instance of this is created by the DLLGetClassObject entrypoint
34 // it uses the CFactoryTemplate object it is given to support the
35 // IClassFactory interface
36 
37 class CClassFactory : public IClassFactory, public CBaseObject
38 {
39 
40 private:
41  const CFactoryTemplate *const m_pTemplate;
42 
43  ULONG m_cRef;
44 
45  static int m_cLocked;
46 public:
48 
49  // IUnknown
50  STDMETHODIMP QueryInterface(REFIID riid, __deref_out void ** ppv);
51  STDMETHODIMP_(ULONG)AddRef();
52  STDMETHODIMP_(ULONG)Release();
53 
54  // IClassFactory
55  STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, __deref_out void **pv);
56  STDMETHODIMP LockServer(BOOL fLock);
57 
58  // allow DLLGetClassObject to know about global server lock status
59  static BOOL IsLocked() {
60  return (m_cLocked > 0);
61  };
62 };
63 
64 // process-wide dll locked state
65 int CClassFactory::m_cLocked = 0;
66 
68 : CBaseObject(NAME("Class Factory"))
69 , m_cRef(0)
70 , m_pTemplate(pTemplate)
71 {
72 }
73 
74 
75 STDMETHODIMP
76 CClassFactory::QueryInterface(REFIID riid,__deref_out void **ppv)
77 {
78  CheckPointer(ppv,E_POINTER)
79  ValidateReadWritePtr(ppv,sizeof(PVOID));
80  *ppv = NULL;
81 
82  // any interface on this object is the object pointer.
83  if ((riid == IID_IUnknown) || (riid == IID_IClassFactory)) {
84  *ppv = (LPVOID) this;
85  // AddRef returned interface pointer
86  ((LPUNKNOWN) *ppv)->AddRef();
87  return NOERROR;
88  }
89 
90  return ResultFromScode(E_NOINTERFACE);
91 }
92 
93 
95 CClassFactory::AddRef()
96 {
97  return ++m_cRef;
98 }
99 
101 CClassFactory::Release()
102 {
103  LONG lRef = InterlockedDecrement((volatile LONG *)&m_cRef);
104  if (lRef == 0) {
105  delete this;
106  return 0;
107  } else {
108  return lRef;
109  }
110 }
111 
112 STDMETHODIMP
114  LPUNKNOWN pUnkOuter,
115  REFIID riid,
116  __deref_out void **pv)
117 {
118  CheckPointer(pv,E_POINTER)
119  ValidateReadWritePtr(pv,sizeof(void *));
120  *pv = NULL;
121 
122  /* Enforce the normal OLE rules regarding interfaces and delegation */
123 
124  if (pUnkOuter != NULL) {
125  if (IsEqualIID(riid,IID_IUnknown) == FALSE) {
126  *pv = NULL;
127  return ResultFromScode(E_NOINTERFACE);
128  }
129  }
130 
131  /* Create the new object through the derived class's create function */
132 
133  HRESULT hr = NOERROR;
134  CUnknown *pObj = m_pTemplate->CreateInstance(pUnkOuter, &hr);
135 
136  if (pObj == NULL) {
137  *pv = NULL;
138  if (SUCCEEDED(hr)) {
139  hr = E_OUTOFMEMORY;
140  }
141  return hr;
142  }
143 
144  /* Delete the object if we got a construction error */
145 
146  if (FAILED(hr)) {
147  delete pObj;
148  *pv = NULL;
149  return hr;
150  }
151 
152  /* Get a reference counted interface on the object */
153 
154  /* We wrap the non-delegating QI with NDAddRef & NDRelease. */
155  /* This protects any outer object from being prematurely */
156  /* released by an inner object that may have to be created */
157  /* in order to supply the requested interface. */
158  pObj->NonDelegatingAddRef();
160  pObj->NonDelegatingRelease();
161  /* Note that if NonDelegatingQueryInterface fails, it will */
162  /* not increment the ref count, so the NonDelegatingRelease */
163  /* will drop the ref back to zero and the object will "self-*/
164  /* destruct". Hence we don't need additional tidy-up code */
165  /* to cope with NonDelegatingQueryInterface failing. */
166 
167  if (SUCCEEDED(hr)) {
168  ASSERT(*pv);
169  }
170 
171  return hr;
172 }
173 
174 STDMETHODIMP
176 {
177  if (fLock) {
178  m_cLocked++;
179  } else {
180  m_cLocked--;
181  }
182  return NOERROR;
183 }
184 
185 
186 // --- COM entrypoints -----------------------------------------
187 
188 //called by COM to get the class factory object for a given class
189 __control_entrypoint(DllExport) STDAPI
190 DllGetClassObject(
191  __in REFCLSID rClsID,
192  __in REFIID riid,
193  __deref_out void **pv)
194 {
195  *pv = NULL;
196  if (!(riid == IID_IUnknown) && !(riid == IID_IClassFactory)) {
197  return E_NOINTERFACE;
198  }
199 
200  // traverse the array of templates looking for one with this
201  // class id
202  for (int i = 0; i < g_cTemplates; i++) {
203  const CFactoryTemplate * pT = &g_Templates[i];
204  if (pT->IsClassID(rClsID)) {
205 
206  // found a template - make a class factory based on this
207  // template
208 
209  *pv = (LPVOID) (LPUNKNOWN) new CClassFactory(pT);
210  if (*pv == NULL) {
211  return E_OUTOFMEMORY;
212  }
213  ((LPUNKNOWN)*pv)->AddRef();
214  return NOERROR;
215  }
216  }
218 }
219 
220 //
221 // Call any initialization routines
222 //
223 void
224 DllInitClasses(BOOL bLoading)
225 {
226  int i;
227 
228  // traverse the array of templates calling the init routine
229  // if they have one
230  for (i = 0; i < g_cTemplates; i++) {
231  const CFactoryTemplate * pT = &g_Templates[i];
232  if (pT->m_lpfnInit != NULL) {
233  (*pT->m_lpfnInit)(bLoading, pT->m_ClsID);
234  }
235  }
236 
237 }
238 
239 // called by COM to determine if this dll can be unloaded
240 // return ok unless there are outstanding objects or a lock requested
241 // by IClassFactory::LockServer
242 //
243 // CClassFactory has a static function that can tell us about the locks,
244 // and CCOMObject has a static function that can tell us about the active
245 // object count
246 STDAPI
248 {
249  DbgLog((LOG_MEMORY,2,TEXT("DLLCanUnloadNow called - IsLocked = %d, Active objects = %d"),
252 
254  return S_FALSE;
255  } else {
256  return S_OK;
257  }
258 }
259 
260 
261 // --- standard WIN32 entrypoints --------------------------------------
262 
263 
264 extern "C" void __cdecl __security_init_cookie(void);
265 extern "C" BOOL WINAPI _DllEntryPoint(HINSTANCE, ULONG, __inout_opt LPVOID);
266 #pragma comment(linker, "/merge:.CRT=.rdata")
267 
268 extern "C"
269 DECLSPEC_NOINLINE
270 BOOL
271 WINAPI
273  HINSTANCE hInstance,
274  ULONG ulReason,
275  __inout_opt LPVOID pv
276  )
277 {
278  if ( ulReason == DLL_PROCESS_ATTACH ) {
279  // Must happen before any other code is executed. Thankfully - it's re-entrant
281  }
282  return _DllEntryPoint(hInstance, ulReason, pv);
283 }
284 
285 
286 DECLSPEC_NOINLINE
287 BOOL
288 WINAPI
290  HINSTANCE hInstance,
291  ULONG ulReason,
292  __inout_opt LPVOID pv
293  )
294 {
295 #ifdef DEBUG
296  extern bool g_fDbgInDllEntryPoint;
297  g_fDbgInDllEntryPoint = true;
298 #endif
299 
300  switch (ulReason)
301  {
302 
303  case DLL_PROCESS_ATTACH:
304  DisableThreadLibraryCalls(hInstance);
305  DbgInitialise(hInstance);
306 
307  {
308  // The platform identifier is used to work out whether
309  // full unicode support is available or not. Hence the
310  // default will be the lowest common denominator - i.e. N/A
311  g_amPlatform = VER_PLATFORM_WIN32_WINDOWS; // win95 assumed in case GetVersionEx fails
312 
313  g_osInfo.dwOSVersionInfoSize = sizeof(g_osInfo);
314  if (GetVersionEx(&g_osInfo)) {
315  g_amPlatform = g_osInfo.dwPlatformId;
316  } else {
317  DbgLog((LOG_ERROR, 1, TEXT("Failed to get the OS platform, assuming Win95")));
318  }
319  }
320 
321  g_hInst = hInstance;
322  DllInitClasses(TRUE);
323  break;
324 
325  case DLL_PROCESS_DETACH:
326  DllInitClasses(FALSE);
327 
328 #ifdef DEBUG
331  TCHAR szInfo[512];
332  extern TCHAR m_ModuleName[]; // Cut down module name
333 
334  TCHAR FullName[_MAX_PATH]; // Load the full path and module name
335  TCHAR *pName; // Searches from the end for a backslash
336 
337  GetModuleFileName(NULL,FullName,_MAX_PATH);
338  pName = _tcsrchr(FullName,'\\');
339  if (pName == NULL) {
340  pName = FullName;
341  } else {
342  pName++;
343  }
344 
345  (void)StringCchPrintf(szInfo, NUMELMS(szInfo), TEXT("Executable: %s Pid %x Tid %x. "),
346  pName, GetCurrentProcessId(), GetCurrentThreadId());
347 
348  (void)StringCchPrintf(szInfo+lstrlen(szInfo), NUMELMS(szInfo) - lstrlen(szInfo), TEXT("Module %s, %d objects left active!"),
349  m_ModuleName, CBaseObject::ObjectsActive());
350  DbgAssert(szInfo, TEXT(__FILE__),__LINE__);
351 
352  // If running remotely wait for the Assert to be acknowledged
353  // before dumping out the object register
355  }
356  DbgTerminate();
357 #endif
358  break;
359  }
360 
361 #ifdef DEBUG
362  g_fDbgInDllEntryPoint = false;
363 #endif
364  return TRUE;
365 }
366 
367 
CFactoryTemplate::IsClassID
BOOL IsClassID(REFCLSID rclsid) const
Definition: combase.h:270
CClassFactory::LockServer
STDMETHODIMP LockServer(BOOL fLock)
Definition: dllentry.cpp:175
streams.h
NULL
#define NULL
Definition: ntv2caption608types.h:19
CFactoryTemplate::m_lpfnInit
LPFNInitRoutine m_lpfnInit
Definition: combase.h:267
__security_init_cookie
void __cdecl __security_init_cookie(void)
CUnknown::NonDelegatingQueryInterface
STDMETHODIMP NonDelegatingQueryInterface(REFIID, __deref_out void **)
Definition: combase.cpp:135
NUMELMS
#define NUMELMS(aa)
Definition: types.h:430
NAME
#define NAME(_x_)
Definition: wxdebug.h:179
CClassFactory::QueryInterface
STDMETHODIMP QueryInterface(REFIID riid, __deref_out void **ppv)
Definition: dllentry.cpp:76
STDMETHODIMP_
STDMETHODIMP_(ULONG) CUnknown
Definition: combase.cpp:163
CClassFactory::CreateInstance
STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, __deref_out void **pv)
Definition: dllentry.cpp:113
g_amPlatform
DWORD g_amPlatform
Definition: dllentry.cpp:29
nlohmann::json_abiNLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON_v3_11_NLOHMANN_JSON_VERSION_PATCH::detail::void
j template void())
Definition: json.hpp:4893
CLASS_E_CLASSNOTAVAILABLE
return CLASS_E_CLASSNOTAVAILABLE
Definition: dllentry.cpp:217
_DllEntryPoint
BOOL WINAPI _DllEntryPoint(HINSTANCE, ULONG, __inout_opt LPVOID)
Definition: dllentry.cpp:289
ValidateReadWritePtr
#define ValidateReadWritePtr(p, cb)
Definition: wxdebug.h:241
g_hInst
HINSTANCE g_hInst
Definition: dllentry.cpp:28
CClassFactory::IsLocked
static BOOL IsLocked()
Definition: dllentry.cpp:59
CFactoryTemplate
Definition: combase.h:260
CClassFactory
Definition: dllentry.cpp:37
LOG_ERROR
@ LOG_ERROR
Definition: wxdebug.h:48
pName
CHAR * pName
Definition: amvideo.cpp:26
DbgLog
#define DbgLog(_x_)
Definition: wxdebug.h:183
CClassFactory::CClassFactory
CClassFactory(const CFactoryTemplate *)
Definition: dllentry.cpp:67
CBaseObject::ObjectsActive
static LONG ObjectsActive()
Definition: combase.h:190
DllEntryPoint
DECLSPEC_NOINLINE BOOL WINAPI DllEntryPoint(HINSTANCE hInstance, ULONG ulReason, __inout_opt LPVOID pv)
Definition: dllentry.cpp:272
riid
__in REFIID riid
Definition: dllentry.cpp:192
CFactoryTemplate::CreateInstance
CUnknown * CreateInstance(__inout_opt LPUNKNOWN pUnk, __inout_opt HRESULT *phr) const
Definition: combase.h:274
PVOID
void * PVOID
Definition: ajatypes.h:319
LOG_MEMORY
@ LOG_MEMORY
Definition: wxdebug.h:46
CFactoryTemplate::m_ClsID
const CLSID * m_ClsID
Definition: combase.h:265
DbgSetModuleLevel
#define DbgSetModuleLevel(Type, Level)
Definition: wxdebug.h:192
CUnknown
Definition: combase.h:200
g_Templates
CFactoryTemplate g_Templates[]
CClassFactory::STDMETHODIMP_
STDMETHODIMP_(ULONG) AddRef()
g_osInfo
OSVERSIONINFO g_osInfo
Definition: dllentry.cpp:30
g_cTemplates
int g_cTemplates
ULONG
ULONG(__stdcall *_RegisterTraceGuids)(__in IN WMIDPREQUEST RequestAddress
__control_entrypoint
__control_entrypoint(DllExport) STDAPI DllGetClassObject(__in REFCLSID rClsID
DbgDumpObjectRegister
#define DbgDumpObjectRegister()
Definition: wxdebug.h:189
DbgInitialise
#define DbgInitialise(hInst)
Definition: wxdebug.h:181
DbgTerminate
#define DbgTerminate()
Definition: wxdebug.h:182
DllInitClasses
void DllInitClasses(BOOL bLoading)
Definition: dllentry.cpp:224
pv
__in REFIID __deref_out void ** pv
Definition: dllentry.cpp:194
CheckPointer
#define CheckPointer(p, ret)
Definition: wxdebug.h:225
ASSERT
#define ASSERT(_x_)
Definition: wxdebug.h:205
hr
__out HRESULT & hr
Definition: pstream.cpp:145
CBaseObject
Definition: combase.h:158
DllCanUnloadNow
STDAPI DllCanUnloadNow()
Definition: dllentry.cpp:247