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.9 KiB
249 lines
7.9 KiB
//******************************************************************************
|
|
//
|
|
// QSINK.H
|
|
//
|
|
// Copyright (C) 1996-1999 Microsoft Corporation
|
|
//
|
|
//******************************************************************************
|
|
#ifndef __QSINK_H__
|
|
#define __QSINK_H__
|
|
|
|
#include <sync.h>
|
|
#include <unk.h>
|
|
#include <winntsec.h>
|
|
#include <callsec.h>
|
|
#include <newnew.h>
|
|
#include <buffer.h>
|
|
#include <comutl.h>
|
|
#include <wmimsg.h>
|
|
#include <map>
|
|
|
|
#include "eventrep.h"
|
|
#include "evsink.h"
|
|
#include "delivrec.h"
|
|
|
|
/***************************************************************************
|
|
CQueueingEventSink
|
|
****************************************************************************/
|
|
|
|
class CQueueingEventSink : public CEventSink
|
|
{
|
|
protected:
|
|
|
|
CUniquePointerQueue<CDeliveryRecord> m_qpEvents;
|
|
CCritSec m_cs;
|
|
CCritSec m_sl;
|
|
BOOL m_bDelivering;
|
|
DWORD m_dwTotalSize;
|
|
DWORD m_dwMaxSize;
|
|
CEssNamespace* m_pNamespace;
|
|
|
|
//
|
|
// the logical name of this queueing sink. Queueing sinks can be
|
|
// as fined grained ( e.g one per logical consumer instance ) or
|
|
// they can be more coarse grained (e.g one per consumer provider)
|
|
//
|
|
LPWSTR m_wszName;
|
|
|
|
//
|
|
// aquired when performing and testing persistent queue initialization.
|
|
//
|
|
CCritSec m_csQueue;
|
|
|
|
//
|
|
// if recovery fails, then it stores its failure here. When new
|
|
// deliveries come in we use this to tell us if we should reinitiate
|
|
// recovery.
|
|
//
|
|
HRESULT m_hrRecovery;
|
|
|
|
//
|
|
// Used to synchronize with recovery.
|
|
//
|
|
HANDLE m_hRecoveryComplete;
|
|
BOOL m_bRecovering;
|
|
|
|
//
|
|
// These buffers are used to marshal guaranteed deliveries. This
|
|
// happens in SaveDeliveryRecord(). All calls to SaveDeliveryRecord()
|
|
// are serialized, so we can keep re-using the buffers.
|
|
//
|
|
CBuffer m_MsgData;
|
|
CBuffer m_MsgAuxData;
|
|
|
|
//
|
|
// Is used for removing messages after delivery.
|
|
//
|
|
CWbemPtr<IWmiMessageQueueReceiver> m_pRcvr;
|
|
CWbemPtr<IWmiMessageQueueReceiver> m_pXactRcvr; // TODO : XACT
|
|
|
|
//
|
|
// Is used for saving deliveries before they are put into the
|
|
// transient queue.
|
|
//
|
|
CWbemPtr<IWmiMessageSendReceive> m_pSend;
|
|
CWbemPtr<IWmiMessageSendReceive> m_pXactSend; // TODO : XACT
|
|
|
|
//
|
|
// saves the record in the specified queue. called before the
|
|
// delivery record is put on the transient queue. after a
|
|
// guaranteed type record is actually delivered to the
|
|
// consumer, then it will be removed from the queue. This happens
|
|
// in delivery record's PostDeliveryAction.
|
|
//
|
|
HRESULT SaveDeliveryRecord( IWmiMessageSendReceive* pSend,
|
|
CDeliveryRecord* pRecord );
|
|
|
|
//
|
|
// Handles the creation of the appropriate persistent record type
|
|
// based on QoS ( right now just guaranteed ). Saves records before
|
|
// returning.
|
|
//
|
|
HRESULT GetPersistentRecord( ULONG cEvents,
|
|
IWbemEvent** apEvents,
|
|
DWORD dwQoS,
|
|
CEventContext* pContext,
|
|
CDeliveryRecord** ppRecord );
|
|
//
|
|
// Handles creation of the appropriate record type based on the
|
|
// QoS specified. If the QoS is a guaranteed type, then
|
|
// it will call GetPersistentRecord().
|
|
//
|
|
HRESULT GetDeliveryRecord( ULONG cEvents,
|
|
IWbemEvent** apEvents,
|
|
DWORD dwQoS,
|
|
CEventContext* pContext,
|
|
IWbemCallSecurity* pCallSec,
|
|
CDeliveryRecord** ppRecord );
|
|
|
|
//
|
|
// Called if GetPersistentRecord() returns an error. If the problem
|
|
// can be corrected ( e.g. msmq service can be restarted ), then
|
|
// recovery will be initiated. a return code of S_OK indicates to
|
|
// the caller that they should retry their GetPersistentRecord() request.
|
|
//
|
|
HRESULT HandlePersistentQueueError( HRESULT hr, DWORD dwQos );
|
|
|
|
HRESULT InternalRecover( LPCWSTR wszQueueName, DWORD dwQoS );
|
|
|
|
HRESULT OpenReceiver( LPCWSTR wszQueueName,
|
|
DWORD dwQoS,
|
|
IWmiMessageSendReceive* pRecv,
|
|
IWmiMessageQueueReceiver** pRcvr );
|
|
|
|
HRESULT OpenSender( LPCWSTR wszQueueName,
|
|
DWORD dwQoS,
|
|
IWmiMessageSendReceive** ppSend );
|
|
|
|
~CQueueingEventSink();
|
|
|
|
public:
|
|
|
|
CQueueingEventSink( CEssNamespace* pNamespace );
|
|
|
|
HRESULT SetName( LPCWSTR wszName );
|
|
|
|
void SetMaxQueueSize(DWORD dwMaxSize) {m_dwMaxSize = dwMaxSize;}
|
|
|
|
// TODO : a lot of these parameters should go inside the context.
|
|
STDMETHODIMP SecureIndicate( long lNumEvents,
|
|
IWbemEvent** apEvents,
|
|
BOOL bMaintainSecurity,
|
|
BOOL bSlowDown,
|
|
DWORD dwQoS,
|
|
CEventContext* pContext );
|
|
|
|
HRESULT Indicate( long lNumEvents,
|
|
IWbemEvent** apEvents,
|
|
CEventContext* pContext )
|
|
{
|
|
return SecureIndicate( lNumEvents,
|
|
apEvents,
|
|
TRUE,
|
|
FALSE,
|
|
WMIMSG_FLAG_QOS_EXPRESS,
|
|
pContext);
|
|
}
|
|
|
|
HRESULT DeliverAll();
|
|
virtual HRESULT ActuallyDeliver(long lNumEvents, IWbemEvent** apEvents,
|
|
BOOL bSecure, CEventContext* pContext) = 0;
|
|
|
|
virtual HRESULT ReportQueueOverflow(IWbemEvent* pEvent, DWORD dwQueueSize)
|
|
{return S_OK;}
|
|
virtual HRESULT ReportQosFailure(IWbemEvent* pEvent, HRESULT hresError )
|
|
{return S_OK;}
|
|
|
|
static HRESULT QueueNameToSinkName( LPCWSTR wszQueueName,
|
|
WString& rwsSinkName,
|
|
WString& rwsNamespace,
|
|
DWORD& rdwQoS );
|
|
|
|
static HRESULT SinkNameToQueueName( LPCWSTR wszSinkName,
|
|
LPCWSTR wszNamespace,
|
|
DWORD dwQoS,
|
|
WString& rwsQueueName );
|
|
|
|
//
|
|
// called by guaranteed delivery record when it needs to remove a
|
|
// delivery from the guaranteed queue.
|
|
//
|
|
HRESULT GuaranteedPostDeliverAction( IWmiMessageQueueReceiver* pRcvr );
|
|
|
|
//
|
|
// Opens the specified queue and initiates the delivery of persisted
|
|
// records. Called on startup by the ess object on a background thread.
|
|
// Also called when encountering errors with saving or removing
|
|
// delivery records from the persistent queues.
|
|
//
|
|
HRESULT Recover( LPCWSTR wszQueueName, DWORD dwQoS );
|
|
|
|
//
|
|
// this method is called when a queueing sink is removed because all of
|
|
// the consumers associated with it have been removed.
|
|
//
|
|
HRESULT CleanupPersistentQueues();
|
|
|
|
protected:
|
|
|
|
DWORD GetMaxDeliverySize();
|
|
|
|
BOOL DoesRecordFitBatch( CDeliveryRecord* pRecord,
|
|
IWbemCallSecurity* pBatchSecurity,
|
|
LUID luidBatch );
|
|
|
|
HRESULT DeliverSome( );
|
|
void ClearAll();
|
|
HRESULT DeliverEvents( IWbemCallSecurity* pBatchSecurity,
|
|
long lNumEvents,
|
|
IWbemEvent** apEvents);
|
|
|
|
BOOL AddRecord( ACQUIRE CDeliveryRecord* pRecord,
|
|
BOOL bSlowDown,
|
|
DWORD* pdwSleep,
|
|
BOOL* pbFirst);
|
|
|
|
void WaitABit();
|
|
};
|
|
|
|
#endif // __QSINK_H__
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|