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

  1. //-----------------------------------------------------------------------------
  2. //
  3. //
  4. // File: aqadmsvr.h
  5. //
  6. // Description: Contains definitions for internal structures, classes and
  7. // enums that are needed by to handle the Queue Admin functionality
  8. //
  9. // Author: Mike Swafford (MikeSwa)
  10. //
  11. // History:
  12. // 12/3/98 - MikeSwa Created
  13. // 2/21/98 - MikeSwa added support for IQueueAdmin* interfaces
  14. //
  15. // Copyright (C) 1998 Microsoft Corporation
  16. //
  17. //-----------------------------------------------------------------------------
  18. #ifndef __AQADMSVR_H__
  19. #define __AQADMSVR_H__
  20. #include <aqueue.h>
  21. #include <intrnlqa.h>
  22. #include <aqnotify.h>
  23. #define AQ_MSG_FILTER_SIG 'FMQA'
  24. //Assumed default msg size (if no hint is present)
  25. #define DEFAULT_MSG_HINT_SIZE 1000
  26. //enum describing internal flags
  27. typedef enum tagAQ_MSG_FILTER
  28. {
  29. AQ_MSG_FILTER_MESSAGEID = 0x00000001,
  30. AQ_MSG_FILTER_SENDER = 0x00000002,
  31. AQ_MSG_FILTER_RECIPIENT = 0x00000004,
  32. AQ_MSG_FILTER_OLDER_THAN = 0x00000008,
  33. AQ_MSG_FILTER_LARGER_THAN = 0x00000010,
  34. AQ_MSG_FILTER_FROZEN = 0x00000020,
  35. AQ_MSG_FILTER_FIRST_N_MESSAGES = 0x00000040,
  36. AQ_MSG_FILTER_N_LARGEST_MESSAGES = 0x00000080,
  37. AQ_MSG_FILTER_N_OLDEST_MESSAGES = 0x00000100,
  38. AQ_MSG_FILTER_FAILED = 0x00000200,
  39. AQ_MSG_FILTER_ENUMERATION = 0x10000000,
  40. AQ_MSG_FILTER_ACTION = 0x20000000,
  41. AQ_MSG_FILTER_ALL = 0x40000000,
  42. AQ_MSG_FILTER_INVERTSENSE = 0x80000000,
  43. } AQ_MSG_FILTER;
  44. #define AQUEUE_DEFAULT_SUPPORTED_ENUM_FILTERS (\
  45. MEF_FIRST_N_MESSAGES | \
  46. MEF_SENDER | \
  47. MEF_RECIPIENT | \
  48. MEF_LARGER_THAN | \
  49. MEF_OLDER_THAN | \
  50. MEF_FROZEN | \
  51. MEF_FAILED | \
  52. MEF_ALL | \
  53. MEF_INVERTSENSE)
  54. HRESULT QueryDefaultSupportedActions(DWORD *pdwSupportedActions,
  55. DWORD *pdwSupportedFilterFlags);
  56. //QueueAdmin Map function (can be used on CFifoQueue).
  57. typedef HRESULT (* QueueAdminMapFn)(CMsgRef *, PVOID, BOOL *, BOOL *);
  58. //---[ CAQAdminMessageFilter ]-------------------------------------------------
  59. //
  60. //
  61. // Description:
  62. // Internal representation for the MESSAGE_FILTER and MESSAGE_ENUM_FILETER
  63. // structures. Provides helper functions to help maintain search lists
  64. // and allow a CMsgRef to complare itself to the filter description in an
  65. // efficient manner.
  66. //
  67. // The idea is that a CMsgRef will query for the properties requested
  68. // in this filter by calling dwGetMsgFilterFlags() and calling the
  69. // specialize compare functions (which will handle the mechanics of
  70. // AQ_MSG_FILTER_INVERTSENSE).
  71. // Hungarian:
  72. // aqmf, paqmf
  73. //
  74. //-----------------------------------------------------------------------------
  75. class CAQAdminMessageFilter :
  76. public IQueueAdminMessageFilter,
  77. public CBaseObject
  78. {
  79. private:
  80. DWORD m_dwSignature;
  81. DWORD m_cMessagesToFind; //0 => find as many as possible
  82. DWORD m_cMessagesToSkip;
  83. DWORD m_cMessagesFound;
  84. DWORD m_dwFilterFlags;
  85. MESSAGE_ACTION m_dwMessageAction;
  86. LPSTR m_szMessageId;
  87. LPSTR m_szMessageSender;
  88. LPSTR m_szMessageRecipient;
  89. DWORD m_dwSenderAddressType;
  90. DWORD m_dwRecipientAddressType;
  91. DWORD m_dwThresholdSize;
  92. BOOL m_fSenderAddressTypeSpecified;
  93. BOOL m_fRecipientAddressTypeSpecified;
  94. FILETIME m_ftThresholdTime;
  95. MESSAGE_INFO *m_rgMsgInfo;
  96. MESSAGE_INFO *m_pCurrentMsgInfo;
  97. DWORD m_dwMsgIdHash;
  98. IQueueAdminAction *m_pIQueueAdminAction;
  99. PVOID m_pvUserContext;
  100. public:
  101. CAQAdminMessageFilter()
  102. {
  103. //Don't zero vtable :)
  104. ZeroMemory(((BYTE *)this)+
  105. FIELD_OFFSET(CAQAdminMessageFilter, m_dwSignature),
  106. sizeof(CAQAdminMessageFilter) -
  107. FIELD_OFFSET(CAQAdminMessageFilter, m_dwSignature));
  108. m_dwSignature = AQ_MSG_FILTER_SIG;
  109. };
  110. ~CAQAdminMessageFilter();
  111. void InitFromMsgFilter(PMESSAGE_FILTER pmf);
  112. void InitFromMsgEnumFilter(PMESSAGE_ENUM_FILTER pemf);
  113. void SetSearchContext(DWORD cMessagesToFind, MESSAGE_INFO *rgMsgInfo);
  114. void SetMessageAction(MESSAGE_ACTION MessageAction);
  115. DWORD dwGetMsgFilterFlags() {return m_dwFilterFlags;};
  116. BOOL fFoundEnoughMsgs();
  117. BOOL fFoundMsg();
  118. BOOL fSkipMsg()
  119. {
  120. if (m_cMessagesToSkip)
  121. {
  122. m_cMessagesToSkip--;
  123. return TRUE;
  124. }
  125. else
  126. {
  127. return FALSE;
  128. }
  129. }
  130. //Returns true if hash matches or is value NULL string & fMatchesId
  131. //should be called
  132. BOOL fMatchesIdHash(DWORD dwMsgIdHash)
  133. {return dwMsgIdHash ? (dwMsgIdHash == m_dwMsgIdHash) : TRUE;};
  134. DWORD cMessagesFound() {return m_cMessagesFound;};
  135. MESSAGE_INFO *pmfGetMsgInfo() {return m_pCurrentMsgInfo;};
  136. MESSAGE_INFO *pmfGetMsgInfoAtIndex(DWORD iMsgInfo)
  137. {
  138. _ASSERT(iMsgInfo < m_cMessagesFound);
  139. _ASSERT(iMsgInfo < m_cMessagesToFind);
  140. return &(m_rgMsgInfo[iMsgInfo]);
  141. };
  142. BOOL fMatchesId(LPCSTR szMessageId);
  143. BOOL fMatchesSize(DWORD dwSize);
  144. BOOL fMatchesTime(FILETIME *pftTime);
  145. BOOL fMatchesMailMsgSender(IMailMsgProperties *pIMailMsgProperties);
  146. BOOL fMatchesMailMsgRecipient(IMailMsgProperties *pIMailMsgProperties);
  147. protected: //These functions are now worker functions
  148. BOOL fMatchesSender(LPCSTR szMessageSender);
  149. BOOL fMatchesRecipient(LPCSTR szMessageRecipient);
  150. BOOL fMatchesP1Recipient(IMailMsgProperties *pIMailMsgProperties);
  151. BOOL fQueueAdminIsP1Recip(IMailMsgProperties *pIMailMsgProperties);
  152. public: //IUnknown
  153. //CBaseObject handles addref and release
  154. STDMETHOD(QueryInterface)(REFIID riid, LPVOID * ppvObj);
  155. STDMETHOD_(ULONG, AddRef)(void) {return CBaseObject::AddRef();};
  156. STDMETHOD_(ULONG, Release)(void) {return CBaseObject::Release();};
  157. public: //IQueueAdminMessageFilter
  158. STDMETHOD(HrProcessMessage)(
  159. IUnknown *pIUnknownMsg,
  160. BOOL *pfContinue,
  161. BOOL *pfDelete);
  162. STDMETHOD(HrSetQueueAdminAction)(
  163. IQueueAdminAction *pIQueueAdminAction);
  164. STDMETHOD(HrSetCurrentUserContext)(
  165. PVOID pvContext);
  166. STDMETHOD(HrGetCurrentUserContext)(
  167. PVOID *ppvContext);
  168. };
  169. #define ASYNCQ_ADMIN_CONTEXT_SIG 'CASQ'
  170. #define ASYNCQ_ADMIN_CONTEXT_SIG_FREE '!ASQ'
  171. //---[ CQueueAdminContext ]----------------------------------------------------
  172. //
  173. //
  174. // Description:
  175. // Context set on filter object when enumeration/applying actions to
  176. // to messages.
  177. // Hungarian:
  178. // qapictx, pqapictx
  179. //
  180. //-----------------------------------------------------------------------------
  181. class CQueueAdminContext
  182. {
  183. protected:
  184. DWORD m_dwSignature;
  185. IAQNotify *m_pAQNotify;
  186. LINK_INFO_FLAGS m_lfQueueState; // Is currnetfrozen / retry ?
  187. DWORD m_cMsgsThawed;
  188. CAQSvrInst *m_paqinst;
  189. public:
  190. CQueueAdminContext(IAQNotify *pAQNotify, CAQSvrInst *paqinst)
  191. {
  192. m_dwSignature = ASYNCQ_ADMIN_CONTEXT_SIG;
  193. m_pAQNotify = pAQNotify;
  194. m_cMsgsThawed = 0;
  195. m_lfQueueState = LI_READY;
  196. m_paqinst = paqinst;
  197. };
  198. ~CQueueAdminContext()
  199. {
  200. m_dwSignature = ASYNCQ_ADMIN_CONTEXT_SIG_FREE;
  201. m_pAQNotify = NULL;
  202. m_paqinst = NULL;
  203. };
  204. //
  205. // This context is thrown around as a PVOID... make sure it is valid
  206. //
  207. inline BOOL fIsValid() {return(ASYNCQ_ADMIN_CONTEXT_SIG == m_dwSignature);};
  208. //
  209. // In some cases... the state of the queue determines the state
  210. // of the message (messages on the retry queue are in retry).
  211. // the following can be used to get and set this state
  212. //
  213. inline void SetQueueState(LINK_INFO_FLAGS lfQueueType)
  214. { m_lfQueueState = lfQueueType;};
  215. inline LINK_INFO_FLAGS lfGetQueueState() {return m_lfQueueState;};
  216. //
  217. // Used to update stats when a message is removed from the queue
  218. //
  219. void NotifyMessageRemoved(CAQStats *paqstats)
  220. {
  221. _ASSERT(fIsValid());
  222. if (m_pAQNotify)
  223. m_pAQNotify->HrNotify(paqstats, FALSE);
  224. };
  225. //
  226. // Used to keep track of if we had to thaw messages
  227. //
  228. inline void IncThawedMsgs() {m_cMsgsThawed++;};
  229. inline DWORD cGetNumThawedMsgs() {return m_cMsgsThawed;};
  230. inline CAQSvrInst * paqinstGetAQ() {return m_paqinst;};
  231. };
  232. //---[ CQueueAdminRetryNotify ]---------------------------------------------------
  233. //
  234. //
  235. // Description:
  236. // Pure virtual class that defines an "interface" to update the next
  237. // retry time
  238. // Hungarian:
  239. // qapiret, pqapiret
  240. //
  241. //-----------------------------------------------------------------------------
  242. class CQueueAdminRetryNotify : public IUnknown
  243. {
  244. public:
  245. virtual void SetNextRetry(FILETIME *pft) = 0;
  246. };
  247. //Allocator funcations that are safe for the required RPC calls made by QueueAdmin
  248. inline PVOID pvQueueAdminAlloc(size_t cbSize)
  249. {
  250. return LocalAlloc(0, cbSize);
  251. }
  252. inline PVOID pvQueueAdminReAlloc(PVOID pvSrc, size_t cbSize)
  253. {
  254. return LocalReAlloc(pvSrc, cbSize, LMEM_MOVEABLE);
  255. }
  256. inline void QueueAdminFree(PVOID pvFree)
  257. {
  258. LocalFree(pvFree);
  259. }
  260. //Convert internal AQ config into to exportable UNICODE
  261. LPWSTR wszQueueAdminConvertToUnicode(LPSTR szSrc, DWORD cSrc, BOOL fUTF8 = FALSE);
  262. //Convert QueueAdmin parameter to UNICODE
  263. LPSTR szUnicodeToAscii(LPCWSTR szSrc);
  264. BOOL fBiStrcmpi(LPSTR sz, LPWSTR wsz); //compares UNICODE to ASCII string
  265. HRESULT HrQueueAdminGetStringProp(IMailMsgProperties *pIMailMsgProperties,
  266. DWORD dwPropID, LPSTR *pszProp,
  267. DWORD *pcbProp = NULL);
  268. HRESULT HrQueueAdminGetUnicodeStringProp(
  269. IMailMsgProperties *pIMailMsgProperties,
  270. DWORD dwPropID, LPWSTR *pwszProp,
  271. DWORD *pcbProp = NULL);
  272. DWORD cQueueAdminGetNumRecipsFromRFC822(LPSTR szHeader, DWORD cbHeader);
  273. void QueueAdminGetRecipListFromP1(
  274. IMailMsgProperties *pIMailMsgProperties,
  275. MESSAGE_INFO *pMsgInfo);
  276. HRESULT HrQueueAdminGetP1Sender(IMailMsgProperties *pIMailMsgProperties,
  277. LPSTR *pszSender,
  278. DWORD *pcbSender,
  279. DWORD *piAddressType,
  280. DWORD iStartAddressType = 0,
  281. BOOL fRequireAddressTypeMatch = FALSE);
  282. //---[ dwQueueAdminHash ]------------------------------------------------------
  283. //
  284. //
  285. // Description:
  286. // Function To Hash Queue Admin Strings. Specifically designed for MSGIDs
  287. // so we do not have to open the property stream to check the MSGID during
  288. // QueueAdmin operations.
  289. // Parameters:
  290. // IN szString String to Hash
  291. // Returns:
  292. // DWORD hash
  293. // History:
  294. // 1/18/99 - MikeSwa Created
  295. //
  296. //-----------------------------------------------------------------------------
  297. inline DWORD dwQueueAdminHash(LPCSTR szString)
  298. {
  299. DWORD dwHash = 0;
  300. if (szString)
  301. {
  302. while (szString && *szString)
  303. {
  304. //Use Hash from Domhash.lib
  305. dwHash *= 131; //First prime after ASCII character codes
  306. dwHash += *szString;
  307. szString++;
  308. }
  309. }
  310. return dwHash;
  311. }
  312. //FifoQ Map function used to implement a majority of queue admin functionality
  313. //pvContext should be a pointer to a IQueueAdminMessageFilter interface
  314. HRESULT QueueAdminApplyActionToMessages(IN CMsgRef *pmsgref, IN PVOID pvContext,
  315. OUT BOOL *pfContinue, OUT BOOL *pfDelete);
  316. HRESULT HrQADMApplyActionToIMailMessages(IN IMailMsgProperties *pIMailMsgProperties,
  317. IN PVOID pvContext,
  318. OUT BOOL *pfContinue,
  319. OUT BOOL *pfDelete);
  320. //
  321. // Common QAPI functinoality that both CMsgRef and IMailMsgProperties QAPI
  322. // providers will need.
  323. //
  324. HRESULT HrGetMsgInfoFromIMailMsgProperty(IMailMsgProperties* pIMailMsgProperties,
  325. MESSAGE_INFO* pMsgInfo,
  326. LINK_INFO_FLAGS flags = LI_TYPE_REMOTE_DELIVERY);
  327. HRESULT HrQADMGetMsgSize(IMailMsgProperties* pIMailMsgProperties,
  328. DWORD* pcbMsgSize);
  329. VOID UpdateCountersForLinkType(CAQSvrInst *paqinst, DWORD dwLinkType);
  330. VOID QueueAdminFileTimeToSystemTime(FILETIME *pft, SYSTEMTIME *pst);
  331. #endif //__AQADMSVR_H__