2024年3月10日发(作者:)

s etD e s 

李朝中 囊 | |编写贪缀l 

摘 要:Filter Drivers提供了针对微端口驱动(Miniport Drivers)的过滤服务(filtering service), 

NDIS驱动栈上必须包含微端口驱动(Miniport Drivers)和协议驱动(Protocol Drivers),而对 

Filter Drivers的包含是可选的。可以用它实现基于网络数据包过滤流量、统计监视等功能。 

关键词:NDIS:Filter Drivers 

表1 

1 安装NDIS Filter Drivers 

这一节主要介绍如何安装NDIS Filter Driver的信息。 

Filter Driver安装不同于中间层过滤驱动.Filter Driver需要被 

安装成自启动的服务,这类似于协议驱动。对于每一个微端 

El适配器(Miniport Adapter)为NDIS提供一个Filter Module 

的列表。但Filter Driver不像中间层过滤驱动那样联结一个虚 

拟设备。 

要安装一个Filter Driver需要提供一个INF的配置文件。 

一 

值 描述 

ethernet 下边缘是一个Ethernet adapter 

atm 下边缘是一个ATM adapter 

tokenring 下边缘是一个token ring adapter 

serial 下边缘是一个serial adapter 

配置管理器从这个配置文件中读取相关的配置信息并复制到 

注册表。与此不同的是中间层过滤驱动.它有两个配置文件 

fddi 下边缘是一个FDDI adapter 

baseband 下边缘是一个baseband adapter 

broadband 下边缘是一个broadband adapter 

arcnet 

isdn 

下边缘是一个Arcnet adapter 

下边缘是一个ISDN adapter 

个提供上边缘协议驱动的接口配置信息,另一个提供下边 

缘虚拟微端口驱动的接口配置信息。Filter Driver的INF配 

置文件类似于中间层过滤驱动的协议INF配置文件 

(Prolocol INF File),它没有微端口INF配置文件(Miniport 

INF File)。下面将介绍如何为一个Filter Driver生成一个INF 

文件。 

locahalk 下边缘是一个LocalTalk adapter 

1.1 指定Filter Driver的绑定关系 

在一个网络驱动的INF文件中。需要在UpperRanget条目 

列出可能的上边缘绑定和LowerRange条目列出可能的上边缘 

下边缘是一个WAN adapter 

nolower 不对任何组件执行下边缘绑定 

rndis5 下边缘为NDIS 5.x及之前的任一网络部件.都是非ATM网络部件 

绑定。这些条目包含的值都是系统预定义的。 

对Filter Driver来说.必须设置UpperRange和LowerRange 

条目分别为noupper和nolower。下面示例了一个Filter Driver 

的INF文件的条目。 

HKR,NdNnterfaces,UpperRange noupper' 

Ndisarm 下边缘为ND1S 5.x及之前的任一网络部件.都是ATM网络部件 

an 下边缘是一个native 802.11 wireless LAN adapter. 

HKR,Ndhlnterfaces,LowerRangelIHnolower" 

在一个Filter Driver的INF文件中FilterMediaTypes条目用 

当计算机加载一个Filter Driver时,Filter Driver会被插入 

到已经存在的协议适配器的绑定上(Protocol—to—Adapter 

于定义Filter Driver要绑定的驱动服务的媒体类型。下面列出 

在一个Filter Driver的INF文件中的FiherMediaTypes定义及 

FilterMediaTypes可取值的列表,如表1所示。 

HKR,NdNnterfaces.?FilterMediaTypes,,"ethemet" 

Banding),这时就依赖FilterMediaTypes提供一个列表来决定插 

入到哪些协议到适配器的绑定上。 

1.2 Filter Driver的INF文件设置 

个Filter Driver的INF设置指定了它的特性.例如:可 

FiherMediaTypes可取值列表,它和LowerRange一样。 

以指定这个驱动是Modifying类型的还是Monitoring类型的,是 

赫螭 文 

…I_ ” Il 、 J、 、 

实用第一 智慧密集 

强制加载的(Mandatory)还是呵选加载的(Optiona1)的。此 

处,在INF文件中还可以指定Filter Driver的FiherModule的通 

用配置参数和其他有具体微端口适配口相关联的细节信息。 

Filter Drivr还要指定一个唯一的过滤器识别GUID(这个ID需 

要自己生成,可以用VS中自带GUID牛成器来生成) 

1_2.1 Monitoring Filter Driver的INF文件配置 

(1)设置INF文件的Class条目为NetService(同时要指定 

ClassGUID)下面是一个示例: 

Class:NetService 

ClassGUlD=(4D36E974一E325—11CE-BFC1-08002BE10318) 

(2)必须设置安装节的Characteristics条目为0x40000.下 

边示例一个设置: 

【Install】 

AddReg=lnst Ndi 

Characteristics=Ox4OO00 

NetCfglnstanceld=”{5cbf8 1 bd一5055—47cd一9055一 

a76b2b4e3697)” 

Copyfiles=NdisMon.copyfiles.sys 

Ox40000这个是指NCF—Lvv_FILTER集合,一个Filter Driver 

不能设置为NCF—FILTER(Ox400)这个标记 

(3)设置NetCfgInstanceId条目,这个Id必须和Filter 

Driver中渊用NdisFRegister lterDriver是指定Filter Driver的唯 

名保持一致 它可以用VS中自带GUID生成器来生成。下 

面示例这个条目的配置: 

IInstall】 

AddReg=lnst Ndi 

Characteristics=Ox4OOO0 

NetCfgInstanceId=”f5cbf81 bd一5055—47cd一9055一 

a76b2b4e3697)” 

Copyfiles=NdisMon copyfiles sys 

(4)一个安装节必须指定一个AddReg条目用于配置Ndi 

键的信息,在Ndi节下面必须指定驱动服务的名字: 

IInstall】 

AddReg=lnst Nd 

Characteristics:Ox4OOOO 

NetCfgInstanceId:“{5cbf81 bd一5055—47cd-9055一 

a76b2b4e3697)” 

Copyfiles=NdisMon.copyfiles.sys 

【InsLNdi】 

H KR,Ndi,ServiceI『¨NdisMon 

HKR,Ndi,CoServices,OxO001 0000,"NdisMon” 

HKR Ndi HelpText,,%NdisMon

HelpText% 

HKR,N FjIterCIass,,compression 

HKR.Ndi,FilterType,OxO001 0001,OxO000O002 

HKR,NdNnterfaces,UpperRange noupper'。 

HKR,Ndi\lnterfaces,LowerRange iinolower” 

HKR.Ndiklnterfaces,FilterMediaTypes iiethernet。。 

HKR,Ndi,FilterRunmype,OxO001 0001,1 

6 幽20勰1 2.幽13 豫 

(5)Filter Driver的安装节必须指定FiherType和FiherRun 

