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.

280 lines
6.7 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. * 10/05/2000 rodtoll Bug #46541 - DPVOICE: A/V linking to dpvoice.lib could cause application to fail init and crash
  22. ***************************************************************************/
  23. #include "dxvoicepch.h"
  24. HRESULT DVT_Create(LPDIRECTVOICESETUPOBJECT *piDVT);
  25. HRESULT DVS_Create(LPDIRECTVOICESERVEROBJECT *piDVS);
  26. HRESULT DVC_Create(LPDIRECTVOICECLIENTOBJECT *piDVC);
  27. #define EXP __declspec(dllexport)
  28. class CClassFactory : IClassFactory
  29. {
  30. public:
  31. CClassFactory(const CLSID* pclsid) : m_lRefCnt(0), m_clsid(*pclsid) {}
  32. STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppvObj);
  33. STDMETHOD_(ULONG, AddRef)()
  34. {
  35. return InterlockedIncrement(&m_lRefCnt);
  36. }
  37. STDMETHOD_(ULONG, Release)()
  38. {
  39. ULONG l = InterlockedDecrement(&m_lRefCnt);
  40. if (l == 0)
  41. {
  42. delete this;
  43. DecrementObjectCount();
  44. }
  45. return l;
  46. }
  47. STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj);
  48. STDMETHOD(LockServer)(BOOL fLock)
  49. {
  50. if( fLock )
  51. {
  52. InterlockedIncrement( &g_lNumLocks );
  53. }
  54. else
  55. {
  56. InterlockedDecrement( &g_lNumLocks );
  57. }
  58. return S_OK;
  59. }
  60. private:
  61. LONG m_lRefCnt;
  62. CLSID m_clsid;
  63. };
  64. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, LPVOID* ppvObj)
  65. {
  66. *ppvObj = NULL;
  67. if( IsEqualIID(riid, IID_IClassFactory) ||
  68. IsEqualIID(riid, IID_IUnknown))
  69. {
  70. InterlockedIncrement( &m_lRefCnt );
  71. *ppvObj = this;
  72. return S_OK;
  73. }
  74. else
  75. {
  76. return E_NOINTERFACE;
  77. }
  78. }
  79. #undef DPF_MODNAME
  80. #define DPF_MODNAME "CClassFactory::CreateInstance"
  81. STDMETHODIMP CClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
  82. {
  83. HRESULT hr = DV_OK;
  84. if( ppvObj == NULL ||
  85. !DNVALID_WRITEPTR( ppvObj, sizeof(LPVOID) ) )
  86. {
  87. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer passed for object" );
  88. return DVERR_INVALIDPOINTER;
  89. }
  90. if( pUnkOuter != NULL )
  91. {
  92. DPFX(DPFPREP, DVF_ERRORLEVEL, "Object does not support aggregation" );
  93. return CLASS_E_NOAGGREGATION;
  94. }
  95. if( IsEqualGUID(riid,IID_IDirectPlayVoiceClient) )
  96. {
  97. hr = DVC_Create((LPDIRECTVOICECLIENTOBJECT *) ppvObj);
  98. if (FAILED(hr))
  99. {
  100. DPFX(DPFPREP, DVF_ERRORLEVEL, "DVC_Create Failed hr=0x%x", hr );
  101. return hr;
  102. }
  103. // get the right interface and bump the refcount
  104. hr = DVC_QueryInterface((LPDIRECTVOICECLIENTOBJECT) *ppvObj, riid, ppvObj);
  105. }
  106. else if( IsEqualGUID(riid,IID_IDirectPlayVoiceServer) )
  107. {
  108. hr = DVS_Create((LPDIRECTVOICESERVEROBJECT *) ppvObj);
  109. if (FAILED(hr))
  110. {
  111. DPFX(DPFPREP, DVF_ERRORLEVEL, "DVS_Create Failed hr=0x%x", hr );
  112. return hr;
  113. }
  114. // get the right interface and bump the refcount
  115. hr = DVS_QueryInterface((LPDIRECTVOICESERVEROBJECT) *ppvObj, riid, ppvObj);
  116. }
  117. else if( IsEqualGUID(riid,IID_IDirectPlayVoiceTest) )
  118. {
  119. hr = DVT_Create((LPDIRECTVOICESETUPOBJECT *) ppvObj);
  120. if (FAILED(hr))
  121. {
  122. DPFX(DPFPREP, DVF_ERRORLEVEL, "DVT_Create Failed hr=0x%x", hr );
  123. return hr;
  124. }
  125. // get the right interface and bump the refcount
  126. hr = DVT_QueryInterface((LPDIRECTVOICESETUPOBJECT) *ppvObj, riid, ppvObj);
  127. }
  128. else if( IsEqualGUID(riid,IID_IUnknown) )
  129. {
  130. if( m_clsid == CLSID_DirectPlayVoice )
  131. {
  132. DPFX(DPFPREP, 0, "Requesting IUnknown through generic CLSID" );
  133. return E_NOINTERFACE;
  134. }
  135. else if( m_clsid == CLSID_DirectPlayVoiceClient )
  136. {
  137. hr = DVC_Create((LPDIRECTVOICECLIENTOBJECT *) ppvObj);
  138. if (FAILED(hr))
  139. {
  140. DPFX(DPFPREP, DVF_ERRORLEVEL, "DVC_Create Failed hr=0x%x", hr );
  141. return hr;
  142. }
  143. // get the right interface and bump the refcount
  144. hr = DVC_QueryInterface((LPDIRECTVOICECLIENTOBJECT) *ppvObj, riid, ppvObj);
  145. }
  146. else if( m_clsid == CLSID_DirectPlayVoiceServer )
  147. {
  148. hr = DVS_Create((LPDIRECTVOICESERVEROBJECT *) ppvObj);
  149. if (FAILED(hr))
  150. {
  151. DPFX(DPFPREP, DVF_ERRORLEVEL, "DVS_Create Failed hr=0x%x", hr );
  152. return hr;
  153. }
  154. // get the right interface and bump the refcount
  155. hr = DVS_QueryInterface((LPDIRECTVOICESERVEROBJECT) *ppvObj, riid, ppvObj);
  156. }
  157. else if( m_clsid == CLSID_DirectPlayVoiceTest )
  158. {
  159. hr = DVT_Create((LPDIRECTVOICESETUPOBJECT *) ppvObj);
  160. if (FAILED(hr))
  161. {
  162. DPFX(DPFPREP, DVF_ERRORLEVEL, "DVT_Create Failed hr=0x%x", hr );
  163. return hr;
  164. }
  165. // get the right interface and bump the refcount
  166. hr = DVT_QueryInterface((LPDIRECTVOICESETUPOBJECT) *ppvObj, riid, ppvObj);
  167. }
  168. else
  169. {
  170. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unknown interface" );
  171. return E_NOINTERFACE;
  172. }
  173. }
  174. else
  175. {
  176. return E_NOINTERFACE;
  177. }
  178. IncrementObjectCount();
  179. return hr;
  180. }
  181. /*
  182. * DllGetClassObject
  183. *
  184. * Entry point called by COM to get a ClassFactory pointer
  185. */
  186. STDAPI DllGetClassObject(
  187. REFCLSID rclsid,
  188. REFIID riid,
  189. LPVOID *ppvObj )
  190. {
  191. CClassFactory* pcf;
  192. HRESULT hr;
  193. *ppvObj = NULL;
  194. /*
  195. * is this our class id?
  196. */
  197. if( !IsEqualCLSID(rclsid, CLSID_DirectPlayVoice) &&
  198. !IsEqualCLSID(rclsid, CLSID_DirectPlayVoiceClient) &&
  199. !IsEqualCLSID(rclsid, CLSID_DirectPlayVoiceServer) &&
  200. !IsEqualCLSID(rclsid, CLSID_DirectPlayVoiceTest) )
  201. {
  202. return CLASS_E_CLASSNOTAVAILABLE;
  203. }
  204. /*
  205. * only allow IUnknown and IClassFactory
  206. */
  207. if( !IsEqualIID( riid, IID_IUnknown ) &&
  208. !IsEqualIID( riid, IID_IClassFactory ) )
  209. {
  210. return E_NOINTERFACE;
  211. }
  212. /*
  213. * create a class factory object
  214. */
  215. pcf = new CClassFactory((CLSID*)&rclsid);
  216. if( NULL == pcf)
  217. {
  218. return E_OUTOFMEMORY;
  219. }
  220. hr = pcf->QueryInterface( riid, ppvObj );
  221. if( FAILED( hr ) )
  222. {
  223. delete ( pcf );
  224. *ppvObj = NULL;
  225. }
  226. else
  227. {
  228. IncrementObjectCount();
  229. }
  230. return hr;
  231. } /* DllGetClassObject */
  232. /*
  233. * DllCanUnloadNow
  234. *
  235. * Entry point called by COM to see if it is OK to free our DLL
  236. */
  237. STDAPI DllCanUnloadNow( void )
  238. {
  239. HRESULT hr = S_FALSE;
  240. if ( (0 == g_lNumObjects) && (0 == g_lNumLocks) )
  241. {
  242. hr = S_OK;
  243. }
  244. return hr;
  245. } /* DllCanUnloadNow */