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

//+------------------------------------------------------------
//
// Copyright (C) 1998, Microsoft Corporation
//
// File: ccatrecip.h
//
// Contents: Class definitions for CIMsgRecipListAddr/CCatRecip
//
// Classes:
// CIMsgRecipListAddr
// CCatRecip
// CCatExpandableRecip
// CCatDLRecip
//
// Functions:
//
// History:
// jstamerj 980324 19:17:48: Created.
//
//-------------------------------------------------------------
#ifndef __CCATRECIP_H__
#define __CCATRECIP_H__
#include "ccataddr.h"
#include "icatlistresolve.h"
#include <caterr.h>
//
// CIMsgRecipListAddr, abstract class
// class to define methods for user property storage and retreival
//
class CIMsgRecipListAddr : public CCatAddr
{
public:
CIMsgRecipListAddr(CICategorizerListResolveIMP *pCICatListResolve);
virtual ~CIMsgRecipListAddr();
//
// Storage and retreival procedures
//
HRESULT GetSpecificOrigAddress(CAT_ADDRESS_TYPE CAType, LPTSTR psz, DWORD dwcc);
virtual HRESULT HrAddAddresses(DWORD dwNumAddresses, CAT_ADDRESS_TYPE *rgCAType, LPTSTR *rgpsz);
HRESULT GetICategorizerItem(ICategorizerItem **ppICatItem);
HRESULT GetICategorizerMailMsgs(ICategorizerMailMsgs *ppICatMsgs);
protected:
HRESULT CreateNewCatAddr(
CAT_ADDRESS_TYPE CAType,
LPTSTR pszAddress,
CCatAddr **ppCCatAddr,
BOOL fPrimary = FALSE);
HRESULT SetUnresolved(HRESULT hrReason);
HRESULT SetDontDeliver(BOOL fDontDeliver);
HRESULT RemoveFromDuplicateRejectionScheme(BOOL fRemove);
HRESULT HrSetDisplayNameProp(LPWSTR pwszDisplayName);
// Helper routines for checking loops
HRESULT CheckForLoop(DWORD dwNumAddresses, CAT_ADDRESS_TYPE *rgCAType, LPSTR *rgpsz, BOOL fCheckSelf);
HRESULT CheckForLoop(CAT_ADDRESS_TYPE CAType, LPTSTR pszAddress, BOOL fCheckSelf);
// Raise an event log for NDRing this recipient
VOID LogNDREvent(HRESULT hrNDRReason);
HRESULT PutICategorizerItemParent(ICategorizerItem *pItemParent,
ICategorizerItem *pItem)
{
return pItem->PutICategorizerItem(
ICATEGORIZERITEM_PARENT,
pItemParent);
}
protected:
HRESULT GetIMailMsgProperties(IMailMsgProperties **ppIMailMsgProps)
{
return CICategorizerItemIMP::GetIMailMsgProperties(
ICATEGORIZERITEM_IMAILMSGPROPERTIES,
ppIMailMsgProps);
}
HRESULT GetIMailMsgRecipientsAdd(IMailMsgRecipientsAdd **ppRecipientsAdd)
{
return CICategorizerItemIMP::GetIMailMsgRecipientsAdd(
ICATEGORIZERITEM_IMAILMSGRECIPIENTSADD,
ppRecipientsAdd);
}
HRESULT GetIMailMsgRecipientsAddIndex(DWORD *pdwIndex)
{
return GetDWORD(
ICATEGORIZERITEM_IMAILMSGRECIPIENTSADDINDEX,
pdwIndex);
}
HRESULT GetFPrimary(BOOL *pfPrimary)
{
return GetBool(
ICATEGORIZERITEM_FPRIMARY,
pfPrimary);
}
HRESULT PutIMailMsgProperties(IMailMsgProperties *pIMailMsgProps,
ICategorizerItem *pItem)
{
return pItem->PutIMailMsgProperties(
ICATEGORIZERITEM_IMAILMSGPROPERTIES,
pIMailMsgProps);
}
HRESULT PutIMailMsgRecipientsAdd(IMailMsgRecipientsAdd *pRecipientsAdd,
ICategorizerItem *pItem)
{
return pItem->PutIMailMsgRecipientsAdd(
ICATEGORIZERITEM_IMAILMSGRECIPIENTSADD,
pRecipientsAdd);
}
HRESULT PutIMailMsgRecipientsAddIndex(DWORD dwIndex, ICategorizerItem *pItem)
{
return pItem->PutDWORD(
ICATEGORIZERITEM_IMAILMSGRECIPIENTSADDINDEX,
dwIndex);
}
HRESULT PutDWLevel(DWORD dwLevel, ICategorizerItem *pItem)
{
return pItem->PutDWORD(
ICATEGORIZERITEM_DWLEVEL,
dwLevel);
}
HRESULT PutFPrimary(BOOL fPrimary, ICategorizerItem *pItem)
{
return pItem->PutBool(
ICATEGORIZERITEM_FPRIMARY,
fPrimary);
}
//
// Return the recipent level or -1 if not set
//
DWORD DWLevel()
{
HRESULT hr;
DWORD dwLevel;
hr = GetDWORD(
ICATEGORIZERITEM_DWLEVEL,
&dwLevel);
return SUCCEEDED(hr) ? dwLevel : (DWORD)-1;
}
HRESULT GetIMsgRecipInfo(
IMailMsgRecipientsAdd **ppRecipientsAdd,
DWORD *pdwIndex,
BOOL *pfPrimary,
IMailMsgProperties **ppIMailMsgProps)
{
HRESULT hr = S_OK;
//
// Initialize interface pointers to NULL
//
if(ppRecipientsAdd)
*ppRecipientsAdd = NULL;
if(ppIMailMsgProps)
*ppIMailMsgProps = NULL;
if(pfPrimary) {
hr = GetFPrimary(pfPrimary);
if(FAILED(hr))
goto CLEANUP;
}
if(pdwIndex) {
hr = GetIMailMsgRecipientsAddIndex(pdwIndex);
if(FAILED(hr))
goto CLEANUP;
}
if(ppRecipientsAdd) {
hr = GetIMailMsgRecipientsAdd(ppRecipientsAdd);
if(FAILED(hr))
goto CLEANUP;
}
if(ppIMailMsgProps) {
hr = GetIMailMsgProperties(ppIMailMsgProps);
if(FAILED(hr))
goto CLEANUP;
}
CLEANUP:
if(FAILED(hr)) {
if(ppRecipientsAdd && (*ppRecipientsAdd)) {
(*ppRecipientsAdd)->Release();
*ppRecipientsAdd = NULL;
}
if(ppIMailMsgProps && (*ppIMailMsgProps)) {
(*ppIMailMsgProps)->Release();
*ppIMailMsgProps = NULL;
}
}
return hr;
}
HRESULT PutIMsgRecipInfo(
IMailMsgRecipientsAdd **ppRecipientsAdd,
DWORD *pdwIndex,
BOOL *pfPrimary,
IMailMsgProperties **ppIMailMsgProps,
DWORD *pdwLevel,
ICategorizerItem *pItem)
{
HRESULT hr = S_OK;
if(pdwIndex)
hr = PutIMailMsgRecipientsAddIndex(*pdwIndex, pItem);
if(SUCCEEDED(hr) && pfPrimary)
hr = PutFPrimary(*pfPrimary, pItem);
if(SUCCEEDED(hr) && ppRecipientsAdd)
hr = PutIMailMsgRecipientsAdd(*ppRecipientsAdd, pItem);
if(SUCCEEDED(hr) && ppIMailMsgProps)
hr = PutIMailMsgProperties(*ppIMailMsgProps, pItem);
if(SUCCEEDED(hr) && pdwLevel)
hr = PutDWLevel(*pdwLevel, pItem);
return hr;
}
DWORD PropIdFromCAType(CAT_ADDRESS_TYPE CAType)
{
switch(CAType) {
case CAT_SMTP:
return IMMPID_RP_ADDRESS_SMTP;
case CAT_X500:
case CAT_DN:
return IMMPID_RP_ADDRESS_X500;
case CAT_X400:
return IMMPID_RP_ADDRESS_X400;
case CAT_LEGACYEXDN:
return IMMPID_RP_LEGACY_EX_DN;
case CAT_CUSTOMTYPE:
return IMMPID_RP_ADDRESS_OTHER;
break;
default:
_ASSERT(0 && "Unknown address type");
break;
}
return 0;
}
};
//
// CCatExpandableRecip
// purpose: Provide DL expansion functionality
//
class CCatExpandableRecip :
public CIMsgRecipListAddr
{
public:
typedef enum _DLOBJTYPE {
DLT_NONE,
DLT_X500,
DLT_SMTP,
DLT_DYNAMIC,
} DLOBJTYPE, *PDLOBJTYPE;
CCatExpandableRecip(CICategorizerListResolveIMP
*pCICatListResolve) :
CIMsgRecipListAddr(pCICatListResolve) {}
// Helper routing to expand DLs and forwarding addresses
HRESULT HrAddDlMembersAndForwardingAddresses(
PFN_EXPANDITEMCOMPLETION pfnCompletion,
PVOID pContext);
HRESULT HrAddDlMembers(
DLOBJTYPE dlt,
PFN_EXPANDITEMCOMPLETION pfnCompletion,
PVOID pContext);
static VOID DlExpansionCompletion(
HRESULT hrStatus,
PVOID pContext);
HRESULT HrExpandAttribute(
ICategorizerItemAttributes *pICatItemAttr,
CAT_ADDRESS_TYPE CAType,
LPSTR pszAttributeName,
PDWORD pdwNumberMembers);
HRESULT HrAddForwardingAddresses();
private:
typedef struct _tagDlCompletionContext {
CCatExpandableRecip *pCCatAddr;
PFN_EXPANDITEMCOMPLETION pfnCompletion;
PVOID pContext;
} DLCOMPLETIONCONTEXT, *PDLCOMPLETIONCONTEXT;
PDLCOMPLETIONCONTEXT AllocDlCompletionContext(
CCatExpandableRecip *pCCatAddr,
PFN_EXPANDITEMCOMPLETION pfnCompletion,
PVOID pContext)
{
PDLCOMPLETIONCONTEXT pDLContext;
pDLContext = new DLCOMPLETIONCONTEXT;
if(pDLContext) {
pDLContext->pCCatAddr = pCCatAddr;
pDLContext->pfnCompletion = pfnCompletion;
pDLContext->pContext = pContext;
}
return pDLContext;
}
friend class CMembersInsertionRequest;
};
//
// CCatRecip
//
class CCatRecip :
public CCatExpandableRecip,
public CCatDLO<CCatRecip_didx>
{
public:
//
// Flags that indicate a recipient should be NDR'd if not found in the DS
//
#define LOCFS_NDR ( LOCF_LOCALMAILBOX )
CCatRecip(CICategorizerListResolveIMP *pCICatListResolve);
virtual ~CCatRecip();
//
// lookup completion
//
VOID LookupCompletion();
//
// lookup completion only called after sender's completion
//
VOID RecipLookupCompletion();
//
// Default event sinks
//
HRESULT HrProcessItem_Default();
HRESULT HrExpandItem_Default(
PFN_EXPANDITEMCOMPLETION pfnCompletion,
PVOID pContext);
HRESULT HrCompleteItem_Default();
// Property setting routines
HRESULT AddForward(CAT_ADDRESS_TYPE CAType, LPTSTR szForwardingAddress);
HRESULT AddDLMember(CAT_ADDRESS_TYPE CAType, LPTSTR pszAddress);
HRESULT AddDynamicDLMember(
ICategorizerItemAttributes *pICatItemAttr);
// Forward loop head notification
HRESULT HandleLoopHead();
// Catch invalid addresses
HRESULT HrHandleInvalidAddress();
private:
// Helper routine of HrCompletion
HRESULT HandleFailure(HRESULT HrFailure);
HRESULT HrNeedsResolveing();
HRESULT HrSetDisplayName();
HRESULT HrNdrUnresolvedRecip(
BOOL *pfNDR)
{
DWORD dw;
dw = DwGetOrigAddressLocFlags();
if(dw == LOCF_UNKNOWN) {
//
// Assume we couldn't get locality flags because of an
// illegal address
//
return CAT_E_ILLEGAL_ADDRESS;
}
*pfNDR = (dw & LOCFS_NDR) ? TRUE : FALSE;
return S_OK;
}
private:
//
// List entry used for deferring recip completion processing until
// the sender is resolved
//
LIST_ENTRY m_le;
static DWORD m_dwRecips;
friend class CICategorizerListResolveIMP;
};
//
// CCatDLRecip -- the recip used to expand DLs only (no forwarding/alt recip/events/etc)
//
class CCatDLRecip :
public CCatRecip,
public CCatDLO<CCatDLRecip_didx>
{
public:
#define EXPANDOPT_MATCHONLY 1
CCatDLRecip(CICategorizerDLListResolveIMP *pIListResolve);
virtual ~CCatDLRecip();
//
// lookup completion
//
VOID LookupCompletion();
//
// Catch adding addresses so we can notify ICatDLListResolve
//
HRESULT HrAddAddresses(DWORD dwNumAddresses, CAT_ADDRESS_TYPE *rgCAType, LPTSTR *rgpsz);
// Property setting routines
HRESULT AddForward(CAT_ADDRESS_TYPE CAType, LPTSTR pszForwardingAddress);
HRESULT AddDLMember(CAT_ADDRESS_TYPE CAType, LPTSTR pszAddress);
// Forward loop head notification
HRESULT HandleLoopHead()
{
// Who cares about loops, we're just doing DL expansion
return S_OK;
}
// Catch invalid addresses
HRESULT HrHandleInvalidAddress()
{
// Who cares if we forward to an invalid address?
return S_OK;
}
private:
static VOID ExpansionCompletion(PVOID pContext);
CICategorizerDLListResolveIMP *m_pIListResolve;
};
//
// CMembersInsertionRequest
// -- The throttled insertion reuqest for the DL members
//
CatDebugClass(CMembersInsertionRequest),
public CInsertionRequest
{
public:
HRESULT HrInsertSearches(
DWORD dwcSearches);
VOID NotifyDeQueue(
HRESULT hr);
private:
#define SIGNATURE_CMEMBERSINSERTIONREQUEST (DWORD)'qRIM'
#define SIGNATURE_CMEMBERSINSERTIONREQUEST_INVALID (DWORD)'XRIM'
CMembersInsertionRequest(
CCatExpandableRecip *pDLRecipAddr,
ICategorizerUTF8Attributes *pItemAttributes,
PATTRIBUTE_ENUMERATOR penumerator,
CAT_ADDRESS_TYPE CAType)
{
m_dwSignature = SIGNATURE_CMEMBERSINSERTIONREQUEST;
m_pDLRecipAddr = pDLRecipAddr;
m_pDLRecipAddr->AddRef();
m_pDLRecipAddr->IncPendingLookups();
CopyMemory(&m_enumerator, penumerator, sizeof(ATTRIBUTE_ENUMERATOR));
m_CAType = CAType;
m_hr = S_OK;
m_pUTF8Attributes = pItemAttributes;
m_pUTF8Attributes->AddRef();
}
~CMembersInsertionRequest()
{
m_pUTF8Attributes->EndUTF8AttributeEnumeration(
&m_enumerator);
m_pUTF8Attributes->Release();
m_pDLRecipAddr->DecrPendingLookups();
m_pDLRecipAddr->Release();
_ASSERT(m_dwSignature == SIGNATURE_CMEMBERSINSERTIONREQUEST);
m_dwSignature = SIGNATURE_CMEMBERSINSERTIONREQUEST_INVALID;
}
ISMTPServerEx *GetISMTPServerEx()
{
return m_pDLRecipAddr->GetISMTPServerEx();
}
private:
DWORD m_dwSignature;
CCatExpandableRecip *m_pDLRecipAddr;
ICategorizerUTF8Attributes *m_pUTF8Attributes;
ATTRIBUTE_ENUMERATOR m_enumerator;
CAT_ADDRESS_TYPE m_CAType;
HRESULT m_hr;
friend class CCatExpandableRecip;
};
#endif // __CCATRECIP_H__