C 一个二进制文件中的两个过滤器驱动程序导致第二个驱动程序出现系统错误2

C 一个二进制文件中的两个过滤器驱动程序导致第二个驱动程序出现系统错误2,c,windows,networking,driver,ndis,C,Windows,Networking,Driver,Ndis,我在同一个二进制文件中有两个NDIS筛选器驱动程序。这似乎是基于 我遇到了一个问题:两个驱动程序都已使用netcfgapi成功安装。但是,第二个安装的驱动程序不会启动。它会导致系统错误2: C:\Program Files\Npcap>net start npcap The requested service has already been started. More help is available by typing NET HELPMSG 2182. C:\Program

我在同一个二进制文件中有两个NDIS筛选器驱动程序。这似乎是基于

我遇到了一个问题:两个驱动程序都已使用
netcfgapi
成功安装。但是,第二个安装的驱动程序不会启动。它会导致
系统错误2

C:\Program Files\Npcap>net start npcap
The requested service has already been started.

More help is available by typing NET HELPMSG 2182.


C:\Program Files\Npcap>net start npcap_wifi
System error 2 has occurred.


The system cannot find the file specified.
如果我先安装
npcap\u wifi
,然后再安装
npcap
,则
npcap
服务无法启动。DbgView显示从未调用第二个驱动程序的
DriverEntry
。netcfgapi安装也没有显示任何错误。所以我不知道这里怎么了?谢谢


我的源代码:

第一个驱动程序的INF是:。它使用服务名称
npcap

第二个驱动程序的INF是:它使用服务名称
npcap\u wifi

共享二进制文件为:。我使用
DriverEntry
RegistryPath
来确定二进制文件作为哪个服务运行

驱动程序安装程序是:。命令
NPFInstall.exe-i
用于安装第一个驱动程序,而
NPFInstall.exe-i2
用于安装第二个驱动程序


更新:

我根据您的假服务方法修改了
npcap.inf

;-------------------------------------------------------------------------
; NPCAP.INF -- Npcap NDIS 6.x LightWeight Filter Driver
;
; Copyright (c) 2015, Insecure.Com LLC.  All rights reserved.
;------------------------------------------------------------------------
[version]
Signature       = "$Windows NT$"
Class           = NetService
ClassGUID       = {4D36E974-E325-11CE-BFC1-08002BE10318}
CatalogFile     = %NPF_DriverName%.cat
Provider        = %Insecure%
DriverVer=05/15/2015,14.48.38.905


[Manufacturer]
%Insecure%=Insecure,NTx86,NTia64,NTamd64

[Insecure.NTx86]
%NPF_Desc_Standard%=FilterStandard, INSECURE_NPCAP
%NPF_Desc_WiFi%=FilterWiFi, INSECURE_NPCAP_WIFI

[Insecure.NTia64]
%NPF_Desc_Standard%=FilterStandard, INSECURE_NPCAP
%NPF_Desc_WiFi%=FilterWiFi, INSECURE_NPCAP_WIFI

[Insecure.NTamd64]
%NPF_Desc_Standard%=FilterStandard, INSECURE_NPCAP
%NPF_Desc_WiFi%=FilterWiFi, INSECURE_NPCAP_WIFI

;-------------------------------------------------------------------------
; Installation Section
;-------------------------------------------------------------------------
[FilterStandard]
NetCfgInstanceId="{7daf2ac8-e9f6-4765-a842-f1f5d2501341}"
Copyfiles = npf.copyfiles.sys
Characteristics=0x40000
AddReg=FilterStandard.reg

[FilterWiFi]
NetCfgInstanceId="{7daf2ac8-e9f6-4765-a842-f1f5d2501351}"
Characteristics=0x40000
AddReg=FilterWiFi.reg

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

[SourceDisksFiles]
npcap.sys=1

[DestinationDirs]
DefaultDestDir=12
npf.copyfiles.sys=12

[npf.copyfiles.sys]
%NPF_DriverName%.sys,,,2


;-------------------------------------------------------------------------
; Ndi installation support for the standard filter
;-------------------------------------------------------------------------
[FilterStandard.reg]
HKR, Ndi,Service,,%NPF_Filter_Name_Standard%
HKR, Ndi,CoServices,0x00010000,%NPF_Filter_Name_Standard%
HKR, Ndi,HelpText,,%NPF_HelpText%
HKR, Ndi,FilterClass,, compression


