天天看点

NDIS笔记---(1)

<Introduction of NDIS>

Filter Driver提供了针对微端口驱动的过滤服务。

NDIS驱动栈上必须包含微端口驱动和协议驱动,可选的包含Filter Driver。

        Protocol Binding

               ↓↑

        Filter Module 1

               ↓↑

        Filter Module 2

               ↓↑

        ...............

               ↓↑

        Filter Module n

               ↓↑

        Miniport Adapter

目的:

    1)基于安全或其它目录的数据过滤应用;

    2)对网络数据进行监视,收集及统计的应用。

<Filter Driver Characteristics>

    1)一个Filter Driver 实例叫做Filter Module,它附加在一个适配器的微端口驱动上,

      来自相同或不同的Filter Driver 的多个Filter Module 都可以被堆叠在一个网络适配器上。

    2)在Filter Module 被安装到驱动栈时,之上的协议驱动和之下的微端口驱动都不需要提供

      额外的支持功能。

    3)因为Filter Module不像中间层驱动那样提供一个虚拟的微口,也不与某个设备对象联接,

      所以在微端口适配器上的Filter Module 功能相当于一个修改过版本的微端口适配器

     (Miniport Adapter)。

    4)NDIS使用配置信息来到决定一个Filter Module附加到一个网络适配器栈上的顺序。

    5)在不用拆除整驱动栈的情况下,NDIS可以动态的插入,删除Filter Module或进行重新配置。

    6)当NDIS重启驱动栈的时候,协议驱动可以获得在栈上的Filter Module列表。

    7)Filter Driver可以过滤下层网络适配器上绝大部分的通信。Filter Module不联接某特定

      的绑定。

    8)Filter Drvier 可以选择为过滤服务也可以选择为分流的不过滤服务,选择为哪一种是可以动

      态配置的。

    9)NDIS保证有效的上下文空间,也不就是说Filter Driver 不需要通过代码COPY缓冲区来获得

      上下文空间。

<Filter Driver Service>

    1)发起一个发送请求和接受请求;

    2)改变数据缓冲区的顺序或对发送和接受数据进行调速;

    3)在一个驱动栈的接收或发送路径上更改,删除,添加数据;

    4)发起查询或设置OID的请求给下层驱动;

    5)过滤对下层驱动的OID查询或设置请求;

    6)过滤从下层驱动传来的OID查询和设置请求的应答;

    7)过滤下层来的状态指示;

    8)给上层设备发起状态指示;

    9)管理注册表中每一个微端口适配器和其接口的参数;

<Filter Drvier Parameters>

    1) Monitoring

      这种类型可以在驱动栈上做监视行为,但是它不能在驱动栈上进行数据修改行为。

      Monitoring Filter Drvier 不在修改或发送数据。

    2)Modifying

      这种类型可以在驱动栈上做更改行为,该类修改类型是特定于驱动的(The type of modification

       is driver-specific)。

    INF文件中:

        Filter Type的值是0x00000001:  monitoring filter

        Filter Type的值是0x00000002:  modifying filter

        也可指定一个过滤驱动是mandatory(强制)的,通常用在modifying filter驱动上,如果一个

        mandatory的Filter驱动不能加载,那么它联接的驱动栈将被拆除。

<Mandatory Filter Driver>

    Mandatory Filter Driver 必须存在于驱动栈上,驱动栈才能正常工作,如果一个Mandatory Filter

    Module 不附加,那么驱动栈也将会被拆除。Modifying或Monitoring类型的Filter Driver可以被指定

    为Mandatory的所有中间层过滤驱动都是可选的。

    附加Mandatory Filter Driver在驱动栈上:

        NDIS先解绑定所有协议驱动,附加Filter Module后再重新绑定协议驱动,如果不能成功,则

        拆除驱动栈下边界;

    分离Mandatory Filter Driver在驱动栈上:

        NDIS先解绑所有协议驱动,分离Filter Module后重新绑定协议驱动。要分离一个Optional Filter

        Driver时,NDIS只暂停驱动栈,分离后重启驱动栈这时并不解绑定协议驱动。

    如果计算机重启,这时倘若一个Mandatory Filter Driver还没有附加到微端口适配器,这时NDIS是不会

    绑定协议驱动的。

    INF文件中:

        FilterRunType是0x00000001代表驱动是Mandatory;

        FilterRunType是0x00000002代表驱动是Optional。

