Windows 8下未调用NDIS筛选器驱动程序的FilterAttach例程 [英] NDIS filter driver's FilterAttach routine isn't called under Windows 8

查看:328
本文介绍了Windows 8下未调用NDIS筛选器驱动程序的FilterAttach例程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家.我已经将著名的数据包捕获软件WinPcap从NDIS 5协议移植到了NDIS 6 LWF.在Win7下一切正常.但是,在Win8下永远不会调用FilterAttach例程.我发现在DriverEntry中调用NdisFRegisterFilterDriver会返回NDIS_STATUS_SUCCESS,这很奇怪.谁能帮我?谢谢!

everybody. I have ported the famous packet capture software WinPcap from the NDIS 5 protocol to an NDIS 6 LWF. Everything is OK under Win7. However, the FilterAttach routine is never called under Win8. I found NdisFRegisterFilterDriver invoke in DriverEntry returns NDIS_STATUS_SUCCESS, this is so strange. Can anyone help me? thx!

这是DriverEntry的代码

Here's the code of DriverEntry

_Use_decl_annotations_
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
    NDIS_FILTER_DRIVER_CHARACTERISTICS FChars;
    NTSTATUS Status = STATUS_SUCCESS;
//  NDIS_STRING FriendlyName = NDIS_STRING_CONST("WinPcap NDIS LightWeight Filter");
//  NDIS_STRING UniqueName   = NDIS_STRING_CONST("{5cbf81bd-5055-47cd-9055-a76b2b4e2637}"); //unique name, quid name
//  NDIS_STRING ServiceName = NDIS_STRING_CONST("npf6x"); //this to match the service name in the INF
    NDIS_STRING FriendlyName = RTL_CONSTANT_STRING(L"WinPcap NDIS LightWeight Filter");
    NDIS_STRING UniqueName   = RTL_CONSTANT_STRING(L"{5cbf81bd-5055-47cd-9055-a76b2b4e2637}"); //unique name, quid name
    NDIS_STRING ServiceName = RTL_CONSTANT_STRING(L"npf6x"); //this to match the service name in the INF
    WCHAR* bindT;
    PKEY_VALUE_PARTIAL_INFORMATION tcpBindingsP;
    UNICODE_STRING macName;
    ULONG OsMajorVersion, OsMinorVersion;

    TRACE_ENTER();

    UNREFERENCED_PARAMETER(RegistryPath);

    FilterDriverObject = DriverObject;

    //
    // Get OS version and store it in a global variable. 
    //
    // Note: both RtlGetVersion() and PsGetVersion() are documented to always return success.
    //
    //  OsVersion.dwOSVersionInfoSize = sizeof(OsVersion);
    //  RtlGetVersion(&OsVersion);
    //
    PsGetVersion(&OsMajorVersion, &OsMinorVersion, NULL, NULL);
    TRACE_MESSAGE2(PACKET_DEBUG_INIT, "OS Version: %d.%d\n", OsMajorVersion, OsMinorVersion);


    NdisInitUnicodeString(&g_NPF_Prefix, g_NPF_PrefixBuffer);

    //
    // Get number of CPUs and save it
    //
#ifdef NDIS620
    g_NCpu = NdisGroupMaxProcessorCount(ALL_PROCESSOR_GROUPS);
#else
    g_NCpu = NdisSystemProcessorCount();
#endif

    //
    // TODO: Most handlers are optional, however, this sample includes them
    // all for illustrative purposes.  If you do not need a particular 
    // handler, set it to NULL and NDIS will more efficiently pass the
    // operation through on your behalf.
    //

    //
    // Register as a service with NDIS
    //
    NdisZeroMemory(&FChars, sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS));
    FChars.Header.Type = NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;
    FChars.Header.Size = sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS);
#if NDIS_SUPPORT_NDIS61
    FChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_2;
#else
    FChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_1;
