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.

299 lines
7.4 KiB

  1. /*****************************************************************************
  2. *
  3. * Clsfact.c
  4. *
  5. * Copyright (c) 1999, 2000 Microsoft Corporation. All Rights Reserved.
  6. *
  7. *
  8. * Abstract:
  9. *
  10. * Class factory.
  11. *
  12. *****************************************************************************/
  13. #include "dimapp.h"
  14. #include "dimap.h"
  15. /*****************************************************************************
  16. *
  17. * CClassFactory_AddRef
  18. *
  19. * Optimization: Since the class factory is static, reference
  20. * counting can be shunted to the DLL itself.
  21. *
  22. *****************************************************************************/
  23. STDMETHODIMP_(ULONG)
  24. CClassFactory_AddRef(IClassFactory *pcf)
  25. {
  26. return DllAddRef();
  27. }
  28. /*****************************************************************************
  29. *
  30. * CClassFactory_Release
  31. *
  32. * Optimization: Since the class factory is static, reference
  33. * counting can be shunted to the DLL itself.
  34. *
  35. *****************************************************************************/
  36. STDMETHODIMP_(ULONG)
  37. CClassFactory_Release(IClassFactory *pcf)
  38. {
  39. return DllRelease();
  40. }
  41. /*****************************************************************************
  42. *
  43. * CClassFactory_QueryInterface
  44. *
  45. * Our QI is very simple because we support no interfaces beyond
  46. * ourselves.
  47. *
  48. *****************************************************************************/
  49. STDMETHODIMP
  50. CClassFactory_QueryInterface(IClassFactory *pcf, REFIID riid, LPVOID *ppvOut)
  51. {
  52. HRESULT hres;
  53. if (IsEqualIID(riid, &IID_IUnknown) ||
  54. IsEqualIID(riid, &IID_IClassFactory)) {
  55. CClassFactory_AddRef(pcf);
  56. *ppvOut = pcf;
  57. hres = S_OK;
  58. } else {
  59. *ppvOut = 0;
  60. hres = E_NOINTERFACE;
  61. }
  62. return hres;
  63. }
  64. /*****************************************************************************
  65. *
  66. * CClassFactory_CreateInstance
  67. *
  68. * Create the effect driver object itself.
  69. *
  70. *****************************************************************************/
  71. STDMETHODIMP
  72. CClassFactory_CreateInstance(IClassFactory *pcf, IUnknown *punkOuter,
  73. REFIID riid, LPVOID *ppvObj)
  74. {
  75. HRESULT hres;
  76. if (punkOuter == 0) {
  77. hres = Map_New(riid, ppvObj);
  78. } else {
  79. /*
  80. * We don't support aggregation.
  81. */
  82. hres = CLASS_E_NOAGGREGATION;
  83. }
  84. return hres;
  85. }
  86. /*****************************************************************************
  87. *
  88. * CClassFactory_LockServer
  89. *
  90. *****************************************************************************/
  91. STDMETHODIMP
  92. CClassFactory_LockServer(IClassFactory *pcf, BOOL fLock)
  93. {
  94. if (fLock) {
  95. DllAddRef();
  96. } else {
  97. DllRelease();
  98. }
  99. return S_OK;
  100. }
  101. /*****************************************************************************
  102. *
  103. * The VTBL for our Class Factory
  104. *
  105. *****************************************************************************/
  106. IClassFactoryVtbl CClassFactory_Vtbl = {
  107. CClassFactory_QueryInterface,
  108. CClassFactory_AddRef,
  109. CClassFactory_Release,
  110. CClassFactory_CreateInstance,
  111. CClassFactory_LockServer,
  112. };
  113. /*****************************************************************************
  114. *
  115. * Our static class factory.
  116. *
  117. *****************************************************************************/
  118. IClassFactory g_cf = { &CClassFactory_Vtbl };
  119. /*****************************************************************************
  120. *
  121. * CClassFactory_New
  122. *
  123. *****************************************************************************/
  124. STDMETHODIMP
  125. CClassFactory_New(REFIID riid, LPVOID *ppvOut)
  126. {
  127. HRESULT hres;
  128. /*
  129. * Attempt to obtain the desired interface. QueryInterface
  130. * will do an AddRef if it succeeds.
  131. */
  132. hres = CClassFactory_QueryInterface(&g_cf, riid, ppvOut);
  133. return hres;
  134. }
  135. /*****************************************************************************/
  136. /*****************************************************************************
  137. *
  138. * Dynamic Globals. There should be as few of these as possible.
  139. *
  140. * All access to dynamic globals must be thread-safe.
  141. *
  142. *****************************************************************************/
  143. ULONG g_cRef = 0; /* Global reference count */
  144. CRITICAL_SECTION g_crst; /* Global critical section */
  145. /*****************************************************************************
  146. *
  147. * DllAddRef / DllRelease
  148. *
  149. * Adjust the DLL reference count.
  150. *
  151. *****************************************************************************/
  152. STDAPI_(ULONG)
  153. DllAddRef(void)
  154. {
  155. return (ULONG)InterlockedIncrement((LPLONG)&g_cRef);
  156. }
  157. STDAPI_(ULONG)
  158. DllRelease(void)
  159. {
  160. return (ULONG)InterlockedDecrement((LPLONG)&g_cRef);
  161. }
  162. /*****************************************************************************
  163. *
  164. * DllGetClassObject
  165. *
  166. * OLE entry point. Produces an IClassFactory for the indicated GUID.
  167. *
  168. *****************************************************************************/
  169. STDAPI
  170. DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvObj)
  171. {
  172. HRESULT hres;
  173. if (IsEqualGUID(rclsid, &IID_IDirectInputMapClsFact)) {
  174. hres = CClassFactory_New(riid, ppvObj);
  175. } else {
  176. *ppvObj = 0;
  177. hres = CLASS_E_CLASSNOTAVAILABLE;
  178. }
  179. return hres;
  180. }
  181. /*****************************************************************************
  182. *
  183. * DllCanUnloadNow
  184. *
  185. * OLE entry point. Fail iff there are outstanding refs.
  186. *
  187. *****************************************************************************/
  188. STDAPI
  189. DllCanUnloadNow(void)
  190. {
  191. return g_cRef ? S_FALSE : S_OK;
  192. }
  193. /*****************************************************************************
  194. *
  195. * DllOnProcessAttach
  196. *
  197. * Initialize the DLL.
  198. *
  199. *****************************************************************************/
  200. STDAPI_(BOOL)
  201. DllOnProcessAttach(HINSTANCE hinst)
  202. {
  203. /*
  204. * Performance tweak: We do not need thread notifications.
  205. */
  206. DisableThreadLibraryCalls(hinst);
  207. __try
  208. {
  209. InitializeCriticalSection(&g_crst);
  210. return TRUE;
  211. }
  212. __except( EXCEPTION_EXECUTE_HANDLER )
  213. {
  214. return FALSE; // usually out of memory condition
  215. }
  216. return TRUE;
  217. }
  218. /*****************************************************************************
  219. *
  220. * DllOnProcessDetach
  221. *
  222. * De-initialize the DLL.
  223. *
  224. *****************************************************************************/
  225. STDAPI_(void)
  226. DllOnProcessDetach(void)
  227. {
  228. DeleteCriticalSection(&g_crst);
  229. }
  230. /*****************************************************************************
  231. *
  232. * MapDllEntryPoint
  233. *
  234. * DLL entry point.
  235. *
  236. *****************************************************************************/
  237. /*STDAPI_(BOOL)
  238. MapDllEntryPoint*/
  239. BOOL APIENTRY DllMain
  240. (HINSTANCE hinst, DWORD dwReason, LPVOID lpReserved)
  241. {
  242. switch (dwReason) {
  243. case DLL_PROCESS_ATTACH:
  244. return DllOnProcessAttach(hinst);
  245. case DLL_PROCESS_DETACH:
  246. DllOnProcessDetach();
  247. break;
  248. }
  249. return 1;
  250. }