<Writer NDIS Filter Driver>

    <Initialization of Filter Driver>

        系统加载Filter Driver 后初始化立即发生,Filter Driver 被加载为系统服务。

    系统加载Filter Driver 可在Miniport Driver 被加载的之前,期间和之后。如果一个微端

    口适配器所支持的类型与Filter Driver 所要绑定的类匹配且Filter Driver也完成了初始化

    ,那么NDIS可以加附加一个Filter Module到这个微端口适配器上。

        Filter Driver 没有加载,那即使驱动栈启动了那么系统还是会加载它。

        Filter Driver 被加载后,系统会调用驱动的DriverEntry例程。在DriverEntry中

    立即调用NdisFRegistryFilterDriver注册Filterxxx入口例程。NdisFRegistryFilterDriver

    成功将会返回STATUS_SUCCESS。然后申请相关资源,如果失败,则释放所有申请到的资源。

    并通过一个NDIS_FILTER_DRIVER_CHARACTERISTICS结构做NdisFRegistryFilterDriver的Filter

    Characteristics参数。

        NDIS_FILTER_DRIVER_CHARACTERISTICS 结构指定Mandatory和Optional Filterxxx的

    例程入口。有些Optional例程可以被Bypass。

    NDIS_FILTER_DRIVER_CHARACTERISTICS 中的 Mandatory例程:

        FilterDetach

        FilterAttach

        FilterRestart

        FilterPause

    NDIS_FILTER_DRIVER_CHARACTERISTICS 中的 Optional且不能在运行时变更的例程:

        FilterSetOptional

        FilterSetModuleOptions

        FilterOidRequest

        FilterOidRequestComplete

        FilterStatus

        FilterNetPnPEvent

        FilterDevicePnPEventNotify

        FilterCancelSendNetBufferLists

    NDIS_FILTER_DRIVER_CHARACTERISTICS 中的 Optional且能在运行时变更的例程:

        FilterSendNetBufferLists

        FilterSendNetBufferListsComplete

        FilterReturnNetBufferLists

        FilterReceiveNetBufferLists

    这个结构指定的例程可以在运行时的FilterSetModuleOptionals例中调用 NdisSetOptionHandles

    来改变,如果FilterDriver 要在例中改自身的一个特性就必须提供FilterSetModuleOptional例程

    部分特性每一个不同的 Filter Module 可以各不相同。

    NdisFRegisterFilterDriver调用完成后,会返回一个FilterDriver句柄,并保存它。之后会用。

    FilterSetOption返回后,Filter Module处于Detached状态。NDIS可以在FilterSetOptions返回后

    的任何时间调用FilterAttach例程。FilterModule处于Detached状态。NDIS可以在FilterSetOptions

    返回后的任何时间调用FilterAttach例程。Filter Module在FilterAttach中完成和它相关的特定初

    始化。

----DriverEntry Code----

NTSTATUS DriverEntry(IN  PDRIVER_OBJECT  DriverObject, IN  PUNICODE_STRING   RegistryPath)