; For a Monitoring filter, use this:
;     HKR, Ndi,FilterType,0x00010001, 1 ; Monitoring filter
; For a Modifying filter, use this:
;     HKR, Ndi,FilterType,0x00010001, 2 ; Modifying filter
HKR, Ndi,FilterType,0x00010001,2


HKR, Ndi\Interfaces,UpperRange, , noupper
HKR, Ndi\Interfaces,LowerRange, , "ndis5,ndis4"


; TODO: Ensure that the list of media types below is correct.  Typically,
; filters include "ethernet".  Filters may also include "ppip" to include
; native WWAN stacks, but you must be prepared to handle the packet framing.
; Possible values are listed on MSDN, but common values include:
;     ethernet, wan, ppip, wlan
HKR, Ndi\Interfaces, FilterMediaTypes,,"ethernet, fddi, wan, ppip, wlan, bluetooth, ndis5, vwifi, flpp4, flpp6, vchannel, nolower"


; For a Mandatory filter, use this:
;     HKR, Ndi,FilterRunType,0x00010001, 1 ; Mandatory filter
; For an Optional filter, use this:
;     HKR, Ndi,FilterRunType,0x00010001, 2 ; Optional filter
HKR, Ndi,FilterRunType,0x00010001, 2 ; Optional filter


; By default, Mandatory filters unbind all protocols when they are
; installed/uninstalled, while Optional filters merely pause the stack.  If you
; would like to override this behavior, you can include these options.  These
; options only take effect with 6.30 filters on Windows "8" or later.
; To prevent a full unbind, and merely pause/restart protocols:
;     HKR, Ndi,UnbindOnAttach,0x00010001, 0 ; Do not unbind during FilterAttach
;     HKR, Ndi,UnbindOnDetach,0x00010001, 0 ; Do not unbind during FilterDetach
; To force a full unbind/bind (which includes pause/restart, of course):
;     HKR, Ndi,UnbindOnAttach,0x00010001, 1 ; Unbind during FilterAttach
;     HKR, Ndi,UnbindOnDetach,0x00010001, 1 ; Unbind during FilterDetach
;

;-------------------------------------------------------------------------
; Ndi installation support for the WiFi filter
;-------------------------------------------------------------------------
[FilterWiFi.reg]
HKR, Ndi,Service,,%NPF_Filter_Name_WiFi%
HKR, Ndi,CoServices,0x00010000,%NPF_Filter_Name_WiFi%
HKR, Ndi,HelpText,,%NPF_HelpText%
HKR, Ndi,FilterClass,, ms_medium_converter_128


; For a Monitoring filter, use this:
;     HKR, Ndi,FilterType,0x00010001, 1 ; Monitoring filter
; For a Modifying filter, use this:
;     HKR, Ndi,FilterType,0x00010001, 2 ; Modifying filter
HKR, Ndi,FilterType,0x00010001,2


HKR, Ndi\Interfaces,UpperRange, , noupper
HKR, Ndi\Interfaces,LowerRange, , "ndis5,ndis4"


; TODO: Ensure that the list of media types below is correct.  Typically,
; filters include "ethernet".  Filters may also include "ppip" to include
; native WWAN stacks, but you must be prepared to handle the packet framing.
; Possible values are listed on MSDN, but common values include:
;     ethernet, wan, ppip, wlan
HKR, Ndi\Interfaces, FilterMediaTypes,,"ethernet, fddi, wan, ppip, wlan, bluetooth, ndis5, vwifi, flpp4, flpp6, vchannel, nolower"


; For a Mandatory filter, use this:
;     HKR, Ndi,FilterRunType,0x00010001, 1 ; Mandatory filter
; For an Optional filter, use this:
;     HKR, Ndi,FilterRunType,0x00010001, 2 ; Optional filter
HKR, Ndi,FilterRunType,0x00010001, 2 ; Optional filter


