得到"系统错误2"系统重启后,在WFP标注驱动程序中指定SERVICE_SYSTEM_START时

时间:2015-07-23 05:31:29

标签: c windows driver wfp

我在这里有一个示例 WFP标注驱动程序。它可以通过使用" net start lbtest"来启动和停止。和" net start lbtest"。但是当我将StartType从 3(SERVICE_DEMAND_START)更改为 1(SERVICE_SYSTEM_START)时。我可以正常启动这个驱动程序。但是当系统重新启动时,驱动程序不会启动,如果我运行" net start lbtest",我将得到"系统错误2" 如下:

J:\nmap\mswin32\Debug>net start lbtest
System error 2 has occurred.

我的测试平台是Win8.1 x64。我认为这是世界粮食计划署的一个错误?或者在系统重新启动时使WFP标注驱动程序自动启动的正确方法是什么?

我的INF文件就像:

;
; lbtest.inf
;

[Version]
    Signature = "$WINDOWS NT$"
    Class = WFPCALLOUTS
    ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
    Provider = %LBTest%
    CatalogFile = LBTest.cat

[DestinationDirs]
    DefaultDestDir = 12
    LBTest.DriverFiles = 12

[SourceDisksNames]
    1 = %DiskName%,,,""

[SourceDisksFiles]
    lbtest.sys = 1,,

[DefaultInstall]
    OptionDesc = %LBTestServiceDesc%
    CopyFiles  = LBTest.DriverFiles

[DefaultInstall.Services]
    AddService = %LBTestServiceName%,,LBTest.Service

[DefaultUninstall]
    DelFiles = LBTest.DriverFiles

[DefaultUninstall.Services]
    DelService = %LBTestServiceName%,0x200                                ; SPSVCINST_STOPSERVICE
    DelReg     = LBTest.DelRegistry

[LBTest.DriverFiles]
    lbtest.sys,,,0x00000040                                               ; COPYFLG_OVERWRITE_OLDER_ONLY

[LBTest.Service]
    DisplayName   = %LBTestServiceName%
    Description   = %LBTestServiceDesc%
    ServiceType   = 1                                                      ; SERVICE_KERNEL_DRIVER
    StartType     = 1                                                      ; SERVICE_SYSTEM_START
    ErrorControl  = 1                                                      ; SERVICE_ERROR_NORMAL
    ServiceBinary = %12%\lbtest.sys                                       ; %WinDir%\System32\Drivers\lbtest.sys
    AddReg        = LBTest.AddRegistry

[LBTest.AddRegistry]
    HKR,"Parameters","BlockTraffic",0x00010001,"0"                         ; FLG_ADDREG_TYPE_DWORD
    HKR,"Parameters","RemoteAddressToInspect",0x00000000,"192.168.1.2"        ; FLG_ADDREG_TYPE_SZ

[LBTest.DelRegistry]
    HKR,"Parameters",,,


[Strings]
    LBTest            = "LBTest Ltd."
    LBTestServiceDesc = "NPcap Loopback Callout Driver"
    LBTestServiceName = "LBTest"
    DiskName="LBTest Source Disk"

lbtest.c

#include "stdafx.h"

#include <ntddk.h>

#include "Loopback.h"
#include "lbtest.h"
#include "debug.h"

extern HANDLE gWFPEngineHandle;

#ifdef ALLOC_PRAGMA
#pragma NDIS_INIT_FUNCTION(DriverEntry)
#endif // ALLOC_PRAGMA

#if DBG
// Declare the global debug flag for this driver.
ULONG PacketDebugFlag = PACKET_DEBUG_LOUD;

#endif

// 
// Configurable parameters (addresses and ports are in host order)
//

WCHAR g_NPF_PrefixBuffer[512] = L"NPCAP" L"_";

WCHAR* bindT = NULL;

NDIS_STRING g_NPF_Prefix;
NDIS_STRING devicePrefix = NDIS_STRING_CONST("\\Device\\");
NDIS_STRING symbolicLinkPrefix = NDIS_STRING_CONST("\\DosDevices\\");


