502 lines
18 KiB
C++
502 lines
18 KiB
C++
/*++
|
|
|
|
Copyright (c) 1994 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
smtpout.hxx
|
|
|
|
Abstract:
|
|
|
|
This module defines the SMTP_CONNOUT class.
|
|
This object maintains information about a new client connection
|
|
|
|
Author:
|
|
|
|
Rohan Phillips ( Rohanp ) 11-Dec-1995
|
|
|
|
Project:
|
|
|
|
SMTP Server DLL
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#ifndef _SMTP_OUT_HXX_
|
|
#define _SMTP_OUT_HXX_
|
|
|
|
/************************************************************
|
|
* Include Headers
|
|
************************************************************/
|
|
#include "smtpcli.hxx"
|
|
#include "conn.hxx"
|
|
#include "simssl2.h"
|
|
|
|
//
|
|
// Protocl Events
|
|
//
|
|
#include "pe_out.hxx"
|
|
#include <smtpevent.h>
|
|
#include "pe_supp.hxx"
|
|
#include "pe_disp.h"
|
|
|
|
//
|
|
// Forward for IEventRouter
|
|
//
|
|
interface IEventRouter;
|
|
|
|
//
|
|
// Redefine the type to indicate that this is a call-back function
|
|
//
|
|
typedef ATQ_COMPLETION PFN_ATQ_COMPLETION;
|
|
|
|
/************************************************************
|
|
* Symbolic Constants
|
|
************************************************************/
|
|
#define SIZE_OPTION 0x00000001
|
|
#define PIPELINE_OPTION 0x00000002
|
|
#define EBITMIME_OPTION 0x00000004
|
|
#define SMARTHOST_OPTION 0x00000008
|
|
#define DSN_OPTION 0x00000010
|
|
#define TLS_OPTION 0x00000020
|
|
#define AUTH_NTLM 0x00000040
|
|
#define AUTH_CLEARTEXT 0x00000080
|
|
#define ETRN_SENT 0x00000100
|
|
#define ETRN_OPTION 0x00000200
|
|
#define SASL_OPTION 0x00000400
|
|
#define CHUNKING_OPTION 0x00000800
|
|
#define BINMIME_OPTION 0x00001000
|
|
#define ENHANCEDSTATUSCODE_OPTION 0x00002000
|
|
#define AUTH_GSSAPI 0x00004000
|
|
#define AUTH_DIGEST 0x00008000
|
|
#define ETRN_ONLY_OPTION 0x00010000
|
|
#define STARTTLS_OPTION 0x00020000
|
|
#define EMPTY_CONNECTION_OPTION 0x00040000
|
|
#define TURN_ONLY_OPTION 0x00080000
|
|
|
|
const DWORD SMTP_MAX_REPLY_LENGTH = 4096;
|
|
const DWORD SMTP_MAX_COMMAND_LENGTH = 512;
|
|
const char CONTINUATION_CHAR = (char) '-';
|
|
|
|
#define SMTP_PRELIMINARY_SUCCESS (char) '1'
|
|
#define SMTP_COMPLETE_SUCCESS (char) '2'
|
|
#define SMTP_INTERMEDIATE_SUCCESS (char) '3'
|
|
#define SMTP_TRANSIENT_FAILURE (char) '4'
|
|
#define SMTP_COMPLETE_FAILURE (char) '5'
|
|
|
|
#define KNOWN_AUTH_FLAGS ((DWORD)(DOMAIN_INFO_USE_NTLM | DOMAIN_INFO_USE_PLAINTEXT | DOMAIN_INFO_USE_DPA \
|
|
| DOMAIN_INFO_USE_KERBEROS))
|
|
|
|
enum RSETCODE
|
|
{
|
|
NO_SMTP_ERROR, BETWEEN_MSG, NO_RCPTS_SENT, ALL_RCPTS_FAILED, FATAL_ERROR
|
|
};
|
|
|
|
|
|
/************************************************************
|
|
* Type Definitions
|
|
************************************************************/
|
|
|
|
enum FORMAT_SMTP_MESSAGE_LOGLEVEL {
|
|
FSM_LOG_ALL,
|
|
FSM_LOG_VERB_ONLY,
|
|
FSM_LOG_NONE
|
|
};
|
|
|
|
enum TLS_ACTIONS {DONT_DO_TLS, MUST_DO_TLS, STARTTLS_SENT, SSL_NEG, CHANNEL_SECURE};
|
|
|
|
class SMTP_CONNOUT;
|
|
|
|
|
|
/*++
|
|
class SMTP_CONNOUT
|
|
|
|
This class is used for keeping track of individual client
|
|
connections established with the server.
|
|
|
|
It maintains the state of the connection being processed.
|
|
|
|
--*/
|
|
class SMTP_CONNOUT :
|
|
public CLIENT_CONNECTION
|
|
{
|
|
|
|
public:
|
|
enum LASTIOSTATE {READIO, WRITEIO, TRANSFILEIO};
|
|
|
|
static CPool Pool;
|
|
|
|
// override the mem functions to use CPool functions
|
|
void *operator new (size_t cSize)
|
|
{ return Pool.Alloc(); }
|
|
void operator delete (void *pInstance)
|
|
{ Pool.Free(pInstance); }
|
|
~SMTP_CONNOUT(void);
|
|
|
|
VOID DisconnectClient( IN DWORD dwErrorCode = NO_ERROR);
|
|
|
|
BOOL SendSmtpResponse(BOOL SyncSend = TRUE);
|
|
virtual BOOL ProcessClient( IN DWORD cbWritten,
|
|
IN DWORD dwCompletionStatus,
|
|
IN OUT OVERLAPPED * lpo);
|
|
|
|
BOOL IsNTLMSupported(void) {return ((m_Flags & AUTH_NTLM) == AUTH_NTLM);}
|
|
BOOL IsClearTextSupported(void) {return ((m_Flags & AUTH_CLEARTEXT) == AUTH_CLEARTEXT);}
|
|
BOOL IsUsingSASL(void) {return ((m_Flags & SASL_OPTION) == SASL_OPTION);}
|
|
|
|
void SetCarrierOption(DWORD NewOption){ m_Flags |= NewOption;}
|
|
void SetCurrentObjectToNull(void) { m_pISMTPConnection = NULL;}
|
|
void SetCurrentObject(ISMTPConnection * pISMTPConnection)
|
|
{
|
|
m_pISMTPConnection = pISMTPConnection;
|
|
}
|
|
|
|
BOOL ConnectToNextIpAddress(void);
|
|
|
|
void SetConnectedDomain(const char * RealDomain)
|
|
{
|
|
lstrcpyn(m_ConnectedDomain, RealDomain, MAX_INTERNET_NAME);
|
|
}
|
|
|
|
virtual BOOL StartSession( VOID);
|
|
|
|
BOOL ReStartSession(void);
|
|
|
|
BOOL IsSecure (void) const {return m_UsingSSL;}
|
|
BOOL DoEHLOCommand(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoRSETCommand(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoQUITCommand(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoSTARTTLSCommand(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoSASLCommand(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoMAILCommand(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoRCPTCommand(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoDATACommand(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoBDATCommand(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoSSLNegotiation(char *InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoSASLNegotiation(char *InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoTURNCommand(char *InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL WaitForRSETResponse(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL WaitForQuitResponse(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL WaitForConnectResponse(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL ProcessReadIO (IN DWORD InputBufferLen, IN DWORD dwCompletionStatus, IN OUT OVERLAPPED * lpo);
|
|
BOOL ProcessFileIO (IN DWORD InputBufferLen, IN DWORD dwCompletionStatus, IN OUT OVERLAPPED * lpo);
|
|
BOOL ProcessWriteIO (IN DWORD InputBufferLen, IN DWORD dwCompletionStatus, IN OUT OVERLAPPED * lpo);
|
|
BOOL ProcessTransmitFileIO (IN DWORD InputBufferLen, IN DWORD dwCompletionStatus, IN OUT OVERLAPPED * lpo);
|
|
BOOL DoDATACommandEx(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoETRNCommand(void);
|
|
BOOL FormatSmtpMessage(FORMAT_SMTP_MESSAGE_LOGLEVEL eLogLevel,
|
|
IN const char * Format, ...);
|
|
BOOL FormatBinaryBlob(IN PBYTE pbBlob, IN DWORD cbSize);
|
|
//BOOL PipelineRecipients(void);
|
|
BOOL AddRcptsDsns(DWORD NotifyOptions, char * OrcptVal, char * AddrBuf, int& AddrSize);
|
|
//BOOL CheckPipelinedAnswers (char * Buffer, DWORD BufSize, LPDWORD LastSize, DWORD UndecryptedTailSize);
|
|
char * GetConnectedDomain(void) const {return (char *) m_ConnectedDomain;}
|
|
BOOL GetConnectionStatus(void) const {return m_Active;}
|
|
BOOL TransmitFileEx (HANDLE hFile, LARGE_INTEGER &liSize,
|
|
DWORD Offset, LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers);
|
|
BOOL GoToWaitForConnectResponseState(void);
|
|
BOOL GetNextTURNConnection(void);
|
|
BOOL UnMarkHandledRcpts(void);
|
|
|
|
PSMTP_SERVER_INSTANCE QuerySmtpInstance( VOID ) const
|
|
{ _ASSERT(m_pInstance != NULL); return m_pInstance; }
|
|
|
|
BOOL IsSmtpInstance( VOID ) const
|
|
{ return m_pInstance != NULL; }
|
|
|
|
VOID SetSmtpInstance( IN PSMTP_SERVER_INSTANCE pInstance )
|
|
{ _ASSERT(m_pInstance == NULL); m_pInstance = pInstance; }
|
|
|
|
void SetTurnList(IN PTURN_DOMAIN_LIST pTurnList)
|
|
{ m_pmszTurnList = pTurnList->pmsz; m_szCurrentTURNDomain = pTurnList->szCurrentDomain;}
|
|
|
|
void ProtocolLogCommand(LPSTR pszCommand,
|
|
DWORD cParameters,
|
|
LPCSTR pszIpAddress,
|
|
FORMAT_SMTP_MESSAGE_LOGLEVEL eLogLevel);
|
|
|
|
void ProtocolLogResponse(LPSTR pszResponse,
|
|
DWORD cResponse,
|
|
LPCSTR pszIpAddress);
|
|
|
|
void LogRemoteDeliveryTransaction(
|
|
LPCSTR pszOperation,
|
|
LPCSTR pszTarget,
|
|
LPCSTR pszParameters,
|
|
LPCSTR pszIpAddress,
|
|
DWORD dwWin32Error,
|
|
DWORD dwServiceSpecificStatus,
|
|
DWORD dwBytesSent,
|
|
DWORD dwBytesRecieved,
|
|
BOOL fResponse
|
|
);
|
|
|
|
//
|
|
// These are overridden from the base CLIENT_CONNECTION class to support
|
|
// switching of receive buffers. We need to be able to switch buffers to
|
|
// support SSL, which needs upto 32K chunks. Note that even though SSL
|
|
// V3.0 restricts fragment sizes to 16K, our schannel is capable of
|
|
// generating 32K fragments (due to a bug). So, we read up to 32K.
|
|
//
|
|
virtual LPCSTR QueryRcvBuffer( VOID) const
|
|
{ return ((LPCSTR) m_precvBuffer); }
|
|
|
|
virtual LPSTR QueryMRcvBuffer(VOID) // modifiable string
|
|
{ return (LPSTR) m_precvBuffer; }
|
|
|
|
//
|
|
// This method causes this object to allocate 32K buffers and use them as
|
|
// the receive and output buffer.
|
|
//
|
|
BOOL SwitchToBigSSLBuffers();
|
|
|
|
static SMTP_CONNOUT * CreateSmtpConnection (
|
|
IN PSMTP_SERVER_INSTANCE pInstance,
|
|
IN SOCKET sClient,
|
|
IN const SOCKADDR_IN * psockAddrRemote,
|
|
IN const SOCKADDR_IN * psockAddrLocal /* = NULL */ ,
|
|
IN PATQ_CONTEXT pAtqContext /* = NULL */ ,
|
|
IN PVOID pvInitialRequest/* = NULL*/ ,
|
|
IN DWORD cbInitialData /* = 0 */ ,
|
|
IN DWORD Options /* = 0 */,
|
|
IN LPSTR pszSSLVerificationName);
|
|
|
|
//
|
|
// Protocol Events additions ...
|
|
//
|
|
|
|
public:
|
|
|
|
BOOL DoCompletedMessage(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
|
|
BOOL DoSessionStartEvent(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoMessageStartEvent(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoPerRecipientEvent(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoBeforeDataEvent(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoSessionEndEvent(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
|
|
BOOL DoEHLOResponse(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoMAILResponse(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoRCPTResponse(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
BOOL DoContentResponse(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize);
|
|
|
|
BOOL PE_FormatSmtpMessage(IN const char * Format, ...);
|
|
|
|
BOOL DecPendingIoCountEx(void);
|
|
|
|
void SetDnsRec(PSMTPDNS_RECS pDnsRec) {m_pDnsRec = pDnsRec;}
|
|
|
|
void SetConnectionStatus(DWORD dwConnectionStatus) {m_dwConnectionStatus = dwConnectionStatus;};
|
|
|
|
private:
|
|
typedef BOOL (SMTP_CONNOUT::*PMFI)(char * InputLine, DWORD InputLineSize, DWORD UndecryptedTailSize);
|
|
|
|
HRESULT GetNextResponse(
|
|
char *InputLine,
|
|
DWORD BufSize,
|
|
char **NextInputLine,
|
|
LPDWORD pRemainingBufSize,
|
|
DWORD UndecryptedTailSize
|
|
);
|
|
|
|
HRESULT BuildCommandQEntry(
|
|
LPOUTBOUND_COMMAND_Q_ENTRY *ppEntry,
|
|
BOOL *pfUseNative
|
|
);
|
|
|
|
HRESULT OnOutboundCommandEvent(
|
|
IUnknown *pServer,
|
|
IUnknown *pSession,
|
|
DWORD dwEventType,
|
|
BOOL fRepeatLastCommand,
|
|
PMFI pDefaultOutboundHandler
|
|
);
|
|
|
|
HRESULT OnServerResponseEvent(
|
|
IUnknown *pServer,
|
|
IUnknown *pSession,
|
|
PMFI pDefaultResponseHandler
|
|
);
|
|
|
|
BOOL GlueDispatch(
|
|
const char *InputLine,
|
|
DWORD ParameterSize,
|
|
DWORD UndecryptedTailSize,
|
|
DWORD dwOutboundEventType,
|
|
PMFI pDefaultOutboundHandler,
|
|
PMFI pDefaultResponseHandler,
|
|
LPSTR szDefaultResponseHandlerKeyword,
|
|
BOOL *pfDoneWithEvent,
|
|
BOOL *pfAbortEvent
|
|
);
|
|
|
|
IUnknown *GetSessionPropertyBag() { return((IUnknown *)(IMailMsgPropertyBag *)(&m_SessionPropertyBag)); }
|
|
|
|
private:
|
|
|
|
// BOOL m_fRsetBetweenMessages;
|
|
RSETCODE m_RsetReasonCode;
|
|
BOOL m_fNativeHandlerFired;
|
|
|
|
IEventRouter *m_pIEventRouter;
|
|
ISmtpOutboundCommandDispatcher *m_pOutboundDispatcher;
|
|
ISmtpServerResponseDispatcher *m_pResponseDispatcher;
|
|
|
|
CFifoQueue m_FifoQ;
|
|
COutboundContext m_OutboundContext;
|
|
CResponseContext m_ResponseContext;
|
|
|
|
CMailMsgPropertyBag m_SessionPropertyBag;
|
|
|
|
//
|
|
// End protocol events additions
|
|
//
|
|
|
|
private:
|
|
|
|
LASTIOSTATE m_LastClientIo;
|
|
char m_OutputBuffer[SMTP_MAX_REPLY_LENGTH];
|
|
char m_NativeCommandBuffer[SMTP_MAX_COMMAND_LENGTH];
|
|
DWORD m_OutputBufferSize;
|
|
DWORD m_cbMaxOutputBuffer;
|
|
DWORD m_cbMaxRecvBuffer;
|
|
DWORD m_cbParsable;
|
|
DWORD m_Error;
|
|
DWORD m_FileSize;
|
|
DWORD m_MsgOptions;
|
|
DWORD m_Flags;
|
|
DWORD m_AuthToUse;
|
|
DWORD m_NumRcptSent;
|
|
DWORD m_NumRcptSentSaved;
|
|
DWORD m_SizeOptionSize ;
|
|
DWORD m_NumFailedAddrs;
|
|
DWORD m_dwFileOffset;
|
|
LONG m_cActiveThreads;
|
|
LONG m_cPendingIoCount;
|
|
DWORD m_NextAddress;
|
|
DWORD m_FirstPipelinedAddress;
|
|
int m_First552Address;
|
|
DWORD m_NumRcpts;
|
|
DWORD m_FirstAddressinCurrentMail;
|
|
DWORD *m_RcptIndexList;
|
|
PFIO_CONTEXT m_IMsgFileHandle;
|
|
PFIO_CONTEXT m_IMsgDotStuffedFileHandle;
|
|
ISMTPConnection * m_pISMTPConnection;
|
|
PSMTPDNS_RECS m_pDnsRec;
|
|
PMFI m_NextState;
|
|
BOOL m_HeloSent;
|
|
BOOL m_EhloSent;
|
|
BOOL m_EhloFailed;
|
|
BOOL m_FirstRcpt;
|
|
BOOL m_SendAgain;
|
|
BOOL m_SecurePort;
|
|
BOOL m_fNegotiatingSSL;
|
|
BOOL m_UsingSSL;
|
|
BOOL m_HaveDataResponse;
|
|
BOOL m_fUseMbsCta;
|
|
BOOL m_Active;
|
|
BOOL m_fUseBDAT;
|
|
BOOL m_bComplete;
|
|
BOOL m_fCanTurn;
|
|
IMailMsgProperties *m_pIMsg;
|
|
IMailMsgRecipients *m_pIMsgRecips;
|
|
IMailMsgBind *m_pBindInterface;
|
|
PVOID m_AdvContext;
|
|
char m_TransmitTailBuffer [5];
|
|
char m_ConnectedDomain[MAX_INTERNET_NAME + 1];
|
|
TRANSMIT_FILE_BUFFERS m_TransmitBuffers;
|
|
TLS_ACTIONS m_TlsState;
|
|
|
|
PSMTP_SERVER_INSTANCE m_pInstance;
|
|
CEncryptCtx m_encryptCtx;
|
|
CSecurityCtx m_securityCtx;
|
|
HANDLE m_hFile;
|
|
TCP_AUTHENT_INFO AuthInfoStruct;
|
|
char m_szAuthPackage[64];
|
|
char *m_precvBuffer;
|
|
char *m_pOutputBuffer;
|
|
DWORD m_dwConnectionStatus;
|
|
LPSTR m_pszSSLVerificationName;
|
|
SERVEREVENT_OVERLAPPED m_SeoOverlapped;
|
|
|
|
//Turn related data - pointer to a MULTISZ containing all the domain names
|
|
//to be turned on this connection and a pointer into the Multisz for the
|
|
//current domain being turned
|
|
MULTISZ *m_pmszTurnList;
|
|
const char *m_szCurrentTURNDomain;
|
|
|
|
//Keeps track of current place in domains to issue ETRN for
|
|
const char *m_szCurrentETRNDomain;
|
|
|
|
//Connection failure diagnostic information - 2/18/99 MikeSwa
|
|
//This additional information is designed to be used as user-level
|
|
//diagnostic information. It is reported back to Aqueue which
|
|
//will expose it via the QAPI or event logs
|
|
|
|
//HRESULT can be E_FAIL, S_OK, or specific error from mc files
|
|
HRESULT m_hrDiagnosticError;
|
|
LPCSTR m_szDiagnosticVerb; //failed protocol VERB
|
|
CHAR m_szDiagnosticResponse[100]; //response from remote server
|
|
|
|
//DSN related
|
|
BOOL m_fNeedRelayedDSN;
|
|
BOOL m_fHadHardError;
|
|
BOOL m_fHadTempError;
|
|
BOOL m_fHadSuccessfulDelivery;
|
|
|
|
SMTP_CONNOUT(
|
|
IN PSMTP_SERVER_INSTANCE pInstance,
|
|
IN SOCKET sClient,
|
|
IN const SOCKADDR_IN * psockAddrRemote,
|
|
IN const SOCKADDR_IN * psockAddrLocal = NULL,
|
|
IN PATQ_CONTEXT pAtqContext = NULL,
|
|
IN PVOID pvInitialRequest = NULL,
|
|
IN DWORD cbInitialData = 0);
|
|
|
|
BOOL InitializeObject (DWORD Options, LPSTR pszSSLVerificationName);
|
|
BOOL DecryptInputBuffer ();
|
|
|
|
BOOL MessageReadFile(void);
|
|
|
|
void FreeAtqFileContext(void);
|
|
BOOL GetEhloOptions(char * InputLine, DWORD ParameterSize, DWORD UndecryptedTailSize, BOOL fIsHelo);
|
|
void ShrinkBuffer(char * StartPosition, DWORD SizeToMove)
|
|
{
|
|
MoveMemory ((void *)QueryMRcvBuffer(), StartPosition, SizeToMove);
|
|
}
|
|
|
|
void SetIMsgConnObj(ISMTPConnection * ISMTPConnObj) {m_pISMTPConnection = ISMTPConnObj;}
|
|
void SetNextStateEx(PMFI NextState, DWORD Timeout)
|
|
{
|
|
AtqContextSetInfo(m_pAtqContext, ATQ_INFO_TIMEOUT, Timeout);
|
|
m_NextState = NextState;
|
|
}
|
|
|
|
void SetNextState(PMFI NextState)
|
|
{
|
|
m_NextState = NextState;
|
|
}
|
|
|
|
void SetDiagnosticInfo(IN HRESULT hrDiagnosticError,
|
|
IN LPCSTR szDiagnosticVerb,
|
|
IN LPCSTR szDiagnosticResponse);
|
|
|
|
BOOL IsOptionSet(DWORD Option) {return ((m_Flags & Option) == Option);}
|
|
BOOL SaveToErrorFile(char * Buffer, DWORD BufSize);
|
|
void HandleCompletedMailObj(DWORD MsgStatus, char * szExtendedStatus, DWORD cbExtendedStatus);
|
|
void SendRemainingRecipients (void);
|
|
LONG IncPendingIoCount(void) { return InterlockedIncrement( &m_cPendingIoCount ); }
|
|
LONG DecPendingIoCount(void) { return InterlockedDecrement( &m_cPendingIoCount ); }
|
|
LONG IncThreadCount(void) { return InterlockedIncrement( &m_cActiveThreads ); }
|
|
LONG DecThreadCount(void) { return InterlockedDecrement( &m_cActiveThreads ); }
|
|
|
|
BOOL ValidateSSLCertificate ();
|
|
|
|
};
|
|
|
|
|
|
#endif
|
|
|
|
/************************ End of File ***********************/
|