Type条目,下面示例r将Filter Driver配置为Monitoring且 

Mandatory的配置方法: 

fIns1:Ndi】 

H KR,Ndi,Service NdisMon。。 

HKR,Ndi,CoServices,OxO001 0000,"NdisMon 

HKR,Ndi,HelpText,,%NdisMon

——

HelpText% 

HKR Ndi FilterClass ,compression 

HKR,Ndi,FitterType.OxO001 0001,OxO0000001 

HKR,NdNnterfaces,UpperRange.,Hnoupper‘ ‘

H KR,NdNnterfaces,LowerRange nolower‘。 

HKR,NdNnterfaces,FilterMediaTypes,.“ethernet“ 

HKR.Ndi,FilterRunType,OxO001 0001,1 

FiherType为OxO0000001说是一个Monitoring类型的Filter 

Driver,FiherRunType为1是以Mandatory加载,为2是以 

Optional方式加载。 

(6)安装Filter Driver需要在系统中添加一个服务: 

【Instal1.Services】 

AddService=NdisMon,,NdisMon Service Inst 

【NdisMon S;ervice I nst1 

DisplayName:%NdisMon Desc% 

ServiceType=1;SERVICE KERNEL DRlVER 

StartType=1;SERVICE SYSTEM S1_ART 

ErrorControl=1;SERVICE ERR0R N0RMAL 

ServiceBinary=%1 2%\NdisMon.sys 

Load0rderGroup=NDIS 

Description=%NdisMon Desc% 

AddReg=Common.Params.reg 

(7)INF文件中要在CoService条目中为Filter Driver指定 

主服务名(即上一步创建的服务),下面示例: 

【Inst Ndi】 

HKR,Ndi,Service NdisMon” 

HKR,Ndi,CoServices,OxO001 0000,"NdisMon“ 

HKR,Ndi,HelpText %NdisMon

——

HelpText% 

HKR,Ndi,FilterClass,.compression 

HKR,Ndi,FilterType,OxO001 0001,OxO0000002 

HKR,NdNnterfaces,UpperRange noupper‘ 。

HKR,Ndi\lnterfaces,LowerRange,,iinolower” 

HKR,Ndiklnterfaces,FilterMediaTypesIJHethernet” 

HKR,Ndi FiIterRunType,OxO0010001,1 

(8)在INF文件中定FiherClass的值.指定Filter Driver 

在驱动栈上的顺序(位置),但是Monitoring的Filter Driver不 

必指定,它固定加载到离微端口适配口最近的位置。 

(9)必须为驱动指定绑定的信息: 

[1nst Ndi】 

HKR,Ndi,Service NdisMon” 

HKR,Ndi,CoServices OxO001 0000,"NdisMon。‘ 

HKR,Ndi,HelpText,,%NdisMon

_

HelpText% 

HKR,Ndi,FilterClass,,compression 

HKR,Ndi,FilterType,OxO0010001,OxO0000002 

HKR.NdNnterfaces,UpperRange iinoupper‘‘ 

HKR,NdNnterfaces,LowerRange nolower 

HKR.NdNnteffaces,FilterMediaTypes ethernet“ 

HKR,Ndi,FilterRunType,OxO001 0001,1 

(1O)这步可选是为Filter Driver指定通用参数,这些参 

数可以是与具体网络适配器相关的也可以是与具体实例(Filter 

Module)相关的.下面为示例: 

【Common.Params.reg】 

HKR.FilterDriverParams\d3riverParam, 

ParamDesc. , Driverparam for Mon" 

HKR,FilterDriverParamskDriverParam,defauIt, ,” 

HKR,FilterDriverParamskDriverParam,type,, int” 

HKR|FilterAdapterParamskAdapterParam ParamDesc 

”Adapterparam for Mon“ 

HKR,FilterAdapterParamskAdapterParam defau|t, ,” 

10” 

HKR,FilterAdapterParamskAdapterParam,type, 

“int 

HKR,FilterlnstanceParams\lnstanceParam,ParamDesc 

Instance param for 1wfIt 

HKR,FilterlnstanceParams\lnstanceParam,defaultl,”1 5“ 

HKR,FilterInstanceParamsklnstanceParam,type,,”lnt” 

1.2.2 Modifying Filter Driver的INF文件配置 

(1)设置INF文件的Class条目为NetService(同时要指 

定ClassGUID)下面是一个示例: 

Class:NetService 

ClassGUID={4D36E974"E325—1 1 CE_BFC1"08002BE10318) 

(2)必须设置安装节的Characteristics条目为0x40000,下 

边示例一个设置: 

【Install】 

AddReg=lnst Ndi 

Characteristics=Ox40000 

NetCfglnstanceldI=“{5cbf81 bd-5055-47cd一9055一 

a76b2b4e3697)” 

Copyfiles=NdisMon. copyfiles.sys 

Ox40000这个是指NCF

LW

FILTER集合,一个Filter 

Driver不能设置为NCF

FILTER(0x400)这个标记 

(3)设置NetCfgInstanceld条目,这个Id和Filter Driver中 

调用NdisFRegisterFilterDriver是指定Filter Driver的唯一名保持 

样。它可以用Uuidgent.exe来生成。下面示例这个条目的配 

置: 

【Insta I]} 

AddReg=lnst

_

Ndi 

Characteristics=Ox4OOO0 

NetCfglnstanceld= {5cbf81 bd一5055-47cd一9O55一 

a76b2b4e3697} 

Copyfiles=NdisMon.copyfiles.sys 

(4)一个安装节必须指定一个AddReg条目用于配置Ndi 

键的信息,在Ndi节下面必须指定服务名。下面是一个示例: 

【Install】 

AddReg=lnst_Ndj 

Characteristics=Ox4OOO0 

NetCfQInstanceld=”{5cbf81 bd一5055—47cd-9055一 

a76b2b4e3697}” 

Copyfiles=NdisMon.copyfiles.sys 

【Inst,Ndil 

HKR,Ndi,SeⅣic ,“NdisLw 

HKR,Ndi CoServices,OxO001O000,”NdisLwf” 

HKR,Ndi,HelpText %NdisLwLHelpText% 

HKR,Ndi,FilterClass,,compression 

HKR,Ndi,FilterType,OxO0010001,OxO0000002 

HKR NdNnterfaces,UpperRange,,”noupper 

HKR,NdRInterfaces,LowerRange,,”nolower“ 

HKR NdNnterfaces.FilterMediaTypes,,iiethernet 

HKR Ndi;FilterRunType,OxO001 0001,1 

(5) Filter Driver的安装节必须指定FiherType和FiherRu 

nType条目,下面示例了将Filter Driver配置为Monitoring且 

Mandatory的配置方法: 

【Inst_Ndil 

HKR,Ndi,Service,,,NdisLwf 

HKR,Nd CoServices OxO0010000."NdisLwf” 

