Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging

The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.

Check out The OSR Learning Library at:

Windows Filtering Platform: ClassifyFn BSOD at DISPATCH_LEVEL

ViottoViotto Member Posts: 6

I'm trying to implement a simple firewall which filters network connections made by Windows processes.
The firewall should either allow/block the connection.

In order to intercept connections by any process, I created a kernel driver which makes use of Windows Filtering Platform.

I registered a ClassifyFn (FWPS_CALLOUT_CLASSIFY_FN1) callback at the filtering layer FWPM_LAYER_ALE_AUTH_CONNECT_V4:

FWPM_CALLOUT m_callout = { 0 };
m_callout.applicableLayer = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
status = FwpmCalloutAdd(filter_engine_handle, &m_callout, NULL, NULL);

The decision regarding connection allow/block should be taken by userlevel.
I communicate with Userlevel using FltSendMessage, which cannot be used at IRQL DISPATCH_LEVEL.
Following the instructions of the Microsoft documentation regarding how to process callouts asynchronously, I do call FwpsPendOperation0 before calling FltSendMessage.
After the call to FltSendMessage, I resume packet processing by calling FwpsCompleteOperation0.

FwpsPendOperation0 documentation states that calling this function should make possible to operate calls at PASSIVE_LEVEL:

A callout can pend the current processing operation on a packet when the callout must perform processing on one of these layers that may take a long interval to complete or that should occur at IRQL = PASSIVE_LEVEL if the current IRQL > PASSIVE_LEVEL.

However, when the ClassifyFn callback is called at DISPATCH_LEVEL, I do sometimes still get a BSOD on FltSendMessage (INVALID_PROCESS_ATTACH_ATTEMPT).

I don't understand what's wrong.

Thank you in advance for any advice which could point me to the right direction.

Here is the relevant code of the ClassifyFn callback:

ClassifyFn Function
void example_classify(
    const FWPS_INCOMING_VALUES * inFixedValues,
    void * layerData,
    const void * classifyContext,
    const FWPS_FILTER * filter,
    UINT64 flowContext,
    FWPS_CLASSIFY_OUT * classifyOut)

    NTSTATUS status;
    BOOLEAN bIsReauthorize = FALSE;
    BOOLEAN SafeToOpen = TRUE; // Value returned by userlevel which signals to allow/deny packet
    classifyOut->actionType = FWP_ACTION_PERMIT;

    remote_address = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_ADDRESS].value.uint32;
    remote_port = inFixedValues->incomingValue[FWPS_FIELD_ALE_AUTH_CONNECT_V4_IP_REMOTE_PORT].value.uint16;

    bIsReauthorize = IsAleReauthorize(inFixedValues);
    if (!bIsReauthorize)
        // First time receiving packet (not a reauthorized packet)
        // Communicate with userlevel asynchronously

        HANDLE hCompletion;
        status = FwpsPendOperation0(inMetaValues->completionHandle, &hCompletion);

        // FltSendMessage call here
        // ERROR HERE:

        FwpsCompleteOperation0(hCompletion, NULL);

    if (!SafeToOpen) {
        // Packet blocked
        classifyOut->actionType = FWP_ACTION_BLOCK;
    else {
        // Packet allowed

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Writing WDF Drivers 7 Dec 2020 LIVE ONLINE
Internals & Software Drivers 25 Jan 2021 LIVE ONLINE
Developing Minifilters 8 March 2021 LIVE ONLINE