/*!
\brief Port device extension.

Structure containing some data relative to every adapter on which NPF is bound.
*/
typedef struct _DEVICE_EXTENSION
{
    NDIS_STRING AdapterName;            ///< Name of the adapter.
    PWSTR       ExportString;           ///< Name of the exported device, i.e. name that the applications will use 
    ///< to open this adapter through WinPcap.
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;



BOOLEAN
NPF_CreateDevice(
IN OUT PDRIVER_OBJECT adriverObjectP,
IN PUNICODE_STRING amacNameP
)
{
    NTSTATUS status;
    PDEVICE_OBJECT devObjP;
    UNICODE_STRING deviceName;
    UNICODE_STRING deviceSymLink;

    TRACE_ENTER();

    IF_LOUD(DbgPrint("\n\ncreateDevice for MAC %ws\n", amacNameP->Buffer););
    if (RtlCompareMemory(amacNameP->Buffer, devicePrefix.Buffer, devicePrefix.Length) < devicePrefix.Length)
    {
        TRACE_EXIT();
        return FALSE;
    }

    deviceName.Length = 0;
    deviceName.MaximumLength = (USHORT)(amacNameP->Length + g_NPF_Prefix.Length + sizeof(UNICODE_NULL));
    deviceName.Buffer = ExAllocatePoolWithTag(PagedPool, deviceName.MaximumLength, '3PWA');

    if (deviceName.Buffer == NULL)
    {
        TRACE_EXIT();
        return FALSE;
    }

    deviceSymLink.Length = 0;
    deviceSymLink.MaximumLength = (USHORT)(amacNameP->Length - devicePrefix.Length + symbolicLinkPrefix.Length + g_NPF_Prefix.Length + sizeof(UNICODE_NULL));

    deviceSymLink.Buffer = ExAllocatePoolWithTag(NonPagedPool, deviceSymLink.MaximumLength, '3PWA');

    if (deviceSymLink.Buffer == NULL)
    {
        ExFreePool(deviceName.Buffer);
        TRACE_EXIT();
        return FALSE;
    }

    RtlAppendUnicodeStringToString(&deviceName, &devicePrefix);
    RtlAppendUnicodeStringToString(&deviceName, &g_NPF_Prefix);
    RtlAppendUnicodeToString(&deviceName, amacNameP->Buffer + devicePrefix.Length / sizeof(WCHAR));

    RtlAppendUnicodeStringToString(&deviceSymLink, &symbolicLinkPrefix);
    RtlAppendUnicodeStringToString(&deviceSymLink, &g_NPF_Prefix);
    RtlAppendUnicodeToString(&deviceSymLink, amacNameP->Buffer + devicePrefix.Length / sizeof(WCHAR));

    IF_LOUD(DbgPrint("Creating device name: %ws\n", deviceName.Buffer);)

    status = IoCreateDevice(adriverObjectP, sizeof(DEVICE_EXTENSION), &deviceName, FILE_DEVICE_TRANSPORT,
        FILE_DEVICE_SECURE_OPEN, FALSE, &devObjP);
//      UNICODE_STRING sddl = RTL_CONSTANT_STRING(L"D:P(A;;GA;;;SY)(A;;GA;;;BA)");
//  const GUID guidClassNPF = { 0x26e0d1e0L, 0x8189, 0x12e0, { 0x99, 0x14, 0x08, 0x00, 0x22, 0x30, 0x19, 0x04 } };
//  status = IoCreateDeviceSecure(adriverObjectP, sizeof(DEVICE_EXTENSION), &deviceName, FILE_DEVICE_TRANSPORT,
//      FILE_DEVICE_SECURE_OPEN, FALSE, &sddl, (LPCGUID)&guidClassNPF, &devObjP);

    if (NT_SUCCESS(status))
    {
        PDEVICE_EXTENSION devExtP = (PDEVICE_EXTENSION)devObjP->DeviceExtension;

        IF_LOUD(DbgPrint("Device created successfully\n"););

        devObjP->Flags |= DO_DIRECT_IO;
        RtlInitUnicodeString(&devExtP->AdapterName, amacNameP->Buffer);

        IF_LOUD(DbgPrint("Trying to create SymLink %ws\n", deviceSymLink.Buffer););

        if (IoCreateSymbolicLink(&deviceSymLink, &deviceName) != STATUS_SUCCESS)
        {
            IF_LOUD(DbgPrint("\n\nError creating SymLink %ws\nn", deviceSymLink.Buffer););

            ExFreePool(deviceName.Buffer);
            ExFreePool(deviceSymLink.Buffer);

            devExtP->ExportString = NULL;

            TRACE_EXIT();
            return FALSE;
        }

        IF_LOUD(DbgPrint("SymLink %ws successfully created.\n\n", deviceSymLink.Buffer););

        devExtP->ExportString = deviceSymLink.Buffer;

        ExFreePool(deviceName.Buffer);

        TRACE_EXIT();
        return TRUE;
    }
    else
    {
        IF_LOUD(DbgPrint("\n\nIoCreateDevice status = %x\n", status););

        ExFreePool(deviceName.Buffer);
        ExFreePool(deviceSymLink.Buffer);

        TRACE_EXIT();
        return FALSE;
    }
}

_Use_decl_annotations_
VOID
NPF_Unload(
    IN PDRIVER_OBJECT      DriverObject
    )
{
    PDEVICE_OBJECT DeviceObject;
    PDEVICE_OBJECT OldDeviceObject;
    PDEVICE_EXTENSION DeviceExtension;
    NDIS_STRING SymLink;

    TRACE_ENTER();

    DeviceObject = DriverObject->DeviceObject;

    while (DeviceObject != NULL)
    {
        OldDeviceObject = DeviceObject;

        DeviceObject = DeviceObject->NextDevice;

        DeviceExtension = OldDeviceObject->DeviceExtension;

        TRACE_MESSAGE3(PACKET_DEBUG_LOUD, "Deleting Adapter %ws, Protocol Handle=xxx, Device Obj=%p (%p)", DeviceExtension->AdapterName.Buffer, DeviceObject, OldDeviceObject);

        if (DeviceExtension->ExportString)
        {
            RtlInitUnicodeString(&SymLink, DeviceExtension->ExportString);

            TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Deleting SymLink at %p", SymLink.Buffer);

            IoDeleteSymbolicLink(&SymLink);
            ExFreePool(DeviceExtension->ExportString);
        }

        IF_LOUD(DbgPrint("Device successfully deleted.\n\n"););
        IoDeleteDevice(OldDeviceObject);
    }

    NPF_UnregisterCallouts();

    // Free the adapters names
    ExFreePool(bindT);

    TRACE_EXIT();
}

_Use_decl_annotations_
NTSTATUS
DriverEntry(
    DRIVER_OBJECT* DriverObject,
    UNICODE_STRING* RegistryPath
    )
{
    NTSTATUS Status = STATUS_SUCCESS;
    UNICODE_STRING macName;

    UNREFERENCED_PARAMETER(RegistryPath);

    TRACE_ENTER();

    IF_LOUD(DbgPrint("\n\nThis is version [2]!!!.\n");)

    bindT = (PWCHAR)ExAllocatePoolWithTag(PagedPool, 4096, 'NPCA');
    //RtlCopyUnicodeString(bindT, L"\\Device\\{A22932C9-82CB-4080-993B-D5E82CAD06A7}"); //0006, Microsoft KM-TEST Loopback Adapter;
    wcscpy(bindT, L"\\Device\\{A22932C9-82CB-4080-993B-D5E82CAD06A7}");
    RtlInitUnicodeString(&macName, bindT);

    NdisInitUnicodeString(&g_NPF_Prefix, g_NPF_PrefixBuffer);

    DriverObject->DriverUnload = NPF_Unload;

    // 
    // Standard device driver entry points stuff.
    //
//  DriverObject->MajorFunction[IRP_MJ_CREATE] = NULL;
//  DriverObject->MajorFunction[IRP_MJ_CLOSE] = NULL;
//  DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NULL;
//  DriverObject->MajorFunction[IRP_MJ_READ] = NULL;
//  DriverObject->MajorFunction[IRP_MJ_WRITE] = NULL;
//  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NULL;

    Status = NPF_CreateDevice(DriverObject, &macName) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
    if (Status != STATUS_SUCCESS)
    {
        IF_LOUD(DbgPrint("Failed to create WFP device.\n");)
        TRACE_EXIT();
        return STATUS_SUCCESS;
    }

    if (DriverObject->DeviceObject)
    {
        Status = NPF_RegisterCallouts(DriverObject->DeviceObject);
        if (!NT_SUCCESS(Status))
        {
            if (gWFPEngineHandle != NULL)
            {
                NPF_UnregisterCallouts();
            }
            TRACE_EXIT();
            return Status;
        }
    }

    TRACE_EXIT();
    return STATUS_SUCCESS;
};

loopback.c

#include "stdafx.h"

#include "Loopback.h"
#include "debug.h"

#define NPCAP_CALLOUT_DRIVER_TAG (UINT32) 'NPCA'

// 
// Callout and sublayer GUIDs
//

// 2D605B3E-C244-4364-86E8-BD81E6C91B6D
DEFINE_GUID(
    NPF_OUTBOUND_IPPACKET_CALLOUT_V4,
    0x2d605b3e,
    0xc244,
    0x4364,
    0x86, 0xe8, 0xbd, 0x81, 0xe6, 0xc9, 0x1b, 0x6d
    );
// F935E4CD-9499-4934-824D-8E3726BA4A93
DEFINE_GUID(
    NPF_OUTBOUND_IPPACKET_CALLOUT_V6,
    0xf935e4cd,
    0x9499,
    0x4934,
    0x82, 0x4d, 0x8e, 0x37, 0x26, 0xba, 0x4a, 0x93
    );
// ED7E5EB2-6B09-4783-961C-5495EAAD361E
DEFINE_GUID(
    NPF_INBOUND_IPPACKET_CALLOUT_V4,
    0xed7e5eb2,
    0x6b09,
    0x4783,
    0x96, 0x1c, 0x54, 0x95, 0xea, 0xad, 0x36, 0x1e
    );
// 21022F40-9578-4C39-98A5-C97B8D834E27
DEFINE_GUID(
    NPF_INBOUND_IPPACKET_CALLOUT_V6,
    0x21022f40,
    0x9578,
    0x4c39,
    0x98, 0xa5, 0xc9, 0x7b, 0x8d, 0x83, 0x4e, 0x27
    );

// 2F32C254-A054-469B-B99B-3E8810275A71
DEFINE_GUID(
    NPF_SUBLAYER,
    0x2f32c254,
    0xa054,
    0x469b,
    0xb9, 0x9b, 0x3e, 0x88, 0x10, 0x27, 0x5a, 0x71
    );


// 
// Callout driver global variables
//

HANDLE gWFPEngineHandle;
UINT32 gOutboundIPPacketV4 = 0;
UINT32 gOutboundIPPacketV6 = 0;
UINT32 gInboundIPPacketV4 = 0;
UINT32 gInboundIPPacketV6 = 0;

typedef struct CLASSIFY_DATA_
{
    const FWPS_INCOMING_VALUES*          pClassifyValues;
    const FWPS_INCOMING_METADATA_VALUES* pMetadataValues;
    VOID*                                pPacket;               /// NET_BUFFER_LIST | FWPS_STREAM_CALLOUT_IO_PACKET
    const VOID*                          pClassifyContext;
    const FWPS_FILTER*                   pFilter;
    UINT64                               flowContext;
    FWPS_CLASSIFY_OUT*                   pClassifyOut;
    UINT64                               classifyContextHandle;
    BOOLEAN                              chainedNBL;
    UINT32                               numChainedNBLs;
}CLASSIFY_DATA, *PCLASSIFY_DATA;




/* ++

This is the classifyFn function for the Transport (v4 and v6) callout.
packets (inbound or outbound) are ueued to the packet queue to be processed
by the worker thread.

-- */
void
NPF_NetworkClassify(
    _In_ const FWPS_INCOMING_VALUES* inFixedValues,
    _In_ const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
    _Inout_opt_ void* layerData,
    _In_opt_ const void* classifyContext,
    _In_ const FWPS_FILTER* filter,
    _In_ UINT64 flowContext,
    _Inout_ FWPS_CLASSIFY_OUT* classifyOut
    )

#else

void
NPF_NetworkClassify(
    _In_ const FWPS_INCOMING_VALUES* inFixedValues,
    _In_ const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
    _Inout_opt_ void* layerData,
    _In_ const FWPS_FILTER* filter,
    _In_ UINT64 flowContext,
    _Inout_ FWPS_CLASSIFY_OUT* classifyOut
    )

#endif

{
    UNREFERENCED_PARAMETER(classifyContext);
    UNREFERENCED_PARAMETER(filter);
    UNREFERENCED_PARAMETER(flowContext);

    // filter out fragment packets and reassembled packets.
    if (inMetaValues->currentMetadataValues & FWPS_METADATA_FIELD_FRAGMENT_DATA)
    {
        return;
    }
    if (inMetaValues->currentMetadataValues & FWP_CONDITION_FLAG_IS_REASSEMBLED)
    {
        return;
    }
    TRACE_ENTER();

    // make the default action.
    if (classifyOut->rights & FWPS_RIGHT_ACTION_WRITE)
        classifyOut->actionType = FWP_ACTION_CONTINUE;

    inMetaValues->frameLength;
    layerData;


    // print "protocol, direction, fragment, reassembled" info for the current packet.
    int iProtocol = -1;
    if (inFixedValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V4 || inFixedValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4)
    {
        iProtocol = 0;
    }
    else if (inFixedValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V6 || inFixedValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6)
    {
        iProtocol = 1;
    }

    int iDrection = -1;
    if (inFixedValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V4 || inFixedValues->layerId == FWPS_LAYER_OUTBOUND_IPPACKET_V6)
    {
        iDrection = 0;
    }
    else if (inFixedValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V4 || inFixedValues->layerId == FWPS_LAYER_INBOUND_IPPACKET_V6)
    {
        iDrection = 1;
    }

    int iFragment = -1;
    if (inMetaValues->currentMetadataValues & FWPS_METADATA_FIELD_FRAGMENT_DATA)
    {
        iFragment = 1;
    }
    else
    {
        iFragment = 0;
    }

    int iReassembled = -1;
    if (inMetaValues->currentMetadataValues & FWP_CONDITION_FLAG_IS_REASSEMBLED)
    {
        iReassembled = 1;
    }
    else
    {
        iReassembled = 0;
    }
    IF_LOUD(DbgPrint("\n\nNPF_NetworkClassify: Loopback packet found !!! protocol=[%d] (ipv4=0, ipv6=1), direction=[%d] (out=0, in=1), fragment=[%d], reassembled=[%d]\n", iProtocol, iDrection, iFragment, iReassembled);)


    TRACE_EXIT();
    return;
}

NTSTATUS
NPF_NetworkNotify(
    _In_ FWPS_CALLOUT_NOTIFY_TYPE notifyType,
    _In_ const GUID* filterKey,
    _Inout_ const FWPS_FILTER* filter
    )
{
    UNREFERENCED_PARAMETER(notifyType);
    UNREFERENCED_PARAMETER(filterKey);
    UNREFERENCED_PARAMETER(filter);

    TRACE_ENTER();

    TRACE_EXIT();
    return STATUS_SUCCESS;
}

// 
// Callout driver implementation
//

NTSTATUS
NPF_AddFilter(
_In_ const GUID* layerKey,
_In_ const GUID* calloutKey,
_In_ const int iFlag
)
{
    TRACE_ENTER();
    NTSTATUS status = STATUS_SUCCESS;

    FWPM_FILTER filter = { 0 };
    FWPM_FILTER_CONDITION filterConditions[1] = { 0 };
    UINT conditionIndex;

    filter.layerKey = *layerKey;
    filter.displayData.name = L"Network NPcap Filter (Outbound)";
    filter.displayData.description = L"NPcap inbound/outbound network traffic";

    filter.action.calloutKey = *calloutKey;
    filter.filterCondition = filterConditions;
    filter.subLayerKey = NPF_SUBLAYER;
    filter.rawContext = 0;
    conditionIndex = 0;

    if (iFlag == 0)
    {
        filter.action.type = FWP_ACTION_PERMIT;
        filter.weight.type = FWP_UINT8;
        filter.weight.uint8 = 0x5;
        filterConditions[conditionIndex].fieldKey = FWPM_CONDITION_FLAGS;
        filterConditions[conditionIndex].matchType = FWP_MATCH_FLAGS_NONE_SET;
        filterConditions[conditionIndex].conditionValue.type = FWP_UINT32;
        filterConditions[conditionIndex].conditionValue.uint32 = FWP_CONDITION_FLAG_IS_LOOPBACK;
        conditionIndex++;
    }
    else if (iFlag == 1)
    {
        filter.action.type = FWP_ACTION_PERMIT;
        filter.weight.type = FWP_UINT8;
        filter.weight.uint8 = 0x4;
        filterConditions[conditionIndex].fieldKey = FWPM_CONDITION_FLAGS;
        filterConditions[conditionIndex].matchType = FWP_MATCH_FLAGS_ALL_SET;
        filterConditions[conditionIndex].conditionValue.type = FWP_UINT32;
        filterConditions[conditionIndex].conditionValue.uint32 = FWPS_METADATA_FIELD_FRAGMENT_DATA;
        conditionIndex++;
    }
    else if (iFlag == 2)
    {
        filter.action.type = FWP_ACTION_PERMIT;
        filter.weight.type = FWP_UINT8;
        filter.weight.uint8 = 0x3;
        filterConditions[conditionIndex].fieldKey = FWPM_CONDITION_FLAGS;
        filterConditions[conditionIndex].matchType = FWP_MATCH_FLAGS_ALL_SET;
        filterConditions[conditionIndex].conditionValue.type = FWP_UINT32;
        filterConditions[conditionIndex].conditionValue.uint32 = FWP_CONDITION_FLAG_IS_REASSEMBLED;
        conditionIndex++;
    }
    else if (iFlag == 3)
    {
        filter.action.type = FWP_ACTION_CALLOUT_INSPECTION;
        filter.weight.type = FWP_UINT8;
        filter.weight.uint8 = 0x2;
        filter.filterCondition = NULL;
    }
    //  else if (iFlag == 1)
    //  {
    //      filter.action.type = FWP_ACTION_CALLOUT_INSPECTION;
    //      filter.weight.type = FWP_UINT8;
    //      filter.weight.uint8 = 0x4;
    //      filterConditions[conditionIndex].fieldKey = FWPM_CONDITION_FLAGS;
    //      filterConditions[conditionIndex].matchType = FWP_MATCH_FLAGS_NONE_SET;
    //      filterConditions[conditionIndex].conditionValue.type = FWP_UINT32;
    //      filterConditions[conditionIndex].conditionValue.uint32 = FWPS_METADATA_FIELD_FRAGMENT_DATA | FWP_CONDITION_FLAG_IS_REASSEMBLED;
    //      conditionIndex++;
    //  }

    filter.numFilterConditions = conditionIndex;

    status = FwpmFilterAdd(
        gWFPEngineHandle,
        &filter,
        NULL,
        NULL);

    TRACE_EXIT();
    return status;
}

NTSTATUS
NPF_RegisterCallout(
_In_ const GUID* layerKey,
_In_ const GUID* calloutKey,
_Inout_ void* deviceObject,
_Out_ UINT32* calloutId
)
/* ++

This function registers callouts and filters that intercept transport
traffic at the following layers --

FWPM_LAYER_INBOUND_IPPACKET_V4
FWPM_LAYER_INBOUND_IPPACKET_V6
FWPM_LAYER_OUTBOUND_IPPACKET_V4
FWPM_LAYER_OUTBOUND_IPPACKET_V4_DISCARD

-- */
{
    TRACE_ENTER();
    NTSTATUS status = STATUS_SUCCESS;

    FWPS_CALLOUT sCallout = { 0 };
    FWPM_CALLOUT mCallout = { 0 };

    FWPM_DISPLAY_DATA displayData = { 0 };

    BOOLEAN calloutRegistered = FALSE;

    sCallout.calloutKey = *calloutKey;
    sCallout.classifyFn = NPF_NetworkClassify;
    sCallout.notifyFn = NPF_NetworkNotify;

    status = FwpsCalloutRegister(
        deviceObject,
        &sCallout,
        calloutId
        );
    if (!NT_SUCCESS(status))
    {
        goto Exit;
    }
    calloutRegistered = TRUE;

    displayData.name = L"NPcap Network Callout";
    displayData.description = L"NPcap inbound/outbound network traffic";

    mCallout.calloutKey = *calloutKey;
    mCallout.displayData = displayData;
    mCallout.applicableLayer = *layerKey;

    status = FwpmCalloutAdd(
        gWFPEngineHandle,
        &mCallout,
        NULL,
        NULL
        );
    if (!NT_SUCCESS(status))
    {
        goto Exit;
    }

    status = NPF_AddFilter(layerKey, calloutKey, 0);
    if (!NT_SUCCESS(status))
    {
        goto Exit;
    }

    status = NPF_AddFilter(layerKey, calloutKey, 1);
    if (!NT_SUCCESS(status))
    {
        goto Exit;
    }

    status = NPF_AddFilter(layerKey, calloutKey, 2);
    if (!NT_SUCCESS(status))
    {
        goto Exit;
    }

    status = NPF_AddFilter(layerKey, calloutKey, 3);
    if (!NT_SUCCESS(status))
    {
        goto Exit;
    }

Exit:

    if (!NT_SUCCESS(status))
    {
        IF_LOUD(DbgPrint("NPF_RegisterCallout: failed to register callout\n");)
            if (calloutRegistered)
            {
                FwpsCalloutUnregisterById(*calloutId);
                *calloutId = 0;
            }
    }

    TRACE_EXIT();
    return status;
}

NTSTATUS
NPF_RegisterCallouts(
_Inout_ void* deviceObject
)
/* ++

This function registers dynamic callouts and filters that intercept
transport traffic at ALE AUTH_CONNECT/AUTH_RECV_ACCEPT and
INBOUND/OUTBOUND transport layers.

Callouts and filters will be removed during DriverUnload.

-- */
{
    TRACE_ENTER();
    NTSTATUS status = STATUS_SUCCESS;
    FWPM_SUBLAYER NPFSubLayer;

    BOOLEAN engineOpened = FALSE;
    BOOLEAN inTransaction = FALSE;

    FWPM_SESSION session = { 0 };

    session.flags = FWPM_SESSION_FLAG_DYNAMIC;

    status = FwpmEngineOpen(
        NULL,
        RPC_C_AUTHN_WINNT,
        NULL,
        &session,
        &gWFPEngineHandle
        );
    if (!NT_SUCCESS(status))
    {
        goto Exit;
    }
    engineOpened = TRUE;

    status = FwpmTransactionBegin(gWFPEngineHandle, 0);
    if (!NT_SUCCESS(status))
    {
        goto Exit;
    }
    inTransaction = TRUE;

    RtlZeroMemory(&NPFSubLayer, sizeof(FWPM_SUBLAYER));

    NPFSubLayer.subLayerKey = NPF_SUBLAYER;
    NPFSubLayer.displayData.name = L"NPcap Loopback Sub-Layer";
    NPFSubLayer.displayData.description = L"Sub-Layer for use by NPcap Loopback callouts";
    NPFSubLayer.flags = 0;
    NPFSubLayer.weight = 0; // must be less than the weight of 
    // FWPM_SUBLAYER_UNIVERSAL to be
    // compatible with Vista's IpSec
    // implementation.

    status = FwpmSubLayerAdd(gWFPEngineHandle, &NPFSubLayer, NULL);
    if (!NT_SUCCESS(status))
    {
        goto Exit;
    }

    //if (isV4)
    {
        status = NPF_RegisterCallout(
            &FWPM_LAYER_OUTBOUND_IPPACKET_V4,
            &NPF_OUTBOUND_IPPACKET_CALLOUT_V4,
            deviceObject,
            &gOutboundIPPacketV4
            );
        if (!NT_SUCCESS(status))
        {
            goto Exit;
        }

        status = NPF_RegisterCallout(
            &FWPM_LAYER_INBOUND_IPPACKET_V4,
            &NPF_INBOUND_IPPACKET_CALLOUT_V4,
            deviceObject,
            &gInboundIPPacketV4
            );
        if (!NT_SUCCESS(status))
        {
            goto Exit;
        }
    }
    //else
    {
        status = NPF_RegisterCallout(
            &FWPM_LAYER_OUTBOUND_IPPACKET_V6,
            &NPF_OUTBOUND_IPPACKET_CALLOUT_V6,
            deviceObject,
            &gOutboundIPPacketV6
            );
        if (!NT_SUCCESS(status))
        {
            goto Exit;
        }

        status = NPF_RegisterCallout(
            &FWPM_LAYER_INBOUND_IPPACKET_V6,
            &NPF_INBOUND_IPPACKET_CALLOUT_V6,
            deviceObject,
            &gInboundIPPacketV6
            );
        if (!NT_SUCCESS(status))
        {
            goto Exit;
        }
    }

    status = FwpmTransactionCommit(gWFPEngineHandle);
    if (!NT_SUCCESS(status))
    {
        goto Exit;
    }
    inTransaction = FALSE;

Exit:

    if (!NT_SUCCESS(status))
    {
        IF_LOUD(DbgPrint("NPF_RegisterCallouts: failed to register callouts\n");)
            if (inTransaction)
            {
                FwpmTransactionAbort(gWFPEngineHandle);
                _Analysis_assume_lock_not_held_(gWFPEngineHandle); // Potential leak if "FwpmTransactionAbort" fails
            }
        if (engineOpened)
        {
            FwpmEngineClose(gWFPEngineHandle);
            gWFPEngineHandle = NULL;
        }
    }

    TRACE_EXIT();
    return status;
}

void
NPF_UnregisterCallouts(
)
{
    TRACE_ENTER();

    if (gWFPEngineHandle)
    {
        FwpmEngineClose(gWFPEngineHandle);
        gWFPEngineHandle = NULL;
    }

    if (gOutboundIPPacketV4)
    {
        FwpsCalloutUnregisterById(gOutboundIPPacketV4);
    }
    if (gOutboundIPPacketV6)
    {
        FwpsCalloutUnregisterById(gOutboundIPPacketV6);
    }
    if (gInboundIPPacketV4)
    {
        FwpsCalloutUnregisterById(gInboundIPPacketV4);
    }
    if (gInboundIPPacketV6)
    {
        FwpsCalloutUnregisterById(gInboundIPPacketV6);
    }

    TRACE_EXIT();
}

0 个答案:

没有答案