Microsoft Internet Security and Acceleration Server 2000

Attach the Data Filter

In this procedure you will attach a data filter in CSessionFilter::FirewallEventHandler.

To attach the data filter

  1. For a data filter to be attached to the session when an fwx_AcceptedConnection event occurs, at the beginning of FWXSessionFilter.cpp, you must add the following code:
    #include "SMTPDataFilter.h"
    CComPtr <IFWXDataFilter> spIFWXDataFilter;
    
  2. In FWXSessionFilter.cpp, in the switch statement of the FirewallEventHandler method, add this code to the fwx_AcceptedConnection case:
    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);
    }
    
  3. Implement the IFWXDataFilter::SetSockets method.

    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).

  4. Implement the IFWXDataFilter::SetSockets method.

    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;
    }
    
  5. Implement the IFWXDataFilter::Detach method.

    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;
    }
    
  6. Build the project.