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.

249 lines
7.6 KiB

  1. //******************************************************************************
  2. //
  3. // QSINK.H
  4. //
  5. // Copyright (C) 1996-1999 Microsoft Corporation
  6. //
  7. //******************************************************************************
  8. #ifndef __QSINK_H__
  9. #define __QSINK_H__
  10. #include <sync.h>
  11. #include <unk.h>
  12. #include <winntsec.h>
  13. #include <callsec.h>
  14. #include <newnew.h>
  15. #include <buffer.h>
  16. #include <comutl.h>
  17. #include <wmimsg.h>
  18. #include <map>
  19. #include "eventrep.h"
  20. #include "evsink.h"
  21. #include "delivrec.h"
  22. /***************************************************************************
  23. CQueueingEventSink
  24. ****************************************************************************/
  25. class CQueueingEventSink : public CEventSink
  26. {
  27. protected:
  28. CUniquePointerQueue<CDeliveryRecord> m_qpEvents;
  29. CCritSec m_cs;
  30. CCritSec m_sl;
  31. BOOL m_bDelivering;
  32. DWORD m_dwTotalSize;
  33. DWORD m_dwMaxSize;
  34. CEssNamespace* m_pNamespace;
  35. //
  36. // the logical name of this queueing sink. Queueing sinks can be
  37. // as fined grained ( e.g one per logical consumer instance ) or
  38. // they can be more coarse grained (e.g one per consumer provider)
  39. //
  40. LPWSTR m_wszName;
  41. //
  42. // aquired when performing and testing persistent queue initialization.
  43. //
  44. CCritSec m_csQueue;
  45. //
  46. // if recovery fails, then it stores its failure here. When new
  47. // deliveries come in we use this to tell us if we should reinitiate
  48. // recovery.
  49. //
  50. HRESULT m_hrRecovery;
  51. //
  52. // Used to synchronize with recovery.
  53. //
  54. HANDLE m_hRecoveryComplete;
  55. BOOL m_bRecovering;
  56. //
  57. // These buffers are used to marshal guaranteed deliveries. This
  58. // happens in SaveDeliveryRecord(). All calls to SaveDeliveryRecord()
  59. // are serialized, so we can keep re-using the buffers.
  60. //
  61. CBuffer m_MsgData;
  62. CBuffer m_MsgAuxData;
  63. //
  64. // Is used for removing messages after delivery.
  65. //
  66. CWbemPtr<IWmiMessageQueueReceiver> m_pRcvr;
  67. CWbemPtr<IWmiMessageQueueReceiver> m_pXactRcvr; // TODO : XACT
  68. //
  69. // Is used for saving deliveries before they are put into the
  70. // transient queue.
  71. //
  72. CWbemPtr<IWmiMessageSendReceive> m_pSend;
  73. CWbemPtr<IWmiMessageSendReceive> m_pXactSend; // TODO : XACT
  74. //
  75. // saves the record in the specified queue. called before the
  76. // delivery record is put on the transient queue. after a
  77. // guaranteed type record is actually delivered to the
  78. // consumer, then it will be removed from the queue. This happens
  79. // in delivery record's PostDeliveryAction.
  80. //
  81. HRESULT SaveDeliveryRecord( IWmiMessageSendReceive* pSend,
  82. CDeliveryRecord* pRecord );
  83. //
  84. // Handles the creation of the appropriate persistent record type
  85. // based on QoS ( right now just guaranteed ). Saves records before
  86. // returning.
  87. //
  88. HRESULT GetPersistentRecord( ULONG cEvents,
  89. IWbemEvent** apEvents,
  90. DWORD dwQoS,
  91. CEventContext* pContext,
  92. CDeliveryRecord** ppRecord );
  93. //
  94. // Handles creation of the appropriate record type based on the
  95. // QoS specified. If the QoS is a guaranteed type, then
  96. // it will call GetPersistentRecord().
  97. //
  98. HRESULT GetDeliveryRecord( ULONG cEvents,
  99. IWbemEvent** apEvents,
  100. DWORD dwQoS,
  101. CEventContext* pContext,
  102. IWbemCallSecurity* pCallSec,
  103. CDeliveryRecord** ppRecord );
  104. //
  105. // Called if GetPersistentRecord() returns an error. If the problem
  106. // can be corrected ( e.g. msmq service can be restarted ), then
  107. // recovery will be initiated. a return code of S_OK indicates to
  108. // the caller that they should retry their GetPersistentRecord() request.
  109. //
  110. HRESULT HandlePersistentQueueError( HRESULT hr, DWORD dwQos );
  111. HRESULT InternalRecover( LPCWSTR wszQueueName, DWORD dwQoS );
  112. HRESULT OpenReceiver( LPCWSTR wszQueueName,
  113. DWORD dwQoS,
  114. IWmiMessageSendReceive* pRecv,
  115. IWmiMessageQueueReceiver** pRcvr );
  116. HRESULT OpenSender( LPCWSTR wszQueueName,
  117. DWORD dwQoS,
  118. IWmiMessageSendReceive** ppSend );
  119. ~CQueueingEventSink();
  120. public:
  121. CQueueingEventSink( CEssNamespace* pNamespace );
  122. HRESULT SetName( LPCWSTR wszName );
  123. void SetMaxQueueSize(DWORD dwMaxSize) {m_dwMaxSize = dwMaxSize;}
  124. // TODO : a lot of these parameters should go inside the context.
  125. STDMETHODIMP SecureIndicate( long lNumEvents,
  126. IWbemEvent** apEvents,
  127. BOOL bMaintainSecurity,
  128. BOOL bSlowDown,
  129. DWORD dwQoS,
  130. CEventContext* pContext );
  131. HRESULT Indicate( long lNumEvents,
  132. IWbemEvent** apEvents,
  133. CEventContext* pContext )
  134. {
  135. return SecureIndicate( lNumEvents,
  136. apEvents,
  137. TRUE,
  138. FALSE,
  139. WMIMSG_FLAG_QOS_EXPRESS,
  140. pContext);
  141. }
  142. HRESULT DeliverAll();
  143. virtual HRESULT ActuallyDeliver(long lNumEvents, IWbemEvent** apEvents,
  144. BOOL bSecure, CEventContext* pContext) = 0;
  145. virtual HRESULT ReportQueueOverflow(IWbemEvent* pEvent, DWORD dwQueueSize)
  146. {return S_OK;}
  147. virtual HRESULT ReportQosFailure(IWbemEvent* pEvent, HRESULT hresError )
  148. {return S_OK;}
  149. static HRESULT QueueNameToSinkName( LPCWSTR wszQueueName,
  150. WString& rwsSinkName,
  151. WString& rwsNamespace,
  152. DWORD& rdwQoS );
  153. static HRESULT SinkNameToQueueName( LPCWSTR wszSinkName,
  154. LPCWSTR wszNamespace,
  155. DWORD dwQoS,
  156. WString& rwsQueueName );
  157. //
  158. // called by guaranteed delivery record when it needs to remove a
  159. // delivery from the guaranteed queue.
  160. //
  161. HRESULT GuaranteedPostDeliverAction( IWmiMessageQueueReceiver* pRcvr );
  162. //
  163. // Opens the specified queue and initiates the delivery of persisted
  164. // records. Called on startup by the ess object on a background thread.
  165. // Also called when encountering errors with saving or removing
  166. // delivery records from the persistent queues.
  167. //
  168. HRESULT Recover( LPCWSTR wszQueueName, DWORD dwQoS );
  169. //
  170. // this method is called when a queueing sink is removed because all of
  171. // the consumers associated with it have been removed.
  172. //
  173. HRESULT CleanupPersistentQueues();
  174. protected:
  175. DWORD GetMaxDeliverySize();
  176. BOOL DoesRecordFitBatch( CDeliveryRecord* pRecord,
  177. IWbemCallSecurity* pBatchSecurity,
  178. LUID luidBatch );
  179. HRESULT DeliverSome( );
  180. void ClearAll();
  181. HRESULT DeliverEvents( IWbemCallSecurity* pBatchSecurity,
  182. long lNumEvents,
  183. IWbemEvent** apEvents);
  184. BOOL AddRecord( ACQUIRE CDeliveryRecord* pRecord,
  185. BOOL bSlowDown,
  186. DWORD* pdwSleep,
  187. BOOL* pbFirst);
  188. void WaitABit();
  189. };
  190. #endif // __QSINK_H__