HKR,Ndi,HelpText,,%NdisLwf HelpText% 

HKR,Ndi,FilterClass,,compression 

HKR,Ndi,FilterType,OxO0010001,OxO0000002 

HKR NdNnterfaces,UpperRange noupper 

HKR NdNnterfacesiLowerRange,,"nolower“ 

HKR,NdNnterfaces,FiIterMediaTypes ethernet“ 

HKR Ndi,FiltetRunType,0x00010001,1 

FilterType为OxO0000002说是一个Modifying类型的Filter 

Driver.FiherRunType为1是以Mandatory加载,为2是以 

Optiona[方式加载。 

(6)安装Filter Driver需要在系统中添加一个服务: 

nnsta Services] 

AddService=NdisLwfi,NdisLwt:Service

Inst 

【NdisLwf,Service_lnst1 

DisplayName %NdisLwf

_

Desc% 

ServiceType=1;SERVlCE_KERNEL—DRIVER 

StartType。1:SERVtCE

_

SYSTEM—START 

ErrorControI=1:SERVICE—ERROR

NORMAL 

ServiceBinary=%1 2%\NdisLwf.sys 

LoadOrderGroup=NDIS 

Description=%N sL ̄Desc% 

AddReg=Cornmon,Params,reg 

(7) INF文件中要在CoService条目中为Filter Driver指 

定主服务名(即上一步创建的服务),下面示例: 

【lnst l、.Idil 

HKR,Ndi,Service uN口I,sLwln 

HKR.Ndi,CoServices,OxO001 0000,”NdisLwf 

脯螭 丞 

I¨ …1I L I_ I_  、J 1 J 、 I= 

实用第一 智慧密集 

 ‘…  ^ 1q 

HKR,Ndi,HelpText %NdisLwf

_

HelpText% 

HKR,Ndi,FilterClass,,compression 

HKR,Ndi,FilterType,Ox0001 0001,0x00000002 

HKR,Ndi\lnterfaces,UpperRange nnoupper“ 

HKR,Ndi\lnterfaces,LowerRange nolower” 

HKR,NdNnterfaces,FilterMediaTypes,.nethernet。 

HKR,Ndi,FilterRunType,OxO0O10001,1 

(8)在INF文件中定FilterClass的值,指定Filter Driver 

在驱动栈J-的顺序(位置),Modifying类型的Filter Driver必 

须为它指定・个值。这个值丌j‘以是下面值中的一个,如表2 

所示 . 

表2 

描述 

分组渊度服务.这类的Filter Driver在驱动栈的最高层且在 

Encryt)tion之 它检测802.1p是的优先级信息同时给f【.质 

scheduler 虽服务的信令组件和发送数据包的调度级别

按照其优先级 

传到下层驱动 

Encryption 这类驱动存丁Scheduler和Compression之间 

Compression 这类驱动存丁Enctyption和Vpn之间 

Vpn 这类驱动存于Compression和load balance之问 

负载均衡过滤服务。这类驱动存T Vpn和Failover之问.一个 

Loadbalance 负载均衡的Fiher ver主要是均衡包传输到下层第一个微端 

l1适配器L的T作茸 

aihwer 

故障切换过滤服务 这类驱动存在于Loadbalance和 

Diagnostic之间 

Diagnostic 这类Fiher Driver存在于Fail—Over之下 

Custom 这类Filter Drivcr存在于J)iagnostie之下。 

注意:多个Modifying类型的Filter Driver可以存在于州 

个栈层I 。例如,两个Modifying类型的Filter Driver可以 

都指定FiherClassic为“scheduler”并存在于这个驱动栈的这 

个层』 。Filter Driver后安装的在先安装的下层,也就是说 

后安装的离微端口适配器最近。此外,多个具有相同类型 

Filter Driver在同一计算机』I不同微端口适配器上的顺序是相 

同的 

看下面的示例: 

【Inst—Ndi】 

HKR,Ndi,Service.,“NdisLwf“ 

HKR,Ndi CoServices,0x0001 0000,"NdisLwf“ 

HKR,Ndi,HelpText,,%NdisLwf

——

HelpText% 

H KR,Ndi FilterClass.,compression 

HKR,Ndi FilterType,OxO0010001,0x00000002 

HKR,Ndi\lnterfaces,UpperRange,,Unoupper” 

HKR,Ndklnterfaces,LowerRanger,¨nolower“ 

HKR,Ndklnterfaces,FilterMediaTypes ethernet“ 

HKR,Ndi.FilterRunType,Ox0001 0001,1 

8:之, 电 i/电 品与囊螽缡l幢醢巧与罐 

(9)必须为Filter指定绑定的信息: 

fInst Ndil 

HKR,Ndi,Service r,¨NdisLwf” 

HKR,Ndi,CoServices,0x0001 0000,"NdisLIvvf“ 

HKR Ndi.HelpText %NdisLwf

HeIpText% 

H KR,Ndi,FilterClass,,compression 

HKR,Ndi,FilterType,0xO0010001,0x00000002 

H KR,NdNnterfaces,UpperRangeI,¨noupper“ 

HKR,Ndi\lnterfaces,LowerRange nolower。‘ 

H KR,NdRInterfaces,FilterMediaTypesI,¨ethernet” 

HKR,Ndi,FilterRunType 0x0001 0001,1 

(10)这步可选它是为Filter Driver指定通用参数,这些 

参数可以是与具体网络适配器相关的也可以是与具体实例 

(Filter Module)相关的: 

【Common.Params.reg】 

HKR,FilterDriverParams ̄d3riverParam, 

ParamDesc, ,‘。Driverparam for Lwf” 

HKR,FilterDriverParamskDriverParam,default.,”5“ 

HKR,FilterDriverParams\DriverParam,type,.。‘int” 

HKR,FilterAdapterParams' ̄dapterParam, 

ParamDesc. ,"Adapterparam for Lwf 

H KR,FilterAdapterParamskAdapterParam,default,,“1 0“ 

HKR,FilterAdapterParams ̄dapterParam,type, 

。’int“ 

HKR,FilterlnstanceParams\lnstanceParam ParamDesc,,” 

Instance param for 1wf 

HKR,FilterlnstanceParams\lnstanceParam,default,, 1 5“ 

HKR,FilterlnstanceParams\lnstanceParam,type,,”int“ 

1.3 Filter Driver访问配置信息 

NDIS支持一个函数集合用来访问Filter Driver的注册表参 

数。Filter Driver町以在附加和重启操作时或接收到PnP和电 

源管理通知事件时访问这 参数: 

NDIS STATUS 

NdisOpenConfigurati0nEx( 

IN PNDIS

CONFlGURATION

OBJECT ConfigObject, 

0UT PNDIS HANDLE COnf guratiOnHandle 

): 

过滤驱动可以通过调用NdisOpenConfigurationEx来访问注 

