Microsoft Internet Security and Acceleration Server 2000 |
In this procedure you will attach a data filter in CSessionFilter::FirewallEventHandler.
To attach the data filter
#include "SMTPDataFilter.h" CComPtr <IFWXDataFilter> spIFWXDataFilter;
CComObject<CSMTPDataFilter> *pSMTPDataFilter; //Create an instance of the SMTPDataFilter hr = CComObject<CSMTPDataFilter>::CreateInstance(&pSMTPDataFilter); if (SUCCEEDED(hr)) { pSMTPDataFilter->AddRef(); hr = pSMTPDataFilter-> QueryInterface(IID_IFWXDataFilter, reinterpret_cast<void**>(&spIFWXDataFilter)); pSMTPDataFilter->Release(); if (FAILED(hr)) { OutputDebugString("\tFail to init DataFilter\n"); return hr; } //Attach the data filter to the connection piConnection=pFirewallEvent-> Parameters.Accept.piConnectionAccepted; hr=piConnection-> AttachDataFilter(spIFWXDataFilter, fwx_dfpc_External, NULL); }
For the data filter to create a data pump — moving data between the internal SMTP server and the external server or client — the data filter must keep a reference to the sockets at each end of the connection. Therefore , add the following code to SMTPDataFilter.h:
private: CComPtr<IFWXSocket> m_spExternalSocket; CComPtr<IFWXSocket> m_spInternalSocket;
The Firewall service passes a reference to the external and internal sockets used in this connection and the IFWXDataFilter::SetSockets method starts the data-pumping process. The filter must reserve a reference to these sockets.
Due to the multithreaded architecture of the Firewall service, access to members must be synchronized. In particular, access to the socket interfaces must be synchronized because they are changed by IFWXDataFilter::Detach (see Step 5, following).
In place of the simple implementation code you previously wrote, use the following code in SMTPDataFilter.cpp:
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(); return S_OK; }
The Firewall service calls this method when the data filter is no longer needed. IFWXDataFilter::Detach must release the references to the sockets because they are not valid after this method returns.
In place of the simple implementation code you previously wrote, use the following code in SMTPDataFilter.cpp:
HRESULT STDMETHODCALLTYPE CSMTPDataFilter::Detach( void) { // // Dereference sockets. // Lock(); m_spExternalSocket = NULL; m_spInternalSocket = NULL; Unlock(); return S_OK; }