Microsoft Internet Security and Acceleration Server 2000

Perform Data Pumping

This example uses a simple data pump that moves data between the server and the client. The actual SMTP filter code uses more sophisticated data pumping and filtering. See SMTPFLTR for more information.

The _CloseSockets function defined in the stepImplement _CloseSockets and _GetSockets Functions is used here.

Add the following code in SMTPDataFilter.cpp in place of the simple implementation of CSMTPDataFilter::CompleteAsyncIO, then build the project:

HRESULT STDMETHODCALLTYPE CSMTPDataFilter::CompleteAsyncIO(
	BOOL	fSuccess,
	DWORD	 Win32ErrorCode,
	IFWXIOBuffer *pIOBuffer,
	UserContextType	 UserData,
	LPSOCKADDR ExternalAddress,
	INT ExternalAddressLength
	)
{
	DWORD DataLength = 0;
	char *pchCurrent;
 
	//If the buffer exists, get a reference to it and get its size
	if (pIOBuffer)
		pIOBuffer->GetBufferAndSize((PBYTE*)&pchCurrent, &DataLength);
 
	//No data was sent, close the sockets
	if (DataLength == 0 || !fSuccess)
	{
		_CloseSockets(!fSuccess);
		return S_OK;
}
 
	Lock();
	CComPtr<IFWXSocket> spExternalSocket = m_spExternalSocket;
	CComPtr<IFWXSocket> spInternalSocket = m_spInternalSocket;
	Unlock();
 
	if (UserData==SOURCE_IS_SERVER)
	{
		//Source of the data is the server; filter needs to send
		//it to the external client
		spExternalSocket->Send(pIOBuffer,NULL,0);
		//Read from internal SMTP server
		spInternalSocket ->Recv(NULL,this,SOURCE_IS_SERVER);
}
	else
	{
		//Source of the data is the client, filter needs to send
		//it to the server
		spInternalSocket ->Send(pIOBuffer,NULL,0);
	
		//Read from client
		spExternalSocket ->Recv(NULL,this,SOURCE_IS_CLIENT);
}
return S_OK;
}