//----------------------------------------------------------------------------- // // // File: dsnsink.h // // Description: Header file for CDefaultDSNSink - Default DSN Generation Sink // // Author: Mike Swafford (MikeSwa) // // History: // 6/30/98 - MikeSwa Created // // Copyright (C) 1998 Microsoft Corporation // //----------------------------------------------------------------------------- #ifndef __DSNSINK_H__ #define __DSNSINK_H__ #include #include #define DSN_SINK_SIG 'sNSD' #define DSN_SINK_SIG_FREED 'NSD!' class CDSNBuffer; //Limit on the MIME boundary string set by RFC2046 #define MIME_BOUNDARY_RFC2046_LIMIT 70 //RFCs 2045-2048 suggests that we inlcude "=_" somewhere in the MIME Boundry #define MIME_BOUNDARY_CONSTANT "9B095B5ADSN=_" #define MIME_BOUNDARY_START_TIME_SIZE 16*sizeof(CHAR) //Size of string with file-time #define MIME_BOUNDARY_SIZE MIME_BOUNDARY_START_TIME_SIZE + \ sizeof(MIME_BOUNDARY_CONSTANT) + \ 24*sizeof(CHAR) //room for 8 char count and portion of host name //needs room for "x.xxx.xxx", plus an optional comment #define MAX_STATUS_COMMENT_SIZE 50 #define STATUS_STRING_SIZE 10+MAX_STATUS_COMMENT_SIZE // // The default implementation of the DSN Generation sink // class CDefaultDSNSink : public IDSNGenerationSink { public: //IUnknown STDMETHOD(QueryInterface)(REFIID riid, LPVOID * ppvObj); // // This class is allocated as a part of another object. Pass // AddRef/Release to the parent object // STDMETHOD_(ULONG, AddRef)(void) { return m_pUnk->AddRef(); } STDMETHOD_(ULONG, Release)(void) { return m_pUnk->Release(); } public: //IDSNGenerationSink STDMETHOD(OnSyncSinkInit) ( IN DWORD dwVSID); STDMETHOD(OnSyncGetDSNRecipientIterator) ( IN ISMTPServer *pISMTPServer, IN IMailMsgProperties *pIMsg, IN IMailMsgPropertyBag *pDSNProperties, IN DWORD dwStartDomain, IN DWORD dwDSNActions, IN IDSNRecipientIterator *pRecipIterIN, OUT IDSNRecipientIterator **ppRecipIterOUT); STDMETHOD(OnSyncGenerateDSN) ( IN ISMTPServer *pISMTPServer, IN IDSNSubmission *pIDSNSubmission, IN IMailMsgProperties *pIMsg, IN IMailMsgPropertyBag *pDSNProperties, IN IDSNRecipientIterator *pRecipIter); STDMETHOD(OnSyncPostGenerateDSN) ( IN ISMTPServer *pISMTPServer, IN IMailMsgProperties *pIMsgOrig, IN DWORD dwDSNAction, IN DWORD cRecipsDSNd, IN IMailMsgProperties *pIMsgDSN, IN IMailMsgPropertyBag *pDSNProperties) { return E_NOTIMPL; } #define SIGNATURE_CDEFAULTDSNSINK (DWORD)'NSDC' #define SIGNATURE_CDEFAULTDSNSINK_INVALID (DWORD)'NSDX' CDefaultDSNSink(IUnknown *pUnk); ~CDefaultDSNSink() { _ASSERT(m_dwSig == SIGNATURE_CDEFAULTDSNSINK); m_dwSig = SIGNATURE_CDEFAULTDSNSINK_INVALID; } HRESULT HrInitialize(); private: HRESULT HrGenerateDSNInternal( ISMTPServer *pISMTPServer, IMailMsgProperties *pIMailMsgProperties, IDSNRecipientIterator *pIRecipIter, IDSNSubmission *pIDSNSubmission, DWORD dwDSNActions, DWORD dwRFC821Status, HRESULT hrStatus, LPSTR szDefaultDomain, DWORD cbDefaultDomain, LPSTR szReportingMTA, DWORD cbReportingMTA, LPSTR szReportingMTAType, DWORD cbReportingMTAType, LPSTR szDSNContext, DWORD cbDSNContext, DWORD dwPreferredLangId, DWORD dwDSNOptions, LPSTR szCopyNDRTo, DWORD cbCopyNDRTo, FILETIME *pftExpireTime, LPSTR szHRTopCustomText, LPWSTR wszHRTopCustomText, LPSTR szHRBottomCustomText, LPWSTR wszHRBottomCustomText, IMailMsgProperties **ppIMailMsgPropertiesDSN, DWORD *pdwDSNTypesGenerated, DWORD *pcRecipsDSNd, DWORD *pcIterationsLeft, DWORD dwDSNRetType, HRESULT hrContentFailure); //Used to mark all recipient flags, when there is no per recip processing //happening (like NDR of DSN). HRESULT HrMarkAllRecipFlags( IN DWORD dwDSNActions, IN IDSNRecipientIterator *pIRecipIter); VOID GetCurrentIterationsDSNAction( IN OUT DWORD *pdwActualDSNAction, IN OUT DWORD *pcIterationsLeft); //Writes global DSN P1 Properties to IMailMsgProperties and P2 headers to content HRESULT HrWriteDSNP1AndP2Headers( IN DWORD dwDSNAction, IN IMailMsgProperties *pIMailMsgProperties, IN IMailMsgProperties *pIMailMsgPropertiesDSN, IN CDSNBuffer *pdsnbuff, IN LPSTR szDefaultDomain, IN DWORD cbDefaultDomain, IN LPSTR szReportingMTA, IN DWORD cbReportingMTA, IN LPSTR szDSNContext, IN DWORD cbDSNContext, IN LPSTR szCopyNDRTo, IN HRESULT hrStatus, IN LPSTR szMimeBoundary, IN DWORD cbMimeBoundary, IN DWORD dwDSNOptions, IN HRESULT hrContent); //Write human readable portion of DSN HRESULT HrWriteDSNHumanReadable( IN IMailMsgProperties *pIMailMsgProperties, IN IMailMsgRecipients *pIMailMsgRecipients, IN IDSNRecipientIterator *pIRecipIter, IN DWORD dwDSNActions, IN CDSNBuffer *pdsnbuff, IN DWORD dwPreferredLangId, IN LPSTR szMimeBoundary, IN DWORD cbMimeBoundary, IN HRESULT hrStatus, IN LPSTR szHRTopCustomText, IN LPWSTR wszHRTopCustomText, IN LPSTR szHRBottomCustomText, IN LPWSTR wszHRBottomCustomText); //Write the per-msg portion of the DSN Report HRESULT HrWriteDSNReportPerMsgProperties( IN IMailMsgProperties *pIMailMsgProperties, IN CDSNBuffer *pdsnbuff, IN LPSTR szReportingMTA, IN DWORD cbReportingMTA, IN LPSTR szMimeBoundary, IN DWORD cbMimeBoundary); //Write a per-recipient portion of the DSN Report HRESULT HrWriteDSNReportPreRecipientProperties( IN IMailMsgRecipients *pIMailMsgRecipients, IN CDSNBuffer *pdsnbuff, IN DWORD iRecip, IN LPSTR szExpireTime, IN DWORD cbExpireTime, IN DWORD dwDSNAction, IN DWORD dwRFC821Status, IN HRESULT hrStatus); //Logs events for DSN generation HRESULT HrLogDSNGenerationEvent( ISMTPServer *pISMTPServer, IMailMsgProperties *pIMailMsgProperties, IN IMailMsgRecipients *pIMailMsgRecipients, IN DWORD iRecip, IN DWORD dwDSNAction, IN DWORD dwRFC821Status, IN HRESULT hrStatus); //Writes last mime-headers, flush dsnbuffer, and copy original message HRESULT HrWriteDSNClosingAndOriginalMessage( IN IMailMsgProperties *pIMailMsgProperties, IN IMailMsgProperties *pIMailMsgPropertiesDSN, IN CDSNBuffer *pdsnbuff, IN PFIO_CONTEXT pDestFile, IN DWORD dwDSNAction, IN LPSTR szMimeBoundary, IN DWORD cbMimeBoundary, IN DWORD dwDSNRetType, IN DWORD dwOrigMsgSize); void GetCurrentMimeBoundary( IN LPSTR szReportingMTA, IN DWORD cbReportingMTA, IN OUT CHAR szMimeBoundary[MIME_BOUNDARY_SIZE], OUT DWORD *pcbMimeBoundary); //Writes the original full message to the third DSN part HRESULT HrWriteOriginalMessageFull( IN IMailMsgProperties *pIMailMsgProperties, IN IMailMsgProperties *pIMailMsgPropertiesDSN, IN CDSNBuffer *pdsnbuff, IN PFIO_CONTEXT pDestFile, IN LPSTR szMimeBoundary, IN DWORD cbMimeBoundary, IN DWORD dwOrigMsgSize); //Write only some headers of the orignal message to the third DSN part HRESULT HrWriteOriginalMessagePartialHeaders( IN IMailMsgProperties *pIMailMsgProperties, IN IMailMsgProperties *pIMailMsgPropertiesDSN, IN CDSNBuffer *pdsnbuff, IN PFIO_CONTEXT pDestFile, IN LPSTR szMimeBoundary, IN DWORD cbMimeBoundary); //Write MIME headers to finish message HRESULT HrWriteMimeClosing( IN CDSNBuffer *pdsnbuff, IN LPSTR szMimeBoundary, IN DWORD cbMimeBoundary, OUT DWORD *pcbDSNSize); //Gets the per-recipient DSN status code HRESULT HrGetStatusCode( IN IMailMsgRecipients *pIMailMsgRecipients, IN DWORD iRecip, IN DWORD dwDSNAction, IN DWORD dwStatus, IN HRESULT hrStatus, IN DWORD cbExtendedStatus, IN OUT LPSTR szExtendedStatus, IN OUT CHAR szStatus[STATUS_STRING_SIZE]); //Parse status code from RFC2034 extended status code string HRESULT HrGetStatusFromStatus( IN DWORD cbExtendedStatus, IN OUT LPSTR szExtendedStatus, IN OUT CHAR szStatus[STATUS_STRING_SIZE]); //Determine status based on supplied context information HRESULT HrGetStatusFromContext( IN HRESULT hrRecipient, IN DWORD dwRecipFlags, IN DWORD dwDSNAction, IN OUT CHAR szStatus[STATUS_STRING_SIZE]); HRESULT HrGetStatusFromRFC821Status( IN DWORD dwRFC821Status, IN OUT CHAR szStatus[STATUS_STRING_SIZE]); //Writes a list of recipients being DSN'd... one per line HRESULT HrWriteHumanReadableListOfRecips( IN IMailMsgRecipients *pIMailMsgRecipients, IN IDSNRecipientIterator *pIRecipIter, IN DWORD dwDSNActionsNeeded, IN CDSNBuffer *pdsnbuff); //Get the recipient address and type... checks multple mailmsg props HRESULT HrGetRecipAddressAndType( IN IMailMsgRecipients *pIMailMsgRecipients, IN DWORD iRecip, IN DWORD cbAddressBuffer, IN OUT LPSTR szAddressBuffer, IN DWORD cbAddressType, IN OUT LPSTR szAddressType); private: DWORD m_dwSig; IUnknown *m_pUnk; DWORD m_dwVSID; DWORD m_cDSNsRequested; BOOL m_fInit; CHAR m_szPerInstanceMimeBoundary[MIME_BOUNDARY_START_TIME_SIZE + 1]; }; //---[ CDSNGenerator ]------------------------------------------------------- // // // Description: // Default DSN Generation sink... // Hungarian: // dsnsink, pdsnsink // //----------------------------------------------------------------------------- class CDSNGenerator { protected: DWORD m_dwSignature; public: CDSNGenerator(IUnknown *pUnk); ~CDSNGenerator(); HRESULT HrInitialize() { return m_CDefaultDSNSink.HrInitialize(); } public: STDMETHOD(GenerateDSN)( IAQServerEvent *pIServerEvent, DWORD dwVSID, ISMTPServer *pISMTPServer, IMailMsgProperties *pIMailMsgProperties, DWORD dwStartDomain, DWORD dwDSNActions, DWORD dwRFC821Status, HRESULT hrStatus, LPSTR szDefaultDomain, LPSTR szReportingMTA, LPSTR szReportingMTAType, LPSTR szDSNContext, DWORD dwPreferredLangId, DWORD dwDSNOptions, LPSTR szCopyNDRTo, FILETIME *pftExpireTime, IDSNSubmission *pIAQDSNSubmission, DWORD dwMaxDSNSize); HRESULT HrTriggerGetDSNRecipientIterator( IAQServerEvent *pIServerEvent, DWORD dwVSID, ISMTPServer *pISMTPServer, IMailMsgProperties *pIMsg, IMailMsgPropertyBag *pIDSNProperties, DWORD dwStartDomain, DWORD dwDSNActions, IDSNRecipientIterator **ppIRecipIterator); HRESULT HrTriggerGenerateDSN( IAQServerEvent *pIServerEvent, DWORD dwVSID, ISMTPServer *pISMTPServer, IDSNSubmission *pIDSNSubmission, IMailMsgProperties *pIMsg, IMailMsgPropertyBag *pIDSNProperties, IDSNRecipientIterator *pIRecipIterator); HRESULT HrTriggerPostGenerateDSN( IAQServerEvent *pIServerEvent, DWORD dwVSID, ISMTPServer *pISMTPServer, IMailMsgProperties *pIMsgOrig, DWORD dwDSNAction, DWORD cRecipsDSNd, IMailMsgProperties *pIMsgDSN, IMailMsgPropertyBag *pIDSNProperties); static HRESULT HrStaticInit(); static VOID StaticDeinit(); private: HRESULT HrSetRetType( IN DWORD dwMaxDSNSize, IN IMailMsgProperties *pIMsg, IN IMailMsgPropertyBag *pDSNProps); private: CDefaultDSNSink m_CDefaultDSNSink; }; #endif //__DSNSINK_H__