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

960 lines
19 KiB
C++

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name :
pe_supp.hxx
Abstract:
This module defines the support classes for outbound
protocol events
Author:
Keith Lau (KeithLau) 6/23/98
Project:
SMTP Server DLL
Revision History:
--*/
#ifndef _PE_SUPP_HXX_
#define _PE_SUPP_HXX_
// =================================================================
// Defines
//
#define _VALID_INBOUND_CONTEXT ((DWORD)'CNIv')
#define _VALID_OUTBOUND_CONTEXT ((DWORD)'CUOv')
#define _VALID_RESPONSE_CONTEXT ((DWORD)'CERv')
// =================================================================
// Forward definitions
//
// =================================================================
// Define the inbound context classes
//
class CInboundContext :
public ISmtpInCommandContext,
public ISmtpInCallbackContext
{
public:
CInboundContext()
{
m_pbBlob = NULL;
m_cbBlob = 0;
ResetInboundContext();
m_dwSignature = _VALID_INBOUND_CONTEXT;
}
BOOL IsValid() { return(m_dwSignature == _VALID_INBOUND_CONTEXT); }
void ResetInboundContext()
{
m_cabCommand.Reset();
m_cabResponse.Reset();
m_cabNativeResponse.Reset();
m_pCurrentBinding = NULL;
m_pPreviousBinding = NULL;
m_dwCommandStatus = EXPE_UNHANDLED;
m_dwSmtpStatus = 0;
m_fProtocolError = FALSE;
m_dwWin32Status = NO_ERROR;
m_pICallback = NULL;
m_pbBlob = NULL;
m_cbBlob = 0;
}
void SetWin32Status(DWORD dwWin32Status) { m_dwWin32Status = dwWin32Status; }
DWORD QueryWin32Status() { return m_dwWin32Status; }
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj)
{
if (riid == IID_IUnknown)
*ppvObj = (IUnknown *)(ISmtpInCommandContext *)this;
else if (riid == IID_ISmtpInCommandContext)
*ppvObj = (ISmtpInCommandContext *)this;
else if (riid == IID_ISmtpInCallbackContext)
*ppvObj = (ISmtpInCallbackContext *)this;
else
return(E_NOINTERFACE);
AddRef();
return(S_OK);
}
unsigned long STDMETHODCALLTYPE AddRef() { return(0); }
unsigned long STDMETHODCALLTYPE Release() { return(0); }
// Query methods
HRESULT STDMETHODCALLTYPE QueryCommand(
LPSTR pszCommand,
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
if (!pszCommand)
{
*pdwSize = 0;
return(E_POINTER);
}
if (*pdwSize < m_cabCommand.Length())
{
*pdwSize = 0;
return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
}
*pdwSize = m_cabCommand.Length();
memcpy(pszCommand, m_cabCommand.Buffer(), *pdwSize);
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryBlob(
PBYTE *ppbBlob,
DWORD *pdwSize
)
{
*ppbBlob = m_pbBlob;
*pdwSize = m_cbBlob;
return S_OK;
}
HRESULT STDMETHODCALLTYPE QueryCommandKeyword(
LPSTR pszKeyword,
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
if (!pszKeyword)
{
*pdwSize = 0;
return(E_POINTER);
}
if (!m_pCurrentCommandContext ||
!m_pCurrentCommandContext->pszCommandKeyword)
{
*pdwSize = 0;
return(E_POINTER);
}
DWORD dwLength = strlen(m_pCurrentCommandContext->pszCommandKeyword) + 1;
if (*pdwSize < dwLength)
{
*pdwSize = 0;
return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
}
*pdwSize = dwLength;
memcpy(pszKeyword,
m_pCurrentCommandContext->pszCommandKeyword,
dwLength);
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryNativeResponse(
LPSTR pszNativeResponse,
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
if (!pszNativeResponse)
{
*pdwSize = 0;
return(E_POINTER);
}
if (*pdwSize < m_cabNativeResponse.Length())
{
*pdwSize = 0;
return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
}
*pdwSize = m_cabNativeResponse.Length();
memcpy(pszNativeResponse,
m_cabNativeResponse.Buffer(),
*pdwSize);
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryResponse(
LPSTR pszResponse,
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
if (!pszResponse)
{
*pdwSize = 0;
return(E_POINTER);
}
if (*pdwSize < m_cabResponse.Length())
{
*pdwSize = 0;
return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
}
*pdwSize = m_cabResponse.Length();
memcpy(pszResponse,
m_cabResponse.Buffer(),
*pdwSize);
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryCommandSize(
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
*pdwSize = m_cabCommand.Length();
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryBlobSize(
DWORD *pdwSize
)
{
*pdwSize = m_cbBlob;
return S_OK;
}
HRESULT STDMETHODCALLTYPE QueryCommandKeywordSize(
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
if (!m_pCurrentCommandContext ||
!m_pCurrentCommandContext->pszCommandKeyword)
return(E_POINTER);
*pdwSize = strlen(m_pCurrentCommandContext->pszCommandKeyword) + 1;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryNativeResponseSize(
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
*pdwSize = m_cabNativeResponse.Length();
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryResponseSize(
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
*pdwSize = m_cabResponse.Length();
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryCommandStatus(
DWORD *pdwCommandStatus
)
{
if (!pdwCommandStatus)
return(E_POINTER);
*pdwCommandStatus = m_dwCommandStatus;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QuerySmtpStatusCode(
DWORD *pdwSmtpStatus
)
{
if (!pdwSmtpStatus)
return(E_POINTER);
*pdwSmtpStatus = m_dwSmtpStatus;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryProtocolErrorFlag(
BOOL *pfProtocolError
)
{
if (!pfProtocolError)
return(E_POINTER);
*pfProtocolError = m_fProtocolError;
return(S_OK);
}
// Set methods
HRESULT STDMETHODCALLTYPE SetResponse(
LPSTR szResponse,
DWORD dwSize
)
{
if (!szResponse)
return(E_POINTER);
m_cabResponse.Reset();
return(m_cabResponse.Append(szResponse, dwSize, NULL));
}
HRESULT STDMETHODCALLTYPE AppendResponse(
LPSTR szResponse,
DWORD dwSize
)
{
if (!szResponse)
return(E_POINTER);
return(m_cabResponse.Append(szResponse, dwSize, NULL));
}
HRESULT STDMETHODCALLTYPE SetNativeResponse(
LPSTR szNativeResponse,
DWORD dwSize
)
{
if (!szNativeResponse)
return(E_POINTER);
m_cabNativeResponse.Reset();
return(m_cabNativeResponse.Append(szNativeResponse, dwSize, NULL));
}
HRESULT STDMETHODCALLTYPE AppendNativeResponse(
LPSTR szNativeResponse,
DWORD dwSize
)
{
if (!szNativeResponse)
return(E_POINTER);
return(m_cabNativeResponse.Append(szNativeResponse, dwSize, NULL));
}
HRESULT STDMETHODCALLTYPE SetCommandStatus(
DWORD dwCommandStatus
)
{
m_dwCommandStatus = dwCommandStatus;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE SetProtocolErrorFlag(
BOOL fProtocolError
)
{
m_fProtocolError = fProtocolError;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE SetSmtpStatusCode(
DWORD dwSmtpStatus
)
{
m_dwSmtpStatus = dwSmtpStatus;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE SetCallback(
ISmtpInCallbackSink * pCallback
)
{
if ( NULL != m_pICallback) {
m_pICallback->Release();
}
if ( NULL != pCallback) {
pCallback->AddRef();
}
m_pICallback = pCallback;
return S_OK;
}
HRESULT STDMETHODCALLTYPE NotifyAsyncCompletion(
HRESULT hrResult
);
public:
DWORD m_dwSignature;
CAppendBuffer m_cabCommand;
CAppendBuffer m_cabResponse;
CAppendBuffer m_cabNativeResponse;
LPPE_COMMAND_NODE m_pCurrentCommandContext;
LPPE_BINDING_NODE m_pPreviousBinding;
LPPE_BINDING_NODE m_pCurrentBinding;
PBYTE m_pbBlob;
DWORD m_cbBlob;
ISmtpInCallbackSink * m_pICallback;
DWORD m_dwCommandStatus;
DWORD m_dwSmtpStatus;
DWORD m_dwWin32Status;
BOOL m_fProtocolError;
};
// =================================================================
// Define the outbound context classes
//
class COutboundContext :
public ISmtpOutCommandContext
{
public:
COutboundContext()
{
m_pbBlob = NULL;
m_cbBlob = 0;
ResetOutboundContext();
m_pCurrentCommandContext = NULL;
m_pCurrentBinding = NULL;
m_dwSignature = _VALID_OUTBOUND_CONTEXT;
}
~COutboundContext()
{
if ( NULL != m_pbBlob) {
delete [] m_pbBlob;
m_pbBlob = NULL;
}
m_cbBlob = 0;
}
BOOL IsValid() { return(m_dwSignature == _VALID_OUTBOUND_CONTEXT); }
void ResetOutboundContext()
{
m_cabCommand.Reset();
m_cabNativeCommand.Reset();
m_dwCommandStatus = EXPE_UNHANDLED;
m_dwCurrentRecipient = 0;
if ( NULL != m_pbBlob) {
delete [] m_pbBlob;
m_pbBlob = NULL;
}
m_cbBlob = 0;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj)
{
if (riid == IID_IUnknown)
*ppvObj = (IUnknown *)(ISmtpOutCommandContext *)this;
else if (riid == IID_ISmtpOutCommandContext)
*ppvObj = (ISmtpOutCommandContext *)this;
else
return(E_NOINTERFACE);
AddRef();
return(S_OK);
}
unsigned long STDMETHODCALLTYPE AddRef() { return(0); }
unsigned long STDMETHODCALLTYPE Release() { return(0); }
HRESULT STDMETHODCALLTYPE QueryCommand(
LPSTR pszCommand,
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
if (!pszCommand)
{
*pdwSize = 0;
return(E_POINTER);
}
if (*pdwSize < m_cabCommand.Length())
{
*pdwSize = 0;
return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
}
*pdwSize = m_cabCommand.Length();
memcpy(pszCommand, m_cabCommand.Buffer(), *pdwSize);
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryCommandKeyword(
LPSTR pszKeyword,
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
if (!pszKeyword)
{
*pdwSize = 0;
return(E_POINTER);
}
if (!m_pCurrentCommandContext ||
!m_pCurrentCommandContext->pszCommandKeyword)
{
*pdwSize = 0;
return(E_POINTER);
}
DWORD dwLength = strlen(m_pCurrentCommandContext->pszCommandKeyword) + 1;
if (*pdwSize < dwLength)
{
*pdwSize = 0;
return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
}
*pdwSize = dwLength;
memcpy(pszKeyword,
m_pCurrentCommandContext->pszCommandKeyword,
dwLength);
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryNativeCommand(
LPSTR pszNativeCommand,
DWORD *pdwSize
)
{
if(!pdwSize)
return(E_POINTER);
if (!pszNativeCommand)
{
*pdwSize = 0;
return(E_POINTER);
}
if (*pdwSize < m_cabNativeCommand.Length())
{
*pdwSize = 0;
return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
}
*pdwSize = m_cabNativeCommand.Length();
memcpy(pszNativeCommand,
m_cabNativeCommand.Buffer(),
*pdwSize);
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryCommandSize(
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
*pdwSize = m_cabCommand.Length();
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryCommandKeywordSize(
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
if (!m_pCurrentCommandContext ||
!m_pCurrentCommandContext->pszCommandKeyword)
return(E_POINTER);
*pdwSize = strlen(m_pCurrentCommandContext->pszCommandKeyword) + 1;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryNativeCommandSize(
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
*pdwSize = m_cabNativeCommand.Length();
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryCurrentRecipientIndex(
DWORD *pdwRecipientIndex
)
{
if (!pdwRecipientIndex)
return(E_POINTER);
*pdwRecipientIndex = m_dwCurrentRecipient;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryCommandStatus(
DWORD *pdwCommandStatus
)
{
if (!pdwCommandStatus)
return(E_POINTER);
*pdwCommandStatus = m_dwCommandStatus;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE SetCommand(
LPSTR szCommand,
DWORD dwSize
)
{
if (!szCommand)
return(E_POINTER);
m_cabCommand.Reset();
return(m_cabCommand.Append(szCommand, dwSize, NULL));
}
HRESULT STDMETHODCALLTYPE SetBlob(
BYTE * pbBlob,
DWORD dwSize
)
{
BYTE * pbTempBlob;
if (!pbBlob) {
return(E_POINTER);
}
pbTempBlob = new BYTE[ dwSize];
if ( NULL == pbTempBlob) {
return E_OUTOFMEMORY;
}
if ( NULL != m_pbBlob) {
delete [] m_pbBlob;
}
m_pbBlob = pbTempBlob;
memcpy(m_pbBlob, pbBlob, dwSize);
m_cbBlob = dwSize;
return S_OK;
}
HRESULT STDMETHODCALLTYPE AppendCommand(
LPSTR szCommand,
DWORD dwSize
)
{
if (!szCommand)
return(E_POINTER);
return(m_cabCommand.Append(szCommand, dwSize, NULL));
}
HRESULT STDMETHODCALLTYPE SetCommandStatus(
DWORD dwCommandStatus
)
{
m_dwCommandStatus = dwCommandStatus;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE NotifyAsyncCompletion(
HRESULT hrResult
);
public:
DWORD m_dwSignature;
CAppendBuffer m_cabCommand;
CAppendBuffer m_cabNativeCommand;
LPPE_COMMAND_NODE m_pCurrentCommandContext;
LPPE_BINDING_NODE m_pCurrentBinding;
DWORD m_dwCommandStatus;
DWORD m_dwCurrentRecipient;
PBYTE m_pbBlob;
DWORD m_cbBlob;
};
// =================================================================
// Define the response context classes
//
class CResponseContext :
public ISmtpServerResponseContext
{
public:
CResponseContext()
{
ResetResponseContext();
m_dwSignature = _VALID_RESPONSE_CONTEXT;
}
BOOL IsValid() { return(m_dwSignature == _VALID_RESPONSE_CONTEXT); }
void ResetResponseContext()
{
m_cabResponse.Reset();
m_pCommand = NULL;
m_dwResponseStatus = EXPE_UNHANDLED;
m_pCurrentBinding = NULL;
m_dwSmtpStatus = 0;
m_dwNextState = PE_STATE_DEFAULT;
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj)
{
if (riid == IID_IUnknown)
*ppvObj = (IUnknown *)(ISmtpServerResponseContext *)this;
else if (riid == IID_ISmtpServerResponseContext)
*ppvObj = (ISmtpServerResponseContext *)this;
else
return(E_NOINTERFACE);
AddRef();
return(S_OK);
}
unsigned long STDMETHODCALLTYPE AddRef() { return(0); }
unsigned long STDMETHODCALLTYPE Release() { return(0); }
HRESULT STDMETHODCALLTYPE QueryCommand(
LPSTR pszCommand,
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
if (!pszCommand || !m_pCommand)
{
*pdwSize = 0;
return(E_POINTER);
}
if (!m_pCommand->pszFullCommand)
{
*pdwSize = 0;
return(E_POINTER);
}
DWORD dwLength = strlen(m_pCommand->pszFullCommand) + 1;
if (*pdwSize < dwLength)
{
*pdwSize = 0;
return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
}
*pdwSize = dwLength;
memcpy(pszCommand,
m_pCommand->pszFullCommand,
dwLength);
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryCommandKeyword(
LPSTR pszKeyword,
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
if(!pszKeyword)
{
*pdwSize = 0;
return(E_POINTER);
}
if (!m_pCommand || !m_pCommand->pszCommandKeyword)
{
*pdwSize = 0;
return(E_POINTER);
}
DWORD dwLength = strlen(m_pCommand->pszCommandKeyword) + 1;
if (*pdwSize < dwLength)
{
*pdwSize = 0;
return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
}
*pdwSize = dwLength;
memcpy(pszKeyword,
m_pCommand->pszCommandKeyword,
dwLength);
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryResponse(
LPSTR pszResponse,
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
if (!pszResponse)
{
*pdwSize = 0;
return(E_POINTER);
}
if (*pdwSize < m_cabResponse.Length())
{
*pdwSize = 0;
return(HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
}
*pdwSize = m_cabResponse.Length();
memcpy(pszResponse,
m_cabResponse.Buffer(),
*pdwSize);
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryCommandSize(
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
*pdwSize = 0;
if (!m_pCommand || !m_pCommand->pszFullCommand)
return(E_POINTER);
*pdwSize = strlen(m_pCommand->pszFullCommand) + 1;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryCommandKeywordSize(
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
*pdwSize = 0;
if (!m_pCommand || !m_pCommand->pszCommandKeyword)
return(E_POINTER);
*pdwSize = strlen(m_pCommand->pszCommandKeyword) + 1;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryResponseSize(
DWORD *pdwSize
)
{
if (!pdwSize)
return(E_POINTER);
*pdwSize = m_cabResponse.Length();
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QuerySmtpStatusCode(
DWORD *pdwSmtpStatus
)
{
if (!pdwSmtpStatus)
return(E_POINTER);
*pdwSmtpStatus = m_dwSmtpStatus;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryResponseStatus(
DWORD *pdwResponseStatus
)
{
if (!pdwResponseStatus)
return(E_POINTER);
*pdwResponseStatus = m_dwResponseStatus;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryPipelinedFlag(
BOOL *pfResponseIsPipelined
)
{
if (!pfResponseIsPipelined)
return(E_POINTER);
_ASSERT(m_pCommand);
*pfResponseIsPipelined =
((m_pCommand->dwFlags & PECQ_PIPELINED)?TRUE:FALSE);
return(S_OK);
}
HRESULT STDMETHODCALLTYPE QueryNextEventState(
DWORD *pdwNextState
)
{
if (!pdwNextState)
return(E_POINTER);
*pdwNextState = m_dwNextState;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE SetSmtpStatus(
DWORD dwSmtpStatus
)
{
m_dwSmtpStatus = dwSmtpStatus;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE SetResponseStatus(
DWORD dwResponseStatus
)
{
m_dwResponseStatus = dwResponseStatus;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE SetNextEventState(
DWORD dwNextState
)
{
// Note PE_STATE_MAX_STATES is valid!
if (dwNextState > PE_STATE_MAX_STATES)
return(E_INVALIDARG);
m_dwNextState = dwNextState;
return(S_OK);
}
HRESULT STDMETHODCALLTYPE NotifyAsyncCompletion(
HRESULT hrResult
);
public:
DWORD m_dwSignature;
LPOUTBOUND_COMMAND_Q_ENTRY m_pCommand;
LPPE_BINDING_NODE m_pCurrentBinding;
CAppendBuffer m_cabResponse;
DWORD m_dwResponseStatus;
DWORD m_dwSmtpStatus;
DWORD m_dwNextState;
};
#endif