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.
 
 
 
 
 
 

388 lines
13 KiB

//-----------------------------------------------------------------------------
//
//
// File: aqadmsvr.h
//
// Description: Contains definitions for internal structures, classes and
// enums that are needed by to handle the Queue Admin functionality
//
// Author: Mike Swafford (MikeSwa)
//
// History:
// 12/3/98 - MikeSwa Created
// 2/21/98 - MikeSwa added support for IQueueAdmin* interfaces
//
// Copyright (C) 1998 Microsoft Corporation
//
//-----------------------------------------------------------------------------
#ifndef __AQADMSVR_H__
#define __AQADMSVR_H__
#include <aqueue.h>
#include <intrnlqa.h>
#include <aqnotify.h>
#define AQ_MSG_FILTER_SIG 'FMQA'
//Assumed default msg size (if no hint is present)
#define DEFAULT_MSG_HINT_SIZE 1000
//enum describing internal flags
typedef enum tagAQ_MSG_FILTER
{
AQ_MSG_FILTER_MESSAGEID = 0x00000001,
AQ_MSG_FILTER_SENDER = 0x00000002,
AQ_MSG_FILTER_RECIPIENT = 0x00000004,
AQ_MSG_FILTER_OLDER_THAN = 0x00000008,
AQ_MSG_FILTER_LARGER_THAN = 0x00000010,
AQ_MSG_FILTER_FROZEN = 0x00000020,
AQ_MSG_FILTER_FIRST_N_MESSAGES = 0x00000040,
AQ_MSG_FILTER_N_LARGEST_MESSAGES = 0x00000080,
AQ_MSG_FILTER_N_OLDEST_MESSAGES = 0x00000100,
AQ_MSG_FILTER_FAILED = 0x00000200,
AQ_MSG_FILTER_ENUMERATION = 0x10000000,
AQ_MSG_FILTER_ACTION = 0x20000000,
AQ_MSG_FILTER_ALL = 0x40000000,
AQ_MSG_FILTER_INVERTSENSE = 0x80000000,
} AQ_MSG_FILTER;
#define AQUEUE_DEFAULT_SUPPORTED_ENUM_FILTERS (\
MEF_FIRST_N_MESSAGES | \
MEF_SENDER | \
MEF_RECIPIENT | \
MEF_LARGER_THAN | \
MEF_OLDER_THAN | \
MEF_FROZEN | \
MEF_FAILED | \
MEF_ALL | \
MEF_INVERTSENSE)
HRESULT QueryDefaultSupportedActions(DWORD *pdwSupportedActions,
DWORD *pdwSupportedFilterFlags);
//QueueAdmin Map function (can be used on CFifoQueue).
typedef HRESULT (* QueueAdminMapFn)(CMsgRef *, PVOID, BOOL *, BOOL *);
//---[ CAQAdminMessageFilter ]-------------------------------------------------
//
//
// Description:
// Internal representation for the MESSAGE_FILTER and MESSAGE_ENUM_FILETER
// structures. Provides helper functions to help maintain search lists
// and allow a CMsgRef to complare itself to the filter description in an
// efficient manner.
//
// The idea is that a CMsgRef will query for the properties requested
// in this filter by calling dwGetMsgFilterFlags() and calling the
// specialize compare functions (which will handle the mechanics of
// AQ_MSG_FILTER_INVERTSENSE).
// Hungarian:
// aqmf, paqmf
//
//-----------------------------------------------------------------------------
class CAQAdminMessageFilter :
public IQueueAdminMessageFilter,
public CBaseObject
{
private:
DWORD m_dwSignature;
DWORD m_cMessagesToFind; //0 => find as many as possible
DWORD m_cMessagesToSkip;
DWORD m_cMessagesFound;
DWORD m_dwFilterFlags;
MESSAGE_ACTION m_dwMessageAction;
LPSTR m_szMessageId;
LPSTR m_szMessageSender;
LPSTR m_szMessageRecipient;
DWORD m_dwSenderAddressType;
DWORD m_dwRecipientAddressType;
DWORD m_dwThresholdSize;
BOOL m_fSenderAddressTypeSpecified;
BOOL m_fRecipientAddressTypeSpecified;
FILETIME m_ftThresholdTime;
MESSAGE_INFO *m_rgMsgInfo;
MESSAGE_INFO *m_pCurrentMsgInfo;
DWORD m_dwMsgIdHash;
IQueueAdminAction *m_pIQueueAdminAction;
PVOID m_pvUserContext;
public:
CAQAdminMessageFilter()
{
//Don't zero vtable :)
ZeroMemory(((BYTE *)this)+
FIELD_OFFSET(CAQAdminMessageFilter, m_dwSignature),
sizeof(CAQAdminMessageFilter) -
FIELD_OFFSET(CAQAdminMessageFilter, m_dwSignature));
m_dwSignature = AQ_MSG_FILTER_SIG;
};
~CAQAdminMessageFilter();
void InitFromMsgFilter(PMESSAGE_FILTER pmf);
void InitFromMsgEnumFilter(PMESSAGE_ENUM_FILTER pemf);
void SetSearchContext(DWORD cMessagesToFind, MESSAGE_INFO *rgMsgInfo);
void SetMessageAction(MESSAGE_ACTION MessageAction);
DWORD dwGetMsgFilterFlags() {return m_dwFilterFlags;};
BOOL fFoundEnoughMsgs();
BOOL fFoundMsg();
BOOL fSkipMsg()
{
if (m_cMessagesToSkip)
{
m_cMessagesToSkip--;
return TRUE;
}
else
{
return FALSE;
}
}
//Returns true if hash matches or is value NULL string & fMatchesId
//should be called
BOOL fMatchesIdHash(DWORD dwMsgIdHash)
{return dwMsgIdHash ? (dwMsgIdHash == m_dwMsgIdHash) : TRUE;};
DWORD cMessagesFound() {return m_cMessagesFound;};
MESSAGE_INFO *pmfGetMsgInfo() {return m_pCurrentMsgInfo;};
MESSAGE_INFO *pmfGetMsgInfoAtIndex(DWORD iMsgInfo)
{
_ASSERT(iMsgInfo < m_cMessagesFound);
_ASSERT(iMsgInfo < m_cMessagesToFind);
return &(m_rgMsgInfo[iMsgInfo]);
};
BOOL fMatchesId(LPCSTR szMessageId);
BOOL fMatchesSize(DWORD dwSize);
BOOL fMatchesTime(FILETIME *pftTime);
BOOL fMatchesMailMsgSender(IMailMsgProperties *pIMailMsgProperties);
BOOL fMatchesMailMsgRecipient(IMailMsgProperties *pIMailMsgProperties);
protected: //These functions are now worker functions
BOOL fMatchesSender(LPCSTR szMessageSender);
BOOL fMatchesRecipient(LPCSTR szMessageRecipient);
BOOL fMatchesP1Recipient(IMailMsgProperties *pIMailMsgProperties);
BOOL fQueueAdminIsP1Recip(IMailMsgProperties *pIMailMsgProperties);
public: //IUnknown
//CBaseObject handles addref and release
STDMETHOD(QueryInterface)(REFIID riid, LPVOID * ppvObj);
STDMETHOD_(ULONG, AddRef)(void) {return CBaseObject::AddRef();};
STDMETHOD_(ULONG, Release)(void) {return CBaseObject::Release();};
public: //IQueueAdminMessageFilter
STDMETHOD(HrProcessMessage)(
IUnknown *pIUnknownMsg,
BOOL *pfContinue,
BOOL *pfDelete);
STDMETHOD(HrSetQueueAdminAction)(
IQueueAdminAction *pIQueueAdminAction);
STDMETHOD(HrSetCurrentUserContext)(
PVOID pvContext);
STDMETHOD(HrGetCurrentUserContext)(
PVOID *ppvContext);
};
#define ASYNCQ_ADMIN_CONTEXT_SIG 'CASQ'
#define ASYNCQ_ADMIN_CONTEXT_SIG_FREE '!ASQ'
//---[ CQueueAdminContext ]----------------------------------------------------
//
//
// Description:
// Context set on filter object when enumeration/applying actions to
// to messages.
// Hungarian:
// qapictx, pqapictx
//
//-----------------------------------------------------------------------------
class CQueueAdminContext
{
protected:
DWORD m_dwSignature;
IAQNotify *m_pAQNotify;
LINK_INFO_FLAGS m_lfQueueState; // Is currnetfrozen / retry ?
DWORD m_cMsgsThawed;
CAQSvrInst *m_paqinst;
public:
CQueueAdminContext(IAQNotify *pAQNotify, CAQSvrInst *paqinst)
{
m_dwSignature = ASYNCQ_ADMIN_CONTEXT_SIG;
m_pAQNotify = pAQNotify;
m_cMsgsThawed = 0;
m_lfQueueState = LI_READY;
m_paqinst = paqinst;
};
~CQueueAdminContext()
{
m_dwSignature = ASYNCQ_ADMIN_CONTEXT_SIG_FREE;
m_pAQNotify = NULL;
m_paqinst = NULL;
};
//
// This context is thrown around as a PVOID... make sure it is valid
//
inline BOOL fIsValid() {return(ASYNCQ_ADMIN_CONTEXT_SIG == m_dwSignature);};
//
// In some cases... the state of the queue determines the state
// of the message (messages on the retry queue are in retry).
// the following can be used to get and set this state
//
inline void SetQueueState(LINK_INFO_FLAGS lfQueueType)
{ m_lfQueueState = lfQueueType;};
inline LINK_INFO_FLAGS lfGetQueueState() {return m_lfQueueState;};
//
// Used to update stats when a message is removed from the queue
//
void NotifyMessageRemoved(CAQStats *paqstats)
{
_ASSERT(fIsValid());
if (m_pAQNotify)
m_pAQNotify->HrNotify(paqstats, FALSE);
};
//
// Used to keep track of if we had to thaw messages
//
inline void IncThawedMsgs() {m_cMsgsThawed++;};
inline DWORD cGetNumThawedMsgs() {return m_cMsgsThawed;};
inline CAQSvrInst * paqinstGetAQ() {return m_paqinst;};
};
//---[ CQueueAdminRetryNotify ]---------------------------------------------------
//
//
// Description:
// Pure virtual class that defines an "interface" to update the next
// retry time
// Hungarian:
// qapiret, pqapiret
//
//-----------------------------------------------------------------------------
class CQueueAdminRetryNotify : public IUnknown
{
public:
virtual void SetNextRetry(FILETIME *pft) = 0;
};
//Allocator funcations that are safe for the required RPC calls made by QueueAdmin
inline PVOID pvQueueAdminAlloc(size_t cbSize)
{
return LocalAlloc(0, cbSize);
}
inline PVOID pvQueueAdminReAlloc(PVOID pvSrc, size_t cbSize)
{
return LocalReAlloc(pvSrc, cbSize, LMEM_MOVEABLE);
}
inline void QueueAdminFree(PVOID pvFree)
{
LocalFree(pvFree);
}
//Convert internal AQ config into to exportable UNICODE
LPWSTR wszQueueAdminConvertToUnicode(LPSTR szSrc, DWORD cSrc, BOOL fUTF8 = FALSE);
//Convert QueueAdmin parameter to UNICODE
LPSTR szUnicodeToAscii(LPCWSTR szSrc);
BOOL fBiStrcmpi(LPSTR sz, LPWSTR wsz); //compares UNICODE to ASCII string
HRESULT HrQueueAdminGetStringProp(IMailMsgProperties *pIMailMsgProperties,
DWORD dwPropID, LPSTR *pszProp,
DWORD *pcbProp = NULL);
HRESULT HrQueueAdminGetUnicodeStringProp(
IMailMsgProperties *pIMailMsgProperties,
DWORD dwPropID, LPWSTR *pwszProp,
DWORD *pcbProp = NULL);
DWORD cQueueAdminGetNumRecipsFromRFC822(LPSTR szHeader, DWORD cbHeader);
void QueueAdminGetRecipListFromP1(
IMailMsgProperties *pIMailMsgProperties,
MESSAGE_INFO *pMsgInfo);
HRESULT HrQueueAdminGetP1Sender(IMailMsgProperties *pIMailMsgProperties,
LPSTR *pszSender,
DWORD *pcbSender,
DWORD *piAddressType,
DWORD iStartAddressType = 0,
BOOL fRequireAddressTypeMatch = FALSE);
//---[ dwQueueAdminHash ]------------------------------------------------------
//
//
// Description:
// Function To Hash Queue Admin Strings. Specifically designed for MSGIDs
// so we do not have to open the property stream to check the MSGID during
// QueueAdmin operations.
// Parameters:
// IN szString String to Hash
// Returns:
// DWORD hash
// History:
// 1/18/99 - MikeSwa Created
//
//-----------------------------------------------------------------------------
inline DWORD dwQueueAdminHash(LPCSTR szString)
{
DWORD dwHash = 0;
if (szString)
{
while (szString && *szString)
{
//Use Hash from Domhash.lib
dwHash *= 131; //First prime after ASCII character codes
dwHash += *szString;
szString++;
}
}
return dwHash;
}
//FifoQ Map function used to implement a majority of queue admin functionality
//pvContext should be a pointer to a IQueueAdminMessageFilter interface
HRESULT QueueAdminApplyActionToMessages(IN CMsgRef *pmsgref, IN PVOID pvContext,
OUT BOOL *pfContinue, OUT BOOL *pfDelete);
HRESULT HrQADMApplyActionToIMailMessages(IN IMailMsgProperties *pIMailMsgProperties,
IN PVOID pvContext,
OUT BOOL *pfContinue,
OUT BOOL *pfDelete);
//
// Common QAPI functinoality that both CMsgRef and IMailMsgProperties QAPI
// providers will need.
//
HRESULT HrGetMsgInfoFromIMailMsgProperty(IMailMsgProperties* pIMailMsgProperties,
MESSAGE_INFO* pMsgInfo,
LINK_INFO_FLAGS flags = LI_TYPE_REMOTE_DELIVERY);
HRESULT HrQADMGetMsgSize(IMailMsgProperties* pIMailMsgProperties,
DWORD* pcbMsgSize);
VOID UpdateCountersForLinkType(CAQSvrInst *paqinst, DWORD dwLinkType);
VOID QueueAdminFileTimeToSystemTime(FILETIME *pft, SYSTEMTIME *pst);
#endif //__AQADMSVR_H__