NDIS filter驱动可能是最容易生成的驱动之一,如果你安装了VS 2015 + WDK之后,你可以直接生成一个能运行的Filter驱动,它一般是ndislwf。
和大部分硬件不同,NDIS Filter驱动介于软件和硬件抽象层之上,它和硬件相关,但是只需要很少的硬件知识就可以理解;同时也需要一定的网络协议知识,并且NDIS对windows内核进行了很好的封转,故它是一个非常适合拿来入门的驱动程序,许多人也使用这个驱动来进行开发入门。
还有另外一点是,NDIS filter驱动是性能提升最大的驱动之一,它相比于socket来说会提升非常巨大。
Filter模块 PnP 事件通知
Filter驱动程序可以接收基础微型端口驱动程序接收的所有设备即插即用 (PnP) 通知。 此外,Filter驱动程序可以接收过度协议驱动程序接收的所有网络 PnP 通知。PnP 通知的处理特定于驱动程序。
下图演示了经过筛选的设备 PnP 事件通知:
Filter驱动程序提供 FilterDevicePnPEventNotify 函数,NDIS 调用该函数以传入设备 PnP 和电源管理事件通知。 这类似于 MiniportDevicePnPEventNotify 函数。
Filter驱动程序可以将设备 PnP 和电源管理事件转发到基础驱动程序。 若要转发设备 PnP 或电源管理事件,请调用 NdisFDevicePnPEventNotify 函数。
下图演示了经过筛选的网络 PnP 事件通知:
Filter驱动程序提供 FilterNetPnPEvent 函数,NDIS 调用该函数以传入网络 PnP 和电源管理事件通知。 这类似于 ProtocolNetPnPEvent 函数。
Filter驱动程序可以将网络 PnP 和电源管理事件转发到过度覆盖的驱动程序。 若要转发网络 PnP 或电源管理事件,请调用 NdisFNetPnPEvent 函数。
Filter驱动程序应处理驱动程序堆栈更改。 如果需要允许处理这些事件,NDIS 可以在 PnP 或电源管理通知后启动暂停操作。
Filter模块状态指示
Filter驱动程序可以提供 NDIS 在基础驱动程序报告状态时调用的 FilterStatus 函数。 Filter驱动程序还可以启动状态指示。
下图演示了筛选的状态指示:
在基础驱动程序调用状态指示函数 (NdisMIndicateStatusEx 或 NdisFIndicateStatus) 之后,NDIS 调用Filter驱动程序的 FilterStatus 函数。
Filter驱动程序在其 FilterStatus 函数中调用 NdisFIndicateStatus,以将筛选的状态指示传递给过分的驱动程序。 Filter驱动程序可以通过不调用 NdisFIndicateStatus) 来筛选出状态指示,或者在调用 NdisFIndicateStatus 之前修改指示的状态。
若要发出状态指示,Filter驱动程序调用 NdisFIndicateStatus ,而无需事先调用 FilterStatus。
在这种情况下,Filter驱动程序应将 SourceHandle 成员设置为 NDIS 传递给 FilterAttach 函数的 NdisFilterHandle 参数的句柄。 如果状态指示与 OID 请求相关联,则Filter驱动程序可以设置 DestinationHandle 和 RequestId 成员,以便 NDIS 可以提供特定协议绑定的状态指示。
在Filter驱动程序调用 NdisFIndicateStatus 后,NDIS (ProtocolStatusEx 或 FilterStatus 调用状态函数) 下一个过度覆盖的驱动程序。
NDIS Filter驱动程序安装
本部分提供有关安装 NDIS Filter驱动程序的信息。 轻型Filter驱动程序不同于Filter中间驱动程序。 配置管理器为每个微型端口适配器提供 NDIS Filter模块列表。 没有与Filter驱动程序关联的虚拟设备 (或虚拟微型端口) 与 NDIS Filter中间驱动程序一样。
若要安装Filter驱动程序,必须提供单个 INF 文件。 配置管理器从 INF 文件读取有关Filter驱动程序的配置信息,并将其复制到注册表。
Filter驱动程序 INF 文件定义网络服务,Filter驱动程序没有微型端口 INF 文件。
指定Filter驱动程序绑定关系
在网络驱动程序 INF 文件中, UpperRange 条目列出了可能的上限绑定, LowerRange 条目列出了可能的较低绑定。 这些条目可以包含各种系统定义的值。
对于Filter驱动程序,必须将 UpperRange 和 LowerRange 条目的值分别设置为 noupper 和 nolower。 以下示例演示了Filter驱动程序的这些 INF 文件条目。
HKR, Ndi\Interfaces,UpperRange,,"noupper"
HKR, Ndi\Interfaces,LowerRange,,"nolower"
在Filter驱动程序中,Filter INF 文件中的 FilterMediaTypes 条目定义驱动程序与其他驱动程序的绑定。 FilterMediaTypes 指定筛选驱动程序服务的媒体类型。 以下示例演示了 Filter驱动程序的 FilterMediaTypes 条目。
HKR, Ndi\Interfaces, FilterMediaTypes,,"ethernet"
当计算机加载Filter驱动程序时,驱动程序将插入到所有现有的协议到适配器绑定中,具体取决于 FilterMediaTypes 列出的媒体类型。
注意: 在某些版本上,Filter驱动存在个数限制。
访问Filter驱动程序的配置信息
NDIS 支持一组函数,这些函数提供对Filter驱动程序注册表参数的访问权限。 Filter驱动程序可以在附加或重启操作期间或在处理即插即用 (PnP) 通知时访问这些参数。
Filter驱动程序调用 NdisOpenConfigurationEx 函数来访问注册表设置。 如果Filter驱动程序通过调用 NdisFRegisterFilterDriver 函数获取了 NDIS_CONFIGURATION_OBJECT 结构的 NdisHandle 成员中的句柄,则 NdisOpenConfigurationEx 函数将提供存储Filter驱动程序配置参数的注册表位置的句柄。 Filter驱动程序可以使用配置句柄,直到调用 NdisFDeregisterFilterDriver 函数。
如果Filter驱动程序从 FilterAttach 函数的 NdisFilterHandle 参数中获取了 NdisHandle 中的句柄,则 NdisOpenConfigurationEx 提供存储Filter模块配置参数的注册表位置的句柄。 Filter驱动程序可以使用配置句柄,直到 NDIS 分离Filter模块并且 FilterDetach 函数返回。 如果监视Filter驱动程序在 NDIS_CONFIGURATION_OBJECT 结构的 Flags 成员中指定 NDIS_CONFIG_FLAG_FILTER_INSTANCE_CONFIGURATION 标志,则当在同一微型端口适配器上配置多个Filter模块时,驱动程序可以访问特定Filter模块的Filter模块配置。 修改Filter驱动程序不得使用此标志。
驱动程序访问配置信息后,驱动程序必须调用 NdisCloseConfiguration 函数来释放配置句柄和相关资源。
下面是系统默认生成的Filter inf文件
;-------------------------------------------------------------------------
; ndislwf1.INF -- NDIS LightWeight Filter Driver
;
; TODO: Search for comments marked "TODO:", and follow their instructions to
; customize this INF for your driver. Then delete the "TODO:" comments.
;-------------------------------------------------------------------------[version]
; Do not change these values
Signature = "$Windows NT$"
Class = NetService
ClassGUID = {4D36E974-E325-11CE-BFC1-08002BE10318}
; TODO: Customize this string for your company name
Provider = %Msft%
DriverVer =
CatalogFile = ndislwf1.cat; TODO: Include each architecture for which your driver package contains a
; compiled binary. If you do not supply a driver compiled for ia64, delete the
; NTia64 section.
[Manufacturer]
%Msft%=MSFT,NTx86,NTia64,NTamd64,NTarm,NTarm64; MS_ndislwf1 can be used with netcfg.exe to install/uninstall the driver.
[MSFT.NTx86]
%ndislwf1_Desc%=Install, MS_ndislwf1[MSFT.NTia64]
%ndislwf1_Desc%=Install, MS_ndislwf1[MSFT.NTamd64]
%ndislwf1_Desc%=Install, MS_ndislwf1[MSFT.NTarm]
%ndislwf1_Desc%=Install, MS_ndislwf1[MSFT.NTarm64]
%ndislwf1_Desc%=Install, MS_ndislwf1;-------------------------------------------------------------------------
; Installation Section
;-------------------------------------------------------------------------
[Install]
AddReg=Inst_Ndi
; All LWFs must include the 0x40000 bit (NCF_LW_FILTER). Unlike miniports, you
; don't usually need to customize this value.
Characteristics=0x40000; This must be a random, unique value.
; FILTER_UNIQUE_NAME in filter.h must match this GUID identically.
; Both should have {curly braces}.
NetCfgInstanceId="{76610a0d-1aed-494e-84c8-9661e499deee}"Copyfiles = ndislwf1.copyfiles.sys[SourceDisksNames]
1=%ndislwf1_Desc%,"",,[SourceDisksFiles]
; TODO: Include any related files that should be installed with your driver.
ndislwf1.sys=1[DestinationDirs]
DefaultDestDir=12
ndislwf1.copyfiles.sys=12[ndislwf1.copyfiles.sys]
ndislwf1.sys,,,2;-------------------------------------------------------------------------
; Ndi installation support
;-------------------------------------------------------------------------
[Inst_Ndi]
HKR, Ndi,Service,,"ndislwf1"
HKR, Ndi,CoServices,0x00010000,"ndislwf1"
HKR, Ndi,HelpText,,%ndislwf1_HelpText%
; TODO: Set the FilterClass here. The FilterClass controls the order in which
; filters are bound to the underlying miniport. Possible options include:
; Custom, Diagnostic, Failover, Loadbalance, Vpn, Compression, Encryption, Scheduler
; See MSDN for a description of each.
HKR, Ndi,FilterClass,, compression
; TODO: Specify whether you have a Modifying or Monitoring filter.
; 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
; Do not change these values
HKR, Ndi\Interfaces,UpperRange,,"noupper"
HKR, Ndi\Interfaces,LowerRange,,"nolower"
; 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, wan, ppip"
; TODO: Specify whether you have a Mandatory or Optional filter.
; 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, 1 ; Mandatory filter;-------------------------------------------------------------------------
; Service installation support
;-------------------------------------------------------------------------
[Install.Services]
; TODO: You may want to add the SPSVCINST_STARTSERVICE flag, like this:
; AddService=ndislwf1,0x800,ndislwf1_Service_Inst ; SPSVCINST_STARTSERVICE
AddService=ndislwf1,,ndislwf1_Service_Inst[ndislwf1_Service_Inst]
DisplayName = %ndislwf1_Desc%
ServiceType = 1 ;SERVICE_KERNEL_DRIVER
; Typically you will want your filter driver to start with SERVICE_SYSTEM_START.
; If it is an Optional filter, you may also use 3;SERVICE_DEMAND_START.
StartType = 1 ;SERVICE_SYSTEM_START
ErrorControl = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary = %12%\ndislwf1.sys
LoadOrderGroup = NDIS
Description = %ndislwf1_Desc%
AddReg = Common.Params.reg, NdisImPlatformBindingOptions.reg[Install.Remove.Services]
; The SPSVCINST_STOPSERVICE flag instructs SCM to stop the NT service
; before uninstalling the driver.
DelService=ndislwf1,0x200 ; SPSVCINST_STOPSERVICE[Common.Params.reg]
; TODO: You can add any sort of NDIS parameters here. Filter drivers
; don't always need NDIS parameters, so it's okay to have nothing here.; TODO: Remove the sample parameters below.; Sample 1: "DriverParam" is a per-driver parameter.
HKR, FilterDriverParams\DriverParam, ParamDesc, , "Driverparam for lwf"
HKR, FilterDriverParams\DriverParam, default, , "5"
HKR, FilterDriverParams\DriverParam, type, , "int"; Sample 2: "AdapterParam" is a per-module parameter.
HKR, FilterAdapterParams\AdapterParam, ParamDesc, , "Adapterparam for lwf"
HKR, FilterAdapterParams\AdapterParam, default, , "10"
HKR, FilterAdapterParams\AdapterParam, type, , "int"[NdisImPlatformBindingOptions.reg]
; By default, when an LBFO team or Bridge is created, all filters will be
; unbound from the underlying members and bound to the TNic(s). This keyword
; allows a component to opt out of the default behavior
; To prevent binding this filter to the TNic(s):
; HKR, Parameters, NdisImPlatformBindingOptions,0x00010001,1 ; Do not bind to TNic
; To prevent unbinding this filter from underlying members:
; HKR, Parameters, NdisImPlatformBindingOptions,0x00010001,2 ; Do not unbind from Members
; To prevent both binding to TNic and unbinding from members:
; HKR, Parameters, NdisImPlatformBindingOptions,0x00010001,3 ; Do not bind to TNic or unbind from Members
HKR, Parameters, NdisImPlatformBindingOptions,0x00010001,0 ; Subscribe to default behavior[Strings]
; TODO: Customize these strings.
Msft = "<Your manufacturer name>" ;TODO: Replace with your manufacturer name
ndislwf1_Desc = "ndislwf1 NDIS LightWeight Filter"
ndislwf1_HelpText = "ndislwf1 NDIS LightWeight Filter"