Microsoft Internet Security and Acceleration Server 2004 SDK

Implementing a Session Filter Object

After the Microsoft Firewall service calls the IFWXFilter::AttachToSession method, which creates an instance of the filter's session filter object, it notifies the filter about events for which it is registered by calling the IFWXSessionFilter::FirewallEventHandler method.

In the Data Filter sample, the implementation of the IFWXSessionFilter::FirewallEventHandler method obtains a pointer to the connection object in accordance with the type of event. It retrieves the per-rule policy, and then calls the CreateDataFilter helper function. This process is shown in the following code.

STDMETHODIMP CDMSessionFilter::FirewallEventHandler(const FwxFirewallEvent *pProxyEvent )
{
	HRESULT hr = S_OK;
	IFWXConnection* pConnection  = NULL;
	CDMPerRulePolicy* pPerRulePolicy = NULL;
 
	switch (pProxyEvent->EventType)
	{
		case fwx_Connect_Tcp:
		{
			pConnection = pProxyEvent->Parameters.Connect.piConnection;
			pPerRulePolicy = (CDMPerRulePolicy*)pProxyEvent->Parameters.Connect.PerRuleProcessedData;
			break;
	}
		case fwx_AcceptedConnection:
		{
			pConnection = pProxyEvent->Parameters.Accept.piConnectionAccepted;
			pPerRulePolicy = (CDMPerRulePolicy*)pProxyEvent->Parameters.Accept.PerRuleProcessedData;
			break;
	}

		default:					 // An unexpected event type
			ATLASSERT(false);
			return E_FAIL;
}
	hr = CreateDataFilter(pConnection,pPerRulePolicy);

	return  hr;

}

The following code implements the CreateDataFilter helper function, which creates a data filter object and attaches it to the current connection.

HRESULT CDMSessionFilter::CreateDataFilter(IFWXConnection* pConnection, 
										 CDMPerRulePolicy* pPerRulePolicy)
{
	// Create a data filter for this connection.
	HRESULT hr;
	CComObject<CDMDataFilter>*	pDataFilter;
	CHECK_HR(CComObject<CDMDataFilter>::CreateInstance(&pDataFilter));
	pDataFilter->AddRef();

	// If no per-rule policy was provided, create a default one.
	bool fFreePerRulePolicy = false;
	if (pPerRulePolicy == NULL)
	{
		pPerRulePolicy = new CComObject<CDMPerRulePolicy>;
		if (pPerRulePolicy == NULL)
		{
			return E_OUTOFMEMORY;
	}
		pPerRulePolicy->AddRef();
		fFreePerRulePolicy = true;
}

	// Initialize and attach to the connection object.
	pDataFilter->Initialize(pConnection,pPerRulePolicy, m_spFilter);
	hr = pConnection->AttachDataFilter(pDataFilter, fwx_dfpc_Middle, NULL);
	if (FAILED(hr))
	{
		DBGTRACEF(("AttachDataFilter failed, error = %08x\n", hr));
}

	if (fFreePerRulePolicy)
	{
		pPerRulePolicy->Release();
}

	// The connection now owns the DataFilter ref-count, so we can release 
	// it. (or if failed, we still have to release it to avoid leaks)
	pDataFilter->Release();

	return hr;
}