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.

506 lines
14 KiB

  1. //+------------------------------------------------------------
  2. //
  3. // Copyright (C) 1998, Microsoft Corporation
  4. //
  5. // File: ccatrecip.h
  6. //
  7. // Contents: Class definitions for CIMsgRecipListAddr/CCatRecip
  8. //
  9. // Classes:
  10. // CIMsgRecipListAddr
  11. // CCatRecip
  12. // CCatExpandableRecip
  13. // CCatDLRecip
  14. //
  15. // Functions:
  16. //
  17. // History:
  18. // jstamerj 980324 19:17:48: Created.
  19. //
  20. //-------------------------------------------------------------
  21. #ifndef __CCATRECIP_H__
  22. #define __CCATRECIP_H__
  23. #include "ccataddr.h"
  24. #include "icatlistresolve.h"
  25. #include <caterr.h>
  26. //
  27. // CIMsgRecipListAddr, abstract class
  28. // class to define methods for user property storage and retreival
  29. //
  30. class CIMsgRecipListAddr : public CCatAddr
  31. {
  32. public:
  33. CIMsgRecipListAddr(CICategorizerListResolveIMP *pCICatListResolve);
  34. virtual ~CIMsgRecipListAddr();
  35. //
  36. // Storage and retreival procedures
  37. //
  38. HRESULT GetSpecificOrigAddress(CAT_ADDRESS_TYPE CAType, LPTSTR psz, DWORD dwcc);
  39. virtual HRESULT HrAddAddresses(DWORD dwNumAddresses, CAT_ADDRESS_TYPE *rgCAType, LPTSTR *rgpsz);
  40. HRESULT GetICategorizerItem(ICategorizerItem **ppICatItem);
  41. HRESULT GetICategorizerMailMsgs(ICategorizerMailMsgs *ppICatMsgs);
  42. protected:
  43. HRESULT CreateNewCatAddr(
  44. CAT_ADDRESS_TYPE CAType,
  45. LPTSTR pszAddress,
  46. CCatAddr **ppCCatAddr,
  47. BOOL fPrimary = FALSE);
  48. HRESULT SetUnresolved(HRESULT hrReason);
  49. HRESULT SetDontDeliver(BOOL fDontDeliver);
  50. HRESULT RemoveFromDuplicateRejectionScheme(BOOL fRemove);
  51. HRESULT HrSetDisplayNameProp(LPWSTR pwszDisplayName);
  52. // Helper routines for checking loops
  53. HRESULT CheckForLoop(DWORD dwNumAddresses, CAT_ADDRESS_TYPE *rgCAType, LPSTR *rgpsz, BOOL fCheckSelf);
  54. HRESULT CheckForLoop(CAT_ADDRESS_TYPE CAType, LPTSTR pszAddress, BOOL fCheckSelf);
  55. // Raise an event log for NDRing this recipient
  56. VOID LogNDREvent(HRESULT hrNDRReason);
  57. HRESULT PutICategorizerItemParent(ICategorizerItem *pItemParent,
  58. ICategorizerItem *pItem)
  59. {
  60. return pItem->PutICategorizerItem(
  61. ICATEGORIZERITEM_PARENT,
  62. pItemParent);
  63. }
  64. protected:
  65. HRESULT GetIMailMsgProperties(IMailMsgProperties **ppIMailMsgProps)
  66. {
  67. return CICategorizerItemIMP::GetIMailMsgProperties(
  68. ICATEGORIZERITEM_IMAILMSGPROPERTIES,
  69. ppIMailMsgProps);
  70. }
  71. HRESULT GetIMailMsgRecipientsAdd(IMailMsgRecipientsAdd **ppRecipientsAdd)
  72. {
  73. return CICategorizerItemIMP::GetIMailMsgRecipientsAdd(
  74. ICATEGORIZERITEM_IMAILMSGRECIPIENTSADD,
  75. ppRecipientsAdd);
  76. }
  77. HRESULT GetIMailMsgRecipientsAddIndex(DWORD *pdwIndex)
  78. {
  79. return GetDWORD(
  80. ICATEGORIZERITEM_IMAILMSGRECIPIENTSADDINDEX,
  81. pdwIndex);
  82. }
  83. HRESULT GetFPrimary(BOOL *pfPrimary)
  84. {
  85. return GetBool(
  86. ICATEGORIZERITEM_FPRIMARY,
  87. pfPrimary);
  88. }
  89. HRESULT PutIMailMsgProperties(IMailMsgProperties *pIMailMsgProps,
  90. ICategorizerItem *pItem)
  91. {
  92. return pItem->PutIMailMsgProperties(
  93. ICATEGORIZERITEM_IMAILMSGPROPERTIES,
  94. pIMailMsgProps);
  95. }
  96. HRESULT PutIMailMsgRecipientsAdd(IMailMsgRecipientsAdd *pRecipientsAdd,
  97. ICategorizerItem *pItem)
  98. {
  99. return pItem->PutIMailMsgRecipientsAdd(
  100. ICATEGORIZERITEM_IMAILMSGRECIPIENTSADD,
  101. pRecipientsAdd);
  102. }
  103. HRESULT PutIMailMsgRecipientsAddIndex(DWORD dwIndex, ICategorizerItem *pItem)
  104. {
  105. return pItem->PutDWORD(
  106. ICATEGORIZERITEM_IMAILMSGRECIPIENTSADDINDEX,
  107. dwIndex);
  108. }
  109. HRESULT PutDWLevel(DWORD dwLevel, ICategorizerItem *pItem)
  110. {
  111. return pItem->PutDWORD(
  112. ICATEGORIZERITEM_DWLEVEL,
  113. dwLevel);
  114. }
  115. HRESULT PutFPrimary(BOOL fPrimary, ICategorizerItem *pItem)
  116. {
  117. return pItem->PutBool(
  118. ICATEGORIZERITEM_FPRIMARY,
  119. fPrimary);
  120. }
  121. //
  122. // Return the recipent level or -1 if not set
  123. //
  124. DWORD DWLevel()
  125. {
  126. HRESULT hr;
  127. DWORD dwLevel;
  128. hr = GetDWORD(
  129. ICATEGORIZERITEM_DWLEVEL,
  130. &dwLevel);
  131. return SUCCEEDED(hr) ? dwLevel : (DWORD)-1;
  132. }
  133. HRESULT GetIMsgRecipInfo(
  134. IMailMsgRecipientsAdd **ppRecipientsAdd,
  135. DWORD *pdwIndex,
  136. BOOL *pfPrimary,
  137. IMailMsgProperties **ppIMailMsgProps)
  138. {
  139. HRESULT hr = S_OK;
  140. //
  141. // Initialize interface pointers to NULL
  142. //
  143. if(ppRecipientsAdd)
  144. *ppRecipientsAdd = NULL;
  145. if(ppIMailMsgProps)
  146. *ppIMailMsgProps = NULL;
  147. if(pfPrimary) {
  148. hr = GetFPrimary(pfPrimary);
  149. if(FAILED(hr))
  150. goto CLEANUP;
  151. }
  152. if(pdwIndex) {
  153. hr = GetIMailMsgRecipientsAddIndex(pdwIndex);
  154. if(FAILED(hr))
  155. goto CLEANUP;
  156. }
  157. if(ppRecipientsAdd) {
  158. hr = GetIMailMsgRecipientsAdd(ppRecipientsAdd);
  159. if(FAILED(hr))
  160. goto CLEANUP;
  161. }
  162. if(ppIMailMsgProps) {
  163. hr = GetIMailMsgProperties(ppIMailMsgProps);
  164. if(FAILED(hr))
  165. goto CLEANUP;
  166. }
  167. CLEANUP:
  168. if(FAILED(hr)) {
  169. if(ppRecipientsAdd && (*ppRecipientsAdd)) {
  170. (*ppRecipientsAdd)->Release();
  171. *ppRecipientsAdd = NULL;
  172. }
  173. if(ppIMailMsgProps && (*ppIMailMsgProps)) {
  174. (*ppIMailMsgProps)->Release();
  175. *ppIMailMsgProps = NULL;
  176. }
  177. }
  178. return hr;
  179. }
  180. HRESULT PutIMsgRecipInfo(
  181. IMailMsgRecipientsAdd **ppRecipientsAdd,
  182. DWORD *pdwIndex,
  183. BOOL *pfPrimary,
  184. IMailMsgProperties **ppIMailMsgProps,
  185. DWORD *pdwLevel,
  186. ICategorizerItem *pItem)
  187. {
  188. HRESULT hr = S_OK;
  189. if(pdwIndex)
  190. hr = PutIMailMsgRecipientsAddIndex(*pdwIndex, pItem);
  191. if(SUCCEEDED(hr) && pfPrimary)
  192. hr = PutFPrimary(*pfPrimary, pItem);
  193. if(SUCCEEDED(hr) && ppRecipientsAdd)
  194. hr = PutIMailMsgRecipientsAdd(*ppRecipientsAdd, pItem);
  195. if(SUCCEEDED(hr) && ppIMailMsgProps)
  196. hr = PutIMailMsgProperties(*ppIMailMsgProps, pItem);
  197. if(SUCCEEDED(hr) && pdwLevel)
  198. hr = PutDWLevel(*pdwLevel, pItem);
  199. return hr;
  200. }
  201. DWORD PropIdFromCAType(CAT_ADDRESS_TYPE CAType)
  202. {
  203. switch(CAType) {
  204. case CAT_SMTP:
  205. return IMMPID_RP_ADDRESS_SMTP;
  206. case CAT_X500:
  207. case CAT_DN:
  208. return IMMPID_RP_ADDRESS_X500;
  209. case CAT_X400:
  210. return IMMPID_RP_ADDRESS_X400;
  211. case CAT_LEGACYEXDN:
  212. return IMMPID_RP_LEGACY_EX_DN;
  213. case CAT_CUSTOMTYPE:
  214. return IMMPID_RP_ADDRESS_OTHER;
  215. break;
  216. default:
  217. _ASSERT(0 && "Unknown address type");
  218. break;
  219. }
  220. return 0;
  221. }
  222. };
  223. //
  224. // CCatExpandableRecip
  225. // purpose: Provide DL expansion functionality
  226. //
  227. class CCatExpandableRecip :
  228. public CIMsgRecipListAddr
  229. {
  230. public:
  231. typedef enum _DLOBJTYPE {
  232. DLT_NONE,
  233. DLT_X500,
  234. DLT_SMTP,
  235. DLT_DYNAMIC,
  236. } DLOBJTYPE, *PDLOBJTYPE;
  237. CCatExpandableRecip(CICategorizerListResolveIMP
  238. *pCICatListResolve) :
  239. CIMsgRecipListAddr(pCICatListResolve) {}
  240. // Helper routing to expand DLs and forwarding addresses
  241. HRESULT HrAddDlMembersAndForwardingAddresses(
  242. PFN_EXPANDITEMCOMPLETION pfnCompletion,
  243. PVOID pContext);
  244. HRESULT HrAddDlMembers(
  245. DLOBJTYPE dlt,
  246. PFN_EXPANDITEMCOMPLETION pfnCompletion,
  247. PVOID pContext);
  248. static VOID DlExpansionCompletion(
  249. HRESULT hrStatus,
  250. PVOID pContext);
  251. HRESULT HrExpandAttribute(
  252. ICategorizerItemAttributes *pICatItemAttr,
  253. CAT_ADDRESS_TYPE CAType,
  254. LPSTR pszAttributeName,
  255. PDWORD pdwNumberMembers);
  256. HRESULT HrAddForwardingAddresses();
  257. private:
  258. typedef struct _tagDlCompletionContext {
  259. CCatExpandableRecip *pCCatAddr;
  260. PFN_EXPANDITEMCOMPLETION pfnCompletion;
  261. PVOID pContext;
  262. } DLCOMPLETIONCONTEXT, *PDLCOMPLETIONCONTEXT;
  263. PDLCOMPLETIONCONTEXT AllocDlCompletionContext(
  264. CCatExpandableRecip *pCCatAddr,
  265. PFN_EXPANDITEMCOMPLETION pfnCompletion,
  266. PVOID pContext)
  267. {
  268. PDLCOMPLETIONCONTEXT pDLContext;
  269. pDLContext = new DLCOMPLETIONCONTEXT;
  270. if(pDLContext) {
  271. pDLContext->pCCatAddr = pCCatAddr;
  272. pDLContext->pfnCompletion = pfnCompletion;
  273. pDLContext->pContext = pContext;
  274. }
  275. return pDLContext;
  276. }
  277. friend class CMembersInsertionRequest;
  278. };
  279. //
  280. // CCatRecip
  281. //
  282. class CCatRecip :
  283. public CCatExpandableRecip,
  284. public CCatDLO<CCatRecip_didx>
  285. {
  286. public:
  287. //
  288. // Flags that indicate a recipient should be NDR'd if not found in the DS
  289. //
  290. #define LOCFS_NDR ( LOCF_LOCALMAILBOX )
  291. CCatRecip(CICategorizerListResolveIMP *pCICatListResolve);
  292. virtual ~CCatRecip();
  293. //
  294. // lookup completion
  295. //
  296. VOID LookupCompletion();
  297. //
  298. // lookup completion only called after sender's completion
  299. //
  300. VOID RecipLookupCompletion();
  301. //
  302. // Default event sinks
  303. //
  304. HRESULT HrProcessItem_Default();
  305. HRESULT HrExpandItem_Default(
  306. PFN_EXPANDITEMCOMPLETION pfnCompletion,
  307. PVOID pContext);
  308. HRESULT HrCompleteItem_Default();
  309. // Property setting routines
  310. HRESULT AddForward(CAT_ADDRESS_TYPE CAType, LPTSTR szForwardingAddress);
  311. HRESULT AddDLMember(CAT_ADDRESS_TYPE CAType, LPTSTR pszAddress);
  312. HRESULT AddDynamicDLMember(
  313. ICategorizerItemAttributes *pICatItemAttr);
  314. // Forward loop head notification
  315. HRESULT HandleLoopHead();
  316. // Catch invalid addresses
  317. HRESULT HrHandleInvalidAddress();
  318. private:
  319. // Helper routine of HrCompletion
  320. HRESULT HandleFailure(HRESULT HrFailure);
  321. HRESULT HrNeedsResolveing();
  322. HRESULT HrSetDisplayName();
  323. HRESULT HrNdrUnresolvedRecip(
  324. BOOL *pfNDR)
  325. {
  326. DWORD dw;
  327. dw = DwGetOrigAddressLocFlags();
  328. if(dw == LOCF_UNKNOWN) {
  329. //
  330. // Assume we couldn't get locality flags because of an
  331. // illegal address
  332. //
  333. return CAT_E_ILLEGAL_ADDRESS;
  334. }
  335. *pfNDR = (dw & LOCFS_NDR) ? TRUE : FALSE;
  336. return S_OK;
  337. }
  338. private:
  339. //
  340. // List entry used for deferring recip completion processing until
  341. // the sender is resolved
  342. //
  343. LIST_ENTRY m_le;
  344. static DWORD m_dwRecips;
  345. friend class CICategorizerListResolveIMP;
  346. };
  347. //
  348. // CCatDLRecip -- the recip used to expand DLs only (no forwarding/alt recip/events/etc)
  349. //
  350. class CCatDLRecip :
  351. public CCatRecip,
  352. public CCatDLO<CCatDLRecip_didx>
  353. {
  354. public:
  355. #define EXPANDOPT_MATCHONLY 1
  356. CCatDLRecip(CICategorizerDLListResolveIMP *pIListResolve);
  357. virtual ~CCatDLRecip();
  358. //
  359. // lookup completion
  360. //
  361. VOID LookupCompletion();
  362. //
  363. // Catch adding addresses so we can notify ICatDLListResolve
  364. //
  365. HRESULT HrAddAddresses(DWORD dwNumAddresses, CAT_ADDRESS_TYPE *rgCAType, LPTSTR *rgpsz);
  366. // Property setting routines
  367. HRESULT AddForward(CAT_ADDRESS_TYPE CAType, LPTSTR pszForwardingAddress);
  368. HRESULT AddDLMember(CAT_ADDRESS_TYPE CAType, LPTSTR pszAddress);
  369. // Forward loop head notification
  370. HRESULT HandleLoopHead()
  371. {
  372. // Who cares about loops, we're just doing DL expansion
  373. return S_OK;
  374. }
  375. // Catch invalid addresses
  376. HRESULT HrHandleInvalidAddress()
  377. {
  378. // Who cares if we forward to an invalid address?
  379. return S_OK;
  380. }
  381. private:
  382. static VOID ExpansionCompletion(PVOID pContext);
  383. CICategorizerDLListResolveIMP *m_pIListResolve;
  384. };
  385. //
  386. // CMembersInsertionRequest
  387. // -- The throttled insertion reuqest for the DL members
  388. //
  389. CatDebugClass(CMembersInsertionRequest),
  390. public CInsertionRequest
  391. {
  392. public:
  393. HRESULT HrInsertSearches(
  394. DWORD dwcSearches);
  395. VOID NotifyDeQueue(
  396. HRESULT hr);
  397. private:
  398. #define SIGNATURE_CMEMBERSINSERTIONREQUEST (DWORD)'qRIM'
  399. #define SIGNATURE_CMEMBERSINSERTIONREQUEST_INVALID (DWORD)'XRIM'
  400. CMembersInsertionRequest(
  401. CCatExpandableRecip *pDLRecipAddr,
  402. ICategorizerUTF8Attributes *pItemAttributes,
  403. PATTRIBUTE_ENUMERATOR penumerator,
  404. CAT_ADDRESS_TYPE CAType)
  405. {
  406. m_dwSignature = SIGNATURE_CMEMBERSINSERTIONREQUEST;
  407. m_pDLRecipAddr = pDLRecipAddr;
  408. m_pDLRecipAddr->AddRef();
  409. m_pDLRecipAddr->IncPendingLookups();
  410. CopyMemory(&m_enumerator, penumerator, sizeof(ATTRIBUTE_ENUMERATOR));
  411. m_CAType = CAType;
  412. m_hr = S_OK;
  413. m_pUTF8Attributes = pItemAttributes;
  414. m_pUTF8Attributes->AddRef();
  415. }
  416. ~CMembersInsertionRequest()
  417. {
  418. m_pUTF8Attributes->EndUTF8AttributeEnumeration(
  419. &m_enumerator);
  420. m_pUTF8Attributes->Release();
  421. m_pDLRecipAddr->DecrPendingLookups();
  422. m_pDLRecipAddr->Release();
  423. _ASSERT(m_dwSignature == SIGNATURE_CMEMBERSINSERTIONREQUEST);
  424. m_dwSignature = SIGNATURE_CMEMBERSINSERTIONREQUEST_INVALID;
  425. }
  426. ISMTPServerEx *GetISMTPServerEx()
  427. {
  428. return m_pDLRecipAddr->GetISMTPServerEx();
  429. }
  430. private:
  431. DWORD m_dwSignature;
  432. CCatExpandableRecip *m_pDLRecipAddr;
  433. ICategorizerUTF8Attributes *m_pUTF8Attributes;
  434. ATTRIBUTE_ENUMERATOR m_enumerator;
  435. CAT_ADDRESS_TYPE m_CAType;
  436. HRESULT m_hr;
  437. friend class CCatExpandableRecip;
  438. };
  439. #endif // __CCATRECIP_H__