; By default, Mandatory filters unbind all protocols when they are
; installed/uninstalled, while Optional filters merely pause the stack.  If you
; would like to override this behavior, you can include these options.  These
; options only take effect with 6.30 filters on Windows "8" or later.
; To prevent a full unbind, and merely pause/restart protocols:
;     HKR, Ndi,UnbindOnAttach,0x00010001, 0 ; Do not unbind during FilterAttach
;     HKR, Ndi,UnbindOnDetach,0x00010001, 0 ; Do not unbind during FilterDetach
; To force a full unbind/bind (which includes pause/restart, of course):
;     HKR, Ndi,UnbindOnAttach,0x00010001, 1 ; Unbind during FilterAttach
;     HKR, Ndi,UnbindOnDetach,0x00010001, 1 ; Unbind during FilterDetach
;

;-------------------------------------------------------------------------
; Service installation support
;-------------------------------------------------------------------------
[FilterStandard.Services]
AddService=%NPF_Filter_Name_Standard%,,FilterStandard.svc

[FilterWiFi.Services]
AddService=%NPF_Filter_Name_WiFi%,,FilterWiFi.svc

[FilterStandard.svc]
DisplayName     = %NPF_Desc_Standard%
ServiceType     = 1 ;SERVICE_KERNEL_DRIVER
StartType       = 3 ;SERVICE_DEMAND_START
ErrorControl    = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary   = %12%\%NPF_DriverName%.sys
LoadOrderGroup  = NDIS
Description     = %NPF_Desc_Standard%
AddReg          = Common.Params.reg, NdisImPlatformBindingOptions.reg

[FilterWiFi.svc]
DisplayName     = %NPF_Desc_WiFi%
ServiceType     = 1 ;SERVICE_KERNEL_DRIVER
StartType       = 3 ;SERVICE_DEMAND_START
ErrorControl    = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary   = %12%\%NPF_DriverName%.sys
LoadOrderGroup  = NDIS
Description     = %NPF_Desc_WiFi%
AddReg          = Common.Params.reg, NdisImPlatformBindingOptions.reg

[FilterStandard.Remove.Services]
DelService=%NPF_Filter_Name_Standard%,0x200 ; SPSVCINST_STOPSERVICE

[FilterWiFi.Remove.Services]
DelService=%NPF_Filter_Name_WiFi%,0x200 ; SPSVCINST_STOPSERVICE

[Common.Params.reg]

[NdisImPlatformBindingOptions.reg]
HKR, Parameters, NdisImPlatformBindingOptions,0x00010001,0 ; Subscribe to default behavior

[Strings]
NPF_DriverName = "npcap"
NPF_Filter_Name_Standard = "npcap"
NPF_Filter_Name_WiFi = "npcap_wifi"
Insecure = "Nmap Project"
NPF_Desc_Standard = "Npcap Packet Driver (NPCAP)"
NPF_Desc_WiFi = "Npcap Packet Driver (NPCAP) (Wi-Fi)"
NPF_HelpText = "A NDIS 6 filter driver & WFP callout driver to support packet capturing and sending under Windows 7, 8 & 10"
我的安装程序代码更改为:

HRESULT HrInstallNetComponent(IN INetCfg* pnc, IN LPCTSTR lpszComponentId, IN const GUID* pguidClass, IN LPCTSTR lpszInfFullPath)
{
    DWORD dwError;
    HRESULT hr = S_OK;
    TCHAR szDrive[_MAX_DRIVE];
    TCHAR szDir[_MAX_DIR];
    TCHAR szDirWithDrive[_MAX_DRIVE + _MAX_DIR];

    //
    // If full path to INF has been specified, the INF
    // needs to be copied using Setup API to ensure that any other files
    // that the primary INF copies will be correctly found by Setup API
    //
    if (lpszInfFullPath)
    {
        //
        // Get the path where the INF file is.
        //
        _tsplitpath(lpszInfFullPath, szDrive, szDir, NULL, NULL);

        _tcscpy(szDirWithDrive, szDrive);
        _tcscat(szDirWithDrive, szDir);

        //
        // Copy the Service INF file to the \Windows\Inf Folder
        //
        if (!SetupCopyOEMInfW(lpszInfFullPath, szDirWithDrive, // Other files are in the
            // same dir. as primary INF
            SPOST_PATH,    // First param is path to INF
            0,             // Default copy style
            NULL,          // Name of the INF after
            // it's copied to %windir%\inf
            0,             // Max buf. size for the above
            NULL,          // Required size if non-null
            NULL)          // Optionally get the filename
            // part of Inf name after it is copied.
           )
        {
            dwError = GetLastError();

            hr = HRESULT_FROM_WIN32(dwError);
        }
    }

    if (S_OK == hr)
    {
        //
        // Install the network component.
        //
        hr = HrInstallComponent(pnc, NDISLWF_SERVICE_PNP_DEVICE_ID, pguidClass);

        if (hr == S_OK)
        {
            hr = HrInstallComponent(pnc, NDISLWF_SERVICE_PNP_DEVICE_ID_WIFI, pguidClass);

            if (hr == S_OK)
            {
                //
                // On success, apply the changes
                //
                hr = pnc->Apply();
            }
        }
    }

    return hr;
}
结果是第二个服务
npcap_wifi
以系统错误2结束:

