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
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__
|