{

    NDIS_STATUS                             Status;

    NDIS_FILTER_DRIVER_CHARACTERISTICS      FChars;

    NDIS_STRING                             ServiceName;

    NDIS_STRING                             UniqueName;

    NDIS_STRING                             FriendlyName;

    BOOLEAN                                 bFalse = FALSE;

    UNREFERENCED_PARAMETER(RegistryPath);

    DEBUGP(DL_TRACE,("===>DriverEntry...\n"));

    RtlInitUnicodeString(&ServiceName, FILTER_SERVICE_NAME);

    RtlInitUnicodeString(&FriendlyName, FILTER_FRIENDLY_NAME);

    RtlInitUnicodeString(&UniqueName, FILTER_UNIQUE_NAME);

    FilterDriverObject = DriverObject;

    do

    {

        NdisZeroMemory(&FChars, sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS));  

        FChars.Header.Type =  

        NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;

        FChars.Header.Size = sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS);

        FChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_1;

        FChars.MajorNdisVersion = FILTER_MAJOR_NDIS_VERSION;

        FChars.MinorNdisVersion = FILTER_MINOR_NDIS_VERSION;

        FChars.MajorDriverVersion = 1;

        FChars.MinorDriverVersion = 0;

        FChars.Flags = 0;

        FChars.FriendlyName = FriendlyName;

        FChars.UniqueName = UniqueName;

        FChars.ServiceName = ServiceName;

        FChars.AttachHandler = FilterAttach;

        FChars.DetachHandler = FilterDetach;

        FChars.RestartHandler = FilterRestart;

        FChars.PauseHandler = FilterPause;

        FChars.SetOptionsHandler = FilterRegisterOptions;

        FChars.SetFilterModuleOptionsHandler = FilterSetModuleOptions;

        FChars.OidRequestHandler = FilterOidRequest;

        FChars.OidRequestCompleteHandler = FilterOidRequestComplete;

        FChars.StatusHandler = FilterStatus;

        FChars.DevicePnPEventNotifyHandler = FilterDevicePnPEventNotify;

        FChars.NetPnPEventHandler = FilterNetPnPEvent;      

        FChars.CancelSendNetBufferListsHandler = FilterCancelSendNetBufferLists;

        FChars.SendNetBufferListsHandler = FilterSendNetBufferLists;  

       FChars.SendNetBufferListsCompleteHandler = FilterSendNetBufferListsComplete;

        FChars.ReturnNetBufferListsHandler = FilterReturnNetBufferLists;

        FChars.ReceiveNetBufferListsHandler = FilterReceiveNetBufferLists;

        FChars.CancelOidRequestHandler = FilterCancelOidRequest;        

        DriverObject->DriverUnload = FilterUnload;

        FilterDriverHandle = NULL;

        FILTER_INIT_LOCK(&FilterListLock);

        InitializeListHead(&FilterModuleList);

  // 把Filter驱动注册给NDIS

        Status = NdisFRegisterFilterDriver(DriverObject,

                                           (NDIS_HANDLE)FilterDriverObject,

                                           &FChars,

                                           &FilterDriverHandle);

        if (Status != NDIS_STATUS_SUCCESS)

        {

            DEBUGP(DL_WARN, ("MSFilter: Register filter driver failed.\n"));

            break;

        }

        // Initilize spin locks

        Status = FilterRegisterDevice();

        if (Status != NDIS_STATUS_SUCCESS)

        {

            NdisFDeregisterFilterDriver(FilterDriverHandle);

            FILTER_FREE_LOCK(&FilterListLock);

            DEBUGP(DL_WARN, ("MSFilter: Register device for the filter driver failed.\n"));

            break;

        }

    }

    while(bFalse);

    DEBUGP(DL_TRACE, ("<===DriverEntry, Status = %8x\n", Status));

    return Status;

}

    <Unload Filter Driver>

    在FilterDriverUnload中调用NdisFDeregisterFilterDriver来撤销NdisFRegisterFilterDriver的

    注册。

    系统只会在调用FilterDetach分离了所有和本FilterDriver相关的FilterModule后才会调用DriverUnload。

-----DriverUnload Code---------

VOID

FilterUnload(IN  PDRIVER_OBJECT      DriverObject){

#if DBG    

    BOOLEAN               bFalse = FALSE;

#endif

    UNREFERENCED_PARAMETER(DriverObject);

    DEBUGP(DL_TRACE, ("===>FilterUnload\n"));

    //

    // Should free the filter context list

    //

    FilterDeregisterDevice();

    NdisFDeregisterFilterDriver(FilterDriverHandle);

#if DBG    

    FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);

    ASSERT(IsListEmpty(&FilterModuleList));

    FILTER_RELEASE_LOCK(&FilterListLock, bFalse);

#endif    

    FILTER_FREE_LOCK(&FilterListLock);

    DEBUGP(DL_TRACE, ("<===FilterUnload\n"));

    return;

}

<FIlter Driver Status & Operation>

    Detached:初始状态

        ↓

    Attaching:FilterAttach → Detached:AttachFailed

        ↓

    Paused(OID)     →     Restarting(OID) → Running(Send&Recv,OID) → Pausing(Send&Recv,OID)

    :AttachComplete         :FilterRestart            :RestartComplete                        :FilterPause

        ↓                                              ↓                                               ↓

    Detached:FilterDetach    Paused:RestartFailed                Paused:PauseComplete

<FilterAttach---Attach Filter Module>

A filter driver performs the following operations when NDIS calls FilterAttach.

? Creates a context area for the filter module and allocates buffer pools and any other resources.

? Calls the NdisFSetAttributes function together with the NdisFilterHandle that NDIS passed to FilterAttach.

The FilterModuleContext parameter of NdisFSetAttributes specifies the filter driver's context area for this filter module.

NDIS passes this context area to the filter driver's FilterXxx functions.

? Optionally reads configuration parameters from the registry.

? If the preceding operations completed successfully, the filter module enters the Paused state.

? If the preceding operations failed, the filter driver must release any resources that it allocated in the FilterAttach

function and return the filter module to the Detached state.

?Returns NDIS_STATUS_SUCCESS or an appropriate failure code.

继续阅读