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 and returns a pointer to the IFWXSessionFilter interface on the object created, the Firewall service 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 applicable IFWXConnection interface from the FwxFirewallEvent structure provided in the pFirewallEvent parameter for events of the fwx_Connect_Tcp and fwx_AcceptedConnection types. 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 an instance of the filter's data filter object and calls the AttachDataFilter method on the IFWXConnection interface to attach 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;
}
The Firewall service responds to the call to the AttachDataFilter method by providing two sockets that implement the IFWXSocket interface in a call to the IFWXDataFilter::SetSockets method, and the filter can start pumping data and filtering for the specific connection.
Build date: 7/12/2010