册表设置。调用NdisFRegisterFiherDriver时会获得一个句柄, 

如果用这个句柄初始化NDIS

CONFIGURATION

OBJECT结构 

的NdisHandle成员并调用NdisOpenConfigurationEx可以得到一 

个标识参数存储点的注册表句柄。Filter Driver n 以使川这个 

句柄一直到NdisDeregisterFiherDriver调用。 

如果用FiherAttech中系统传来的句柄来初始化NdisHandle 

成员那么调用NdisOpenConfigurationEx得到的就是Filter 

Module的配置存储点。获得的这个句柄到FiherDetach调用完 

成就失效了。当有多个Filter Module配置在相同的微端口适配 

器卜时.如果Monitoring类型的Filter Driver设置 

NDIS

C0NFIGURA,n0N

OBJECT的Flags值为NDIS—CONFIG_ 

FLAGFILTER INSTANCE

CONFIGURATION,这样驱动就可 

以访问特定的Filter Module配置信息。但是Modifying类型的 

Filter Driver不能应用这个标记。 

个Filter Driver在访问过配置信息后一定要用 

NdisClosConfiguration关闭配置句柄和相关的资源。 

2实现过程 

2.1 NET

_

BUFFER体系结构 

2.1.1网络数据结构 

网络数据由在网络上发送和接收的数据包组成。NDIS提 

供了数据结构来描述它们,NDIS 6.0提供了如下数据结构: 

(1) NE r_BUFFER 

(2)NET_BUFFER LIST 

(3)NET_BUFFER_LIST

CONTEXT 

图l说明了这些结构之间的关系。 

NBL C=NETBUFFERLI吼 CONTEXT 

NBI;NETBUFFERLIST 

NB=NET BUFFER 

图1 

在NDIS 6.0中,NET

_

BUFFER是封闭网络数据的基本构 

建块。每一个NET_BUFFER都有一个MDL链。这些MDL映 

射的缓冲区地址是NET_BUFFER指定的数据空间。这种数据 

映射同NDIS 5.X及之前的版本使用的NDIS

_

PACKET中的映 

射是一样的。NDIS提供函数来管理这些MDL链。 

多个NET_BUFFER可以被附加到(可以被串到)一个 

NET

BUFFER

LIS上。这些NET-BUFFER被组织成一个以 

NULL结束的单链表。驱动或NDIS仅创建一个 

NET_BUFFER_LIST.应该修改它的链表给它插入或删除一些 

Nl T_BUFFER结构。 

NET_BUFFER_LIST结构中包含的信息中描述了所有被串 

到一个链表上的NET_BUFFER结构。如果NET

_

BUFFER

_

LIST 

需要上下文信息,可以分配额外的空间来存储一个 

NET

_

BUFFER

_

LIST

CONTEXT结构。NDIS提供函数来分配、 

访问NET

BUFFER

LIST

CONTEXT中的数据。 

多个NET-BUFFER

_

LIST结构可以串成一个NET_BUFFER 

LIST链表。它们可以被组织成一个以NULL结尾的单向链表。 

驱动可以对这个链表直接进行插入、删除操作。 

2.1.1.1 NE丁BUFFER结构 

NDIS 6.0中使用的NETBUFFER结构相似于NDIS 5.X以 

前使用的NDIS_PACKET结构,每一个NET_BUFFER结构中 

都包装了一个网络数据包。 

图2显示了NET

_

BUFFER的各个域。 

BUFFF.R NET 辟 ¨融 R 髓T BUFFER,,DATA 

图2 

NET_BUFFER结构包含一个NetBufferHeader成员它是一 

个NET_BUFFER_HEADER结构。这个成员又包含一个 

NET_BUFFER—DATA结构的NetBufferData成员。应该用NDIS 

提供宏和相关函数来访问NET_BUFFER结构。下面是相关宏 

的列表: 

NET BUFFER NEXT NB 

NET BUFFER 

FIR 

S下MDL

ZBUFFER_DA, OFFSET 

NET

_

BUFFER

_

DATA

LENGTH 

NET_BUFFER

_

PROTOCOL

RESERVED 

N ET

_

BUFFER

_

MINIPORT

_

1RESERVED 

NET

_

BUFFER_CHECKSUMLBIAS 

NELBUFFER_cURRENT_MDL 

NET BUFF日R_CURRENT

_

MDL

_

OFFSET 

NdisGetPootFromNetBuffer 

NET

BUFFER中的一些成员仅仅被NDIS使用.下面列出 

些编写驱动中常会用到的成员。 

l_I螭 淼 

| … … 。。 ” ” … 一 。、… 

实用第一 智慧密集 

.. . . …  .… … .. 一 … 

ProtocolReserved 

NDIS提供了一个系列的函数来访问这些在MDL链中的数 

据。有些时候一 数据空间对当前驱动来说是未使用的.虽然 它是为协议驱动保留的。 (也可以理解为是为一个发送包 

的引发者保留的) 

MiniportReserved 

是未使用的但也可能包含了有效的数据。例如.在一些应用中 

的接收路径中这个未使用的空间可能包含有下层驱动使用的头 

它是为微端口驱动保留的。 (也可以理解为是为一个接收 

指示的引发者保留的) 

NdisPoolHandle 

信息。 

驱动使用Retreat和Advance操作来减少和增加使用的数 

据空间。更多关于这方面的信息可在“Retreat和Advance操 

~『  甚上一 ~ 

它指示了NET

BUFFER结构是从哪一个NET

BUFFER池 

_

作”小节看到。 

里分配的. .

Next 

以一个NET BUFFER链表中它是指向下一个 

NET

_

BUFFER结构的指针。如果它是最后个元素,那么它的 

这个成员为NULL。 

DataLength 

它指明r网络数据在MDL链中的长度,长度以字节为单 

位。 

Data0ffset 

它表示的是从MDL链所描述的缓冲区的开始位置到网络 

数据(当前驱动要使用的数据)开始位置之间的偏移。它以字 

节为单位。 

CurrentMdl 

它是一个指向当前驱动在MDL链中要使用的第一个MDL 

的指针。它是NDIS提供的一个优化(跳任何驱动不使用的 

MDL直接到驱动要使用的第一个MDL)。 

CurrentMdlOffset 

它是一个从CurrentMdl指向MDL所描述的地址空间的开 

始位置到网络数据(当前驱动要使用的数据)开始位置之间的 

偏移。它以字节为单位。 

各数据成员关系图,如图3所示。 

图3 

电 鑫 与雉 

下列术语和定义描述T NET

BUFFER的数据空间中的元素。 

Used Data Space 

这里包含了当前驱动当前时间可以使用的数据窄间.要增 

加使用的空间可以执行Retreat操作,要减少使用的守间可以 

执行Advance操作。 

Unused Data Space 