C:\Program Files\Npcap>sc query npcap

SERVICE_NAME: npcap
        TYPE               : 1  KERNEL_DRIVER
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

C:\Program Files\Npcap>sc query npcap_wifi
[SC] EnumQueryServicesStatus:OpenService FAILED 1060:

The specified service does not exist as an installed service.


C:\Program Files\Npcap>sc query npcap
SERVICE_NAME: npcap
        TYPE               : 1  KERNEL_DRIVER
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

C:\Program Files\Npcap>sc query npcap_wifi

SERVICE_NAME: npcap_wifi
        TYPE               : 1  KERNEL_DRIVER
        STATE              : 1  STOPPED
        WIN32_EXIT_CODE    : 2  (0x2)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

C:\Program Files\Npcap>net start npcap
The requested service has already been started.

More help is available by typing NET HELPMSG 2182.


C:\Program Files\Npcap>net start npcap_wifi
System error 2 has occurred.

The system cannot find the file specified.


C:\Program Files\Npcap>
这个看起来对吗?问题是我仍然没有接到DbgView中第二个LWF的
DriverEntry
呼叫?那么第二个LWF是如何工作的呢


更新:

我想这就是我下一步应该做的?我在我的
DriverEntry
中调用了两次
ndisfsregisterfilterdriver
,以注册2个LWF。2个
FChars
结构仅在
FriendlyName、UniqueName、ServiceName
中有所不同。但是第二个
NDISRegisterFilterDriver
总是在
NDIS\u状态\u故障时失败(0xc0000001)。我不知道为什么

这是我的密码:

