Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

307 lines
6.0 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1998 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: classfac.c
  6. * Content: a generic class factory
  7. *
  8. *
  9. * This is a generic C class factory. All you need to do is implement
  10. * a function called DoCreateInstance that will create an instace of
  11. * your object.
  12. *
  13. * GP_ stands for "General Purpose"
  14. *
  15. * History:
  16. * Date By Reason
  17. * ==== == ======
  18. * 10/13/98 jwo Created it.
  19. * 04/11/00 rodtoll Added code for redirection for custom builds if registry bit is set
  20. * 08/23/2000 rodtoll DllCanUnloadNow always returning TRUE!
  21. * 06/27/2001 rodtoll RC2: DPVOICE: DPVACM's DllMain calls into acm -- potential hang
  22. * Move global initialization to first object creation
  23. ***************************************************************************/
  24. #include "dpvacmpch.h"
  25. DNCRITICAL_SECTION g_csObjectCountLock;
  26. LONG g_lNumObjects = 0;
  27. HINSTANCE g_hDllInst = NULL;
  28. LONG g_lNumLocks = 0;
  29. typedef struct GPCLASSFACTORY
  30. {
  31. IClassFactoryVtbl *lpVtbl;
  32. LONG lRefCnt;
  33. CLSID clsid;
  34. } GPCLASSFACTORY, *LPGPCLASSFACTORY;
  35. /*
  36. * GP_QueryInterface
  37. */
  38. STDMETHODIMP GP_QueryInterface(
  39. LPCLASSFACTORY This,
  40. REFIID riid,
  41. LPVOID *ppvObj )
  42. {
  43. LPGPCLASSFACTORY pcf;
  44. HRESULT hr;
  45. pcf = (LPGPCLASSFACTORY)This;
  46. *ppvObj = NULL;
  47. if( IsEqualIID(riid, IID_IClassFactory) ||
  48. IsEqualIID(riid, IID_IUnknown))
  49. {
  50. InterlockedIncrement( &pcf->lRefCnt );
  51. *ppvObj = This;
  52. hr = S_OK;
  53. }
  54. else
  55. {
  56. hr = E_NOINTERFACE;
  57. }
  58. return hr;
  59. } /* GP_QueryInterface */
  60. /*
  61. * GP_AddRef
  62. */
  63. STDMETHODIMP_(ULONG) GP_AddRef( LPCLASSFACTORY This )
  64. {
  65. LPGPCLASSFACTORY pcf;
  66. pcf = (LPGPCLASSFACTORY)This;
  67. return InterlockedIncrement( &pcf->lRefCnt );
  68. } /* GP_AddRef */
  69. /*
  70. * GP_Release
  71. */
  72. STDMETHODIMP_(ULONG) GP_Release( LPCLASSFACTORY This )
  73. {
  74. LPGPCLASSFACTORY pcf;
  75. ULONG ulResult;
  76. pcf = (LPGPCLASSFACTORY)This;
  77. if( (ulResult = (ULONG) InterlockedDecrement( &pcf->lRefCnt ) ) == 0 )
  78. {
  79. DNFree( pcf );
  80. DecrementObjectCount();
  81. }
  82. return ulResult;
  83. } /* GP_Release */
  84. /*
  85. * GP_CreateInstance
  86. *
  87. * Creates an instance of a DNServiceProvider object
  88. */
  89. STDMETHODIMP GP_CreateInstance(
  90. LPCLASSFACTORY This,
  91. LPUNKNOWN pUnkOuter,
  92. REFIID riid,
  93. LPVOID *ppvObj
  94. )
  95. {
  96. HRESULT hr = S_OK;
  97. LPGPCLASSFACTORY pcf;
  98. if( pUnkOuter != NULL )
  99. {
  100. return CLASS_E_NOAGGREGATION;
  101. }
  102. pcf = (LPGPCLASSFACTORY) This;
  103. *ppvObj = NULL;
  104. /*
  105. * create the object by calling DoCreateInstance. This function
  106. * must be implemented specifically for your COM object
  107. */
  108. hr = DoCreateInstance(This, pUnkOuter, pcf->clsid, riid, ppvObj);
  109. if (FAILED(hr))
  110. {
  111. *ppvObj = NULL;
  112. return hr;
  113. }
  114. return S_OK;
  115. } /* GP_CreateInstance */
  116. /*
  117. * GP_LockServer
  118. *
  119. * Called to force our DLL to stayed loaded
  120. */
  121. STDMETHODIMP GP_LockServer(
  122. LPCLASSFACTORY This,
  123. BOOL fLock
  124. )
  125. {
  126. if( fLock )
  127. {
  128. InterlockedIncrement( &g_lNumLocks );
  129. }
  130. else
  131. {
  132. InterlockedDecrement( &g_lNumLocks );
  133. }
  134. return S_OK;
  135. } /* GP_LockServer */
  136. static IClassFactoryVtbl GPClassFactoryVtbl =
  137. {
  138. GP_QueryInterface,
  139. GP_AddRef,
  140. GP_Release,
  141. GP_CreateInstance,
  142. GP_LockServer
  143. };
  144. /*
  145. * DllGetClassObject
  146. *
  147. * Entry point called by COM to get a ClassFactory pointer
  148. */
  149. STDAPI DllGetClassObject(
  150. REFCLSID rclsid,
  151. REFIID riid,
  152. LPVOID *ppvObj )
  153. {
  154. LPGPCLASSFACTORY pcf;
  155. HRESULT hr;
  156. *ppvObj = NULL;
  157. /*
  158. * is this our class id?
  159. */
  160. // you must implement GetClassID() for your specific COM object
  161. if (!IsClassImplemented(rclsid))
  162. {
  163. return CLASS_E_CLASSNOTAVAILABLE;
  164. }
  165. /*
  166. * only allow IUnknown and IClassFactory
  167. */
  168. if( !IsEqualIID( riid, IID_IUnknown ) &&
  169. !IsEqualIID( riid, IID_IClassFactory ) )
  170. {
  171. return E_NOINTERFACE;
  172. }
  173. /*
  174. * create a class factory object
  175. */
  176. pcf = (LPGPCLASSFACTORY)DNMalloc( sizeof( GPCLASSFACTORY ) );
  177. if( NULL == pcf)
  178. {
  179. return E_OUTOFMEMORY;
  180. }
  181. pcf->lpVtbl = &GPClassFactoryVtbl;
  182. pcf->lRefCnt = 0;
  183. pcf->clsid = rclsid;
  184. hr = GP_QueryInterface( (LPCLASSFACTORY) pcf, riid, ppvObj );
  185. if( FAILED( hr ) )
  186. {
  187. DNFree ( pcf );
  188. *ppvObj = NULL;
  189. }
  190. else
  191. {
  192. IncrementObjectCount();
  193. }
  194. return hr;
  195. } /* DllGetClassObject */
  196. /*
  197. * DllCanUnloadNow
  198. *
  199. * Entry point called by COM to see if it is OK to free our DLL
  200. */
  201. STDAPI DllCanUnloadNow( void )
  202. {
  203. HRESULT hr = S_FALSE;
  204. // if (0 == gnObjects)
  205. if ( (0 == g_lNumObjects) && (0 == g_lNumLocks) )
  206. {
  207. hr = S_OK;
  208. }
  209. return hr;
  210. } /* DllCanUnloadNow */
  211. #undef DPF_MODNAME
  212. #define DPF_MODNAME "IncrementObjectCount"
  213. LONG IncrementObjectCount()
  214. {
  215. LONG lNewCount;
  216. DNEnterCriticalSection( &g_csObjectCountLock );
  217. g_lNumObjects++;
  218. lNewCount = g_lNumObjects;
  219. if( g_lNumObjects == 1 )
  220. {
  221. DPFX(DPFPREP,1,"Initializing Dll Global State" );
  222. CDPVACMI::InitCompressionList(g_hDllInst,DPVOICE_REGISTRY_BASE DPVOICE_REGISTRY_CP DPVOICE_REGISTRY_DPVACM );
  223. }
  224. DNLeaveCriticalSection( &g_csObjectCountLock );
  225. return lNewCount;
  226. }
  227. #undef DPF_MODNAME
  228. #define DPF_MODNAME "DecrementObjectCount"
  229. LONG DecrementObjectCount()
  230. {
  231. LONG lNewCount;
  232. DNEnterCriticalSection( &g_csObjectCountLock );
  233. g_lNumObjects--;
  234. lNewCount = g_lNumObjects;
  235. if( g_lNumObjects == 0 )
  236. {
  237. DPFX(DPFPREP,1,"Freeing Dll Global State" );
  238. CDPVCPI::DeInitCompressionList();
  239. }
  240. DNLeaveCriticalSection( &g_csObjectCountLock );
  241. return lNewCount;
  242. }