当前驱动当前时间不使用的数据空间。 

Total Data Size 

这是当前Used Data Space和Unused Data Space空间大小 

的和。如果要计算这个总的空间大小就把DataOffset和 

DataLength两个成员相加就可得到。 

Retreat 

这是一个增加使用空间的操作。 

Advance 

这是一个减少使用空间的操作。 

2.1.1.2 NET

BUFFER LIST结构 

个NET BUFFER

LIST结构中包装了一个NET

BUFFER 

的单向链表。下面展示NET

BUFFER

LIST巾的各个域.如图 

4所示 

图4 

在NET_BUFFER LIST结构中包含一个NET_BUFFER

LIS 

HEADER的NetBufferListHeader成员,这个成员里包含一个 

NET

_

BUFFERLIST

_

DATA的NetBufferListData的子成员。应 

该使用NDIS提供的宏和函数来访问这些成员,下面列出这些 

宏和函数: 

NET BUFFER

LIST_NEXT_NBL 

NET

_

BUFFER

LIST

_

FIRST

_

NB 

NET

_

BUFFER_LIST

FLAGS 

NET

_

BUFFER

_

LIST_MlNIPORT_RESERVED 

NET

_

BUFFER

LIST

_

CONTE)(1 DATA START 

NELBUFFER_LIST_CONTEXT_DATA_SIZE 

NET BUFFER

_

LIST}NFO 

NET

_

BUFFER—LIST

_

S1 ATUS 

Nf厂_BUFFER—LIS厂.PROTOCOL_RESERVED 

NdisGetPoolFromNetBufferList 

在NET

BUFFER

_

LIST结构中大部分成员仅仅是NDIS来 

使用的。下面列出的成员是在编写驱动的时候最有可能用的一 

些成员。 

ParentNetBufferList 

如果一个NET BUFFER_LIST是一个从父结构派生(主要 

是指一个对结构做的克隆、分片、重组作操作)过来的一个子 

结构,那么它就指向父结构。其他情况下它为NULL。 

NdisPoolHandle 

分配结构时所用池的句柄。 

ProtocolReserved 

它是为协议驱动保留的。 (也可以理解为是为一个发送包 

的引发者保留的) 

MiniportReserved 

它是为微端El驱动保留的。 (也可以理解为是为一个接收 

指示的引发者保留的) 

SourceHandle 

它标识了分配这个NET-BUFFER—LIST的驱动。NDIS利 

用它来返回这个结构,不应该在驱动中读这个句柄。 

ChildRefCount 

如果结构是一个父结构,它代表着它有几个子结构。其他 

情况下为0。 

Flags 

保留给NET BUFFER_LIST未来标识属性用的,目前版本 

没有相关的属性规范。 

Status 

标识一个网络操作的最终状态,如果微端口操作在完成发 

送后写这个状态返回给上层发送操作的引发者。 

NetBufferListlnfo 

是关于NET-BUFFER_LIST结构的信息.这个些信息通常 

是链表中的所有NET_BUFFER的信息。 

Next 

在一个NET_BUFFER

_

LIST链表中它是指向一个结构的指 

针,如果它是最后一个元素,那么Next为NULL。 

FirstNetBuffer 

它指向一个联结在NET

BUFFER

LIST上的NET_BUFFER 

链表的第一个元素。 

注意:Context成员是指一个NET_BUFFER

HsT-CONTE 

XT结构的,NDIS提供宏和函数来维护这个结构,下面列出这 

些宏和函数。 

NdisAllocateNetBufferListContext 

NdisFreeNetBufferListContext 

NET-BUFFERj』ST—C0N IEX LDATA_sTART 

NET BUFFER

_

LISIr_C0NTEXT_DATA SIZE 

2.1.1.3 NET BUFFER LIST CONTEXT结构 

NDIS使用NET

BUFFERHST

CONTEXT结构来为所联结 

的NET_BUFFER

_

LIST存储一些附加数据。NET_BUFFER—LIST 

的Context成员指一个NET_BUFFER_LIST_CONTEXT结构.这 

个结构存储的信息对NDIS和栈上的其他驱动是不透明的。结 

构的各个域,如图5所示。 

 }Nell 

} 

0 

C 啊 l£’甜斯 

图5 

这个结构的ContextData成员包含了环境信息,这个环境 

信息可以是NET_BUFFER_LIST所需要的任何信息。应该使 

用下面的宏和函数来维护NET

BUFFER

_

LIST

CONTEXT中的 

成员: 

NdisAIIocateNetBufferListContext 

NdisFreeNetBuffer stContext 

NET_BUFFERLLIS ̄CONTEXT_DATA_START 

NET_BUFFER

_

LIS 

SONTE DATA_SIZE 

2.1.2发送和接收操作 

在一次函数调用中.NDIS6.0驱动可以发送多个 

NET_BUFFER_LIST。而每一个NET_BUFFER_LIST都可以是 

多个NET_BUFFER。同样可以一次指示完成多个这样的 

NET

_

BUFFERjJJST。 

在接收路径中.微端口驱动可以用NET_BUFFER

LIST指 

示一个接收。每一个被微端口驱动指示的NET_BUFFER_LIST 

中包含一个NET-BUFFER。但是本地802.11驱动可以包含多 

个NET

BUFFER结构。因为不同的协议绑定可以处理每一个 

NET-BUFFER_LIST.而NDIS也可以独立地返回每一个 

NET_BUFFER_UST给微端口驱动。 

 :

… … …… …… “… ” ” … … 

实用第一 智慧密集 

、 

.…  ... … … … 

对于NDIS5.X和更早的版本,NDIS在基于NDIS_PACKET 

和基于NET BUFFER之间提供了一个转换层(用于做两者的 

协议驱动要用调用Ndis0penAd印terEx时NDIS提供的 

NdisBindingHand1e来设置NET

BUFFER

LIST的SourceHandle 

兼容转换)。NDIS在其中进行两者的转换。要避免性能下降就 

应该在所有路径上支持NET BUFFER结构和NET_BUFFER—LI 

成员 NDIS使用这个成员返回协议驱动发送的 

_

NET

BUFFER

LIST结构。 

ST结构(即应用新的NDIS接口模式)。 

2.1-2.1发送数据 

中间层驱动也需要设置这个NET_BUFFER_LIST结构中的 