//
//  Packet Driver's entry routine.
//
_Use_decl_annotations_
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
    NDIS_FILTER_DRIVER_CHARACTERISTICS FChars;
    NDIS_FILTER_DRIVER_CHARACTERISTICS FChars_WiFi;
    NTSTATUS Status = STATUS_SUCCESS;

    // Use NonPaged Pool instead of No-Execute (NX) Nonpaged Pool for Win8 and later, this is for security purpose.
    ExInitializeDriverRuntime(DrvRtPoolNxOptIn);

    WCHAR* bindT;
    PKEY_VALUE_PARTIAL_INFORMATION tcpBindingsP;
    UNICODE_STRING macName;
    ULONG OsMajorVersion, OsMinorVersion;
    NDISGROUPMAXPROCESSORCOUNT MyNdisGroupMaxProcessorCount;
    NDIS_STRING GroupMaxProcessorCount;
    UNREFERENCED_PARAMETER(RegistryPath);

    TRACE_ENTER();
    FilterDriverObject = DriverObject;

    PsGetVersion(&OsMajorVersion, &OsMinorVersion, NULL, NULL);
    TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "OS Version: %d.%d\n", OsMajorVersion, OsMinorVersion);

    // RegistryPath = "\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\npcap" for standard driver
    // RegistryPath = "\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\npcap_wifi" for WiFi driver
    g_Dot11SupportMode = 0;
    for (USHORT i = 0; i < RegistryPath->Length / 2; i ++)
    {
        if (RegistryPath->Buffer[i] == L'_')
        {
            g_Dot11SupportMode = 1;
            break;
        }
    }
    TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "g_Dot11SupportMode (based on RegistryPath) = %d\n", g_Dot11SupportMode);

    if (g_Dot11SupportMode)
        NdisInitUnicodeString(&g_NPF_Prefix, g_NPF_PrefixBuffer_Wifi);
    else
        NdisInitUnicodeString(&g_NPF_Prefix, g_NPF_PrefixBuffer);

    //
    // Get number of CPUs and save it
    //
    RtlInitUnicodeString(&GroupMaxProcessorCount, L"NdisGroupMaxProcessorCount");
    MyNdisGroupMaxProcessorCount = (NDISGROUPMAXPROCESSORCOUNT) NdisGetRoutineAddress(&GroupMaxProcessorCount);
    if (MyNdisGroupMaxProcessorCount) // for NDIS620 and later (Win7 and later).
    {
        g_NCpu = MyNdisGroupMaxProcessorCount(ALL_PROCESSOR_GROUPS);
        TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "g_NCpu (NdisGroupMaxProcessorCount): %d, NPF_MAX_CPU_NUMBER: %d\n", g_NCpu, NPF_MAX_CPU_NUMBER);
        if (g_NCpu > NPF_MAX_CPU_NUMBER)
        {
            g_NCpu = NPF_MAX_CPU_NUMBER;
        }
    }
    else // for NDIS6 (Vista)
    {
        g_NCpu = NdisSystemProcessorCount();
    }

    //
    // Register as a service with NDIS
    //
    NPF_registerLWF(&FChars, FALSE);
    NPF_registerLWF(&FChars_WiFi, TRUE);

    DriverObject->DriverUnload = NPF_Unload;

    //
    // Standard device driver entry points stuff.
    //
    DriverObject->MajorFunction[IRP_MJ_CREATE] = NPF_OpenAdapter;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = NPF_CloseAdapter;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NPF_Cleanup;
    DriverObject->MajorFunction[IRP_MJ_READ] = NPF_Read;
    DriverObject->MajorFunction[IRP_MJ_WRITE] = NPF_Write;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NPF_IoControl;

    bindP = getAdaptersList();

    if (bindP == NULL)
    {
        TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Adapters not found in the registry, try to copy the bindings of TCP-IP.");

        tcpBindingsP = getTcpBindings();

        if (tcpBindingsP == NULL)
        {
            TRACE_MESSAGE(PACKET_DEBUG_LOUD, "TCP-IP not found, quitting.");
            goto RegistryError;
        }

        bindP = (WCHAR *)tcpBindingsP;
        bindT = (WCHAR *)(tcpBindingsP->Data);
    }
    else
    {
        bindT = bindP;
    }

    for (; *bindT != UNICODE_NULL; bindT += (macName.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR))
    {
        RtlInitUnicodeString(&macName, bindT);
        NPF_CreateDevice(DriverObject, &macName);
    }

    // Register the filter to NDIS.
    Status = NdisFRegisterFilterDriver(DriverObject,
        (NDIS_HANDLE) FilterDriverObject,
        &FChars,
        &FilterDriverHandle);
    if (Status != NDIS_STATUS_SUCCESS)
    {
        TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NdisFRegisterFilterDriver: failed to register filter with NDIS, Status = %x", Status);
        TRACE_EXIT();
        return Status;
    }
    else
    {
        TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "NdisFRegisterFilterDriver: succeed to register filter with NDIS, Status = %x, FilterDriverHandle = %x", Status, FilterDriverHandle);
    }

    // Register the WiFi filter to NDIS.
    Status = NdisFRegisterFilterDriver(DriverObject,
        (NDIS_HANDLE)FilterDriverObject,
        &FChars_WiFi,
        &FilterDriverHandle_WiFi);
    if (Status != NDIS_STATUS_SUCCESS)
    {
        TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "NdisFRegisterFilterDriver: failed to register filter (WiFi) with NDIS, Status = %x", Status);
        TRACE_EXIT();
        return Status;
    }
    else
    {
        TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "NdisFRegisterFilterDriver: succeed to register filter (WiFi) with NDIS, Status = %x, FilterDriverHandle_WiFi = %x", Status, FilterDriverHandle_WiFi);
    }