#endif

    FChars.MajorNdisVersion = NDIS_FILTER_MAJOR_VERSION;
    FChars.MinorNdisVersion = NDIS_FILTER_MINOR_VERSION;
    FChars.MajorDriverVersion = 1;
    FChars.MinorDriverVersion = 0;
    FChars.Flags = 0;

    FChars.FriendlyName = FriendlyName;
    FChars.UniqueName = UniqueName;
    FChars.ServiceName = ServiceName;

    FChars.SetOptionsHandler = NPF_RegisterOptions;
    FChars.AttachHandler = NPF_Attach;
    FChars.DetachHandler = NPF_Detach;
    FChars.RestartHandler = NPF_Restart;
    FChars.PauseHandler = NPF_Pause;
    FChars.SetFilterModuleOptionsHandler = NPF_SetModuleOptions;
    FChars.OidRequestHandler = NPF_OidRequest;
    FChars.OidRequestCompleteHandler = NPF_OidRequestComplete;
    FChars.CancelOidRequestHandler = NPF_CancelOidRequest;

    FChars.SendNetBufferListsHandler = NPF_SendEx;
    FChars.ReturnNetBufferListsHandler = NPF_ReturnEx;
    FChars.SendNetBufferListsCompleteHandler = NPF_SendCompleteEx;
    FChars.ReceiveNetBufferListsHandler = NPF_TapEx;
    FChars.DevicePnPEventNotifyHandler = NPF_DevicePnPEventNotify;
    FChars.NetPnPEventHandler = NPF_NetPnPEvent;
    FChars.StatusHandler = NPF_Status;
    FChars.CancelSendNetBufferListsHandler = NPF_CancelSendNetBufferLists;

    DriverObject->DriverUnload = NPF_Unload;

    //
    // Initialize spin locks
    //
    //NdisAllocateSpinLock(&FilterListLock);

    //InitializeListHead(&FilterModuleList);


    // 
    // 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_INIT, "Adapters not found in the registry, try to copy the bindings of TCP-IP.");

        tcpBindingsP = getTcpBindings();

        if (tcpBindingsP == NULL)
        {
            TRACE_MESSAGE(PACKET_DEBUG_INIT, "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);
    }


    Status = NdisFRegisterFilterDriver(DriverObject,
        (NDIS_HANDLE) FilterDriverObject,
        &FChars,
        &FilterDriverHandle);
    if (Status != NDIS_STATUS_SUCCESS)
    {
        TRACE_MESSAGE(PACKET_DEBUG_INIT, "Failed to register filter with NDIS.");
        TRACE_EXIT();
        return Status;
    }


    TRACE_EXIT();
    return STATUS_SUCCESS;

    RegistryError : NdisFDeregisterFilterDriver(FilterDriverHandle);

    Status = STATUS_UNSUCCESSFUL;
    TRACE_EXIT();
    return(Status);
}

推荐答案

为什么您的FilterAttach例程未称为—我不知道.我想不出Windows 7和Windows 8之间的任何显着差异.(另一方面,Windows 8.1 Preview确实有一些实质性的绑定更改.)

Why your FilterAttach routine isn't called — I don't know. I can't think of any significant differences between Windows 7 and Windows 8. (On the other hand, Windows 8.1 Preview does have some substantial binding changes.)

检查过滤器是否在用户模式下绑定.使用powershell中的Get-NetAdapterBinding来确保NIC与过滤器之间存在绑定,并且已启用该绑定.

Check if the filter is bound in usermode. Use Get-NetAdapterBinding from powershell to ensure that there is a binding from the NIC to your filter, and that the binding is enabled.

验证微型端口是否正常启动.使用!ndiskd.miniport查看微型端口是否正常绑定.检查您的过滤器是否在微型端口的过滤器绑定列表中列出.

Verify the miniports are started normally. Use !ndiskd.miniport to see if the miniports are otherwise bound normally. Check if your filter is listed on the miniport's list of filter bindings.

一些不相关的注释:

  • 我不认为RegistryError标签应调用NdisFDeregisterFilterDriver,因为该过滤器尚未在NDIS中注册.
  • getAdaptersListgetTcpBindings这样的代码听起来很吓人,但是我想那可能是旧驱动程序中预先存在的代码.请注意,我们不支持注册表中的翻箱倒柜,而是希望您在用户模式下使用INetCfg来发现适配器.对于LWF,我们希望您的过滤器始终绑定到所有支持的适配器.如果需要考虑perf,LWF可以选择使用NdisFRestartFilterNdisSetOptionalHandlers根据需要动态地将其自身动态插入/删除到数据路径中.
  • I don't think the RegistryError label should call NdisFDeregisterFilterDriver, since the filter wouldn't have been registered with NDIS yet.
  • Code like getAdaptersList and getTcpBindings sounds scary, but I suppose that's probably pre-existing code from the old driver. Note that we don't support rummaging around in the registry, and would rather you use INetCfg in usermode to discover adapters. For a LWF, we prefer that your filter is always bound to all capable adapters. If perf is a concern, the LWF can optionally insert/remove itself dynamically into the datapath as needed, using NdisFRestartFilter and NdisSetOptionalHandlers.

这篇关于Windows 8下未调用NDIS筛选器驱动程序的FilterAttach例程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