SourceHandle成员为自己调用Ndis0penAdapterEx时返[口I的 

NdisBindingHand1e。 如

发送操作的图示,如图6所示,它包含协议驱动,NDIS 

果中间层驱动转发一个 

和微端口驱动。 

#i髓0艚Ddwr 

s ̄ndNetBufferLists 

| 断t8 4 橼嘲 ‰r 8 

∽㈣ 轴 #牡 婚8 

鲰槲貅 静嘶t ¨弹 辫C 脚0 0 

0锚 8。4 蛐4 心{ | ’ 翳嗡弛 

图6 

议 动在一个绑定中调用NdisSendNetBufierLists发送一 

个NET BUFFER LIST结构 NDIS调用MiniportSendNetBuffer 

Lists将这个NET

BUFFER

LIST结构传递给下层驱动程序。 

所有基于NET BUFFER的发送操作都是异步的,微端口 

骆动凋用NdisMSendNetBufferListsComplete返回一个NET

BUF 

FER LIST并返同一个适当的状态 每一个被发送的 

NET BUFFER

LIST结构都可以被独立地完成。微端口驱动每 

次调刖NdisMSelldNetBufferListsComplete时,NDIS都会去调 

用协议驱动的ProtocolSendNetBufferListsComplete例程。 

当NDIS调用用协议驱动的ProtocolSendNetBufferListsComp 

lete时.协议驱动可以收回对NET_BUFFER_LIST及它所联结 

NET BUFFER及其他资源的所有权。 

微端口驱动和NDIS返回NET_BUFFER_LIST的顺序是不 

确定的(并不一定按发送的顺序来)。在这个期间协议驱动 

应该保证与NET

_

BUFFER

_

LIST相联结的NETBUFFER不被 

修改 

任何NDIS驱动都可以解除NET_BUFFER与 

NETBUFFER

_

LIST的关系,也可以解除NET BUFFER与 

MDL的关系统(就是说可以在发送路径上对数据包做修改), 

但是必须返回原来的NET_BUFFER_LIST(做了修改当完成后 

返回给上层时要返回原来那个NET_BUFFER_LIST)。例如,一 

个中间层驱动可以把一个NET_BUFFER_LIST分解成两个 

NET

_

BUFFER

LIST发送给下层驱动。但是当这两个 

NET

BUFFER

_

LIST发送完成后必须向上层返回 

NET BUFFER

HST时必须返回原来(要求NET_BUFFER及相 

关MDL都要和原来的一样)的那个NET

BUFFER LIST(中间 

层驱动直接产生的NET_BUFFER—LIST不能返回给E层驱动)。 

、 1 电  .电 j20jjI鼻1鑫 与趣疆玛与蛾 蛾 %j《;  

NETBUFI ̄’ER

HST要在设置它的SourceHandle之前保存¨L层 

驱动设置的SourceHandle。并在转发完成后恢复原尤的 

SourceHandle后返回给上层驱动。 

2.1.2.2取消发送 

图7示例中是一个取消发送操作的过程。 

^搠树口0 Drlv ̄ 

图7 

驱动可以调.Hj NDIS SET NET BUFFER LIST CANCEL ID 

给每一个要传输到下层驱动的NET BUFFER

LIST设置一个取 

消ID。 

在分配取消ID时应该先调用NdisGeneratePartialCancelId 

获得取消ID的最高位字节。这是为了保证系统在任意两个驱 

动的取消ID不相同。典型的用法是在DriverEntry中调用它一 

次来获得取消ID的最高字节.但是也可以存不同的地方调用 

多次获得多个取消ID的最高字节。 

要取消一个未完成的发送操作,驱动可以通过取消ID来 

调用过NdisCancelSendNetBufierLists函数(它其中一个参数是 

要取消的发送NET-BUFFER LIST被设置的取消ID)。驱动可 

以用NDIS

GET

NET

BUFFERLIST

CANCELID获得NET_B 

_

UFFER LIST的取消ID。 

如果驱动对所有发送的NET

_

BUFFER

HST设置相同的取 

消ID,那么只要一次取消调用就会取消所有的发送。对一组 

NE|r_BUFFER—UST设置相同的取消ID对这个取消ID的一次 

取消调用则会取消这一组的发送。 

NDIS会调用在绑定上的适合低层驱动的 

MiniportCancelSend.取消正在进行的传输后.微端n驱动渊用 

NdisMSendNetBufferListsComplete返回NET BUFFER UST和一 

个NDIS

STATUS

CANCELLED状态。NDIS会调用适合驱动的 

… 

FOLLOW啊^STER PR0B矗^啊…………………………… …………………………一…… …… … … 一 ……… 

PotocolSendNetBufferListsComplete函数。在这个函数中回收资 

源时应该设置相关NET_BUFFER_LIST的取消ID为NULL,防 

止它再次被使用时出现问题。 

2.1.2.3接收数据 

图8示例是基于一个接收操作的,包括微端口驱动、NDIS 

和协议驱动。 

铆o! ̄olDrlve ̄ 删t|}刚 

图8 

微端口驱动可以调用NdisMIndicateReceiveNetBufferLists来 

给上层驱动指示数据。这些数据组NET_BUFFER

_

HST来组 

织。协议驱动接收到NET_BUFFER_LIST后可以对它进行修改 

转发给客户端。同样的驱动也可以附加更多附加信息在 

NET

_

BUFFER

_

LIST中。 

可以把所有要指示给上层驱动的NET BUFFER UST链接 

到一起通过NdisMIndicateReeeiveNetBufferLists来指示给上层驱 

动。NDIS会校验这些NET_BUFFER_LIST结构并调用每一个 

绑定协议驱动的ProtocolReceiveNetBufferLists。NDIS仅仅把 

NET_BUFFER—UST传递给那些正确有绑定了的协议驱动。同 

时会匹配NET

BUFFER

LIST中NetBufferListFrameType(协议 

驱动在注册是会注册相应该的帧类型与之匹配后NDIS才转发 

给它)来确定转发给某个协议驱动。 

如果设置了给ReceiveFlag设置了NDIS

RECEIVE

FLAGS 

RESOURCES标记,它会传递给上层的协议驱动。NDIS会在 

协议驱动的ProtocolReceiveNetBufferLis 

ts调用返回后收回资源(传给协议驱动的NET_BUFFER_LIST 

及与之关联的所有资源)的所有权。 

注意:如果设置了这个标记上层驱动应该尽快处理返回资 

源给下层驱动。同时在返回时要恢复对资源的修改。例如,一 

个收如此标记的上层驱动,可以对NET

_

BUFFER

_

LIST及相关 

资源进行修改,但返回NDIS进要确保NET_BUFFER LIST是 

原始的内容(这里主要指资源本身,如果其中的 

NET

_

BUFFER链,及NET_BUFFER中的MDL链。而其中的数 

据内容则不必要恢复原始中)。 

如果没有设置这个标记那么协议驱动则持有对这个 

NET

_

BUFFER

_

LIST的所有权。协议驱动可以对它进行排队延 

后处理(注意,如果传递了标记则必须在函数内完成处理,因 

为函数返回后这个NET BUFFER LIST不用属于协议驱动了)。 

在这种情况下协议驱动必须调用NdisReturnNetBufferLists来返 

还资源给下层驱动。 

如果下层的微端口驱动运行在低资源情况下 可以在指示 

数据给上层时传递这个标记。这个微端口驱动就可以在指示结 

束后恢复所有指示所用资源的所有权。 

当协议驱动调用NdisReturnNetBufferLists后NDIS会调用 

微端口驱动的MiniportRetrunNetBufferLists例程。 

注意:如果一个微端口驱动指示数据给上层时传递了 

NDIS RECEIVE FLAGS RES0URCES标记那么NDIS将不会调 

用它的MiniportRetrunNetBufferLists。微端口对资源的所有权会 

在NdisMIndicateReceiveNetBufferLists返回时自动恢复。 

NDIS返回NET_BUFFER_LIST的顺序并不和微端口驱动 

调用NdisMIndicateReeeiveNetBufferLists的顺序一致,NDIS可 

以以任何顺序返回NET_BUFFER—LIST。 

微端口驱动在指示数据给上层时应该设置 

NETBUFFER

U 的SourceHandle成员。这个成员应该设置 

为NDIS在微端口驱动的MiniprotInitEx中传递的那个 

MiniprotAdapterHandle句柄。NDIS要利用这个成员返回 

NET_BUFFER_LIST结构微端口驱动。 

中间层驱动也要在指示数据给上层时应该设置 

NET-BUFFER_LIST的SourceHandle成员。这个成员应该设置 

为NDIS在中间层驱动的MiniprotInitEx中传递的那个 

MiniprotAdapterHandle句柄。如果要转发这个接收指示,驱动 

要保存下层驱动设置的SourceHandle值后再设置这个句柄为中 

间层驱动的。当NDIS返回NET_BUFFER_LIST给中间层驱动 

时.要重新恢复原来的SourceHandle值再调用 

NdisMRetumNetBufferLists返回给下层驱动。 

2.1.2.4 NDIS回环包 

如果NET

BUFFER

LIST的成员NblFlags设置了 

NDIS

NBULAGS—ISJ‘0OPBACK_PACKET标记,那说明这个 

包是一个回环包。协议驱动和Filter Driver可以检查这个标记 

判断这个包是不是回环包。 

回环包要被回传回来要满足下面3个条件: 

(1)下层微端口的类型必须是NdisMedium802—3或 

NdisMedium802

_

5。 

(2)下面3个条件之一必须满足: 

1)协议绑定设置了OID的OID