#ifdef HAVE_WFP_LOOPBACK_SUPPORT
    // Use Winsock Kernel (WSK) to send loopback packets.
    Status = NPF_WSKStartup();
    if (!NT_SUCCESS(Status))
    {
        TRACE_EXIT();
        return Status;
    }

    Status = NPF_WSKInitSockets();
    if (!NT_SUCCESS(Status))
    {
        TRACE_EXIT();
        return Status;
    }
#endif

    NdisAllocateSpinLock(&g_OpenArrayLock);

    TRACE_EXIT();
    return STATUS_SUCCESS;

RegistryError:

    Status = STATUS_UNSUCCESSFUL;
    TRACE_EXIT();
    return(Status);
}
//-------------------------------------------------------------------
VOID
NPF_registerLWF(
    PNDIS_FILTER_DRIVER_CHARACTERISTICS pFChars,
    BOOLEAN bWiFiOrNot
    )
{
    NDIS_STRING FriendlyName = RTL_CONSTANT_STRING(NPF_SERVICE_DESC_WIDECHAR); // display name
    NDIS_STRING UniqueName = RTL_CONSTANT_STRING(FILTER_UNIQUE_NAME); // unique name, quid name
    NDIS_STRING ServiceName = RTL_CONSTANT_STRING(NPF_DRIVER_NAME_SMALL_WIDECHAR); // this to match the service name in the INF
    NDIS_STRING FriendlyName_WiFi = RTL_CONSTANT_STRING(NPF_SERVICE_DESC_WIDECHAR_WIFI); // display name
    NDIS_STRING UniqueName_WiFi = RTL_CONSTANT_STRING(FILTER_UNIQUE_NAME_WIFI); // unique name, quid name
    NDIS_STRING ServiceName_WiFi = RTL_CONSTANT_STRING(NPF_DRIVER_NAME_SMALL_WIDECHAR_WIFI); // this to match the service name in the INF

    NdisZeroMemory(pFChars, sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS));
    pFChars->Header.Type = NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;
    pFChars->Header.Size = sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS);
#if NDIS_SUPPORT_NDIS61
    pFChars->Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_2;
#else
    pFChars->Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_1;
