Source code of Windows XP (NT5)
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.

312 lines
6.5 KiB

  1. //******************************************************************************
  2. //
  3. // EVSINK.CPP
  4. //
  5. // Copyright (C) 1996-1999 Microsoft Corporation
  6. //
  7. //******************************************************************************
  8. #include "precomp.h"
  9. #include <stdio.h>
  10. #include <genutils.h>
  11. #include <cominit.h>
  12. #include "ess.h"
  13. #include "evsink.h"
  14. //****************************** CONTEXT **********************************//
  15. CEventContext::~CEventContext()
  16. {
  17. if( m_bOwning )
  18. {
  19. delete [] m_pSD;
  20. }
  21. }
  22. BOOL CEventContext::SetSD( long lSDLength, BYTE* pSD, BOOL bMakeCopy )
  23. {
  24. BOOL bRes = TRUE;
  25. if ( m_bOwning )
  26. {
  27. delete [] m_pSD;
  28. m_bOwning = false;
  29. }
  30. m_lSDLength = lSDLength;
  31. if ( m_lSDLength > 0 )
  32. {
  33. if ( !bMakeCopy )
  34. {
  35. m_pSD = pSD;
  36. m_bOwning = false;
  37. }
  38. else
  39. {
  40. m_pSD = new BYTE[m_lSDLength];
  41. if ( m_pSD != NULL )
  42. {
  43. memcpy( m_pSD, pSD, m_lSDLength );
  44. m_bOwning = true;
  45. }
  46. else
  47. {
  48. bRes = FALSE;
  49. }
  50. }
  51. }
  52. else
  53. {
  54. m_pSD = NULL;
  55. }
  56. return bRes;
  57. }
  58. CReuseMemoryManager CEventContext::mstatic_Manager(sizeof CEventContext);
  59. void *CEventContext::operator new(size_t nBlock)
  60. {
  61. return mstatic_Manager.Allocate();
  62. }
  63. void CEventContext::operator delete(void* p)
  64. {
  65. mstatic_Manager.Free(p);
  66. }
  67. /*
  68. void* CEventContext::operator new(size_t nSize)
  69. {
  70. return CTemporaryHeap::Alloc(nSize);
  71. }
  72. void CEventContext::operator delete(void* p)
  73. {
  74. CTemporaryHeap::Free(p, sizeof(CEventContext));
  75. }
  76. */
  77. //*************************** ABSTRTACT EVENT SINK *************************//
  78. STDMETHODIMP CAbstractEventSink::QueryInterface(REFIID riid, void** ppv)
  79. {
  80. if(riid == IID_IUnknown || riid == IID_IWbemObjectSink )
  81. {
  82. *ppv = (IWbemObjectSink*)this;
  83. AddRef();
  84. return S_OK;
  85. }
  86. else
  87. return E_NOINTERFACE;
  88. }
  89. STDMETHODIMP CAbstractEventSink::SetStatus(long, long, BSTR, IWbemClassObject*)
  90. {
  91. return E_NOTIMPL;
  92. }
  93. HRESULT CAbstractEventSink::Indicate(long lNumEvemts, IWbemEvent** apEvents,
  94. CEventContext* pContext)
  95. {
  96. return WBEM_E_CRITICAL_ERROR; // if not implemented, but called
  97. }
  98. STDMETHODIMP CAbstractEventSink::Indicate(long lNumEvents,
  99. IWbemClassObject** apEvents)
  100. {
  101. //
  102. // Event is being raised without security --- send it along with an empty
  103. // context
  104. //
  105. return Indicate(lNumEvents, apEvents, NULL);
  106. }
  107. STDMETHODIMP CAbstractEventSink::IndicateWithSD(long lNumEvents,
  108. IUnknown** apEvents,
  109. long lSDLength, BYTE* pSD)
  110. {
  111. HRESULT hres;
  112. //
  113. // Event is being raised with security -- send it along with that SD in the
  114. // context
  115. //
  116. CEventContext Context;
  117. Context.SetSD( lSDLength, pSD, FALSE );
  118. //
  119. // Allocate a stack buffer to cast the pointers
  120. //
  121. IWbemClassObject** apCast = NULL;
  122. try
  123. {
  124. apCast = (IWbemClassObject**)_alloca(sizeof(IUnknown*) * lNumEvents);
  125. }
  126. catch(...)
  127. {
  128. return WBEM_E_OUT_OF_MEMORY;
  129. }
  130. for(int i = 0; i < lNumEvents; i++)
  131. {
  132. hres = apEvents[i]->QueryInterface( IID_IWbemClassObject,
  133. (void**)&apCast[i] );
  134. if ( FAILED(hres) )
  135. {
  136. return hres;
  137. }
  138. }
  139. return Indicate(lNumEvents, apCast, &Context);
  140. }
  141. //*************************** OBJECT SINK *************************//
  142. STDMETHODIMP CObjectSink::QueryInterface(REFIID riid, void** ppv)
  143. {
  144. if(riid == IID_IUnknown || riid == IID_IWbemObjectSink)
  145. {
  146. *ppv = (IWbemObjectSink*)this;
  147. AddRef();
  148. return S_OK;
  149. }
  150. // Hack to idenitfy ourselves to the core as a trusted component
  151. else if(riid == CLSID_WbemLocator)
  152. return S_OK;
  153. else
  154. return E_NOINTERFACE;
  155. }
  156. STDMETHODIMP CObjectSink::SetStatus(long, long, BSTR, IWbemClassObject*)
  157. {
  158. return E_NOTIMPL;
  159. }
  160. ULONG STDMETHODCALLTYPE CObjectSink::AddRef()
  161. {
  162. return InterlockedIncrement(&m_lRef);
  163. }
  164. ULONG STDMETHODCALLTYPE CObjectSink::Release()
  165. {
  166. long lRef = InterlockedDecrement(&m_lRef);
  167. if(lRef == 0)
  168. delete this;
  169. return lRef;
  170. }
  171. //*************************** EVENT SINK *************************//
  172. ULONG STDMETHODCALLTYPE CEventSink::AddRef()
  173. {
  174. return InterlockedIncrement(&m_lRef);
  175. }
  176. ULONG STDMETHODCALLTYPE CEventSink::Release()
  177. {
  178. long lRef = InterlockedDecrement(&m_lRef);
  179. if(lRef == 0)
  180. delete this;
  181. return lRef;
  182. }
  183. //*************************** OWNED EVENT SINK *************************//
  184. COwnedEventSink::COwnedEventSink(CAbstractEventSink* pOwner)
  185. : m_pOwner(pOwner), m_lRef(0), m_bReleasing(false)
  186. {
  187. }
  188. ULONG STDMETHODCALLTYPE COwnedEventSink::AddRef()
  189. {
  190. CInCritSec ics(&m_cs);
  191. //
  192. // Increment our ref count, as well as that of our putative owner
  193. //
  194. m_lRef++;
  195. if(m_pOwner)
  196. m_pOwner->AddRef();
  197. return m_lRef;
  198. }
  199. ULONG STDMETHODCALLTYPE COwnedEventSink::Release()
  200. {
  201. bool bDelete = false;
  202. {
  203. CInCritSec ics(&m_cs);
  204. m_bReleasing = true;
  205. m_lRef--;
  206. //
  207. // Propagate release to our owner. This may cause Disconnect to be
  208. // called, but it will know not to self-destruct because of
  209. // m_bReleasing
  210. //
  211. if(m_pOwner)
  212. m_pOwner->Release();
  213. //
  214. // Determine whether self-destruct is called for
  215. //
  216. if(m_lRef == 0 && m_pOwner == NULL)
  217. {
  218. bDelete = true;
  219. }
  220. m_bReleasing = false;
  221. }
  222. if(bDelete)
  223. delete this;
  224. return 1;
  225. }
  226. void COwnedEventSink::Disconnect()
  227. {
  228. bool bDelete = false;
  229. {
  230. CInCritSec ics(&m_cs);
  231. if(m_pOwner == NULL)
  232. return;
  233. //
  234. // Release all the ref-counts that the owner has received through us
  235. //
  236. for(int i = 0; i < m_lRef; i++)
  237. m_pOwner->Release();
  238. //
  239. // Forget about the owner. Once we have been released by externals,
  240. // we go away
  241. //
  242. m_pOwner = NULL;
  243. //
  244. // Check if we are already fully released by externals
  245. //
  246. if(m_lRef == 0 && !m_bReleasing)
  247. bDelete = true;
  248. }
  249. if(bDelete)
  250. delete this;
  251. }