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.

245 lines
6.0 KiB

  1. //******************************************************************************
  2. //
  3. // TEMPCONS.CPP
  4. //
  5. // Copyright (C) 1996-1999 Microsoft Corporation
  6. //
  7. //******************************************************************************
  8. #include "precomp.h"
  9. #include <stdio.h>
  10. #include "ess.h"
  11. #include "tempcons.h"
  12. CTempConsumer::CTempConsumer(CEssNamespace* pNamespace)
  13. : CEventConsumer(pNamespace), m_pSink(NULL), m_bEffectivelyPermanent(FALSE)
  14. {
  15. pNamespace->IncrementObjectCount();
  16. }
  17. HRESULT CTempConsumer::Initialize( BOOL bEffectivelyPermanent,
  18. IWbemObjectSink* pSink)
  19. {
  20. m_bEffectivelyPermanent = bEffectivelyPermanent;
  21. // Save the sink
  22. // =============
  23. m_pSink = pSink;
  24. if(m_pSink)
  25. m_pSink->AddRef();
  26. // Compute the key from the sink pointer
  27. // =====================================
  28. LPWSTR wszKey = ComputeKeyFromSink(pSink);
  29. if ( NULL == wszKey )
  30. {
  31. return WBEM_E_OUT_OF_MEMORY;
  32. }
  33. CVectorDeleteMe<WCHAR> vdm(wszKey);
  34. // Save the key into the compressed format
  35. // =======================================
  36. if( !( m_isKey = wszKey ) )
  37. {
  38. return WBEM_E_OUT_OF_MEMORY;
  39. }
  40. return WBEM_S_NO_ERROR;
  41. }
  42. // This class represents a postponed request to disconnect a temporary consumer
  43. // Its implementation is to call SetStatus followed by a release
  44. class CPostponedDisconnect : public CPostponedRequest
  45. {
  46. protected:
  47. IWbemObjectSink* m_pSink;
  48. public:
  49. CPostponedDisconnect(IWbemObjectSink* pSink) : m_pSink(pSink)
  50. {
  51. m_pSink->AddRef();
  52. }
  53. ~CPostponedDisconnect()
  54. {
  55. m_pSink->Release();
  56. }
  57. HRESULT Execute(CEssNamespace* pNamespace)
  58. {
  59. m_pSink->SetStatus(0, WBEM_E_CALL_CANCELLED, NULL, NULL);
  60. m_pSink->Release();
  61. return WBEM_S_NO_ERROR;
  62. }
  63. };
  64. HRESULT CTempConsumer::Shutdown(bool bQuiet)
  65. {
  66. IWbemObjectSink* pSink = NULL;
  67. {
  68. CInCritSec ics(&m_cs);
  69. if(m_pSink)
  70. {
  71. pSink = m_pSink;
  72. m_pSink = NULL;
  73. }
  74. }
  75. if(pSink)
  76. {
  77. if(!bQuiet)
  78. pSink->SetStatus(0, WBEM_E_CALL_CANCELLED, NULL, NULL);
  79. pSink->Release();
  80. }
  81. return WBEM_S_NO_ERROR;
  82. }
  83. CTempConsumer::~CTempConsumer()
  84. {
  85. if(m_pSink)
  86. {
  87. //
  88. // Postpone disconnect request --- don't want the consumer to hand us
  89. // here
  90. //
  91. CPostponedList* pList = GetCurrentPostponedList();
  92. if(pList != NULL)
  93. {
  94. CPostponedDisconnect* pReq = new CPostponedDisconnect(m_pSink);
  95. if(pReq != NULL)
  96. pList->AddRequest( m_pNamespace, pReq);
  97. m_pSink = NULL;
  98. }
  99. else
  100. {
  101. m_pSink->Release();
  102. m_pSink = NULL;
  103. }
  104. }
  105. m_pNamespace->DecrementObjectCount();
  106. }
  107. HRESULT CTempConsumer::ActuallyDeliver(long lNumEvents, IWbemEvent** apEvents,
  108. BOOL bSecure, CEventContext* pContext)
  109. {
  110. HRESULT hres;
  111. IWbemObjectSink* pSink = NULL;
  112. {
  113. CInCritSec ics(&m_cs);
  114. if(m_pSink)
  115. {
  116. pSink = m_pSink;
  117. pSink->AddRef();
  118. }
  119. }
  120. CReleaseMe rm1(pSink);
  121. if( pSink )
  122. {
  123. //
  124. // TODO: Separate out an InternalTempConsumer class that is used
  125. // for cross-namespace delivery. This way, we can remove all of the
  126. // cross-namespace hacks ( like one below ) from this class.
  127. //
  128. if ( !m_bEffectivelyPermanent )
  129. {
  130. hres = pSink->Indicate(lNumEvents, apEvents);
  131. }
  132. else
  133. {
  134. //
  135. // before indicating to the sink, decorate the event so that
  136. // the subscribers can tell which namespace the event originated
  137. // from.
  138. //
  139. /*
  140. BUGBUG: Removing because we do not support an event being modified by one
  141. of its consumers. This is because we do not clone the event when delivering
  142. to each consumer.
  143. for( long i=0; i < lNumEvents; i++ )
  144. {
  145. hres = m_pNamespace->DecorateObject( apEvents[i] );
  146. if ( FAILED(hres) )
  147. {
  148. ERRORTRACE((LOG_ESS, "Failed to decorate a "
  149. " cross-namespace event in namespace %S.\n",
  150. m_pNamespace->GetName() ));
  151. }
  152. }
  153. */
  154. hres = ((CAbstractEventSink*)pSink)->Indicate( lNumEvents,
  155. apEvents,
  156. pContext );
  157. }
  158. }
  159. else
  160. hres = WBEM_E_CRITICAL_ERROR;
  161. if(FAILED(hres) && hres != WBEM_E_CALL_CANCELLED)
  162. {
  163. ERRORTRACE((LOG_ESS, "An attempt to deliver an evento to a "
  164. "temporary consumer failed with %X\n", hres));
  165. // The wraper for the sink took care of cancellation
  166. }
  167. return hres;
  168. }
  169. HRESULT CTempConsumer::ReportQueueOverflow(IWbemEvent* pEvent,
  170. DWORD dwQueueSize)
  171. {
  172. IWbemObjectSink* pSink = NULL;
  173. {
  174. CInCritSec ics(&m_cs);
  175. if(m_pSink)
  176. {
  177. pSink = m_pSink;
  178. pSink->AddRef();
  179. }
  180. }
  181. CReleaseMe rm1(pSink);
  182. // Call SetStatus to report
  183. // ========================
  184. if(pSink)
  185. {
  186. pSink->SetStatus(WBEM_STATUS_COMPLETE, WBEM_E_QUEUE_OVERFLOW,
  187. NULL, NULL);
  188. // Keep sink up. Hope it recovers
  189. // ===============================
  190. }
  191. return S_OK;
  192. }
  193. DELETE_ME LPWSTR CTempConsumer::ComputeKeyFromSink(IWbemObjectSink* pSink)
  194. {
  195. LPWSTR wszKey = _new WCHAR[20];
  196. if ( wszKey )
  197. {
  198. StringCchPrintfW( wszKey, 20, L"$%p", pSink );
  199. }
  200. return wszKey;
  201. }