GEN

CURRENrr_PACKE 

_

FILTER请求设定了NDIS ACKET- rYPE_PROMISCUOUS 

标记或下面条件为真。 

①多个绑定到微端口驱动。 

②一个Filter Module附加到微端口并且注册了接收控 

制器。 

2)协议绑定设置了OID的OID

_

GEN

CURRENT-PACKE 

T FILTER请求设定了NDIS_PACKE邺PEALL LOCAL标记 

籀鳙淼 

一 …… ………… ……… …… …… ………… ………一 

实用第一 智慧密集 

… … … .  .. … … 

或下面条件为真。 (4)必须保证NET

BUFFER

LIST中的NET_BUFFER捕 

_

①多个绑定到微端u驱动。 

②一个Filter Module附加到微端口并且注册了接收控 

述的以太网帧是有相同源和目的MAC的。 

(5)如果发送的是TCP或UDP包,那么NET

BUFFER

_

制器. .

31调用者设置NdisSendNetBufferLists的SendFlags参数的 

NDIS

_

SENDFLAGSCHECKFOR

_

LOOPBACK标记。 

(3)包符合微端口的包过滤设置。例如: 

1)如果是一个直接包,它的目的MAC地址和微端口的 

MAC地址一样 

21 如果是一个多播包。微端口的过滤设置了 

NDIS

_

PACKE r.rrYPE—AU MULTICAST标记或目标地址匹配 

微端口的多播地址列表且端口的过滤设置了 

NDIS

PACKE 1 【TYPE

ALL

MULTICAST标记。 

31 如果是一个广播包.微端口的过滤设置了 

NDIS

PACKETJYPE—BROADCAST标记。 

4)微端口的过滤设置r NDIS

PACKE PE

_

PROMISC 

UOUS或NDIS

PACKE PE

ALLLOCAL标记。 

个协}义绑定要接收回环包要满足下面条件: 

(1)协议绑定是回环包原始发送者。 

(2)协议绑定小能设置NDIS—PACKETJYPE—NO—LOCAL 

过滤。 

个协议绑定不接收回环包要满足下面条件: 

(1)协议绑定设置了NDIS

PACKET_TYPE—NO—LOCAL 

过滤且协议绑定是回环包原始发送者。 

(2)协议绑定是原始发送者但没有不能设置SendFlags的 

NDISSENDFLAGSCHECKFOR

LOOPBACK标记。 

下面图9显示了回环包的运算逻辑。 

2.1.3以太网发送和接收操作 

2.1.3.1发送以太网帧 

Windows Vista的TCPflP协议支持对一组以太网帧的发送。 

任何引发发送或修改发送的f 层驱动都必须遵循TCP仃P协议 

规范. .

注意:如果任何 层驱动不遵循下面的规则那么下层的驱 

动的行为将不呵预测 

(1)如果要发送一个以太网帧必须分配一个NET_BUFFE 

LIST结构用于存放以太网帧。每一个NET BUFFER—LIST 

必须包含一个带外数据块(OOB),它被定义在 

NET BUFFER LIST是NetBufferListInfo成员中,被一些特殊处 

理使用。 

(2)如果要发送一个以太网帧必须为以太网帧分配一个 

或多个NET

BUFFER结构且链接到帧的NET_BUFFER_LIST 

结构中。 

(3)必须保证NET_BUFFER_LIST中的NET_BUFFER描 

述的是同一种类形的以太网帧。 

1  ̄

201

2.13 

-l l电奠鳙

与雄 ; 

LIST中的所有NETBUFFER必须是同一TCP或UDP链接的 

包。 

(6)不能把一个MAC头分别放在多个MDL中。如果这 

样做部分MAC头会被当成VLAN标记。 

(7)如果驱动改变了在NET_BUFFER中的MDL链或在 

NET

LIST中的NET_BUFFER

BUFFER

LIST则需要在返回 

NET

BUFFER-UsT给上层驱动之前时恢复原始的状态。但 

NET

BUFFER LIST之间的链接关系不需要和原来的一样(如 

果返回多个NET BUFFERLIST时)。 

图9 

…… 

FOLLOW啊ASTER PROG肌啊…………………………………………………………………………………… 

2.1.3.2接收以太网帧 

Windows Vista的TCP仃P协议支持对一组以太网帧的接收。 

任何引发接指示或修改接收指示的下层驱动都必须遵循TCP/IP 

协议规范。 

注意:如果存在驱动遵循下面的规范,那上层驱动可能行 

为不可预测。 

驱动接收以太网帧必须遵循下面的规范。 

