Windows8内核模式下开发NDIS应用-NDIS Filter讲解

 在Win8系统下开发驱动程序,需要数字证书,还需要驱动签名认证。不能像XP下面那样疯狂滴耍流氓了。


 由于Win8系统的内核做了大幅度的修改,它和XP系统的内核起了很大的变化,最显著的就是刚才说的:需要签名和证书。  还有就是:不能随意的HOOK SSDT了。




在开发NDIS驱动程序的时候,WDK开发包提供了一个新的框架,叫着NDIS Filter
NDIS Filter是一个例子工程。
假入我把WDK安装在E盘,那么这个工程代码就在:
C:\WinDDK\8600.16385.1\src\network\ndis\filter目录下。


把这个例子工程和原来的Passthru工程代码做比较,您会发现,原来需要导出来的2种类型的回调函数MiniportXXX和ProtocolXXX 在新的框架里面被全部隐藏起来了。
微软提供了新的函数。 一起来看看,微软提供了什么。
在这里,为了方便分析, 我把函数代码都做了功能注释,请大家一起看看。
代码如下:



[cpp]  view plain copy
  1. #pragma NDIS_INIT_FUNCTION(DriverEntry)  
  2.   
  3. #define LITTLE_ENDIAN   (1)  
  4. //  
  5. // Global variables  
  6. //   
  7. NDIS_HANDLE         FilterDriverHandle; // NDIS handle for filter driver  
  8. NDIS_HANDLE         FilterDriverObject;  
  9. NDIS_HANDLE         NdisFilterDeviceHandle = NULL;  
  10. PDEVICE_OBJECT      DeviceObject = NULL;  
  11.   
  12. FILTER_LOCK         FilterListLock;  
  13. LIST_ENTRY          FilterModuleList;  
  14. PWCHAR              InstanceStrings = NULL;  
  15.   
  16. NDIS_FILTER_PARTIAL_CHARACTERISTICS DefaultChars = {  
  17. { 0, 0, 0},  
  18.       0,  
  19.       FilterSendNetBufferLists,  
  20.       FilterSendNetBufferListsComplete,  
  21.       NULL,  
  22.       FilterReceiveNetBufferLists,  
  23.       FilterReturnNetBufferLists  
  24. };      
  25.   
  26. typedef struct in_addr {  
  27.   union {  
  28.     struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;  
  29.     struct { USHORT s_w1,s_w2; } S_un_w;  
  30.     ULONG S_addr;  
  31.   } S_un;  
  32. } IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;  
  33.   
  34.   
  35. #pragma push(1)  
  36. typedef struct IP_HEADER  
  37. {  
  38.   
  39. #if LITTLE_ENDIAN  
  40.   unsigned char  ip_hl:4;    /* 头长度 */  
  41.   unsigned char  ip_v:4;      /* 版本号 */  
  42. #else  
  43.   unsigned char   ip_v:4;  
  44.   unsigned char   ip_hl:4;       
  45. #endif  
  46.   
  47.   unsigned char  TOS;           // 服务类型  
  48.   
  49.   unsigned short   TotLen;      // 封包总长度,即整个IP包的长度  
  50.   unsigned short   ID;          // 封包标识,唯一标识发送的每一个数据报  
  51.   unsigned short   FlagOff;     // 标志  
  52.   unsigned char  TTL;           // 生存时间,就是TTL  
  53.   unsigned char  Protocol;      // 协议,可能是TCP、UDP、ICMP等  
  54.   unsigned short Checksum;      // 校验和  
  55.   struct in_addr        iaSrc;  // 源IP地址  
  56.   struct in_addr        iaDst;  // 目的PI地址  
  57.   
  58. }IP_HEADER, *PIP_HEADER;  
  59.   
  60.   
  61. typedef struct tcp_header  
  62. {  
  63.   unsigned short src_port;    //源端口号  
  64.   unsigned short dst_port;    //目的端口号  
  65.   unsigned int   seq_no;      //序列号  
  66.   unsigned int   ack_no;      //确认号  
  67. #if LITTLE_ENDIAN  
  68.   unsigned char reserved_1:4; //保留6位中的4位首部长度  
  69.   unsigned char thl:4;    //tcp头部长度  
  70.   unsigned char flag:6;  //6位标志  
  71.   unsigned char reseverd_2:2; //保留6位中的2位  
  72. #else  
  73.   unsigned char thl:4;    //tcp头部长度  
  74.   unsigned char reserved_1:4; //保留6位中的4位首部长度  
  75.   unsigned char reseverd_2:2; //保留6位中的2位  
  76.   unsigned char flag:6;  //6位标志   
  77. #endif  
  78.   unsigned short wnd_size;   //16位窗口大小  
  79.   unsigned short chk_sum;    //16位TCP检验和  
  80.   unsigned short urgt_p;     //16为紧急指针  
  81.   
  82. }TCP_HEADER,*PTCP_HEADER;  
  83.   
  84.   
  85. typedef struct udp_header   
  86. {  
  87.   USHORT srcport;   // 源端口  
  88.   USHORT dstport;   // 目的端口  
  89.   USHORT total_len; // 包括UDP报头及UDP数据的长度(单位:字节)  
  90.   USHORT chksum;    // 校验和  
  91.   
  92. }UDP_HEADER,*PUDP_HEADER;  
  93. #pragma push()  
  94.   
  95.   
  96. #define IP_OFFSET                               0x0E  
  97.   
  98. //IP 协议类型  
  99. #define PROT_ICMP                               0x01   
  100. #define PROT_TCP                                0x06   
  101. #define PROT_UDP                                0x11   
  102.   
  103.   
  104. USHORT UTIL_htons( USHORT hostshort )  
  105. {  
  106.   PUCHAR  pBuffer;  
  107.   USHORT  nResult;  
  108.   
  109.   nResult = 0;  
  110.   pBuffer = (PUCHAR )&hostshort;  
  111.   
  112.   nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00) | (pBuffer[ 1 ] & 0x00FF);  
  113.   
  114.   return( nResult );  
  115. }  
  116.   
  117.   
  118. /*UTIL_ntohs把网络字节顺序转换成主机字节顺序*/  
  119. USHORT UTIL_ntohs( USHORT netshort )  
  120. {  
  121.   return( UTIL_htons( netshort ) );  
  122. }  
  123.   
  124.   
  125.   
  126. NTSTATUS   
  127. DriverEntry(IN  PDRIVER_OBJECT  DriverObject, IN  PUNICODE_STRING   RegistryPath)  
  128. {  
  129.     NDIS_STATUS                             Status;  
  130.     NDIS_FILTER_DRIVER_CHARACTERISTICS      FChars;  
  131.     NDIS_STRING                             ServiceName;  
  132.     NDIS_STRING                             UniqueName;  
  133.     NDIS_STRING                             FriendlyName;  
  134.     BOOLEAN                                 bFalse = FALSE;  
  135.   
  136.     UNREFERENCED_PARAMETER(RegistryPath);  
  137.       
  138.     DEBUGP(DL_TRACE,("===>DriverEntry...\n"));  
  139.      
  140.     RtlInitUnicodeString(&ServiceName, FILTER_SERVICE_NAME);  
  141.     RtlInitUnicodeString(&FriendlyName, FILTER_FRIENDLY_NAME);  
  142.     RtlInitUnicodeString(&UniqueName, FILTER_UNIQUE_NAME);  
  143.     FilterDriverObject = DriverObject;  
  144.       
  145.     do  
  146.     {  
  147.         NdisZeroMemory(&FChars, sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS));    
  148.   
  149. /* 
  150. 大多数的NDIS6.0数据结构中包含的对象头结构的成员,即NDIS_OBJECT_HEADER结构。 
  151. 对象头有三个成员:类型,大小和修改。如果头信息是不正确的,那么调用NDIS6.0函数将失败。 
  152. */  
  153.         FChars.Header.Type =    
  154.         NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;  
  155.         FChars.Header.Size = sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS);  
  156.         FChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_1;  
  157.   
  158.         FChars.MajorNdisVersion = FILTER_MAJOR_NDIS_VERSION;  
  159.         FChars.MinorNdisVersion = FILTER_MINOR_NDIS_VERSION;  
  160.         FChars.MajorDriverVersion = 1;  
  161.         FChars.MinorDriverVersion = 0;  
  162.         FChars.Flags = 0;  
  163.   
  164.         FChars.FriendlyName = FriendlyName;  
  165.         FChars.UniqueName = UniqueName;  
  166.         FChars.ServiceName = ServiceName;  
  167.   
  168.               
  169. /****************************************************** 
  170. NDIS_FILTER_DRIVER_CHARACTERISTICS结构中Mandatory例程 
  171. ******************************************************/  
  172.         FChars.AttachHandler = FilterAttach;  
  173.         FChars.DetachHandler = FilterDetach;  
  174.         FChars.RestartHandler = FilterRestart;  
  175.         FChars.PauseHandler = FilterPause;  
  176.   
  177.   
  178. /************************************************************ 
  179. NDIS_FILTER_DRIVER_CHARACTERISTICS结构中Optional且不能在运行时变更的例程 
  180. *************************************************************/  
  181.         FChars.SetOptionsHandler = FilterRegisterOptions;  
  182.         FChars.SetFilterModuleOptionsHandler = FilterSetModuleOptions;  
  183.         FChars.OidRequestHandler = FilterOidRequest;  
  184.         FChars.OidRequestCompleteHandler = FilterOidRequestComplete;  
  185.         FChars.StatusHandler = FilterStatus;  
  186.        FChars.DevicePnPEventNotifyHandler = FilterDevicePnPEventNotify;  
  187.        FChars.NetPnPEventHandler = FilterNetPnPEvent;        
  188.       FChars.CancelSendNetBufferListsHandler = FilterCancelSendNetBufferLists;  
  189.   
  190.   
  191.   
  192. /************************************************************** 
  193. DIS_FILTER_DRIVER_CHARACTERISTICS结构中Optional且能在运行时变更的例程。 
  194.          
  195. 下面这4个例程也被定义在NDIS_FILTER_PARTIAL_CHARACTERISTICS中,这个结构指定的 
  196. 例程可以在运行时的FilterSetModuleOptions例程中调用NdisSetOptionHandles来改变。 
  197. 如果过滤驱动要在例程中修改自身的一个特性,那么必须提供FilterSetModuleOptions例程。 
  198. ****************************************************************/  
  199.         FChars.SendNetBufferListsHandler = FilterSendNetBufferLists;    
  200.    FChars.SendNetBufferListsCompleteHandler = FilterSendNetBufferListsComplete;  
  201.         FChars.ReturnNetBufferListsHandler = FilterReturnNetBufferLists;  
  202.         FChars.ReceiveNetBufferListsHandler = FilterReceiveNetBufferLists;  
  203.   
  204.        ///  
  205.         FChars.CancelOidRequestHandler = FilterCancelOidRequest;          
  206.         
  207.         DriverObject->DriverUnload = FilterUnload;  
  208.       
  209.         FilterDriverHandle = NULL;  
  210.   
  211.         FILTER_INIT_LOCK(&FilterListLock);  
  212.   
  213.         InitializeListHead(&FilterModuleList);  
  214.           
  215.   // 把Filter驱动注册给NDIS  
  216.         Status = NdisFRegisterFilterDriver(DriverObject,  
  217.                                            (NDIS_HANDLE)FilterDriverObject,  
  218.                                            &FChars,   
  219.                                            &FilterDriverHandle);  
  220.         if (Status != NDIS_STATUS_SUCCESS)  
  221.         {  
  222.             DEBUGP(DL_WARN, ("MSFilter: Register filter driver failed.\n"));   
  223.             break;  
  224.         }  
  225.         //  
  226.         // Initilize spin locks  
  227.         //  
  228.   
  229.         Status = FilterRegisterDevice();  
  230.   
  231.         if (Status != NDIS_STATUS_SUCCESS)  
  232.         {  
  233.             NdisFDeregisterFilterDriver(FilterDriverHandle);  
  234.             FILTER_FREE_LOCK(&FilterListLock);  
  235.             DEBUGP(DL_WARN, ("MSFilter: Register device for the filter driver failed.\n"));   
  236.             break;  
  237.         }  
  238.   
  239.           
  240.     }   
  241.     while(bFalse);  
  242.       
  243.       
  244.     DEBUGP(DL_TRACE, ("<===DriverEntry, Status = %8x\n", Status));  
  245.     return Status;  
  246.       
  247. }  
  248.   
  249.   
  250.   
  251.   
  252. //过滤驱动注册可选服务  
  253. NDIS_STATUS  
  254. FilterRegisterOptions(  
  255.         IN NDIS_HANDLE  NdisFilterDriverHandle, //它指向了这个过滤驱动  
  256.         IN NDIS_HANDLE  FilterDriverContext     //它是这个驱动的上下文  
  257.         )  
  258. {  
  259.     DEBUGP(DL_TRACE, ("===>FilterRegisterOptions\n"));  
  260.       
  261.     ASSERT(NdisFilterDriverHandle == FilterDriverHandle);  
  262.     ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject);  
  263.   
  264.     if ((NdisFilterDriverHandle != (NDIS_HANDLE)FilterDriverHandle) ||  
  265.         (FilterDriverContext != (NDIS_HANDLE)FilterDriverObject))  
  266.     {  
  267.         return NDIS_STATUS_INVALID_PARAMETER;  
  268.     }  
  269.   
  270.     DEBUGP(DL_TRACE, ("<===FilterRegisterOptions\n"));  
  271.   
  272.     return (NDIS_STATUS_SUCCESS);  
  273. }  
  274.   
  275.       
  276.   
  277. /***************************************************************   
  278. FilterAttach函数的功能: 
  279.    Attaching状态表示:一个Filter Driver正准备附加一个Filter Module到一个驱动栈上。 
  280.    一个过滤驱动进入Attaching状态下不能进行发送请求、接收指示、状态指示、OID请求操作。 
  281.  
  282.    当一个过滤驱动进入Attaching状态时,它可以: 
  283.    (1)创建一个环境上下文区域并且初始化一个缓冲区池以及其Filter Module特点的资源。 
  284.   (2)用NDIS 传来给Filter Attach的NdisFilterHandle作为输入来调用NdisFSetAttributes例程。 
  285.  
  286.  
  287.    Attach is complete 
  288.    当Filter Module在Attaching状态下并且Filter Driver初始化了所有的Filter Module所需要的 
  289.    所有资源时,Filter Module进入Paused状态。 
  290.  
  291.  
  292.    参数说明: 
  293.     NdisFilterHandle     它用于所有过滤驱动中对Ndisxxx类例程的调用时引用指示这个过滤模块。 
  294.     FilterDriverContext  它由NdisFRegisterFilterDriver的FilterDriverContext来指定。 
  295.     AttachParameters     它是过滤模块的初始化参数结构体。 
  296.  **************************************************************/  
  297. NDIS_STATUS  
  298. FilterAttach(  
  299.     IN  NDIS_HANDLE                     NdisFilterHandle,  
  300.     IN  NDIS_HANDLE                     FilterDriverContext,  
  301.     IN  PNDIS_FILTER_ATTACH_PARAMETERS  AttachParameters  
  302.     )  
  303.   
  304. {  
  305.     PMS_FILTER              pFilter = NULL;  
  306.     NDIS_STATUS             Status = NDIS_STATUS_SUCCESS;  
  307.     NDIS_FILTER_ATTRIBUTES  FilterAttributes;  
  308.     ULONG                   Size;  
  309.     BOOLEAN               bFalse = FALSE;  
  310.       
  311.     DEBUGP(DL_TRACE, ("===>FilterAttach: NdisFilterHandle %p\n", NdisFilterHandle));  
  312.   
  313.     do  
  314.     {  
  315.         ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject);  
  316.         if (FilterDriverContext != (NDIS_HANDLE)FilterDriverObject)  
  317.         {  
  318.             Status = NDIS_STATUS_INVALID_PARAMETER;  
  319.             break;  
  320.         }  
  321.           
  322.         if ((AttachParameters->MiniportMediaType != NdisMedium802_3)  
  323.                 && (AttachParameters->MiniportMediaType != NdisMediumWan))  
  324.         {  
  325.            DEBUGP(DL_ERROR, ("MSFilter: Doesn't support media type other than NdisMedium802_3.\n"));   
  326.           
  327.            Status = NDIS_STATUS_INVALID_PARAMETER;  
  328.            break;  
  329.         }  
  330.           
  331.         Size = sizeof(MS_FILTER) +   
  332.                AttachParameters->FilterModuleGuidName->Length +   
  333.                AttachParameters->BaseMiniportInstanceName->Length +   
  334.                AttachParameters->BaseMiniportName->Length;  
  335.           
  336.         pFilter = (PMS_FILTER)FILTER_ALLOC_MEM(NdisFilterHandle, Size);  
  337.         if (pFilter == NULL)  
  338.         {  
  339.             DEBUGP(DL_WARN, ("MSFilter: Failed to allocate context structure.\n"));  
  340.             Status = NDIS_STATUS_RESOURCES;  
  341.             break;  
  342.         }  
  343.           
  344.         NdisZeroMemory(pFilter, sizeof(MS_FILTER));  
  345.   
  346.         pFilter->FilterModuleName.Length = pFilter->FilterModuleName.MaximumLength = AttachParameters->FilterModuleGuidName->Length;  
  347.         pFilter->FilterModuleName.Buffer = (PWSTR)((PUCHAR)pFilter + sizeof(MS_FILTER));  
  348.   
  349.         NdisMoveMemory(pFilter->FilterModuleName.Buffer,   
  350.                         AttachParameters->FilterModuleGuidName->Buffer,  
  351.                         pFilter->FilterModuleName.Length);  
  352.   
  353.           
  354.         pFilter->MiniportFriendlyName.Length = pFilter->MiniportFriendlyName.MaximumLength = AttachParameters->BaseMiniportInstanceName->Length;  
  355.         pFilter->MiniportFriendlyName.Buffer = (PWSTR)((PUCHAR)pFilter->FilterModuleName.Buffer + pFilter->FilterModuleName.Length);  
  356.           
  357.   NdisMoveMemory(pFilter->MiniportFriendlyName.Buffer,   
  358.                        AttachParameters->BaseMiniportInstanceName->Buffer,  
  359.                         pFilter->MiniportFriendlyName.Length);  
  360.   
  361.           
  362.         pFilter->MiniportName.Length = pFilter->MiniportName.MaximumLength = AttachParameters->BaseMiniportName->Length;  
  363.         pFilter->MiniportName.Buffer = (PWSTR)((PUCHAR)pFilter->MiniportFriendlyName.Buffer +   
  364.                                                    pFilter->MiniportFriendlyName.Length);  
  365.         NdisMoveMemory(pFilter->MiniportName.Buffer,   
  366.                         AttachParameters->BaseMiniportName->Buffer,  
  367.                         pFilter->MiniportName.Length);  
  368.   
  369.         pFilter->MiniportIfIndex = AttachParameters->BaseMiniportIfIndex;  
  370.         
  371.         pFilter->TrackReceives = TRUE;  
  372.         pFilter->TrackSends = TRUE;  
  373.         pFilter->FilterHandle = NdisFilterHandle;  
  374.   
  375.   
  376.         NdisZeroMemory(&FilterAttributes, sizeof(NDIS_FILTER_ATTRIBUTES));  
  377.         FilterAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1;  
  378.         FilterAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES);  
  379.         FilterAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES;  
  380.         FilterAttributes.Flags = 0;  
  381.   
  382.   
  383.         Status = NdisFSetAttributes(NdisFilterHandle,   
  384.                                     pFilter, //pFilter参数的功能是,为过滤模块指定环境上下文  
  385.                                     &FilterAttributes);  
  386.   
  387.         if (Status != NDIS_STATUS_SUCCESS)  
  388.         {  
  389.             DEBUGP(DL_WARN, ("MSFilter: Failed to set attributes.\n"));  
  390.             break;  
  391.         }  
  392.           
  393.         pFilter->State = FilterPaused;  
  394.   
  395.         FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);  
  396.         InsertHeadList(&FilterModuleList, &pFilter->FilterModuleLink);  
  397.         FILTER_RELEASE_LOCK(&FilterListLock, bFalse);  
  398.           
  399.     }  
  400.     while (bFalse);  
  401.       
  402.     if (Status != NDIS_STATUS_SUCCESS)  
  403.     {  
  404.         if (pFilter != NULL)  
  405.         {  
  406.             FILTER_FREE_MEM(pFilter);  
  407.         }  
  408.     }  
  409.       
  410.     DEBUGP(DL_TRACE, ("<===FilterAttach:    Status %x\n", Status));  
  411.     return Status;  
  412. }  
  413.   
  414.   
  415.   
  416.   
  417. /**************************************************************   
  418. FilterPause函数的功能: 
  419.    Paused状态:在这种状态下,Filter Driver不能执行接收和发送操作。 
  420.    当FilterDriver执行FilterPause全程时它就进入了Pausing状态。 
  421.  
  422.    Pausing状态:在这种状态下,Filter Driver要为一个Filter Module完成停止发送和接收 
  423.    处理所需要的所有准备工作。 
  424.  
  425.    一个在Pausing状态的Filter Driver有如下的约束: 
  426.  
  427.    (1)Filter Module不能发起任何新的接收指示,但可以传递下层驱动的接收指示。 
  428.    (2)如果有Filter Module发起的接收指示还没有完成,那么必须等到它们全部完成。有只当 
  429.       FilterReturnNetBufferLists完成所有外部接收指示后,暂停操作才能完成。 
  430.    (3)要返回任何未处理的由下层驱动引发的接收指示给NDIS,只有等到NdisFReturnNetBufferLists返回了所有未处理的接收指示后暂停操作才能完成。这里也可以排队缓冲这些未完成的接收指示。 
  431.    (4)立即用NdisFReturnNetBufferLists返回所有下层驱动新传来的接收指示,如果需要可以在返回之前制和排队这些接收指示。 
  432.    (5)不能发起任何新的发送请求。 
  433.    (6)如果有Filter Driver引的但NDIS还未完成的发送操作,必须等待它们完成。 
  434.    (8)应该在FilterSendNetBufferLists例程中立即调用NdisFSendNetBufferListsComplete返回那些新达到的发送请求。并且为每一个NET_BUFFER_LIST设置NDIS_STATUS_PAUSED返回状态。 
  435.    (8)这时可以使用NdisFIndicateStatus提供状态指示。 
  436.    (9)可以在FilterStatus中处理状态指示。 
  437.    (10)可以在FilterOidRequest里面处理OID请求。 
  438.    (11)可以发起一个OID操作。 
  439.    (12)不能释放分配的相关资源,和Filter Module相关的资源最好放在FilterDetach例程里面来释放。 
  440.    (13)如果有用于发送和接收的定时器那么要停止它。 
  441.  
  442.    当成功停止发送和接收操作后就必须完成暂停操作。暂停操作的完成可以是同步的也可以是异步的。 
  443.    若返回值是NDIS_STATUS_SUCCESS则,是同步。 
  444.    若是异步,则返回NDIS_STATUS_PENDING。那么还必须调用NdisFPauseComplete函数。 
  445.  
  446.    暂停操作完成了以后,Filter Module进入了Paused状态。这里它有如下的约束: 
  447.  
  448.    (1)不能发起任何接收指示,但可以传递底层驱动发来的接收指示。 
  449.    (2)需要立即调用NdisFReturnNetBufferLists返回底层驱动的接收指示给NDIS,如果需要可以在返回之前复制和排队这些接收指示。 
  450.    (3)不能引发任何新的发送指示。 
  451.    (4)需要立即调用NdisFSendNetBufferListsComplete完成那些在FilterSendNetBufferLists中收到的发送请求,并为每一个NET_BUFFER_LIST设置NDIS_STATUS_PAUSED返回状态。 
  452.    (5)这时可以使用NdisFIndicateStatus发起状态指示。 
  453.    (6)可以在FilterStatus中进行状态指示处理。 
  454.    (8)可以在FilterOidRequest里面处理OID请求。 
  455.    (8)可以发起一个OID请求。 
  456.  
  457.  
  458.    在Filter Module进行Pausing状态时NDIS不会发起其它PnP操作,比如:附加、分离、重启。只有当Filter Module进入了Paused状态后NDIS才能对它进行分离和重启操作。 
  459.  ***************************************************************/  
  460. NDIS_STATUS  
  461. FilterPause(  
  462.         IN  NDIS_HANDLE                     FilterModuleContext,  
  463.         IN  PNDIS_FILTER_PAUSE_PARAMETERS   PauseParameters  
  464.         )  
  465.   
  466. {  
  467.     PMS_FILTER          pFilter = (PMS_FILTER)(FilterModuleContext);  
  468.     NDIS_STATUS         Status;  
  469.     BOOLEAN               bFalse = FALSE;  
  470.   
  471.     UNREFERENCED_PARAMETER(PauseParameters);  
  472.       
  473.     DEBUGP(DL_TRACE, ("===>NDISLWF FilterPause: FilterInstance %p\n", FilterModuleContext));  
  474.   
  475.        
  476.     FILTER_ASSERT(pFilter->State == FilterRunning);   
  477.       
  478.     FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse);  
  479.     pFilter->State = FilterPausing;  
  480.     FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse);  
  481.   
  482.   
  483.     Status = NDIS_STATUS_SUCCESS;      
  484.   
  485.     pFilter->State = FilterPaused;  
  486.       
  487.     DEBUGP(DL_TRACE, ("<===FilterPause:  Status %x\n", Status));  
  488.     return Status;  
  489. }  
  490.   
  491.   
  492.   
  493.   
  494. /*************************************************************** 
  495.   FilterRestart函数的功能: 
  496.    在Restarting状态下,一个Filter Driver必须为一个Filter Module完成重启发送和接收数据时 
  497.    所需要的所有准备工作。 
  498.  
  499.    Restart is complete 
  500.     当Filter Module在Restarting状态下并且完成所有发送和接收所需要的准备工作时,Filter Module就进入了Running状态。 
  501.  
  502. 要启动一个Paused状态的Filter Module,如果有FilterSetModuleOptions就先调用它,接着调用FilterRestart。 
  503.  
  504.   当Filter Module在Restarting状态下,它可以: 
  505.   (1)完成任何正常的发送和接收所需要的准备工作。 
  506.   (2)可读写Filter Module的配置参数。 
  507.   (3)可以接收网络数据指示,拷贝和排队数据稍后只是给上层驱动或者丢弃数据。 
  508.   (4)不能发起任何新的接收指示。 
  509.   (5)应该立即调用NdisFSendNetBufferListsComplete例程来拒绝FilterSendNetBufferLists传来的发送的请求。应该设置每一个NET_BUFFER_LIST的完成状态为NDIS_STATUS_PAUSED 
  510.                 (6)可以使用NdisFIndicateStatus例程进行状态指示。 
  511.   (8)可以控制OID请求操作。 
  512.   (8)不能发起任何新的发送请求。 
  513.   (9)应该调用NdisFReturnNetBufferLists返回所有新的接收指示。如果需要的话可以在接收指示返回之前拷贝它们。 
  514.   (10)可以制作OID请求发送给下层驱动设置或查询配置信息。 
  515.   (11)可以在FilterStatus中控制状态指示。 
  516.   (12)返回时指示 NDIS_STATUS_SUCCESS 或失败状态,如果不Filter Module不能启动返回了失败,而它又是一个Mandatory的Filter Driver 那个 NDIS将会结束这个驱动栈 
  517. 在一个Filter Driver完成对发送和接收的重启后必须指示完成这个重启操作。  
  518. Filter Driver的重启操作的完成可以是同步也可以是异步的,同步时返回 NDIS_STATUS_SUCCESS 异步时返回NDIS_STATUS_PENDING。如果返回的是 NDIS_STATUS_PENDING 就必须调用NdisFRestartComplete 例程在重启操作完成后。 
  519. 在这种情况下,驱动需要传递给NdisFRestartComplete 一个固定状态(标识重启结果的成功或失败状态)。 
  520.  
  521. 重启操作完成Filter Module就进入了 Running状态,恢得一切正常的发送和接收外理。 
  522. 在Filter Driver的FilterRestart例程执行的时候NDIS不会发起任即插即用操作,如附加,分离,暂停请求等等。Ndis可以在Filter Module进入Running状态后发起一个暂停请求。 
  523. ***************************************************************/  
  524. NDIS_STATUS  
  525. FilterRestart(  
  526.     IN  NDIS_HANDLE                     FilterModuleContext,  
  527.     IN  PNDIS_FILTER_RESTART_PARAMETERS RestartParameters  
  528.     )  
  529.   
  530. {  
  531.     NDIS_STATUS     Status;  
  532.     PMS_FILTER      pFilter = (PMS_FILTER)FilterModuleContext; // BUGBUG, the cast may be wrong  
  533.     NDIS_HANDLE     ConfigurationHandle = NULL;  
  534.   
  535.   
  536.     PNDIS_RESTART_GENERAL_ATTRIBUTES NdisGeneralAttributes;  
  537.     PNDIS_RESTART_ATTRIBUTES         NdisRestartAttributes;  
  538.     NDIS_CONFIGURATION_OBJECT        ConfigObject;  
  539.       
  540.     DEBUGP(DL_TRACE, ("===>FilterRestart:   FilterModuleContext %p\n", FilterModuleContext));  
  541.       
  542.     FILTER_ASSERT(pFilter->State == FilterPaused);  
  543.   
  544.     ConfigObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;  
  545.     ConfigObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;  
  546.     ConfigObject.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);  
  547.     ConfigObject.NdisHandle = FilterDriverHandle;  
  548.     ConfigObject.Flags = 0;  
  549.       
  550.     Status = NdisOpenConfigurationEx(&ConfigObject, &ConfigurationHandle);  
  551.     if (Status != NDIS_STATUS_SUCCESS)  
  552.     {          
  553.           
  554. #if 0  
  555.         //  
  556.         // The code is here just to demonstrate how to call NDIS to write an eventlog. If drivers need to write   
  557.         // an event log.  
  558.         //  
  559.         PWCHAR              ErrorString = L"Ndislwf";  
  560.           
  561.         DEBUGP(DL_WARN, ("FilterRestart: Cannot open configuration.\n"));  
  562.         NdisWriteEventLogEntry(FilterDriverObject,  
  563.                                 EVENT_NDIS_DRIVER_FAILURE,  
  564.                                 0,  
  565.                                 1,  
  566.                                 &ErrorString,  
  567.                                 sizeof(Status),  
  568.                                 &Status);  
  569. #endif                                  
  570.                                   
  571.     }  
  572.   
  573.   
  574.     if (Status == NDIS_STATUS_SUCCESS)  
  575.     {  
  576.         NdisCloseConfiguration(ConfigurationHandle);  
  577.     }  
  578.   
  579.     NdisRestartAttributes = RestartParameters->RestartAttributes;  
  580.   
  581.     
  582.     if (NdisRestartAttributes != NULL)  
  583.     {  
  584.         PNDIS_RESTART_ATTRIBUTES   NextAttributes;  
  585.           
  586.         ASSERT(NdisRestartAttributes->Oid == OID_GEN_MINIPORT_RESTART_ATTRIBUTES);  
  587.       
  588.         NdisGeneralAttributes = (PNDIS_RESTART_GENERAL_ATTRIBUTES)NdisRestartAttributes->Data;  
  589.       
  590.         NdisGeneralAttributes->LookaheadSize = 128;  
  591.   
  592.         NextAttributes = NdisRestartAttributes->Next;  
  593.   
  594.         while (NextAttributes != NULL)  
  595.         {  
  596.   
  597.             NextAttributes = NextAttributes->Next;  
  598.         }  
  599.       
  600.     }  
  601.   
  602.      
  603.     pFilter->State = FilterRunning;   
  604.   
  605.   
  606.     Status = NDIS_STATUS_SUCCESS;  
  607.       
  608.     if (Status != NDIS_STATUS_SUCCESS)  
  609.     {  
  610.         pFilter->State = FilterPaused;  
  611.     }  
  612.       
  613.       
  614.     DEBUGP(DL_TRACE, ("<===FilterRestart:  FilterModuleContext %p, Status %x\n", FilterModuleContext, Status));  
  615.     return Status;  
  616. }  
  617.   
  618.   
  619.   
  620. /**************************************************************   
  621. FilterDetach函数的功能: 
  622.    Detach状态:当Filter Driver从一个驱动栈上分离一个Filter Module时,将发生该事件。 
  623.    在驱动栈上分离一个过滤模块时,NDIS会暂停这个驱动栈。这意味着NDIS已经使过滤模块进入 
  624.    了Parse状态。即FilterPause函数先被调用了。 
  625.  
  626.    在这个例程中释放和这个过滤模块相关的环境上下文和其它资源。这个过程不能失败。 
  627.    当FilterDetach函数返回以后,NDIS会重新启动被暂停的驱动栈。 
  628.     
  629.    参数说明: 
  630.     FilterDriverContext  它由NdisFRegisterFilterDriver的FilterDriverContext来指定。 
  631.  ************************************************************/  
  632. VOID  
  633. FilterDetach(  
  634.         IN  NDIS_HANDLE     FilterModuleContext  
  635.         )  
  636.   
  637. {  
  638.     PMS_FILTER                  pFilter = (PMS_FILTER)FilterModuleContext;  
  639.     BOOLEAN                      bFalse = FALSE;  
  640.   
  641.   
  642.     DEBUGP(DL_TRACE, ("===>FilterDetach:    FilterInstance %p\n", FilterModuleContext));  
  643.   
  644.     
  645.     FILTER_ASSERT(pFilter->State == FilterPaused);  
  646.           
  647.      
  648.     if (pFilter->FilterName.Buffer != NULL)  
  649.     {  
  650.         FILTER_FREE_MEM(pFilter->FilterName.Buffer);  
  651.     }  
  652.   
  653.   
  654.     FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);  
  655.     RemoveEntryList(&pFilter->FilterModuleLink);  
  656.     FILTER_RELEASE_LOCK(&FilterListLock, bFalse);  
  657.   
  658.   
  659.     FILTER_FREE_MEM(pFilter);  
  660.   
  661.     
  662.     DEBUGP(DL_TRACE, ("<===FilterDetach Successfully\n"));  
  663.       
  664.     return;  
  665. }  
  666.   
  667.   
  668.   
  669.   
  670. /************************************************************** 
  671.  系统只会在调用FilterDetach()分离了所有和本Filter Driver相关的Filter Module以后,才会调用FilterUnload例程。 
  672. ****************************************************************/  
  673. VOID  
  674. FilterUnload(  
  675.         IN  PDRIVER_OBJECT      DriverObject  
  676.         )  
  677.   
  678. {  
  679. #if DBG      
  680.     BOOLEAN               bFalse = FALSE;  
  681. #endif  
  682.   
  683.     UNREFERENCED_PARAMETER(DriverObject);  
  684.   
  685.     DEBUGP(DL_TRACE, ("===>FilterUnload\n"));  
  686.       
  687.      
  688.     FilterDeregisterDevice();  
  689.     NdisFDeregisterFilterDriver(FilterDriverHandle);  
  690.       
  691. #if DBG      
  692.     FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);  
  693.     ASSERT(IsListEmpty(&FilterModuleList));  
  694.   
  695.     FILTER_RELEASE_LOCK(&FilterListLock, bFalse);  
  696.       
  697. #endif      
  698.       
  699.     FILTER_FREE_LOCK(&FilterListLock);  
  700.       
  701.     DEBUGP(DL_TRACE, ("<===FilterUnload\n"));  
  702.   
  703.     return;  
  704.       
  705. }  
  706.   
  707.   
  708.   
  709. /*************************************************************** 
  710.  FilterOidRequest函数的功能: 
  711.   Filter Module可以在Runnig状态、Restarting状态、Paused状态和Pauseing状态进行OID的控制和处理。 
  712.   Filter Driver可以处理上层驱动引发的OID请求,NDIS调用Filter Driver的FilterOidRequest例程来处理OID请求,Filter Driver需要调用NdisFOidRequest例程来转发请求给下层驱动。  
  713.  
  714.   Filter Driver可以从FilterOidRequest同步和异步完成一个OID请求,分别返回NDIS_STATS_SUCCESS和NDIS_STATUS_PENDING即可。FilterOidRequest可以用同步的直接完成一个OID请求并返回一个错误状态。  
  715.  
  716.   如果FilterOidRequest返回NDIS_STATUS_PENDING,就必须在OID请求完成后调用 
  717.   NdisFOidRequestComplete来通知上层驱动求请求完成。在这种情况下,请求的结果通过 
  718.   NdisFOidRequestComplete的OidRequest参数返回给上层驱动,并通过Status参数返回请求完成的最终状态。 
  719.     
  720.  
  721.   如果FilterOidRequest返回NDIS_STATUS_SUCCESS,通过FilterOidRequest的OidRequest参数返回一个查询结果到上层。这时不调用 NdisFOidRequestComplete例程。  
  722.  
  723.  
  724.   要转发OID请求到下层驱动,Filter Driver必须调用NdisFOidRequest。如果一个OID请求不能被转发到下层驱动应该当立即返回。要完成一个请求且不转发可以直接返回NDIS_STATUS_SUCCESS或其它错误状态或返回 NDIS_STATUS_PENDING 后调用NdisFOidRequestComplete。  
  725.  
  726.  
  727.   如果NdisFOidRequest返回NDIS_STATUS_PENDING,NDIS在OID请求完成后调用FilterOidRequestComplete来通知求请求完成在这种情况下,请求的结果通过NdisFOidRequestComplete的OidRequest参数返回给上层驱动,并通过 Status 参数返回请求完成的最终状态。 
  728.     
  729.  
  730.   如果 NdisFOidRequest返回NDIS_STATUS_SUCCESS,通过NdisFOidRequest的OidRequest参数返回一个查询结果到上层。这时不调用FilterOidRequestComplete例程。  
  731.   一个Filter Driver可以调用NdisFOidRequest引发OID请求在Restarting、Running、Pausing和Paused 状态。  
  732.    
  733.   注意:Filter Driver必须跟踪这个请求确保不在FilterOidRequestComplete中调用NdisFOidRequestComplete(因为请求是自己引发的不能传到上层)。  
  734.  ****************************************************************/  
  735. NDIS_STATUS  
  736. FilterOidRequest(IN  NDIS_HANDLE   FilterModuleContext,IN  PNDIS_OID_REQUEST   Request)  
  737.   
  738. {  
  739.     PMS_FILTER              pFilter = (PMS_FILTER)FilterModuleContext;  
  740.     NDIS_STATUS             Status;  
  741.     PNDIS_OID_REQUEST       ClonedRequest=NULL;  
  742.     BOOLEAN                 bSubmitted = FALSE;  
  743.     PFILTER_REQUEST_CONTEXT Context;  
  744.     BOOLEAN               bFalse = FALSE;  
  745.   
  746.       
  747.     DEBUGP(DL_TRACE, ("===>FilterOidRequest: Request %p.\n", Request));  
  748.   
  749.     do  
  750.     {  
  751.         Status = NdisAllocateCloneOidRequest(pFilter->FilterHandle,  
  752.                                             Request,  
  753.                                             FILTER_TAG,  
  754.                                             &ClonedRequest);  
  755.         if (Status != NDIS_STATUS_SUCCESS)  
  756.         {  
  757.             DEBUGP(DL_WARN, ("FilerOidRequest: Cannot Clone Request\n"));  
  758.             break;  
  759.         }  
  760.   
  761.         Context = (PFILTER_REQUEST_CONTEXT)(&ClonedRequest->SourceReserved[0]);  
  762.         *Context = Request;  
  763.   
  764.         bSubmitted = TRUE;  
  765.   
  766.          
  767.         ClonedRequest->RequestId = Request->RequestId;  
  768.   
  769.         pFilter->PendingOidRequest = ClonedRequest;  
  770.   
  771.   
  772. //Filter Driver可以调用NdisFOidRequest引发一个OID查询和设置请求给下层驱动。  
  773.         Status = NdisFOidRequest(pFilter->FilterHandle, ClonedRequest);  
  774.   
  775.         if (Status != NDIS_STATUS_PENDING)  
  776.         {  
  777.   
  778.             FilterOidRequestComplete(pFilter, ClonedRequest, Status);  
  779.             Status = NDIS_STATUS_PENDING;  
  780.         }   
  781.   
  782.           
  783.     }while (bFalse);  
  784.   
  785.     if (bSubmitted == FALSE)  
  786.     {  
  787.         switch(Request->RequestType)  
  788.         {  
  789.             case NdisRequestMethod:  
  790.                 Request->DATA.METHOD_INFORMATION.BytesRead = 0;  
  791.                 Request->DATA.METHOD_INFORMATION.BytesNeeded = 0;   
  792.                 Request->DATA.METHOD_INFORMATION.BytesWritten = 0;   
  793.                 break;  
  794.   
  795.             case NdisRequestSetInformation:  
  796.                 Request->DATA.SET_INFORMATION.BytesRead = 0;  
  797.                 Request->DATA.SET_INFORMATION.BytesNeeded = 0;   
  798.                 break;  
  799.   
  800.             case NdisRequestQueryInformation:  
  801.             case NdisRequestQueryStatistics:  
  802.             default:  
  803.                 Request->DATA.QUERY_INFORMATION.BytesWritten = 0;  
  804.                 Request->DATA.QUERY_INFORMATION.BytesNeeded = 0;   
  805.                 break;  
  806.         }  
  807.   
  808.     }  
  809.     DEBUGP(DL_TRACE, ("<===FilterOidRequest: Status %8x.\n", Status));  
  810.   
  811.     return Status;  
  812.   
  813. }  
  814.   
  815.   
  816.   
  817. /************************************************************* 
  818.  FilterCancelOidRequest函数的功能: 
  819.   NDIS调用FilterCancelOidRequest来取消一个OID请求,当NDIS调用FilterCancelOidRequest时, 
  820.   Filter Driver应该尽可能快的调用NdisFCancelOidRequest。  
  821.  *************************************************************/  
  822. VOID  
  823. FilterCancelOidRequest(  
  824.     IN  NDIS_HANDLE             FilterModuleContext,  
  825.     IN  PVOID                   RequestId  
  826.     )  
  827. {  
  828.     PMS_FILTER                          pFilter = (PMS_FILTER)FilterModuleContext;  
  829.     PNDIS_OID_REQUEST                   Request = NULL;  
  830.     PFILTER_REQUEST_CONTEXT             Context;  
  831.     PNDIS_OID_REQUEST                   OriginalRequest = NULL;  
  832.     BOOLEAN               bFalse = FALSE;  
  833.        
  834.     FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse);  
  835.       
  836.     Request = pFilter->PendingOidRequest;  
  837.   
  838.     if (Request != NULL)  
  839.     {  
  840.         Context = (PFILTER_REQUEST_CONTEXT)(&Request->SourceReserved[0]);  
  841.       
  842.         OriginalRequest = (*Context);  
  843.     }  
  844.   
  845.     if ((OriginalRequest != NULL) && (OriginalRequest->RequestId == RequestId))  
  846.     {  
  847.         FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse);  
  848.           
  849.         NdisFCancelOidRequest(pFilter->FilterHandle, RequestId);  
  850.     }  
  851.     else  
  852.     {  
  853.         FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse);  
  854.     }  
  855.           
  856.   
  857. }  
  858.   
  859.       
  860. VOID  
  861. FilterOidRequestComplete(  
  862.         IN  NDIS_HANDLE         FilterModuleContext,  
  863.         IN  PNDIS_OID_REQUEST   Request,  
  864.         IN  NDIS_STATUS         Status  
  865.         )  
  866.   
  867. {  
  868.     PMS_FILTER                          pFilter = (PMS_FILTER)FilterModuleContext;  
  869.     PNDIS_OID_REQUEST                   OriginalRequest;  
  870.     PFILTER_REQUEST_CONTEXT             Context;  
  871.     BOOLEAN               bFalse = FALSE;  
  872.       
  873.     DEBUGP(DL_TRACE, ("===>FilterOidRequestComplete, Request %p.\n", Request));  
  874.   
  875.     Context = (PFILTER_REQUEST_CONTEXT)(&Request->SourceReserved[0]);  
  876.     OriginalRequest = (*Context);  
  877.   
  878.      
  879.     if (OriginalRequest == NULL)  
  880.     {  
  881.         filterInternalRequestComplete(pFilter, Request, Status);  
  882.         return;  
  883.     }  
  884.   
  885.   
  886.     FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse);  
  887.       
  888.     ASSERT(pFilter->PendingOidRequest == Request);  
  889.     pFilter->PendingOidRequest = NULL;  
  890.   
  891.     FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse);  
  892.   
  893.     switch(Request->RequestType)  
  894.     {  
  895.         case NdisRequestMethod:  
  896.             OriginalRequest->DATA.METHOD_INFORMATION.OutputBufferLength =  Request->DATA.METHOD_INFORMATION.OutputBufferLength;  
  897.             OriginalRequest->DATA.METHOD_INFORMATION.BytesRead = Request->DATA.METHOD_INFORMATION.BytesRead;  
  898.             OriginalRequest->DATA.METHOD_INFORMATION.BytesNeeded = Request->DATA.METHOD_INFORMATION.BytesNeeded;   
  899.             OriginalRequest->DATA.METHOD_INFORMATION.BytesWritten = Request->DATA.METHOD_INFORMATION.BytesWritten;   
  900.             break;  
  901.   
  902.         case NdisRequestSetInformation:    
  903.             OriginalRequest->DATA.SET_INFORMATION.BytesRead = Request->DATA.SET_INFORMATION.BytesRead;  
  904.             OriginalRequest->DATA.SET_INFORMATION.BytesNeeded = Request->DATA.SET_INFORMATION.BytesNeeded;   
  905.             break;  
  906.   
  907.         case NdisRequestQueryInformation:  
  908.         case NdisRequestQueryStatistics:  
  909.         default:       
  910.             OriginalRequest->DATA.QUERY_INFORMATION.BytesWritten = Request->DATA.QUERY_INFORMATION.BytesWritten;  
  911.             OriginalRequest->DATA.QUERY_INFORMATION.BytesNeeded = Request->DATA.QUERY_INFORMATION.BytesNeeded;  
  912.             break;  
  913.     }  
  914.   
  915.   
  916.     (*Context) = NULL;  
  917.   
  918.     NdisFreeCloneOidRequest(pFilter->FilterHandle, Request);  
  919.   
  920.   
  921. /* 
  922. 如果FilterOidRequest返回NDIS_STATUS_PENDING,就必须在OID请求完成后调用NdisFOidRequestComplete 来通知上层驱动求请求完成。在这种情况下,请求的结果通过NdisFOidRequestComplete的OidRequest参数返回给上层驱动,并通过Status参数返回请求完成的最终状态。 
  923. 要转发OID请求到下层驱动,Filter Driver必须调用NdisFOidRequest。 
  924. 如果一个OID请求不能被转发到下层驱动应该当立即返回。 
  925. 要完成一个请求且不转发可以直接返回NDIS_STATUS_SUCCESS或其它错误状态 
  926. 或返回NDIS_STATUS_PENDING后调用NdisFOidRequestComplete。   
  927. */  
  928.   
  929.     NdisFOidRequestComplete(pFilter->FilterHandle, OriginalRequest, Status);  
  930.       
  931.     DEBUGP(DL_TRACE, ("<===FilterOidRequestComplete.\n"));  
  932. }  
  933.   
  934.   
  935.   
  936.   
  937. /************************************************************* 
  938.   FilterStatus函数的功能: 
  939.     当下层驱动报告状态的时候 NDIS会调用它。此外,Filter Driver还可以自己引发一个状态指示。 
  940.  
  941. 当下层驱动调用一个状态指示例程时(NdisMIndicateStatusEx或NdisFIndicateStats),NDIS 
  942. 会调用Filter Driver的FilterStatus例程。 
  943.  
  944. Filter Driver在FilterStatus中调用NdisFIndicateStatus传递一个状态指示给上层驱动。此外,还可以过滤状态指示(不用调用 NdisFIndicateStatus)或在调用 NdisFIndicateStatus之前修改状态信息。 
  945.    
  946.     
  947. Filter Driver要自己引发一个状态报告,可以在NDIS未调用 FilterStatus的情况下调用NdisFIndicateStatus。在这种情况下,Filter Driver要设置 SourceHandle 成员为 FilteAttech 参数提供的NdisFilterHandle句柄。 
  948. 如果一个状态指示是一个OID请求相关的(下层请求一个 OID 下层要做相应的状态指示),那么状态的DestinationHandle和RequestId成员要设置成上层的OID请求包携带的数据。  
  949.    
  950.  
  951. Filter Driver调用NdisFIndicateStatus后NDIS会调用相邻上层的状态指示函数(ProtocolStatusEx或FilterStatus)。  
  952. ****************************************************************/  
  953. VOID  
  954. FilterStatus(  
  955.         IN  NDIS_HANDLE             FilterModuleContext,  
  956.         IN  PNDIS_STATUS_INDICATION StatusIndication  
  957.         )  
  958.   
  959. {  
  960.     PMS_FILTER              pFilter = (PMS_FILTER)FilterModuleContext;  
  961. #if DBG      
  962.     BOOLEAN                  bFalse = FALSE;  
  963. #endif  
  964.   
  965.     DEBUGP(DL_TRACE, ("===>FilterStaus, IndicateStatus = %8x.\n", StatusIndication->StatusCode));  
  966.      
  967. #if DBG  
  968.     FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse);  
  969.     ASSERT(pFilter->bIndicating == FALSE);  
  970.     pFilter->bIndicating = TRUE;  
  971.     FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse);  
  972. #endif      
  973.       
  974.      
  975.     NdisFIndicateStatus(pFilter->FilterHandle, StatusIndication);  
  976.   
  977. #if DBG      
  978.     FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse);  
  979.     ASSERT(pFilter->bIndicating == TRUE);  
  980.     pFilter->bIndicating = FALSE;  
  981.       
  982.     FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse);  
  983.   
  984.   
  985. #endif  
  986.       
  987.     DEBUGP(DL_TRACE, ("<===FilterStaus.\n"));  
  988.   
  989. }  
  990.   
  991.   
  992.   
  993.   
  994. /* 
  995. Filter Driver提供FilterPnpEventNotify来接收NDIS传递的PnP和电源管理事件 
  996. */  
  997. VOID  
  998. FilterDevicePnPEventNotify(  
  999.         IN  NDIS_HANDLE             FilterModuleContext,  
  1000.         IN  PNET_DEVICE_PNP_EVENT   NetDevicePnPEvent  
  1001.         )  
  1002.   
  1003. {  
  1004.     PMS_FILTER          pFilter = (PMS_FILTER)FilterModuleContext;  
  1005.     NDIS_DEVICE_PNP_EVENT   DevicePnPEvent = NetDevicePnPEvent->DevicePnPEvent;  
  1006. #if DBG  
  1007.     BOOLEAN             bFalse = FALSE;  
  1008. #endif  
  1009.   
  1010.     DEBUGP(DL_TRACE, ("===>FilterDevicePnPEventNotify: NetPnPEvent = %p.\n", NetDevicePnPEvent));  
  1011.   
  1012.     switch (DevicePnPEvent)  
  1013.     {  
  1014.   
  1015.         case NdisDevicePnPEventQueryRemoved:   
  1016.         case NdisDevicePnPEventRemoved:  
  1017.         case NdisDevicePnPEventSurpriseRemoved:  
  1018.         case NdisDevicePnPEventQueryStopped:  
  1019.         case NdisDevicePnPEventStopped:  
  1020.         case NdisDevicePnPEventPowerProfileChanged:  
  1021.         case NdisDevicePnPEventFilterListChanged:  
  1022.                   
  1023.             break;  
  1024.               
  1025.         default:  
  1026.             DEBUGP(DL_ERROR, ("FilterDevicePnPEventNotify: Invalid event.\n"));  
  1027.             FILTER_ASSERT(bFalse);  
  1028.               
  1029.             break;  
  1030.     }  
  1031.   
  1032.   //Filter Driver要下层驱动转发收到的事件,转发事件要用到NdisFDevicePnPEventNotify例程  
  1033.     NdisFDevicePnPEventNotify(pFilter->FilterHandle, NetDevicePnPEvent);  
  1034.                                 
  1035.     DEBUGP(DL_TRACE, ("<===FilterDevicePnPEventNotify\n"));  
  1036.   
  1037. }  
  1038.   
  1039.   
  1040.   
  1041.   
  1042.   
  1043. /* 
  1044. Filter Driver提供了FilterNetPnpEvent例程来处理网络Pnp和电源管理事件通知。 
  1045. */  
  1046. NDIS_STATUS  
  1047. FilterNetPnPEvent(  
  1048.         IN  NDIS_HANDLE             FilterModuleContext,  
  1049.         IN  PNET_PNP_EVENT_NOTIFICATION NetPnPEventNotification  
  1050.         )  
  1051. {  
  1052.     PMS_FILTER             pFilter = (PMS_FILTER)FilterModuleContext;  
  1053.     NDIS_STATUS           Status = NDIS_STATUS_SUCCESS;  
  1054.   
  1055. //Filter Driver需要转发网络PnP和电源管理事件给上层驱动。转发这些事件是通NdisFNetPnpEvent来完成的。   
  1056.     Status = NdisFNetPnPEvent(pFilter->FilterHandle, NetPnPEventNotification);  
  1057.       
  1058.     return Status;  
  1059. }  
  1060.   
  1061.   
  1062.   
  1063.   
  1064. /************************************************************** 
  1065.  FilterSendNetBufferListsComplete函数的功能: 
  1066.   NDIS调用 FilterSendNetBufferListsComplete 把发送的结构和数据返还给 Filter Driver。NDIS可以收集多次NdisFSendNetBufferLists发送的结构和数据形成一个单链表传递给FilterSendNetBufferListsComplete。除非到NDIS调用FilterSendNetBufferListsComplete,否则一个发送请求的当前状态总是未知的。 
  1067.  
  1068.   一个过滤驱动是不能在NDIS调用FilterSendNetBufferListsComplete返回结构之前对NET_BUFFER_LIST和其关联的数据做检查的。FilterSendNetBufferListsComplete要完成一个发送请求完成后的任何必要的后继处理。当NDIS调用FilterSendNetBufferListsComplete时,Filter Driver就重新获地对结构及结构相关资源的所有权。可以在 FilterSendNetBufferListsComplete中释放相关的资源和准备下一个NdisFSendNetBufferLists调用。  
  1069.   
  1070.   NDIS总是按照过滤驱动调用NdisFSendNetBufferLists提交的顺序传递给下层驱动,但是回返FilterSendNetBufferListsComplete 的顺序则是任意的。Filter Driver可以请求一个回环发送请求,只要把NdisFSendNetBufferLists的SendFlags设置成NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK就行了。NDIS会引发一个包含发送数据的接收包指示。 
  1071.    
  1072.     
  1073.   一个Filter Driver应该对自己引发的发送请求保持跟踪并确保在完成时不调用NdisFSendNetBufferComplete例程。  
  1074.  **************************************************************/  
  1075. VOID  
  1076. FilterSendNetBufferListsComplete(  
  1077.         IN  NDIS_HANDLE         FilterModuleContext,  
  1078.         IN  PNET_BUFFER_LIST    NetBufferLists,  
  1079.         IN  ULONG               SendCompleteFlags  
  1080.         )  
  1081.   
  1082. {  
  1083.     PMS_FILTER         pFilter = (PMS_FILTER)FilterModuleContext;  
  1084.     ULONG              NumOfSendCompletes = 0;  
  1085.     BOOLEAN            DispatchLevel;  
  1086.     PNET_BUFFER_LIST   CurrNbl;  
  1087.      
  1088.     DEBUGP(DL_TRACE, ("===>SendNBLComplete, NetBufferList: %p.\n", NetBufferLists));  
  1089.   
  1090.      
  1091.     if (pFilter->TrackSends)  
  1092.     {  
  1093.         CurrNbl = NetBufferLists;  
  1094.         while (CurrNbl)  
  1095.         {  
  1096.             NumOfSendCompletes++;  
  1097.             CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);  
  1098.               
  1099.         }  
  1100.         DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendCompleteFlags);  
  1101.         FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);  
  1102.         pFilter->OutstandingSends -= NumOfSendCompletes;  
  1103.         FILTER_LOG_SEND_REF(2, pFilter, PrevNbl, pFilter->OutstandingSends);          
  1104.         FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);  
  1105.     }  
  1106.   
  1107.     NdisFSendNetBufferListsComplete(pFilter->FilterHandle, NetBufferLists, SendCompleteFlags);  
  1108.   
  1109.     DEBUGP(DL_TRACE, ("<===SendNBLComplete.\n"));  
  1110. }  
  1111.   
  1112.   
  1113.   
  1114.   
  1115. /************************************************************* 
  1116.  FilterSendNetBufferLists函数的功能: 
  1117.   NDIS调用一个Filter Driver的FilterSendNetBufferLists例程来过滤上层驱动的发送请求。Filter Driver不能改变其它驱动传来的NET_BUFFER_LIST结构中的SourceHandle成员的值。它可以过滤数据并发送过滤的数据到下层驱动。 
  1118.   对每一个提交到FilterSendNetBufferLists的NDIS_BUFFER_LIST,我们可做下面的操作。 
  1119.     
  1120.   1)可以把缓冲区通过 NdisFSendBufferLists 传递给下层驱动,NDIS 保证上下文空间对FilterDriver的有效性。过滤驱动可以在发送前修改缓冲区的内容。可以像处理自己引发的发送请求的缓冲区一样处理这个缓冲区。    
  1121.   2)可以调用 NdisFSendNetBufferListsComplete 拒绝传递这个包  
  1122.   3)排队缓冲区内容到本地的供以后处理。例如要在一定超时后处理或要接收到特定包后才处理等。如果支持这种处理方式就要支持取消请求的操作。      
  1123.   4)可以拷贝缓冲区并引发一个发送请求。它类似自己引发一个发送请求,但必须先调用 NdisFSendNetBufferComplete返回上层驱动的缓冲区。 
  1124.        
  1125.   发送请求在驱动栈继续完成,当一个微端口驱动调用NdisMSendNetBufferListsComplete完成一个发送请求时,NDIS会调用微端口 
  1126.   驱动之上最近的Filter Driver的FilterSendNetBufferLists例程。 
  1127.    
  1128.   在一个发送操作完成后,Filter Driver可以做在FilterSendNetBufferLists中所有修改的相反操作。FilterSendNetBufferListsComplete返回一个NET_BUFFER_LIST结构的单链表和发送请求的最终状态给上层的驱动。当最顶层的 Filter Module的FilterSendNetBufferListsComplete被调用完成后NDIS会调用引发发送请求的协议驱动的ProtocolSendNetBufferListsComplete。如果Filter Driver不提供FilterSendNetBufferLists它还是可以引发一个发送操作的,但它必须提供一个FilterSendNetBufferListsComplete并且不能在这个例程里把这个事件传递给上层驱动。 
  1129.  
  1130.   一个Filter Driver可以传递或过滤一个上层驱动的回环请求,要传递一个回环请求,NDIS会设置FilterSendNetBufferLists的SendFlags参数为NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK,Filter Driver在调用NdisFSendNetBufferLists时把这个标记传给它即可。在回环请求的情况下NDIS会指示一个包含发送数据的接收包。 
  1131.  
  1132.   通常情况下,如果一个Filter Driver修改的任何行为不是NDIS提供的标准服务,那么它应该当自己为NDIS提供相应的服务。例如,如果一个Filter Driver修改了一个硬件地址请求,就必须处理直接到这个新地址回环包。在这种情况下, 因为Filter Driver已经更改了地址NDIS是不能提供一个回环服务的。 
  1133.   还有就是如果Filter Driver设置了混杂模式那它就不能传递额外的数据给上层接收。  
  1134. **************************************************************/  
  1135.   
  1136. VOID  
  1137. FilterSendNetBufferLists(  
  1138.         IN  NDIS_HANDLE         FilterModuleContext,  
  1139.         IN  PNET_BUFFER_LIST    NetBufferLists,  
  1140.         IN  NDIS_PORT_NUMBER    PortNumber,  
  1141.         IN  ULONG               SendFlags  
  1142.         )  
  1143.   
  1144.   
  1145. {  
  1146.     PMS_FILTER          pFilter = (PMS_FILTER)FilterModuleContext;  
  1147.     PNET_BUFFER_LIST    CurrNbl;  
  1148.     BOOLEAN             DispatchLevel;  
  1149.     BOOLEAN               bFalse = FALSE;  
  1150.       
  1151.     DEBUGP(DL_TRACE, ("===>SendNetBufferList: NBL = %p.\n", NetBufferLists));  
  1152.   
  1153.     do  
  1154.     {  
  1155.   
  1156.        DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags);  
  1157.   
  1158. #if DBG   
  1159.           
  1160.         FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);  
  1161.           
  1162.         if (pFilter->State != FilterRunning)  
  1163.         {  
  1164.             FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);  
  1165.               
  1166.             CurrNbl = NetBufferLists;  
  1167.             while (CurrNbl)  
  1168.             {  
  1169.                 NET_BUFFER_LIST_STATUS(CurrNbl) = NDIS_STATUS_PAUSED;  
  1170.                 CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);  
  1171.             }  
  1172.             NdisFSendNetBufferListsComplete(pFilter->FilterHandle,   
  1173.                         NetBufferLists,   
  1174.                         DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0);  
  1175.             break;  
  1176.               
  1177.         }  
  1178.         FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);  
  1179. #endif  
  1180.   
  1181. /******************************************************/  
  1182.   
  1183.              //在这里添加我们的代码  
  1184.   
  1185. /******************************************************/  
  1186.   
  1187.         if (pFilter->TrackSends)  
  1188.         {  
  1189.             FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);  
  1190.             CurrNbl = NetBufferLists;  
  1191.             while (CurrNbl)  
  1192.             {  
  1193.                 pFilter->OutstandingSends++;  
  1194.                 FILTER_LOG_SEND_REF(1, pFilter, CurrNbl, pFilter->OutstandingSends);  
  1195.                   
  1196.                 CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);  
  1197.             }  
  1198.             FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);  
  1199.         }  
  1200.          
  1201.   
  1202.         NdisFSendNetBufferLists(pFilter->FilterHandle, NetBufferLists, PortNumber, SendFlags);  
  1203.           
  1204.           
  1205.     }  
  1206.     while (bFalse);  
  1207.       
  1208.     DEBUGP(DL_TRACE, ("<===SendNetBufferList. \n"));  
  1209. }  
  1210.   
  1211.   
  1212.   
  1213.   
  1214. /************************************************************* 
  1215.  FilterReturnNetBufferLists函数的功能: 
  1216.   如果Filter Driver设置了NdisFIndicateReceiveNetBufferLists的状态为NDIS_STATUS_SUCCESS, NDIS通过驱动的FilterReturnNetBufferLists 
  1217.   返回指示数据。在这种情况下 Filter Driver失去了对NET_BUFFER_LIST的所有权,直到FilterReturnNetBufferLists被调用。 
  1218.  
  1219.   Filter Driver调用NdisFIndicateNetBufferLists 传递接收指示给驱动栈上的上层驱动,如果上层驱动保留了对缓冲区(NET_BUFFER_LIST)的所有权,NDIS会调用Filter Driver的FilterReturnNetBufferLists 例程。 
  1220.    
  1221.   在FilterReturnNetBufferLists中应该撤消在接收路径上(如在 FilterReciveNetBufferLists中做的一些处理)的操作。当最底层的Filter Module完成对缓冲区(NET_BUFFER_LIST)的处理后,NDIS把缓冲区返回给微端口驱动。如果FilterReceiveNetBufferLists的ReceiveFlags没有设置NDIS_RECEIVE_FLAGS_RESOURCES标记, FilterDriver调用NdisFReturnNetBufferList返回这个缓冲区数据,如果设置了FilterReceiveNetBufferLists直接返回时就把缓冲区返还给了下层微端口驱动。   
  1222.  ***************************************************************/  
  1223. VOID  
  1224. FilterReturnNetBufferLists(  
  1225.         IN  NDIS_HANDLE         FilterModuleContext,  
  1226.         IN  PNET_BUFFER_LIST    NetBufferLists,  
  1227.         IN  ULONG               ReturnFlags  
  1228.         )  
  1229.   
  1230. {  
  1231.     PMS_FILTER          pFilter = (PMS_FILTER)FilterModuleContext;  
  1232.     PNET_BUFFER_LIST    CurrNbl = NULL;  
  1233.     UINT                NumOfNetBufferLists = 0;  
  1234.     BOOLEAN             DispatchLevel;  
  1235.     ULONG               Ref;  
  1236.       
  1237.     DEBUGP(DL_TRACE, ("===>ReturnNetBufferLists, NetBufferLists is %p.\n", NetBufferLists));  
  1238.   
  1239.     if (pFilter->TrackReceives)  
  1240.     {  
  1241.         while (CurrNbl)  
  1242.         {  
  1243.               
  1244.             NumOfNetBufferLists ++;  
  1245.             CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);  
  1246.         }  
  1247.     }  
  1248.     NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReturnFlags);  
  1249.    
  1250.     if (pFilter->TrackReceives)  
  1251.     {  
  1252.         DispatchLevel = NDIS_TEST_RETURN_AT_DISPATCH_LEVEL(ReturnFlags);  
  1253.         FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);  
  1254.   
  1255.         pFilter->OutstandingRcvs -= NumOfNetBufferLists;  
  1256.         Ref = pFilter->OutstandingRcvs;  
  1257.         FILTER_LOG_RCV_REF(3, pFilter, NetBufferLists, Ref);  
  1258.         FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);  
  1259.     }                  
  1260.   
  1261.   
  1262.     DEBUGP(DL_TRACE, ("<===ReturnNetBufferLists.\n"));  
  1263.       
  1264.   
  1265. }  
  1266.   
  1267.   
  1268.   
  1269. /*************************************************************** 
  1270.  FilterReceiveNetBufferLists函数的功能: 
  1271.   Filter Driver调用 NdisFIndicateReceiveNetBufferLists来指示发送数据。这个函数通过NET_BUFFER_LIST结构给上层驱动指示数据。Filter Driver可以从池中分配这个结构。如果Filter Driver设置了NdisFIndicateReceiveNetBufferLists的状态为 NDIS_STATUS_SUCCESS, NDIS通过驱动的FilterReturnNetBufferLists返回指示数据。在这种情况下Filter Driver失去了对NET_BUFFER_LIST的所有权直到FilterReturnNetBufferLists被调用。如果Filter Driver在调用NdisFIndicateReceiveNetBufferLists时设置ReceiveFlags为NDIS_RECEIVE_FLAGS_RESOURCES,在函数返回后Filter Driver会立即恢复对NET_BUFFER_LIST的所有权,这时Filter Driver必须立即处理这个NET_BUFFER_LIST的返回,因为NDIS在这种情况下是不会调用FilterReturnNetBufferLists返回NET_BUFFER_LIST结构的。  
  1272.  
  1273.   注意: 一个Filter Driver应该跟踪自己引发的接收指示确保它在FilterReturnNetBufferLists 
  1274.   中不调用NdisFReturnNetBufferLists。  
  1275.  ***************************************************************/  
  1276. VOID  
  1277. FilterReceiveNetBufferLists(  
  1278.         IN  NDIS_HANDLE         FilterModuleContext,  
  1279.         IN  PNET_BUFFER_LIST    NetBufferLists,  
  1280.         IN  NDIS_PORT_NUMBER    PortNumber,  
  1281.         IN  ULONG               NumberOfNetBufferLists,  
  1282.         IN  ULONG               ReceiveFlags  
  1283.          )  
  1284.   
  1285. {  
  1286.   
  1287.     PMS_FILTER          pFilter = (PMS_FILTER)FilterModuleContext;  
  1288.     BOOLEAN             DispatchLevel;  
  1289.     ULONG               Ref;  
  1290.     BOOLEAN               bFalse = FALSE;  
  1291.   
  1292.   
  1293. #if DBG  
  1294.     ULONG               ReturnFlags;  
  1295. #endif  
  1296.       
  1297.     DEBUGP(DL_TRACE, ("===>ReceiveNetBufferList: NetBufferLists = %p.\n", NetBufferLists));  
  1298.     do  
  1299.     {  
  1300.   
  1301.         DispatchLevel = NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags);  
  1302. #if DBG  
  1303.         FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);  
  1304.    
  1305.         if (pFilter->State != FilterRunning)  
  1306.         {  
  1307.             FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);  
  1308.   
  1309.             if (NDIS_TEST_RECEIVE_CAN_PEND(ReceiveFlags))  
  1310.             {     
  1311.                 ReturnFlags = 0;  
  1312.                 if (NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags))  
  1313.                 {  
  1314.                     NDIS_SET_RETURN_FLAG(ReturnFlags, NDIS_RETURN_FLAGS_DISPATCH_LEVEL);  
  1315.                 }  
  1316.                   
  1317.                 NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReturnFlags);  
  1318.             }  
  1319.             break;  
  1320.         }  
  1321.         FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);  
  1322. #endif  
  1323.   
  1324.         ASSERT(NumberOfNetBufferLists >= 1);  
  1325.   
  1326.   
  1327. /*--------------------------------------------------------------------------------------*/            
  1328.   
  1329.                   //在这里添加我们的代码  
  1330.   
  1331.   
  1332. /*---------------------------------------------------------------------------------------*/  
  1333.   
  1334.   
  1335.         if (pFilter->TrackReceives)  
  1336.         {  
  1337.             FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);  
  1338.             pFilter->OutstandingRcvs += NumberOfNetBufferLists;  
  1339.             Ref = pFilter->OutstandingRcvs;  
  1340.               
  1341.             FILTER_LOG_RCV_REF(1, pFilter, NetBufferLists, Ref);  
  1342.             FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);  
  1343.         }  
  1344.   
  1345.   
  1346. /************************************************************ 
  1347. 调用 NdisFIndicateReceiveNetBufferLists来指示发送数据。 
  1348.  
  1349. 如果Filter Driver设置了NdisFIndicateReceiveNetBufferLists的状态为NDIS_STATUS_SUCCESS, NDIS通过驱动的FilterReturnNetBufferLists 返回指示数据。 
  1350.      
  1351. 如果Filter Driver设置了NdisFIndicateReceiveNetBufferLists的ReceiveFlags值为 
  1352. NDIS_RECEIVE_FLAGS_RESOURCES,那么在函数返回后Filter Driver会立即恢复对 
  1353. NET_BUFFER_LIST的所有权,这时Filter Driver必须立即处理这个NET_BUFFER_LIST的返回。 
  1354. 在这种情况下是不会调用FilterReturnNetBufferLists返回NET_BUFFER_LIST结构的。 
  1355. ************************************************************/  
  1356.         NdisFIndicateReceiveNetBufferLists(  
  1357.                    pFilter->FilterHandle,  
  1358.                    NetBufferLists,  
  1359.                    PortNumber,   
  1360.                    NumberOfNetBufferLists,  
  1361.                    ReceiveFlags);  
  1362.   
  1363.   
  1364.         if (NDIS_TEST_RECEIVE_CANNOT_PEND(ReceiveFlags) && pFilter->TrackReceives)  
  1365.         {  
  1366.             FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);  
  1367.             pFilter->OutstandingRcvs -= NumberOfNetBufferLists;  
  1368.             Ref = pFilter->OutstandingRcvs;  
  1369.             FILTER_LOG_RCV_REF(2, pFilter, NetBufferLists, Ref);  
  1370.             FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);  
  1371.         }  
  1372.   
  1373.     } while (bFalse);  
  1374.       
  1375.     DEBUGP(DL_TRACE, ("<===ReceiveNetBufferList: Flags = %8x.\n", ReceiveFlags));  
  1376.       
  1377. }  
  1378.   
  1379.   
  1380.   
  1381. /************************************************************** 
  1382.  FilterCancelSendNetBufferLists函数的功能: 
  1383.  过滤驱动调用NDIS_SET_NET_BUFFER_LIST_CANCEL_ID宏为每一个NET_BUFFER_LIST标记一个取消Id。 
  1384.  在为网络数据分配取消ID之前,必须先调用NdisGenratePartialCanceId获得取消ID的高字节。 
  1385.  这是为了确保不是驱动不会把一个取消ID分配给两个驱动驱动通常在DriverEntry调用 
  1386.  NdisGenratePartialCanceld,但是驱动可以在不同的时间多次调用它来获得多个取消ID。 
  1387.  要取消被标记过取消ID且正在传输的数据,驱动可以调用NdisFCancelSendNetBufferLists例程 
  1388.  来完成。要获得取消ID可以用NDIS_GET_NET_BUFFER_LIST_CANCEL_ID宏来完成。 
  1389.  
  1390.  如果一个Filter Driver对所有发送的NET_BUFFER_LIST标记了相同的取消ID那它可以用一个  
  1391.  NdisFCancelSendNetBufferLists来取消所有的发送请求。如果把一部发送请求的NET_BUFFER_LIST标记相同的取消ID那么就可以调用一次NdisFCancelSendNetBufferLists来取消这部分发送请求。 
  1392.  
  1393.  在实现这个功能时NDIS会调用下层驱动的取消发送功能。中断正在执行的发送任务后,下层驱动会 
  1394.  调用发送完成全程(如:NdisMSendNetBufferListComplete)返回指定的NET_BUFFER_LIST结构并指定 返回状态为 NDIS_STATUS_CANCELLED, NDIS依次调用Filter Driver的FilterSendNetBufferListsComplete例程。在FilterSendNetBufferListsComplete中要用NDIS_SET_NET_BUFFER_LIST_CANCEL_ID设置取消的NET_BUFFER_LIST  
  1395.  的取消ID 为 NULL,这样是为了防止这个ID,在 NET_BUFFER_LIST被再次分配时使用。  
  1396.  
  1397.  
  1398. 上层驱动在取消一个未完成的发送请求时也必须对这个发送请求的 NET_BUFFER_LIST结构设定取消ID。 
  1399.  NDIS会传递给Filter Driver的FilterCancelSendNetBufferLists一个取消ID来取消发送请求的 
  1400.  NET_BUFFER_LIST发送。FilterCanCelSendNetBufferLists下执行下列操作。   
  1401.   1)遍历 Filter Driver的发送队列,用 NDIS_GET_NET_BUFFER_LSIT_CANCEL_ID获得队列中NET_BUFFER_LIST的取消ID与FilterCancelSendBufferLists的取消ID比较。  
  1402.   2)移除队列中取消 ID 和 FilterCancelSentBufferLists中取消ID相同的元素。  
  1403.   3)调用 NdisFSendNetBufferListsComplete来完成这些NET_BUFFER_LIST并设定返回状 
  1404.     态为NDIS_STATUS_CANCELLED。  
  1405.   4)调用NdisFCancelSendNetBufferLists传递取消发送请求给下层驱动。传递取消ID给下层驱动就Filter Driver取消自己引发的发关请求一样。  
  1406.  *************************************************************/  
  1407. VOID  
  1408. FilterCancelSendNetBufferLists(  
  1409.     IN  NDIS_HANDLE             FilterModuleContext,  
  1410.     IN  PVOID                   CancelId  
  1411.     )  
  1412.   
  1413. {  
  1414.     PMS_FILTER  pFilter = (PMS_FILTER)FilterModuleContext;  
  1415.   
  1416.     NdisFCancelSendNetBufferLists(pFilter->FilterHandle,CancelId);  
  1417. }  
  1418.   
  1419.   
  1420.   
  1421.   
  1422. /************************************************************** 
  1423.  FilterSetModuleOptions函数的功能: 
  1424.   必须要在初始化时为驱动注册FilterSetModuleOptions例程,驱动可以在这个例程中初始化 
  1425.   NDIS_FILTER_PARTIAL_CHARACTERISTICS结构来调用NdisSetOptionalHandlers来完成必变。 
  1426.   这个例程如果存在那么在调用Filter Driver的FilterRestart例程之前调用它。 
  1427.  ***************************************************************/   
  1428. NDIS_STATUS  
  1429. FilterSetModuleOptions(  
  1430.     IN  NDIS_HANDLE             FilterModuleContext  
  1431.     )  
  1432. {  
  1433.       
  1434.    PMS_FILTER                   pFilter = (PMS_FILTER)FilterModuleContext;  
  1435.    NDIS_FILTER_PARTIAL_CHARACTERISTICS      OptionalHandlers;  
  1436.    NDIS_STATUS                Status = NDIS_STATUS_SUCCESS;  
  1437.    BOOLEAN               bFalse = FALSE;  
  1438.   
  1439.    
  1440.    if (bFalse)  
  1441.    {  
  1442.        UINT    i;  
  1443.   
  1444.         
  1445.        pFilter->CallsRestart++;  
  1446.   
  1447.        i = pFilter->CallsRestart % 8;  
  1448.   
  1449.        pFilter->TrackReceives = TRUE;  
  1450.        pFilter->TrackSends = TRUE;  
  1451.   
  1452.        NdisMoveMemory(&OptionalHandlers, &DefaultChars, sizeof(OptionalHandlers));  
  1453.        OptionalHandlers.Header.Type = NDIS_OBJECT_TYPE_FILTER_PARTIAL_CHARACTERISTICS;  
  1454.        OptionalHandlers.Header.Size = sizeof(OptionalHandlers);  
  1455.        switch (i)  
  1456.        {  
  1457.              
  1458.             case 0:   
  1459.                 OptionalHandlers.ReceiveNetBufferListsHandler = NULL;  
  1460.                 pFilter->TrackReceives = FALSE;  
  1461.                 break;  
  1462.   
  1463.             case 1:  
  1464.                   
  1465.                 OptionalHandlers.ReturnNetBufferListsHandler = NULL;  
  1466.                 pFilter->TrackReceives = FALSE;  
  1467.                 break;  
  1468.   
  1469.             case 2:  
  1470.                 OptionalHandlers.SendNetBufferListsHandler = NULL;  
  1471.                 pFilter->TrackSends = FALSE;  
  1472.                 break;  
  1473.   
  1474.             case 3:  
  1475.                 OptionalHandlers.SendNetBufferListsCompleteHandler = NULL;  
  1476.                 pFilter->TrackSends = FALSE;  
  1477.                 break;  
  1478.   
  1479.             case 4:  
  1480.                 OptionalHandlers.ReceiveNetBufferListsHandler = NULL;  
  1481.                 OptionalHandlers.ReturnNetBufferListsHandler = NULL;  
  1482.                 break;  
  1483.   
  1484.             case 5:  
  1485.                 OptionalHandlers.SendNetBufferListsHandler = NULL;  
  1486.                 OptionalHandlers.SendNetBufferListsCompleteHandler = NULL;  
  1487.                 break;  
  1488.   
  1489.             case 6:  
  1490.                   
  1491.                 OptionalHandlers.ReceiveNetBufferListsHandler = NULL;  
  1492.                 OptionalHandlers.ReturnNetBufferListsHandler = NULL;  
  1493.                 OptionalHandlers.SendNetBufferListsHandler = NULL;  
  1494.                 OptionalHandlers.SendNetBufferListsCompleteHandler = NULL;  
  1495.                 break;  
  1496.                   
  1497.             case 8:  
  1498.                 break;  
  1499.        }  
  1500.        Status = NdisSetOptionalHandlers(pFilter->FilterHandle, (PNDIS_DRIVER_OPTIONAL_HANDLERS)&OptionalHandlers );  
  1501.    }  
  1502.    return Status;  
  1503. }  
  1504.   
  1505.   
  1506.   
  1507. NDIS_STATUS  
  1508. filterDoInternalRequest(  
  1509.     IN PMS_FILTER                   FilterModuleContext,  
  1510.     IN NDIS_REQUEST_TYPE            RequestType,  
  1511.     IN NDIS_OID                     Oid,  
  1512.     IN PVOID                        InformationBuffer,  
  1513.     IN ULONG                        InformationBufferLength,  
  1514.     IN ULONG                        OutputBufferLength, OPTIONAL  
  1515.     IN ULONG                        MethodId, OPTIONAL  
  1516.     OUT PULONG                      pBytesProcessed  
  1517.     )  
  1518.   
  1519. {  
  1520.     FILTER_REQUEST              FilterRequest;  
  1521.     PNDIS_OID_REQUEST           NdisRequest = &FilterRequest.Request;  
  1522.     NDIS_STATUS                 Status;  
  1523.     BOOLEAN               bFalse;  
  1524.   
  1525.   
  1526.     bFalse = FALSE;  
  1527.     NdisZeroMemory(NdisRequest, sizeof(NDIS_OID_REQUEST));  
  1528.   
  1529.     NdisInitializeEvent(&FilterRequest.ReqEvent);  
  1530.       
  1531.     NdisRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;  
  1532.     NdisRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1;  
  1533.     NdisRequest->Header.Size = sizeof(NDIS_OID_REQUEST);  
  1534.     NdisRequest->RequestType = RequestType;  
  1535.   
  1536.     switch (RequestType)  
  1537.     {  
  1538.         case NdisRequestQueryInformation:  
  1539.              NdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;  
  1540.              NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer =InformationBuffer;  
  1541.                                       
  1542.              NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;  
  1543.                                      
  1544.             break;  
  1545.   
  1546.         case NdisRequestSetInformation:  
  1547.              NdisRequest->DATA.SET_INFORMATION.Oid = Oid;  
  1548.              NdisRequest->DATA.SET_INFORMATION.InformationBuffer =InformationBuffer;  
  1549.                                       
  1550.              NdisRequest->DATA.SET_INFORMATION.InformationBufferLength =InformationBufferLength;  
  1551.                                       
  1552.             break;  
  1553.   
  1554.         case NdisRequestMethod:  
  1555.              NdisRequest->DATA.METHOD_INFORMATION.Oid = Oid;  
  1556.              NdisRequest->DATA.METHOD_INFORMATION.MethodId = MethodId;  
  1557.              NdisRequest->DATA.METHOD_INFORMATION.InformationBuffer = InformationBuffer;  
  1558.                                       
  1559.              NdisRequest->DATA.METHOD_INFORMATION.InputBufferLength = InformationBufferLength;  
  1560.                                       
  1561.              NdisRequest->DATA.METHOD_INFORMATION.OutputBufferLength = OutputBufferLength;  
  1562.              break;  
  1563.                
  1564.                   
  1565.   
  1566.         default:  
  1567.             FILTER_ASSERT(bFalse);  
  1568.             break;  
  1569.     }  
  1570.   
  1571.     NdisRequest->RequestId = (PVOID)FILTER_REQUEST_ID;  
  1572.       
  1573.     Status = NdisFOidRequest(FilterModuleContext->FilterHandle,NdisRequest);  
  1574.       
  1575.   
  1576.     if (Status == NDIS_STATUS_PENDING)  
  1577.     {  
  1578.           
  1579.         NdisWaitEvent(&FilterRequest.ReqEvent, 0);  
  1580.         Status = FilterRequest.Status;  
  1581.     }  
  1582.   
  1583.   
  1584.     if (Status == NDIS_STATUS_SUCCESS)  
  1585.     {  
  1586.         if (RequestType == NdisRequestSetInformation)  
  1587.         {  
  1588.             *pBytesProcessed = NdisRequest->DATA.SET_INFORMATION.BytesRead;  
  1589.         }  
  1590.   
  1591.         if (RequestType == NdisRequestQueryInformation)  
  1592.         {  
  1593.             *pBytesProcessed = NdisRequest->DATA.QUERY_INFORMATION.BytesWritten;  
  1594.         }  
  1595.   
  1596.         if (RequestType == NdisRequestMethod)  
  1597.         {  
  1598.             *pBytesProcessed = NdisRequest->DATA.METHOD_INFORMATION.BytesWritten;  
  1599.         }  
  1600.           
  1601.         if (RequestType == NdisRequestMethod)  
  1602.         {  
  1603.             if (*pBytesProcessed > OutputBufferLength)  
  1604.             {  
  1605.                 *pBytesProcessed = OutputBufferLength;  
  1606.             }  
  1607.         }  
  1608.         else  
  1609.         {  
  1610.               
  1611.             if (*pBytesProcessed > InformationBufferLength)  
  1612.             {  
  1613.                 *pBytesProcessed = InformationBufferLength;  
  1614.             }  
  1615.         }  
  1616.     }  
  1617.   
  1618.   
  1619.     return (Status);  
  1620. }  
  1621.   
  1622.   
  1623.   
  1624. VOID  
  1625. filterInternalRequestComplete(  
  1626.     IN NDIS_HANDLE                  FilterModuleContext,  
  1627.     IN PNDIS_OID_REQUEST            NdisRequest,  
  1628.     IN NDIS_STATUS                  Status  
  1629.     )  
  1630.   
  1631.   
  1632. {  
  1633.     PFILTER_REQUEST              FilterRequest;  
  1634.   
  1635.     UNREFERENCED_PARAMETER(FilterModuleContext);  
  1636.      
  1637.     FilterRequest = CONTAINING_RECORD(NdisRequest, FILTER_REQUEST, Request);  
  1638.   
  1639.     FilterRequest->Status = Status;  
  1640.   
  1641.     NdisSetEvent(&FilterRequest->ReqEvent);  
  1642. }  

原文链接:http://blog.csdn.net/itcastcpp/article/details/7752075
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值