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.

241 lines
7.6 KiB

  1. // @doc
  2. /**********************************************************************
  3. *
  4. * @module IDirectInputEffectDriverClassFactory.cpp |
  5. *
  6. * Contains Class Implementation of CIDirectInputEffectDriverClassFactory:
  7. * Factory for Creating Proper Effect Driver
  8. *
  9. * History
  10. * ----------------------------------------------------------
  11. * Matthew L. Coill (mlc) Original Jul-7-1999
  12. *
  13. * (c) 1999 Microsoft Corporation. All right reserved.
  14. *
  15. * @topic This IDirectInputEffectDriver |
  16. * This Driver sits on top of the standard PID driver (which is also
  17. * an IDirectInputEffectDriver) and passes most requests to the PID driver.
  18. * Some requests such as, DownloadEffect and SendForceFeedback command are
  19. * modified for our use. Modification purposes are described at each function
  20. * definition.
  21. *
  22. **********************************************************************/
  23. #include "IDirectInputEffectDriverClassFactory.h"
  24. #include "IDirectInputEffectDriver.h"
  25. #include <crtdbg.h>
  26. #include <objbase.h>
  27. LONG DllAddRef();
  28. LONG DllRelease();
  29. extern CIDirectInputEffectDriverClassFactory* g_pClassFactoryObject;
  30. /******************** Class CIDirectInputEffectDriverClassFactory ***********************/
  31. /*****************************************************************************
  32. **
  33. ** CIDirectInputEffectDriverClassFactory::CIDirectInputEffectDriverClassFactory()
  34. **
  35. ** @mfunc Constructor
  36. **
  37. *****************************************************************************/
  38. CIDirectInputEffectDriverClassFactory::CIDirectInputEffectDriverClassFactory
  39. (
  40. IClassFactory* pIPIDClassFactory //@parm [IN] Default PID Factory
  41. ) :
  42. m_ulLockCount(0),
  43. m_ulReferenceCount(1),
  44. m_pIPIDClassFactory(pIPIDClassFactory)
  45. {
  46. // Increase global object count
  47. DllAddRef();
  48. // Add count to held object
  49. m_pIPIDClassFactory->AddRef();
  50. }
  51. /*****************************************************************************
  52. **
  53. ** CIDirectInputEffectDriverClassFactory::~CIDirectInputEffectDriverClassFactory()
  54. **
  55. ** @mfunc Destructor
  56. **
  57. *****************************************************************************/
  58. CIDirectInputEffectDriverClassFactory::~CIDirectInputEffectDriverClassFactory()
  59. {
  60. // Decrease Global object count
  61. DllRelease();
  62. _ASSERTE(m_pIPIDClassFactory == NULL);
  63. _ASSERTE(m_ulLockCount == 0);
  64. }
  65. /***********************************************************************************
  66. **
  67. ** ULONG CIDirectInputEffectDriverClassFactory::QueryInterface(REFIID refiid, void** ppvObject)
  68. **
  69. ** @func Query an Unknown for a particular type. This causes increase locally only
  70. ** If it is a type we don't know, should we give the PID factory a crack (PID factory
  71. ** might have a customized private interface, we don't want to ruin that. Currently not
  72. ** going to pass on the Query, because this could screwup Symmetry.
  73. **
  74. ** @rdesc S_OK if all is well, E_INVALIDARG if ppvObject is NULL or E_NOINTERFACE
  75. **
  76. *************************************************************************************/
  77. HRESULT __stdcall CIDirectInputEffectDriverClassFactory::QueryInterface
  78. (
  79. REFIID refiid, //@parm [IN] Identifier of the requested interface
  80. void** ppvObject //@parm [OUT] Address to place requested interface pointer
  81. )
  82. {
  83. HRESULT hrPidQuery = m_pIPIDClassFactory->QueryInterface(refiid, ppvObject);
  84. if (SUCCEEDED(hrPidQuery))
  85. {
  86. *ppvObject = this;
  87. // Increase our reference count only (pid class fact would be incremented by AddRef call)
  88. ::InterlockedIncrement((LONG*)&m_ulReferenceCount);
  89. }
  90. return hrPidQuery;
  91. }
  92. /***********************************************************************************
  93. **
  94. ** ULONG CIDirectInputEffectDriverClassFactory::AddRef()
  95. **
  96. ** @func Bumps up the reference count
  97. ** The PID Factory reference count is left alone. We only decrement it when
  98. ** this factory is ready to go away.
  99. **
  100. ** @rdesc New reference count
  101. **
  102. *************************************************************************************/
  103. ULONG __stdcall CIDirectInputEffectDriverClassFactory::AddRef()
  104. {
  105. m_pIPIDClassFactory->AddRef();
  106. return (ULONG)::InterlockedIncrement((LONG*)&m_ulReferenceCount);
  107. }
  108. /***********************************************************************************
  109. **
  110. ** ULONG CIDirectInputEffectDriverClassFactory::Release()
  111. **
  112. ** @func Decrements the reference count.
  113. ** If both the reference count and the lock count are zero the PID Factory is
  114. ** released and this object is destroyed.
  115. ** The PID Factory reference is only effected if it is time to release all.
  116. **
  117. ** @rdesc New reference count
  118. **
  119. *************************************************************************************/
  120. ULONG __stdcall CIDirectInputEffectDriverClassFactory::Release()
  121. {
  122. m_pIPIDClassFactory->Release();
  123. if (::InterlockedDecrement((LONG*)&m_ulReferenceCount) != 0)
  124. {
  125. return m_ulReferenceCount;
  126. }
  127. m_pIPIDClassFactory = NULL;
  128. g_pClassFactoryObject = NULL;
  129. delete this;
  130. return 0;
  131. }
  132. /***********************************************************************************
  133. **
  134. ** HRESULT CIDirectInputEffectDriverClassFactory::CreateInstance(IUnknown * pUnkOuter, REFIID riid, void** ppvObject)
  135. **
  136. ** @func Create an instance of the object
  137. ** Also tells the PID factory to create an instance, this is stored in our instance.
  138. **
  139. **
  140. ** @rdesc S_OK if intstance is created
  141. ** E_INVALIDARG if (ppvObject == NULL)
  142. ** CLASS_E_NOAGGREGATION if aggrigation is attempted (pUnkOuter != NULL)
  143. **
  144. *************************************************************************************/
  145. HRESULT __stdcall CIDirectInputEffectDriverClassFactory::CreateInstance
  146. (
  147. IUnknown* pUnkOuter, //@parm [IN] Aggregate class or NULL
  148. REFIID riid, //@parm [IN] IID of Object to create
  149. void** ppvObject //@parm [OUT] Address to place the requested object
  150. )
  151. {
  152. if (pUnkOuter != NULL)
  153. {
  154. return CLASS_E_NOAGGREGATION;
  155. }
  156. if (ppvObject == NULL)
  157. {
  158. return E_INVALIDARG;
  159. }
  160. if (riid == IID_IDirectInputEffectDriver)
  161. {
  162. // Let the PID Factory Create its driver
  163. IDirectInputEffectDriver* pPIDDriver = NULL;
  164. HRESULT hrPID = m_pIPIDClassFactory->CreateInstance(pUnkOuter, riid, (void**)(&pPIDDriver));
  165. if (FAILED(hrPID) || (pPIDDriver == NULL))
  166. {
  167. return hrPID;
  168. }
  169. // Create our effect driver
  170. *ppvObject = new CIDirectInputEffectDriver(pPIDDriver, m_pIPIDClassFactory);
  171. pPIDDriver->Release(); // We no longer care about this (held in our CIDirectInputEffectDriver)
  172. if (*ppvObject == NULL)
  173. {
  174. return E_OUTOFMEMORY;
  175. }
  176. return S_OK;
  177. }
  178. return E_NOINTERFACE;
  179. }
  180. /***********************************************************************************
  181. **
  182. ** HRESULT CIDirectInputEffectDriverClassFactory::LockServer(BOOL fLock)
  183. **
  184. ** @func Lock this factory down (prevents Release from causing deletion)
  185. ** If Unlocked compleatly (m_ulLockCount becomes 0) and reference count
  186. ** is at 0 - this Factory is destroyed (and the PID factory is released)
  187. **
  188. ** @rdesc S_OK : All is well
  189. ** E_UNEXPECTED: Unlock on non-locked object
  190. **
  191. *************************************************************************************/
  192. HRESULT __stdcall CIDirectInputEffectDriverClassFactory::LockServer
  193. (
  194. BOOL fLock //@parm [IN] Is the server being locked or unlocked
  195. )
  196. {
  197. HRESULT hrPidLock = m_pIPIDClassFactory->LockServer(fLock);
  198. if (FAILED(hrPidLock))
  199. {
  200. return hrPidLock;
  201. }
  202. if (fLock != FALSE)
  203. {
  204. ::InterlockedIncrement((LONG*)&m_ulLockCount);
  205. return S_OK;
  206. }
  207. if (m_ulLockCount == 0)
  208. {
  209. return E_UNEXPECTED;
  210. }
  211. ::InterlockedDecrement((LONG*)&m_ulLockCount);
  212. return hrPidLock;
  213. }