Windows2003-3790/inetsrv/iis/svcs/smtp/server/dropdir.hxx
2020-09-30 16:53:55 +02:00

199 lines
6.4 KiB
C++

#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_