#endif

    pFChars->MajorNdisVersion = NDIS_FILTER_MAJOR_VERSION; // NDIS version is 6.2 (Windows 7)
    pFChars->MinorNdisVersion = NDIS_FILTER_MINOR_VERSION;
    pFChars->MajorDriverVersion = 1; // Driver version is 1.0
    pFChars->MinorDriverVersion = 0;
    pFChars->Flags = 0;

    // Use different names for the WiFi driver.
    if (bWiFiOrNot)
    {
        pFChars->FriendlyName = FriendlyName_WiFi;
        pFChars->UniqueName = UniqueName_WiFi;
        pFChars->ServiceName = ServiceName;
        // pFChars->ServiceName = ServiceName_WiFi;
    }
    else
    {
        pFChars->FriendlyName = FriendlyName;
        pFChars->UniqueName = UniqueName;
        pFChars->ServiceName = ServiceName;
    }

    pFChars->SetOptionsHandler = NPF_RegisterOptions;
    pFChars->AttachHandler = NPF_AttachAdapter;
    pFChars->DetachHandler = NPF_DetachAdapter;
    pFChars->RestartHandler = NPF_Restart;
    pFChars->PauseHandler = NPF_Pause;
    pFChars->SetFilterModuleOptionsHandler = NPF_SetModuleOptions;
    pFChars->OidRequestHandler = NPF_OidRequest;
    pFChars->OidRequestCompleteHandler = NPF_OidRequestComplete;
    pFChars->CancelOidRequestHandler = NPF_CancelOidRequest;

    pFChars->SendNetBufferListsHandler = NPF_SendEx;
    pFChars->ReturnNetBufferListsHandler = NPF_ReturnEx;
    pFChars->SendNetBufferListsCompleteHandler = NPF_SendCompleteEx;
    pFChars->ReceiveNetBufferListsHandler = NPF_TapEx;
    pFChars->DevicePnPEventNotifyHandler = NPF_DevicePnPEventNotify;
    pFChars->NetPnPEventHandler = NPF_NetPnPEvent;
    pFChars->StatusHandler = NPF_Status;
    pFChars->CancelSendNetBufferListsHandler = NPF_CancelSendNetBufferLists;
}
因此,NDIS似乎没有找到第二个过滤器的注册表
7daf2ac8-e9f6-4765-a842-f1f5d2501351
。但是我在
regedit
中检查了它。关键在于:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4d36e974-e325-11ce-bfc1-08002be10318}\{7DAF2AC8-E9F6-4765-A842-F1F5D2501341}]
"InstallTimeStamp"=hex:e0,07,08,00,00,00,1c,00,0c,00,1a,00,39,00,88,03
"Characteristics"=dword:00040000
"ComponentId"="INSECURE_NPCAP"
"Description"="@oem11.inf,%npf_desc_standard%;Npcap Packet Driver (NPCAP)"
"InfPath"="oem11.inf"
"InfSection"="FilterStandard"
"LocDescription"="@oem11.inf,%npf_desc_standard%;Npcap Packet Driver (NPCAP)"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4d36e974-e325-11ce-bfc1-08002be10318}\{7DAF2AC8-E9F6-4765-A842-F1F5D2501341}\Ndi]
"TimeStamp"=hex:e0,07,08,00,00,00,1c,00,0c,00,1a,00,39,00,88,03
"HelpText"="A NDIS 6 filter driver & WFP callout driver to support packet capturing and sending under Windows 7, 8 & 10"
"Service"="npcap"
"CoServices"=hex(7):6e,00,70,00,63,00,61,00,70,00,00,00,00,00
"FilterClass"="compression"
"FilterType"=dword:00000002
"FilterRunType"=dword:00000002

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4d36e974-e325-11ce-bfc1-08002be10318}\{7DAF2AC8-E9F6-4765-A842-F1F5D2501341}\Ndi\Interfaces]
"LowerRange"="ndis5,ndis4"
"UpperRange"="noupper"
"FilterMediaTypes"="ethernet, fddi, wan, ppip, wlan, bluetooth, ndis5, vwifi, flpp4, flpp6, vchannel, nolower"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4d36e974-e325-11ce-bfc1-08002be10318}\{7DAF2AC8-E9F6-4765-A842-F1F5D2501351}]
"InstallTimeStamp"=hex:e0,07,08,00,00,00,1c,00,0c,00,1a,00,3a,00,7e,02
"Characteristics"=dword:00040000
"ComponentId"="INSECURE_NPCAP_WIFI"
"Description"="@oem11.inf,%npf_desc_wifi%;Npcap Packet Driver (NPCAP) (Wi-Fi)"
"InfPath"="oem11.inf"
"InfSection"="FilterWiFi"
"LocDescription"="@oem11.inf,%npf_desc_wifi%;Npcap Packet Driver (NPCAP) (Wi-Fi)"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4d36e974-e325-11ce-bfc1-08002be10318}\{7DAF2AC8-E9F6-4765-A842-F1F5D2501351}\Ndi]
"TimeStamp"=hex:e0,07,08,00,00,00,1c,00,0c,00,1a,00,3a,00,7e,02
"HelpText"="A NDIS 6 filter driver & WFP callout driver to support packet capturing and sending under Windows 7, 8 & 10"
"Service"="npcap_wifi"
"CoServices"=hex(7):6e,00,70,00,63,00,61,00,70,00,5f,00,77,00,69,00,66,00,69,\
  00,00,00,00,00
"FilterClass"="ms_medium_converter_128"
"FilterType"=dword:00000002
"FilterRunType"=dword:00000002

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4d36e974-e325-11ce-bfc1-08002be10318}\{7DAF2AC8-E9F6-4765-A842-F1F5D2501351}\Ndi\Interfaces]
"LowerRange"="ndis5,ndis4"
"UpperRange"="noupper"
"FilterMediaTypes"="ethernet, fddi, wan, ppip, wlan, bluetooth, ndis5, vwifi, flpp4, flpp6, vchannel, nolower"
所以我不知道为什么NDIS reports
NdisFRegisterFilterDriver:在注册表中找不到过滤器7daf2ac8-e9f6-4765-a842-f1f5d2501351。INetCfg是否成功安装了此筛选器?

系统一次只能加载一个二进制图像(.sys文件)。不能为两个不同的服务同时加载同一映像。(也不能为服务加载一次,为PNP驱动加载一次。)这意味着您将始终看到
DriverEntry
DriverUnload
DriverEntry
DriverUnload
。。。。你永远不会看到
DriverEntry
DriverEntry
drivernload
drivernload

