Microsoft Internet Security and Acceleration Server 2000

Creating a Filter Object that Monitors AcceptedConnection Events

You need to create a filter object that will implement the IFWXFilter interface. This interface is necessary for the creation of a filter. The filter object will monitor fwx_AcceptedConnection events.

Warning  Visual C++ will not create a new ATL object if more than one .idl file is included in your project. Delete all the .idl files except SMTPFLTR.idl from the project, add the ATL object as described in step 1, and then replace the .idl files that you removed.

To create the filter object

  1. Create a COM object that implements the IFWXFilter interface.

    Insert a new ATL object (Simple Object), with the following properties:

  2. Edit the SMTPFLTR.idl file. Because the IFWXFilter interface and its GUID are already defined in wspfwext.idl, you must delete the IFWXFilter definition code that is produced in SMTPFLTR.idl by the wizard. Note that the UUID in this code is only provided as an example.
    [
    		uuid(20F10C85-2C5E-11D2-8C3D-006094EB63EF),
    
    		helpstring("IFWXFilter Interface"),
    		pointer_default(unique)
    ]
    interface IFWXFilter : IUnknown
    {
    };
    
  3. Add declaration of IFWXFilter methods. Use wspfwext.h to get the prototypes of the methods of IFWXFilter and add them to the public section of the class definition in SMTPfilter.h. Note that you must remove =0 from the methods. Insert the following code:
    // IFWXFilter
    	virtual HRESULT STDMETHODCALLTYPE FilterInit( 
    	/* [in] */ IFWXFirewall __RPC_FAR *pIFWXFirewall,
    	/* [out] */ PFwxFilterHookEvents __RPC_FAR *ppFilterHookEvents);
    
    	virtual HRESULT STDMETHODCALLTYPE FilterShutdown(void);
    	
    	virtual HRESULT STDMETHODCALLTYPE AttachToSession( 
    	/* [in] */ IFWXSession __RPC_FAR *piSession,
    	/* [out] */ IFWXSessionFilter __RPC_FAR *__RPC_FAR *piSessionFilter,
    	/* [out] */ PFwxFilterHookEvents __RPC_FAR *ppFilterHookEvents);
    
  4. Add the implementation of IFWXFilter methods. Use wspfwext.h to get the prototypes of the methods of IFWXFilter and add them to SMTPfilter.cpp with implementation code.

    Start with a simple implementation, for example:

    return E_NOTIMPL;
    

    The implementation code should look like this:

    // CSMTPFilter
     
    	HRESULT STDMETHODCALLTYPE CSMTPFilter::FilterInit( 
    			/* [in] */ IFWXFirewall __RPC_FAR *pIFWXFirewall,
    			/* [out] */ PFwxFilterHookEvents __RPC_FAR *ppFilterHookEvents)
    	{
    		return E_NOTIMPL;
     
    }
    
    	HRESULT STDMETHODCALLTYPE CSMTPFilter::FilterShutdown( void)
    	{
    		return E_NOTIMPL;
     
    }
     
     
    	HRESULT STDMETHODCALLTYPE CSMTPFilter::AttachToSession( 
    		/* [in] */ IFWXSession __RPC_FAR *piSession,
    		/* [out] */ IFWXSessionFilter __RPC_FAR *__RPC_FAR *piSessionFilter,
    		/* [out] */ PFwxFilterHookEvents __RPC_FAR *ppFilterHookEvents)
    	{
    		return E_NOTIMPL;
     
    }
    
  5. Build the project.
  6. Add the SMTPFilter object constructor code, and implement the IFWXFilter::FilterInit method. The Firewall service calls this method on startup. In the IFWXFilter::FilterInit method you will save a reference to the IFWXFirewall interface to be used later. Then you will define the set of initial events that the filter will monitor. This example monitors the fwx_AcceptedConnection and fwx_Bind_Tcp events. However, for performance reasons it is better to monitor a minimal set of events at the IFWXFilter level. Therefore, your filter will monitor the fwx_Bind_Tcp events for port 25 and when they occur it will also monitor fwx_AcceptedConnection events. You also must define the port from which you want to receive events. In this example the port is 25.

    In SMTPfilter.h, add the following code:

    private:
    	CComPtr<IFWXFirewall> m_pIFWXFirewall;
    	FwxFilterHookEvents	m_FwxFilterHookEvents;
    	FwxPortRangeEvents	 m_FwxPortRangeEvents;
    

    In SMTPfilter.h, locate the default object constructor code, and remove the default implementation ({}) and add a semicolon as shown:

    	CSMTPFilter();
    	{
    }
    

    and place the following object constructor code and FilterInit implementation in SMTPFilter.cpp:

    CSMTPFilter::CSMTPFilter ()
    {
    	m_FwxPortRangeEvents.StartPort = 25;
    	m_FwxPortRangeEvents.EndPort  = 25;
    	m_FwxPortRangeEvents.dwSocketEvents = 
    		FWX_ALL_SOURCES // Event Source is either NAT or Firewall client
    		| fwx_Bind_Tcp;//At this level, monitor binds
     
    	m_FwxFilterHookEvents.dwGlobalEvents		= 0;
    	m_FwxFilterHookEvents.dwNumPortRanges	 = 1;
    	m_FwxFilterHookEvents.FwxPortRangeEvents	= &m_FwxPortRangeEvents;
    }
     
    HRESULT STDMETHODCALLTYPE CSMTPFilter::FilterInit( 
    	/* [in] */ IFWXFirewall __RPC_FAR *pIFWXFirewall,
    	/* [out] */ FwxFilterHookEvents __RPC_FAR *__RPC_FAR *ppFilterHookEvents)
    {
    	m_pIFWXFirewall = pIFWXFirewall;
    	return m_pIFWXFirewall->DuplicateFilterHookEvents (&m_FwxFilterHookEvents, ppFilterHookEvents);
    }
    
  7. Implement the IFWXFilter::FilterShutdown method. This is a request to the filter to shut down. Because this filter doesn't hold a reference to any object except the firewall callback interface, it can simply return S_OK. The implementation should be in SMTPfilter.cpp, in place of the previously inserted implementation of return E_NOTIMPL.
    HRESULT STDMETHODCALLTYPE CSMTPFilter::FilterShutdown( void)
    {
    	return S_OK; 
    }
    
  8. Build the project.