(1)驱动必须分配一个NET—BUFFER_LIST结构用于存 

放以太网帧。每一个NET

BUFFER

UsT必须包含一个带外数 

据块(OOB),它被定义在NET BUFFER_LIST时NetBufferListIn 

f0成员被一些特殊处理使用。 

(2)必须为以太网帧分配NET_BUFFER结构且链接到帧 

的NET

BUFFERJ 结构中。注意:一个以太网帧可以被分 

离成多块存储在MDL中链接到NET_BUFFER结构中。 

(3)对于VISTA版本不允许把一个接收的以太网帧分成 

多份存储在MDL中。但是以后的版本会允许这样做。 

(4) 任何Windows版本中都不能分离(在一个 

NETBUFFER

LIsT中把数据分别存储到多个MDL中)IP头、 

IPV4选项、IPSEC头、IPV6扩展头或上层协议头,除非第一 

个MDL中包含了个NDIS支持的前视数据(LOOKHEAD)长 

度的数据。 

(5)如果下层驱动遵循上述规则,那么到任何NDIS6.0 

以后的协议驱动和Filter Driver都应该支持以太网帧的分片存 

储(在一个NET

BUFFER

_

LIST中把数据分别存储到多个 

MDL中)。这样做是为了这些驱动在以后的Windows版本中兼 

容运行。 

2.1.4派生NET

BUFFER

LIST结构 

NDIS6.0提供函数来管理NET_BUFFER_LIST结构还可以 

从其他的NET_BUFFER_LIST派生结构。这些函数经常被中间 

层驱动使用。 、 

下面这些函数就支持从一个已经存在的NET BUFFER_LI 

ST中创建一个派生结构: 

NdisAIIocateCIoneNetBufferUst 

NdisAIIocateFragmentNetBufferust 

NdisAIIocateReassembledNetBufferUst 

这些函数改善了系统性能,因为这些函数在派生的过程中 

并不复制网络数据。可以对已经存在的NET

BUFFER_uST做 

以下3种派生操作。 

(1)克隆(Clone) 

克隆一个NE r_BUFFER

LIST的副本(它还是引用原来的 

数据),可以用克隆的副本发送到多个传输路径。 

(2)分片(Fragrance) 

个分片NET BUFFER

_

LIST结构包含一个 

NET

BUFFER集(它还是引用原来的数据)。但是,数据被划 

分成不超过最大大小的单元。驱动可以有效将大缓冲区分解成 

小的。 

(3)重组(Reassembled) 

个重组的NET_BUFFER—LIST结构包含一个 

NET

BUFFER

L1ST结构(它是引用原来多个NET_BUFFER结 

构的原始数据)。驱动可以利用这个操作来合并多个小的 

NET_BUFFER_L1ST成一个大的NET-BUFFER—LIST。 

2.1.4一NET

BUFFER

LIST结构的派生关系 

驱动的编写者应该知道和维护经过克隆,分片.重组后的 

子结构与父结构之间的关系。这些关系主要是为了保证在父结 

构被释放后才能释放子结构。它应用下列规则。 

(1)当一个驱动从NET-BUFFERLIST创建了一个子结 

构后,驱动应该保留父结构的所有权,传递时传递子结构给其 

他驱动。驱动决不能把父结构传递给其他驱动。 

(2)驱动应该仅更新父结构中的子结构数。冈为父结构 

不传递给它其他驱动,所以子结构数被覆盖的机会很小。驱动 

应该设置子结构中的父指针指向父结构。 

(3)当驱动从其他驱动收到一个NET

BUFFER

LIST时 

是不能更改它的父指示的。如果接收到的是一个子结构,那么 

它的父指针是被设置过的。 

(4)NDIS不强制上述规则。当前NET_BUFFER

LIST的 

所有者必须管理维护子结构数和父指针。例如,一个驱动对当 

前的NErLBUFFER

_

LIST进行了克隆和分片,就必须管理维护 

好相关的父指针和子结构总数。 

(5)NDIS在分配一个NET

BUFFER

LIST时总是置它的 

父指针和子结构数据为0。NDIS在任何时间向其他驱动传递这 

个结构时也不会修改它们。 

2.1.4.2克隆 

NBLC=NET BUFFER UST C0NTEXT 

NBL=NET BUFFER UST 

NB=NET BUFFER 

图1O 

I|I臻 

{ 

 m …71 _| … fq… Ⅳd  。一  iJ I_ 

实用第一 智慧密集 

…… . .… … 

个驱动从一个已经存在的NET

BUFFER

LIST克隆一个 

样的。例如,如果有一个父结构有两个NET BUFFER.第一 

个NET_BUFFER分片后剩下的 间小于分片的长度.这时也 

不会把它同下一个NET

BUFFER分并再分片,会像一个 

新的结构,这样新克隆的结构引用的还是原始的数据。驱动可 

以利用这种方法在多个路径上有效地传输相同的数据。 

图l0展示了父结构和克隆结构之间的关系。 

驱动调用NdisAllocateCloneNetBufferList函数来克隆一个已 

经存在的NET_BUFFERLIST,它新分配一个NET BUFFER

NET

BUFFER那做处理。 

驱动可以使用NdisFreeFragmentNetBufferList来释放分片生 

成的NET

BUFFER

LIST结构。 

LIST和NET

BUFFER及MDL同时引用原来的数据,这里并不 

2.1.4.4重组 

复制数据(注意:这里并没有复制网络数据,即MDL描述的 图12展示了重结构包与父结构之间的关系。 

数据只是被引用了)。但是它不会克隆NET BUFFER

LIST的 

NET

BUFFE lJ1s.r_CONTEXT结构成员。要释放这个克隆的 

新结构调用NdisFreeCloneNetBufferList。 

2.1.4.3分片 

图l1展示了父结构与分片子结构之间的关系。 

图11 

驱动可以调用NdisAllocateFragmentNetBufferList来分片一 

个已经存在的NET BUFFER_LIST结构。它新分配一个 

NET

BUFFER

_

LIST结构和多个NET

BUFFER及MDL结构. 

不会分配NET

BUFFER

_

LIST

_

CONTEXT结构成员。其网络数 

据也不复制,只是引用原来的。 

如果父结构有多个NET

BUFFER和单个的分片方法是一 

电器 与堆 

图12 

驱动可以调用NdisReassemledNetBufferList重组一个已经 

存在的NET_BUFFER_LIST结构,它会新分配一个 

NETBUFFER

_

LIST和NET_BUFFER及MDL,但是不分配 

NET

BUFFER LIST

CONTEXT成员结构。重组的结构只是引 

用原来的数据并不复制数据。 

驱动可以调用NdisFreeReassemledNetBufferList释放重组 

时生成的NET_BUFFER_LIST,同时释放与之前链的 

NET

BUFFER和MDL链。 

(收稿日期:2012—03—02)