使用假服务 每个NDIS LWF或协议驱动程序都需要一个服务来保存一些注册表项。但这里有第一个技巧:服务不必运行!您可以为LWF创建虚拟服务记录,然后让其他服务实际使用LWF。NDIS不会验证传递给
NdisFRegisterFilterDriver
ServiceName
。(是的,依靠这个把戏是可以的。我与微软NDIS所有者的权威人士交谈。)

有一些内置的驱动程序正是这样做的。看看TCPIP和TCPIP6。这是两个不同的服务,也是两个不同的协议驱动程序,但只有一个映像(tcpip.sys)。TCPIP服务是真正的服务——它实际上将在引导时启动。TCPIP6服务是假的-它被标记为永不启动,如果您尝试手动启动它,它将无法工作

(旁白:不要以WFPLWFS为例。虽然它也有3个过滤器驱动程序共享1个二进制文件,但如果您尝试这样做,它会产生一些问题。此外,从Windows 10开始,TCPIP和TCPIP6使用的INF是假的,因此您不应该认为它们是如何实现这一技巧的好例子。)

您可以选择注册1个INF或2个INF;这对操作系统没有多大影响。让我们假设1inf,只是为了使示例更短

因此,您需要的是:

  • LWF命名过滤器
  • LWF命名过滤器B
  • 名为ServiceA的服务
  • 名为ServiceB的服务
  • 名为Driver.sys的驱动程序映像
  • 名为Driver.INF的INF
假设ServiceA是真正的服务,ServiceB是假的服务

Driver.inf将具有:

[Manufacturer]
Contoso=Models,NTamd64

[Models.NTamd64]
"Cool Filter A"=FilterA, my_filter_a
"Awesome Filter B"=FilterB, my_filter_b

[FilterA]
NetCfgInstanceId="{guid-aaaa-guid}"
CopyFiles=copy.driver.sys
Characteristics=0x40000
AddReg=FilterA.reg

[FilterB]
NetCfgInstanceId="{guid-bbbb-guid}"
Characteristics=0x40000
AddReg=FilterB.reg

[FilterA.reg]
HKR,Ndi,Service,,"ServiceA"
HKR,etc,etc,etc

[FilterB.reg]
HKR,Ndi,Service,,"ServiceB"
HKR,etc,etc,etc

[FilterA.Services]
AddService=ServiceA,,FilterA.svc

[FilterB.Services]
AddService=ServiceB,,FilterB.svc

[FilterA.svc]
StartType = Demand
ServiceBinary = Driver.sys

[FilterB.svc]
StartType = Demand
ServiceBinary = Driver.sys

[copy.driver.sys]
driver.sys,,,2
请注意,您注册了2个LWF,创建了2个服务,并复制了1个映像

对于
my\u filter\u a
my\u filter\b
中的每一个,您只需调用1次
SetupCopyOEMInf
和2次
INetCfgClassSetup::install
,即可安装它

要启动驱动程序,只需启动1个服务,即ServiceA。切勿启动其他虚拟服务

但是如果你不想两个过滤器同时运行呢?简单-在实际启动LWF之前,不要调用
NdisFRegisterFilterDriver
。您始终可以从ioctl处理程序注册/取消注册筛选器驱动程序。因此,您的
DriverEntry
将相当空-只需创建一个设备对象来侦听ioctl

使用导出驱动程序 另一种选择是创建两个服务,每个服务都有自己的驱动程序映像。但是,驱动程序映像将是对单个共享导出驱动程序(如DLL)调用的薄包装。您可以将所有实际工作放在共享导出驱动程序中

 ServiceA      ServiceB
     |             |
     |             |
DriverA.sys   DriverB.sys
     \             /
      \           /
     TheRealDriver.sys

这使它保持简单,尽管它最终会有一堆额外的司机。

我对你的假服务方式非常感兴趣。这样,我将看到
DriverEntry,DriverEntry,drivernload,drivernload
,对吗?服务的卸载情况如何?对于每个
my_filter\u a
 ServiceA      ServiceB
     |             |
     |             |
DriverA.sys   DriverB.sys
     \             /
      \           /
     TheRealDriver.sys