Microsoft Internet Security and Acceleration Server 2000 |
To carry out data pumping, the data filter must use an asynchronous input/output (I/O) method. To do so, the data filter has to implement the IFWXIOCompletion interface. Using this interface, the Firewall service notifies the filter upon completion of an I/O operation.
You will implement the IFWXIOCompletion::CompleteAsyncIO method.
To the CSMTPDataFilter class definition in SmtpDataFilter.h, add inheritance from the IFWXIOCompletion class:
public IFWXIOCompletion
Also, add COM interface support for this interface by adding the following line to the COM map of the CSMTPDataFilter class:
COM_INTERFACE_ENTRY(IFWXIOCompletion)
Copy the prototype of the IOCompletion::CompleteAsyncIO method from wspfwext.h and add it to SMTPDataFilter.h and SMTPDataFilter.cpp (with a simple implementation):
SMTPDataFilter.h:
//IFWXIOCompletion public: HRESULT STDMETHODCALLTYPE CompleteAsyncIO( /* [in] */ BOOL fSuccess, /* [in] */ DWORD Win32ErrorCode, /* [in] */ IFWXIOBuffer __RPC_FAR *pIOBuffer, /* [in] */ UserContextType UserData, /* [unique][in] */ LPSOCKADDR ExternalAddress, /* [in] */ INT ExternalAddressLength) ;
SMTPDataFilter.cpp:
HRESULT STDMETHODCALLTYPE CSMTPDataFilter::CompleteAsyncIO( /* [in] */ BOOL fSuccess, /* [in] */ DWORD Win32ErrorCode, /* [in] */ IFWXIOBuffer __RPC_FAR *pIOBuffer, /* [in] */ UserContextType UserData, /* [unique][in] */ LPSOCKADDR ExternalAddress, /* [in] */ INT ExternalAddressLength) { return S_OK; }
This method is called when an I/O operation is completed. In this method you should implement the logic of your filter. This logic is based on the protocol in which you are working; in this case, the SMTP protocol. To start the data pump, add the code shown in bold to CSMTPDataFilter::SetSockets (in SMTPDataFilter.cpp):
#define SOURCE_IS_SERVER 0 #define SOURCE_IS_CLIENT 1 HRESULT STDMETHODCALLTYPE CSMTPDataFilter::SetSockets( /* [in] */ IFWXSocket __RPC_FAR *piInternalSocket, /* [in] */ IFWXSocket __RPC_FAR *piExternalSocket, /* [in] */ IFWXConnection __RPC_FAR *piConnection, /* [unique][in] */ IUnknown __RPC_FAR *punkFilterContext) { //Keep a reference to the sockets Lock(); m_spExternalSocket = piExternalSocket; m_spInternalSocket = piInternalSocket; Unlock(); //SOURCE_IS_SERVER and SOURCE_IS_CLIENT are used //to differentiate between recv on external and internal sockets piInternalSocket ->Recv(NULL,this, SOURCE_IS_SERVER); piExternalSocket ->Recv(NULL,this, SOURCE_IS_CLIENT); return S_OK; }