|
|
#ifndef _DROPDIR_HXX_
#define _DROPDIR_HXX_
#define ERROR_OBJECT_DELETED ERROR_ACCESS_DENIED
#define PRIVATE_OPTIMAL_BUFFER_SIZE 64 * 1024
#define PRIVATE_LINE_BUFFER_SIZE 1024
#define INC_REF(u) InterlockedIncrement((LONG*)&u)
#define DEC_REF(u) InterlockedDecrement((LONG*)&u)
#ifndef QWORD
typedef unsigned __int64 QWORD; #define LODWORD(qw) (DWORD)(0xffffffff&(qw))
#define HIDWORD(qw) (DWORD)(((QWORD)(qw))>>32)
#define MAKEQWORD(dwLow,dwHigh) (((QWORD)(dwLow))|(((QWORD)(dwHigh))<<32))
#endif
#define SAFE_ADDREF(p) if( p ) { p->AddRef(); }
#define SAFE_DELETE(p) if( p ) { delete p; p = NULL; }
#define SAFE_RELEASE(p) if( p ) { p->Release(); p = NULL; }
#define SAFE_SHUTRELEASE(p) if( p ) { p->Shutdown(); p->Release(); p = NULL; }
#define SAFE_COTASKMEMFREE(p) if( p ) { CoTaskMemFree( p ); p = NULL; }
#define SAFE_SYSFREESTRING(p) if( p ) { SysFreeString( p ); p = NULL; }
#define SAFE_ARRAYDELETE(p) if( p ) { delete [] p; p = NULL; }
//////////////////////////////////////////////////////////////////////////////
class CAutoTrace { public: CAutoTrace( LPARAM p, LPSTR psz ); ~CAutoTrace(); private: LPARAM m_p; LPSTR m_psz; CAutoTrace(){} }; //////////////////////////////////////////////////////////////////////////////
inline CAutoTrace::CAutoTrace( LPARAM p, LPSTR psz ) { TraceFunctEnterEx((LPARAM) p, psz); m_p = p; m_psz = psz; } //////////////////////////////////////////////////////////////////////////////
inline CAutoTrace::~CAutoTrace() { char *___pszFunctionName = m_psz; TraceFunctLeaveEx((LPARAM)m_p); }
//////////////////////////////////////////////////////////////////////////////
#define DECL_TRACE( a, b ) char *___pszFunctionName = b; \
CAutoTrace __xxCAutoTracexx__( a, b )
//////////////////////////////////////////////////////////////////////////////
#define X_SENDER_HEADER "x-sender: "
#define X_RECEIVER_HEADER "x-receiver: "
#define X_HEADER_EOLN "\r\n"
#define MAX_HEADER_SIZE (sizeof(X_RECEIVER_HEADER))
#define INVALID_RCPT_IDX_VALUE 0xFFFFFFFF
#define DROPDIR_SIG 'aDDR'
#define DROPDIR_SIG_FREE 'fDDR'
typedef struct _DROPDIR_READ_OVERLAPPED { FH_OVERLAPPED Overlapped; PVOID ThisPtr; } DROPDIR_READ_OVERLAPPED, *PDROPDIR_READ_OVERLAPPED;
enum DROPDIR_READ_STATE { DROPDIR_READ_NULL, DROPDIR_READ_X_SENDER, DROPDIR_READ_X_RECEIVER, DROPDIR_READ_DATA };
enum DROPDIR_WRITE_STATE { DROPDIR_WRITE_NULL, DROPDIR_WRITE_DATA, DROPDIR_WRITE_CRLF, DROPDIR_WRITE_SETPOS };
class CDropDir { public: //use CPool for better memory management
static CPool m_Pool;
// override the mem functions to use CPool functions
void *operator new (size_t cSize) { return m_Pool.Alloc(); } void operator delete (void *pInstance) { m_Pool.Free(pInstance); }
ULONG AddRef() { return( INC_REF( m_cRef ) ); }
ULONG Release() { LONG uHint = DEC_REF( m_cRef ); if( 0 == uHint ) { delete this; return 0; } return uHint; }
CDropDir(); HRESULT CopyMailToDropDir( ISMTPConnection *pISMTPConnection, const char *DropDirectory, IMailMsgProperties *pIMsg, PVOID AdvContext, DWORD NumRcpts, DWORD *rgRcptIndexList, SMTP_SERVER_INSTANCE *pParentInst); HRESULT OnIoWriteCompletion( DWORD cbSize, DWORD dwErr, OVERLAPPED *lpo ); HRESULT OnIoReadCompletion( DWORD cbSize, DWORD dwErr, OVERLAPPED *lpo ); VOID SetHr( HRESULT hr ) { if(FAILED(hr) ) { m_hr = hr; } } private: HANDLE CreateDropFile(const char * DropDir); HRESULT ReadFile( IN LPVOID pBuffer, IN DWORD cbSize ); HRESULT WriteFile( IN LPVOID pBuffer, IN DWORD cbSize ); HRESULT CreateXHeaders(); HRESULT CreateXRecvHeaders(); HRESULT CopyMessage(); HRESULT OnCopyMessageRead( DWORD dwBytesRead, DWORD dwErr ); HRESULT OnCopyMessageWrite( DWORD cbWritten ); HRESULT DoLastFileOp(); HRESULT AdjustFilePos(); BOOL CheckIfAllRcptsHandled(); HRESULT SetAllRcptsHandled();
~CDropDir();
private:
DWORD m_dwSig; LONG m_cRef; HRESULT m_hr; DROPDIR_READ_STATE m_ReadState; DROPDIR_WRITE_STATE m_WriteState; DWORD m_idxRecips; QWORD m_cbWriteOffset; QWORD m_cbReadOffset; QWORD m_cbMsgWritten; DWORD m_NumRcpts; PVOID m_AdvContext; SMTP_SERVER_INSTANCE *m_pParentInst; DWORD *m_rgRcptIndexList; IMailMsgProperties *m_pIMsg; IMailMsgBind *m_pBindInterface; ISMTPConnection *m_pISMTPConnection; IMailMsgRecipients *m_pIMsgRecips; HANDLE m_hDrop; PATQ_CONTEXT m_pAtqContext;
PFIO_CONTEXT m_hMail;
DROPDIR_READ_OVERLAPPED m_ReadOverlapped; OVERLAPPED m_WriteOverlapped; MessageAck m_MsgAck; CHAR m_acCrLfDotCrLf[5]; CHAR m_acLastBytes[5]; char m_szDropDir[MAX_PATH +1]; char m_szDropFile[MAX_PATH +1]; char m_szBuffer[PRIVATE_OPTIMAL_BUFFER_SIZE]; };
VOID DropDirWriteCompletion( PVOID pvContext, DWORD cbWritten, DWORD dwCompletionStatus, OVERLAPPED * lpo );
VOID DropDirReadCompletion( PFIO_CONTEXT pContext, PFH_OVERLAPPED lpo, DWORD cbRead, DWORD dwCompletionStatus );
#endif //_DROPDIR_HXX_
|