Under Windows8 kernel mode dev

Win8 system development driver, also need to drive the need for a digital certificate, the signature verification. Not like XP below as crazy drops bullying.

 Win8 system kernel drastic changes, and XP system kernel have been great changes, the most significant is just to say: the need for signatures and certificates. There is: not at liberty HOOK SSDT.

WDK Development Kit provides a new framework in the development of the NDIS driver shouted NDIS Filter
NDIS Filter is an example of engineering.
False in my WDK installed on the E drive, then the engineering code:
C: WinDDK 8600.16385.1 src network ndis filter directory.

Example works and the original the Passthru project code to do, you will find the original need to be guided by the two types the callback function MiniportXXX and ProtocolXXX in the new framework is all hidden.
Microsoft provides a new function. Take a look at what Microsoft provides.
Here, in order to facilitate analysis, I function code do functional annotation, please take a look at.

Code is as follows:

#pragma NDIS_INIT_FUNCTION(DriverEntry)  # Pragma NDIS_INIT_FUNCTION (DriverEntry)
  
#define LITTLE_ENDIAN   (1)  # Define LITTLE_ENDIAN (1)
//  / /
// Global variables  / / Global variables
//   / /
NDIS_HANDLE         FilterDriverHandle; // NDIS handle for filter driver  NDIS_HANDLE FilterDriverHandle; / / NDIS handle for filter driver
NDIS_HANDLE         FilterDriverObject;  NDIS_HANDLE FilterDriverObject;
NDIS_HANDLE         NdisFilterDeviceHandle = NULL;  NDIS_HANDLE NdisFilterDeviceHandle = NULL;
PDEVICE_OBJECT      DeviceObject = NULL;  PDEVICE_OBJECT DeviceObject = NULL;
  
FILTER_LOCK         FilterListLock;  FILTER_LOCK FilterListLock;
LIST_ENTRY          FilterModuleList;  LIST_ENTRY FilterModuleList;
PWCHAR              InstanceStrings = NULL;  PWCHAR InstanceStrings = NULL;
  
NDIS_FILTER_PARTIAL_CHARACTERISTICS DefaultChars = {  NDIS_FILTER_PARTIAL_CHARACTERISTICS DefaultChars = {
{ 0, 0, 0},  {0, 0, 0},
      0,  0,
      FilterSendNetBufferLists,  FilterSendNetBufferLists,
      FilterSendNetBufferListsComplete,  FilterSendNetBufferListsComplete,
      NULL,  NULL,
      FilterReceiveNetBufferLists,  FilterReceiveNetBufferLists,
      FilterReturnNetBufferLists  FilterReturnNetBufferLists
};      };
  
typedef struct in_addr {  typedef struct in_addr {
  union {  union {
    struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;  struct {UCHAR s_b1, s_b2, s_b3, s_b4;} S_un_b;
    struct { USHORT s_w1,s_w2; } S_un_w;  struct {USHORT s_w1, s_w2;} S_un_w;
    ULONG S_addr;  ULONG S_addr;
  } S_un;  } S_un;
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;  } IN_ADDR, * PIN_ADDR, FAR * LPIN_ADDR;
  
  
#pragma push(1)  # Pragma push (1)
typedef struct IP_HEADER  typedef struct IP_HEADER
{  {
  
#if LITTLE_ENDIAN  # If LITTLE_ENDIAN
  unsigned char  ip_hl:4;    /* 头长度 */  unsigned char ip_hl: 4; / * header length * /
  unsigned char  ip_v:4;      /* 版本号 */  unsigned char ip_v: 4; / * version number * /
#else  # Else
  unsigned char   ip_v:4;  unsigned char ip_v: 4;
  unsigned char   ip_hl:4;       unsigned char ip_hl: 4;
#endif  # Endif
  
  unsigned char  TOS;           // 服务类型  unsigned char TOS; / / Type of Service
  
  unsigned short   TotLen;      // 封包总长度,即整个IP包的长度  unsigned short TotLen; / / total length of the packet, ie the length of the entire IP packet
  unsigned short   ID;          // 封包标识,唯一标识发送的每一个数据报  unsigned short ID; / / packet identification uniquely identifying the transmitter each data packets
  unsigned short   FlagOff;     // 标志  unsigned short FlagOff; / / flag
  unsigned char  TTL;           // 生存时间,就是TTL  unsigned char TTL; / / survival time is TTL
  unsigned char  Protocol;      // 协议,可能是TCP、UDP、ICMP等  unsigned char Protocol; / / protocol, may be TCP, UDP, ICMP, etc.
  unsigned short Checksum;      // 校验和  unsigned short Checksum; / / checksum
  struct in_addr        iaSrc;  // 源IP地址  struct in_addr iaSrc; / / source IP address
  struct in_addr        iaDst;  // 目的PI地址  struct in_addr iaDst; / / purpose of PI address
  
}IP_HEADER, *PIP_HEADER;  } IP_HEADER, * PIP_HEADER;
  
  
typedef struct tcp_header  typedef struct tcp_header
{  {
  unsigned short src_port;    //源端口号  unsigned short src_port; / / source port number
  unsigned short dst_port;    //目的端口号  unsigned short dst_port; / / destination port number
  unsigned int   seq_no;      //序列号  unsigned int seq_no; / / serial number
  unsigned int   ack_no;      //确认号  unsigned int ack_no; / / confirmation number
#if LITTLE_ENDIAN  # If LITTLE_ENDIAN
  unsigned char reserved_1:4; //保留6位中的4位首部长度  unsigned char reserved_1: 4; / / 6 4 header length reserved
  unsigned char thl:4;    //tcp头部长度  unsigned char thl: 4; / / tcp header length
  unsigned char flag:6;  //6位标志  unsigned char flag: 6; / / 6 bit flags
  unsigned char reseverd_2:2; //保留6位中的2位  unsigned char reseverd_2: 2; / / retain two of the six
#else  # Else
  unsigned char thl:4;    //tcp头部长度  unsigned char thl: 4; / / tcp header length
  unsigned char reserved_1:4; //保留6位中的4位首部长度  unsigned char reserved_1: 4; / / 6 4 header length reserved
  unsigned char reseverd_2:2; //保留6位中的2位  unsigned char reseverd_2: 2; / / retain two of the six
  unsigned char flag:6;  //6位标志   unsigned char flag: 6; / / 6 bit flags
#endif  # Endif
  unsigned short wnd_size;   //16位窗口大小  unsigned short wnd_size; / / 16-bit window size
  unsigned short chk_sum;    //16位TCP检验和  unsigned short chk_sum; / / 16-bit TCP checksum
  unsigned short urgt_p;     //16为紧急指针  unsigned short urgt_p; / / 16 for urgent pointer
  
}TCP_HEADER,*PTCP_HEADER;  } TCP_HEADER, * PTCP_HEADER;
  
  
typedef struct udp_header   typedef struct udp_header
{  {
  USHORT srcport;   // 源端口  USHORT srcport; / / source port
  USHORT dstport;   // 目的端口  USHORT dstport; / / destination port
  USHORT total_len; // 包括UDP报头及UDP数据的长度(单位:字节)  The USHORT total_len; / / include the UDP header and UDP data length (unit: byte)
  USHORT chksum;    // 校验和  USHORT chksum; / / checksum
  
}UDP_HEADER,*PUDP_HEADER;  } UDP_HEADER, * PUDP_HEADER;
#pragma push()  # Pragma push ()
  
  
#define IP_OFFSET                               0x0E  # Define IP_OFFSET 0x0E
  
//IP 协议类型  / / IP protocol type
#define PROT_ICMP                               0x01   # Define PROT_ICMP 0x01
#define PROT_TCP                                0x06   # Define PROT_TCP 0x06
#define PROT_UDP                                0x11   # Define PROT_UDP 0x11
  
  
USHORT UTIL_htons( USHORT hostshort )  USHORT UTIL_htons (USHORT hostshort)
{  {
  PUCHAR  pBuffer;  PUCHAR pBuffer;
  USHORT  nResult;  USHORT nResult;
  
  nResult = 0;  nResult = 0;
  pBuffer = (PUCHAR )&hostshort;  pBuffer = (PUCHAR) &hostshort;
  
  nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00) | (pBuffer[ 1 ] & 0x00FF);  nResult = ((pBuffer [0] << 8) & 0xFF00) | (pBuffer [1] & 0x00FF);
  
  return( nResult );  return (nResult);
}  }
  
  
/*UTIL_ntohs把网络字节顺序转换成主机字节顺序*/  / * UTIL_ntohs network byte order to host byte order * /
USHORT UTIL_ntohs( USHORT netshort )  USHORT UTIL_ntohs (USHORT netshort)
{  {
  return( UTIL_htons( netshort ) );  return (UTIL_htons (netshort));
}  }
  
  
  
NTSTATUS   NTSTATUS
DriverEntry(IN  PDRIVER_OBJECT  DriverObject, IN  PUNICODE_STRING   RegistryPath)  DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{  {
    NDIS_STATUS                             Status;  NDIS_STATUS Status;
    NDIS_FILTER_DRIVER_CHARACTERISTICS      FChars;  NDIS_FILTER_DRIVER_CHARACTERISTICS FChars;
    NDIS_STRING                             ServiceName;  NDIS_STRING ServiceName;
    NDIS_STRING                             UniqueName;  NDIS_STRING UniqueName;
    NDIS_STRING                             FriendlyName;  NDIS_STRING FriendlyName;
    BOOLEAN                                 bFalse = FALSE;  BOOLEAN bFalse = FALSE;
  
    UNREFERENCED_PARAMETER(RegistryPath);  UNREFERENCED_PARAMETER (RegistryPath);
      
    DEBUGP(DL_TRACE,("===>DriverEntry...
"));  DEBUGP (DL_TRACE, ("===> DriverEntry ...  n"));
     
    RtlInitUnicodeString(&ServiceName, FILTER_SERVICE_NAME);  RtlInitUnicodeString (& ServiceName, FILTER_SERVICE_NAME);
    RtlInitUnicodeString(&FriendlyName, FILTER_FRIENDLY_NAME);  RtlInitUnicodeString (& FriendlyName, FILTER_FRIENDLY_NAME);
    RtlInitUnicodeString(&UniqueName, FILTER_UNIQUE_NAME);  RtlInitUnicodeString (& UniqueName, FILTER_UNIQUE_NAME);
    FilterDriverObject = DriverObject;  FilterDriverObject = DriverObject;
      
    do  do
    {  {
        NdisZeroMemory(&FChars, sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS));    NdisZeroMemory (& FChars, sizeof (NDIS_FILTER_DRIVER_CHARACTERISTICS));
  
/* / *
大多数的NDIS6.0数据结构中包含的对象头结构的成员,即NDIS_OBJECT_HEADER结构。 The majority of NDIS6.0 data structure contains a member of the object header structure, i.e. NDIS_OBJECT_HEADER structure.
对象头有三个成员:类型,大小和修改。 Object header has three members: the type, size, and modify.如果头信息是不正确的,那么调用NDIS6.0函数将失败。 If the header information is incorrect, then call NDIS6.0 function will fail.
*/  * /
        FChars.Header.Type =    FChars.Header.Type =
        NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;  NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;
        FChars.Header.Size = sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS);  FChars.Header.Size = sizeof (NDIS_FILTER_DRIVER_CHARACTERISTICS);
        FChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_1;  FChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_1;
  
        FChars.MajorNdisVersion = FILTER_MAJOR_NDIS_VERSION;  FChars.MajorNdisVersion = FILTER_MAJOR_NDIS_VERSION;
        FChars.MinorNdisVersion = FILTER_MINOR_NDIS_VERSION;  FChars.MinorNdisVersion = FILTER_MINOR_NDIS_VERSION;
        FChars.MajorDriverVersion = 1;  FChars.MajorDriverVersion = 1;
        FChars.MinorDriverVersion = 0;  FChars.MinorDriverVersion = 0;
        FChars.Flags = 0;  FChars.Flags = 0;
  
        FChars.FriendlyName = FriendlyName;  FChars.FriendlyName = FriendlyName;
        FChars.UniqueName = UniqueName;  FChars.UniqueName = UniqueName;
        FChars.ServiceName = ServiceName;  FChars.ServiceName = ServiceName;
  
              
/****************************************************** / ************************************************* *****
NDIS_FILTER_DRIVER_CHARACTERISTICS结构中Mandatory例程 NDIS_FILTER_DRIVER_CHARACTERISTICS structure Mandatory routine
******************************************************/  ************************************************** **** /
        FChars.AttachHandler = FilterAttach;  FChars.AttachHandler = FilterAttach;
        FChars.DetachHandler = FilterDetach;  FChars.DetachHandler = FilterDetach;
        FChars.RestartHandler = FilterRestart;  FChars.RestartHandler = FilterRestart;
        FChars.PauseHandler = FilterPause;  FChars.PauseHandler = FilterPause;
  
  
/************************************************************ / ************************************************* ***********
NDIS_FILTER_DRIVER_CHARACTERISTICS结构中Optional且不能在运行时变更的例程 NDIS_FILTER_DRIVER_CHARACTERISTICS structure Optional and can not be changed at run time routines
*************************************************************/  ************************************************** *********** /
        FChars.SetOptionsHandler = FilterRegisterOptions;  FChars.SetOptionsHandler = FilterRegisterOptions;
        FChars.SetFilterModuleOptionsHandler = FilterSetModuleOptions;  FChars.SetFilterModuleOptionsHandler = FilterSetModuleOptions;
        FChars.OidRequestHandler = FilterOidRequest;  FChars.OidRequestHandler = FilterOidRequest;
        FChars.OidRequestCompleteHandler = FilterOidRequestComplete;  FChars.OidRequestCompleteHandler = FilterOidRequestComplete;
        FChars.StatusHandler = FilterStatus;  FChars.StatusHandler = FilterStatus;
       FChars.DevicePnPEventNotifyHandler = FilterDevicePnPEventNotify;  FChars.DevicePnPEventNotifyHandler = FilterDevicePnPEventNotify;
       FChars.NetPnPEventHandler = FilterNetPnPEvent;        FChars.NetPnPEventHandler = FilterNetPnPEvent;
      FChars.CancelSendNetBufferListsHandler = FilterCancelSendNetBufferLists;  FChars.CancelSendNetBufferListsHandler = FilterCancelSendNetBufferLists;
  
  
  
/************************************************************** / ************************************************* *************
DIS_FILTER_DRIVER_CHARACTERISTICS结构中Optional且能在运行时变更的例程。 DIS_FILTER_DRIVER_CHARACTERISTICS structure Optional and can be changed at run time routines.
         
下面这4个例程也被定义在NDIS_FILTER_PARTIAL_CHARACTERISTICS中,这个结构指定的 The following four routines defined in NDIS_FILTER_PARTIAL_CHARACTERISTICS This structure specifies
例程可以在运行时的FilterSetModuleOptions例程中调用NdisSetOptionHandles来改变。 The routine called the runtime FilterSetModuleOptions routine NdisSetOptionHandles to change.
如果过滤驱动要在例程中修改自身的一个特性,那么必须提供FilterSetModuleOptions例程。 If the filter driver to modify a feature of its own routine, you must provide FilterSetModuleOptions routines.
****************************************************************/  ************************************************** ************** /
        FChars.SendNetBufferListsHandler = FilterSendNetBufferLists;    FChars.SendNetBufferListsHandler = FilterSendNetBufferLists;
   FChars.SendNetBufferListsCompleteHandler = FilterSendNetBufferListsComplete;  FChars.SendNetBufferListsCompleteHandler = FilterSendNetBufferListsComplete;
        FChars.ReturnNetBufferListsHandler = FilterReturnNetBufferLists;  FChars.ReturnNetBufferListsHandler = FilterReturnNetBufferLists;
        FChars.ReceiveNetBufferListsHandler = FilterReceiveNetBufferLists;  FChars.ReceiveNetBufferListsHandler = FilterReceiveNetBufferLists;
  
       ///  / / /
        FChars.CancelOidRequestHandler = FilterCancelOidRequest;          FChars.CancelOidRequestHandler = FilterCancelOidRequest;
        
        DriverObject->DriverUnload = FilterUnload;  DriverObject-> DriverUnload = FilterUnload;
      
        FilterDriverHandle = NULL;  FilterDriverHandle = NULL;
  
        FILTER_INIT_LOCK(&FilterListLock);  FILTER_INIT_LOCK (& FilterListLock);
  
        InitializeListHead(&FilterModuleList);  InitializeListHead (& FilterModuleList);
          
  // 把Filter驱动注册给NDIS  / / Filter driver registered to NDIS
        Status = NdisFRegisterFilterDriver(DriverObject,  Status = NdisFRegisterFilterDriver (DriverObject,
                                           (NDIS_HANDLE)FilterDriverObject,  (NDIS_HANDLE) FilterDriverObject,
                                           &FChars,   & FChars,
                                           &FilterDriverHandle);  & FilterDriverHandle);
        if (Status != NDIS_STATUS_SUCCESS)  if (Status! = NDIS_STATUS_SUCCESS)
        {  {
            DEBUGP(DL_WARN, ("MSFilter: Register filter driver failed.
"));   DEBUGP (DL_WARN, ("MSFilter: Register filter driver failed.  N"));
            break;  break;
        }  }
        //  / /
        // Initilize spin locks  / / Initilize spin locks
        //  / /
  
        Status = FilterRegisterDevice();  Status = FilterRegisterDevice ();
  
        if (Status != NDIS_STATUS_SUCCESS)  if (Status! = NDIS_STATUS_SUCCESS)
        {  {
            NdisFDeregisterFilterDriver(FilterDriverHandle);  NdisFDeregisterFilterDriver (FilterDriverHandle);
            FILTER_FREE_LOCK(&FilterListLock);  FILTER_FREE_LOCK (& FilterListLock);
            DEBUGP(DL_WARN, ("MSFilter: Register device for the filter driver failed.
"));   DEBUGP (DL_WARN, ("MSFilter: Register device for the filter driver failed.  N"));
            break;  break;
        }  }
  
          
    }   }
    while(bFalse);  while (bFalse);
      
      
    DEBUGP(DL_TRACE, ("<===DriverEntry, Status = %8x
", Status));  DEBUGP (DL_TRACE, ("<=== DriverEntry, Status =% 8x  n", Status));
    return Status;  return Status;
      
}  }
  
  
  
  
//过滤驱动注册可选服务  / / Filter driver registration optional services
NDIS_STATUS  NDIS_STATUS
FilterRegisterOptions(  FilterRegisterOptions (
        IN NDIS_HANDLE  NdisFilterDriverHandle, //它指向了这个过滤驱动  IN NDIS_HANDLE NdisFilterDriverHandle, / / ​​it points to the filter driver
        IN NDIS_HANDLE  FilterDriverContext     //它是这个驱动的上下文  IN NDIS_HANDLE FilterDriverContext / / It is the context of this driver
        )  )
{  {
    DEBUGP(DL_TRACE, ("===>FilterRegisterOptions
"));  DEBUGP (DL_TRACE, ("===> FilterRegisterOptions  n"));
      
    ASSERT(NdisFilterDriverHandle == FilterDriverHandle);  ASSERT (NdisFilterDriverHandle == FilterDriverHandle);
    ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject);  ASSERT (FilterDriverContext == (NDIS_HANDLE) FilterDriverObject);
  
    if ((NdisFilterDriverHandle != (NDIS_HANDLE)FilterDriverHandle) ||  if ((NdisFilterDriverHandle! = (NDIS_HANDLE) FilterDriverHandle) | |
        (FilterDriverContext != (NDIS_HANDLE)FilterDriverObject))  (FilterDriverContext! = (NDIS_HANDLE) FilterDriverObject))
    {  {
        return NDIS_STATUS_INVALID_PARAMETER;  return NDIS_STATUS_INVALID_PARAMETER;
    }  }
  
    DEBUGP(DL_TRACE, ("<===FilterRegisterOptions
"));  DEBUGP (DL_TRACE, ("<=== FilterRegisterOptions  n"));
  
    return (NDIS_STATUS_SUCCESS);  return (NDIS_STATUS_SUCCESS);
}  }
  
      
  
/***************************************************************   / ************************************************* **************
FilterAttach函数的功能: Function of function FilterAttach:
   Attaching状态表示:一个Filter Driver正准备附加一个Filter Module到一个驱动栈上。 The Attaching status: a Filter Driver is preparing to attach a Filter Module to a driver on the stack.
   一个过滤驱动进入Attaching状态下不能进行发送请求、接收指示、状态指示、OID请求操作。 A filter can not be driven into the Attaching state sends a request to receive instructions, status indication, OID requested operation.
 
   当一个过滤驱动进入Attaching状态时,它可以: When a filter driver to enter Attaching state, it can:
   (1)创建一个环境上下文区域并且初始化一个缓冲区池以及其Filter Module特点的资源。 (1) to create an environment in the context of regional and initialize a buffer pool and Filter Module features resources.
  (2)用NDIS 传来给Filter Attach的NdisFilterHandle作为输入来调用NdisFSetAttributes例程。 (2) use the NDIS came to the Filter Attach NdisFilterHandle to as input call NdisFSetAttributes routine.
 
 
   Attach is complete Attach is complete
   当Filter Module在Attaching状态下并且Filter Driver初始化了所有的Filter Module所需要的 When the Filter Module Attaching the state and initializes all Filter Module Filter Driver
   所有资源时,Filter Module进入Paused状态。 All resources, Filter Module into the Paused state.
 
 
   参数说明: Parameter Description:
    NdisFilterHandle     它用于所有过滤驱动中对Ndisxxx类例程的调用时引用指示这个过滤模块。 NdisFilterHandle references indicate this filter module for all filter driver Ndisxxx class routine call.
    FilterDriverContext  它由NdisFRegisterFilterDriver的FilterDriverContext来指定。 By NdisFRegisterFilterDriver the FilterDriverContext FilterDriverContext it to be specified.
    AttachParameters     它是过滤模块的初始化参数结构体。 AttachParameters filter module initialization parameter structure.
 **************************************************************/  ************************************************** ************ /
NDIS_STATUS  NDIS_STATUS
FilterAttach(  FilterAttach (
    IN  NDIS_HANDLE                     NdisFilterHandle,  IN NDIS_HANDLE NdisFilterHandle,
    IN  NDIS_HANDLE                     FilterDriverContext,  IN NDIS_HANDLE FilterDriverContext,
    IN  PNDIS_FILTER_ATTACH_PARAMETERS  AttachParameters  IN PNDIS_FILTER_ATTACH_PARAMETERS AttachParameters
    )  )
  
{  {
    PMS_FILTER              pFilter = NULL;  PMS_FILTER pFilter = NULL;
    NDIS_STATUS             Status = NDIS_STATUS_SUCCESS;  NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
    NDIS_FILTER_ATTRIBUTES  FilterAttributes;  NDIS_FILTER_ATTRIBUTES FilterAttributes;
    ULONG                   Size;  ULONG Size;
    BOOLEAN               bFalse = FALSE;  BOOLEAN bFalse = FALSE;
      
    DEBUGP(DL_TRACE, ("===>FilterAttach: NdisFilterHandle %p
", NdisFilterHandle));  DEBUGP (DL_TRACE, ("===> FilterAttach: NdisFilterHandle% p  n", NdisFilterHandle));
  
    do  do
    {  {
        ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject);  ASSERT (FilterDriverContext == (NDIS_HANDLE) FilterDriverObject);
        if (FilterDriverContext != (NDIS_HANDLE)FilterDriverObject)  if (FilterDriverContext! = (NDIS_HANDLE) FilterDriverObject)
        {  {
            Status = NDIS_STATUS_INVALID_PARAMETER;  Status = NDIS_STATUS_INVALID_PARAMETER;
            break;  break;
        }  }
          
        if ((AttachParameters->MiniportMediaType != NdisMedium802_3)  if ((AttachParameters-> MiniportMediaType! = NdisMedium802_3)
                && (AttachParameters->MiniportMediaType != NdisMediumWan))  && (AttachParameters-> MiniportMediaType! = NdisMediumWan))
        {  {
           DEBUGP(DL_ERROR, ("MSFilter: Doesn"t support media type other than NdisMedium802_3.
"));   DEBUGP (DL_ERROR, ("MSFilter: Doesn"t support media type other than NdisMedium802_3.  N"));
          
           Status = NDIS_STATUS_INVALID_PARAMETER;  Status = NDIS_STATUS_INVALID_PARAMETER;
           break;  break;
        }  }
          
        Size = sizeof(MS_FILTER) +   Size = sizeof (MS_FILTER) +
               AttachParameters->FilterModuleGuidName->Length +   AttachParameters-> FilterModuleGuidName-> Length +
               AttachParameters->BaseMiniportInstanceName->Length +   AttachParameters-> BaseMiniportInstanceName-> Length +
               AttachParameters->BaseMiniportName->Length;  AttachParameters-> BaseMiniportName-> Length;
          
        pFilter = (PMS_FILTER)FILTER_ALLOC_MEM(NdisFilterHandle, Size);  pFilter = (PMS_FILTER) FILTER_ALLOC_MEM (NdisFilterHandle, Size);
        if (pFilter == NULL)  if (pFilter == NULL)
        {  {
            DEBUGP(DL_WARN, ("MSFilter: Failed to allocate context structure.
"));  DEBUGP (DL_WARN, ("MSFilter: Failed to allocate context structure.  N"));
            Status = NDIS_STATUS_RESOURCES;  Status = NDIS_STATUS_RESOURCES;
            break;  break;
        }  }
          
        NdisZeroMemory(pFilter, sizeof(MS_FILTER));  NdisZeroMemory (pFilter, sizeof (MS_FILTER));
  
        pFilter->FilterModuleName.Length = pFilter->FilterModuleName.MaximumLength = AttachParameters->FilterModuleGuidName->Length;  pFilter-> FilterModuleName.Length = pFilter-> FilterModuleName.MaximumLength = AttachParameters-> FilterModuleGuidName-> Length;
        pFilter->FilterModuleName.Buffer = (PWSTR)((PUCHAR)pFilter + sizeof(MS_FILTER));  pFilter-> FilterModuleName.Buffer = (PWSTR) ((PUCHAR) pFilter + sizeof (MS_FILTER));
  
        NdisMoveMemory(pFilter->FilterModuleName.Buffer,   NdisMoveMemory (pFilter-> FilterModuleName.Buffer,
                        AttachParameters->FilterModuleGuidName->Buffer,  AttachParameters-> FilterModuleGuidName-> Buffer,
                        pFilter->FilterModuleName.Length);  pFilter-> FilterModuleName.Length);
  
          
        pFilter->MiniportFriendlyName.Length = pFilter->MiniportFriendlyName.MaximumLength = AttachParameters->BaseMiniportInstanceName->Length;  pFilter-> MiniportFriendlyName.Length = pFilter-> MiniportFriendlyName.MaximumLength = AttachParameters-> BaseMiniportInstanceName-> Length;
        pFilter->MiniportFriendlyName.Buffer = (PWSTR)((PUCHAR)pFilter->FilterModuleName.Buffer + pFilter->FilterModuleName.Length);  pFilter-> MiniportFriendlyName.Buffer = (PWSTR) ((PUCHAR) pFilter-> FilterModuleName.Buffer + pFilter-> FilterModuleName.Length);
          
  NdisMoveMemory(pFilter->MiniportFriendlyName.Buffer,   NdisMoveMemory (pFilter-> MiniportFriendlyName.Buffer,
                       AttachParameters->BaseMiniportInstanceName->Buffer,  AttachParameters-> BaseMiniportInstanceName-> Buffer,
                        pFilter->MiniportFriendlyName.Length);  pFilter-> MiniportFriendlyName.Length);
  
          
        pFilter->MiniportName.Length = pFilter->MiniportName.MaximumLength = AttachParameters->BaseMiniportName->Length;  pFilter-> MiniportName.Length = pFilter-> MiniportName.MaximumLength = AttachParameters-> BaseMiniportName-> Length;
        pFilter->MiniportName.Buffer = (PWSTR)((PUCHAR)pFilter->MiniportFriendlyName.Buffer +   pFilter-> MiniportName.Buffer = (PWSTR) ((PUCHAR) pFilter-> MiniportFriendlyName.Buffer +
                                                   pFilter->MiniportFriendlyName.Length);  pFilter-> MiniportFriendlyName.Length);
        NdisMoveMemory(pFilter->MiniportName.Buffer,   NdisMoveMemory (pFilter-> MiniportName.Buffer,
                        AttachParameters->BaseMiniportName->Buffer,  AttachParameters-> BaseMiniportName-> Buffer,
                        pFilter->MiniportName.Length);  pFilter-> MiniportName.Length);
  
        pFilter->MiniportIfIndex = AttachParameters->BaseMiniportIfIndex;  pFilter-> MiniportIfIndex = AttachParameters-> BaseMiniportIfIndex;
        
        pFilter->TrackReceives = TRUE;  pFilter-> TrackReceives = TRUE;
        pFilter->TrackSends = TRUE;  pFilter-> TrackSends = TRUE;
        pFilter->FilterHandle = NdisFilterHandle;  pFilter-> FilterHandle = NdisFilterHandle;
  
  
        NdisZeroMemory(&FilterAttributes, sizeof(NDIS_FILTER_ATTRIBUTES));  NdisZeroMemory (& FilterAttributes, sizeof (NDIS_FILTER_ATTRIBUTES));
        FilterAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1;  FilterAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1;
        FilterAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES);  FilterAttributes.Header.Size = sizeof (NDIS_FILTER_ATTRIBUTES);
        FilterAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES;  FilterAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES;
        FilterAttributes.Flags = 0;  FilterAttributes.Flags = 0;
  
  
        Status = NdisFSetAttributes(NdisFilterHandle,   Status = NdisFSetAttributes (NdisFilterHandle,
                                    pFilter, //pFilter参数的功能是,为过滤模块指定环境上下文  The function of pFilter, / / ​​pFilter parameters specify the environmental context for the filter module
                                    &FilterAttributes);  & FilterAttributes);
  
        if (Status != NDIS_STATUS_SUCCESS)  if (Status! = NDIS_STATUS_SUCCESS)
        {  {
            DEBUGP(DL_WARN, ("MSFilter: Failed to set attributes.
"));  DEBUGP (DL_WARN, ("MSFilter: Failed to set attributes.  N"));
            break;  break;
        }  }
          
        pFilter->State = FilterPaused;  pFilter-> State = FilterPaused;
  
        FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);  FILTER_ACQUIRE_LOCK (& FilterListLock, bFalse);
        InsertHeadList(&FilterModuleList, &pFilter->FilterModuleLink);  InsertHeadList (& FilterModuleList, & pFilter-> FilterModuleLink);
        FILTER_RELEASE_LOCK(&FilterListLock, bFalse);  FILTER_RELEASE_LOCK (& FilterListLock, bFalse);
          
    }  }
    while (bFalse);  while (bFalse);
      
    if (Status != NDIS_STATUS_SUCCESS)  if (Status! = NDIS_STATUS_SUCCESS)
    {  {
        if (pFilter != NULL)  if (pFilter! = NULL)
        {  {
            FILTER_FREE_MEM(pFilter);  FILTER_FREE_MEM (pFilter);
        }  }
    }  }
      
    DEBUGP(DL_TRACE, ("<===FilterAttach:    Status %x
", Status));  DEBUGP (DL_TRACE, ("<=== FilterAttach: Status% x  n", Status));
    return Status;  return Status;
}  }
  
  
  
  
/**************************************************************   / ************************************************* *************
FilterPause函数的功能: Function of function FilterPause:
   Paused状态:在这种状态下,Filter Driver不能执行接收和发送操作。 Paused state: In this state, Filter Driver can not perform transmit and receive operations.
   当FilterDriver执行FilterPause全程时它就进入了Pausing状态。 Pausing state it enters When FilterDriver execute FilterPause full.
 
   Pausing状态:在这种状态下,Filter Driver要为一个Filter Module完成停止发送和接收 The Pausing state: In this state, Filter Driver for a Filter Module stop sending and receiving
   处理所需要的所有准备工作。 Handle all the preparatory work needed.
 
   一个在Pausing状态的Filter Driver有如下的约束: A the Pausing state of Filter Driver has the following constraints:
 
   (1)Filter Module不能发起任何新的接收指示,但可以传递下层驱动的接收指示。 (1) Filter Module can not initiate any new receiving instructions, but can pass the the lower driver receives instructions.
   (2)如果有Filter Module发起的接收指示还没有完成,那么必须等到它们全部完成。 (2) If there are the Filter Module initiated reception indication is not yet complete, then it must wait until they are completed.有只当 There are only when
      FilterReturnNetBufferLists完成所有外部接收指示后,暂停操作才能完成。 FilterReturnNetBufferLists complete all the external receiving instructions, suspend operation to complete.
   (3)要返回任何未处理的由下层驱动引发的接收指示给NDIS,只有等到NdisFReturnNetBufferLists返回了所有未处理的接收指示后暂停操作才能完成。 (3) To return any pending from the lower drive triggered by receiving instructions to NDIS, only until the pause operation to complete NdisFReturnNetBufferLists return all outstanding receive instructions.这里也可以排队缓冲这些未完成的接收指示。 Here also can be queued buffer these unfinished reception indication.
   (4)立即用NdisFReturnNetBufferLists返回所有下层驱动新传来的接收指示,如果需要可以在返回之前制和排队这些接收指示。 (4) with NdisFReturnNetBufferLists immediately return all lower drive receive from the instructions, if necessary before returning the system and queuing receive instructions.
   (5)不能发起任何新的发送请求。 (5) can not initiate any new send request.
   (6)如果有Filter Driver引的但NDIS还未完成的发送操作,必须等待它们完成。 (6) Filter Driver cited but the NDIS has not yet completed the send operation must wait for them to complete.
   (8)应该在FilterSendNetBufferLists例程中立即调用NdisFSendNetBufferListsComplete返回那些新达到的发送请求。 (8) should be called immediately FilterSendNetBufferLists routine NdisFSendNetBufferListsComplete to return newly achieved sent request.并且为每一个NET_BUFFER_LIST设置NDIS_STATUS_PAUSED返回状态。 And for each NET_BUFFER_LIST set NDIS_STATUS_PAUSED return state.
   (8)这时可以使用NdisFIndicateStatus提供状态指示。 (8) At this time you can use NdisFIndicateStatus provides status indication.
   (9)可以在FilterStatus中处理状态指示。 (9) can be treated in FilterStatus status indication.
   (10)可以在FilterOidRequest里面处理OID请求。 (10) can be treated in FilterOidRequest inside OID request.
   (11)可以发起一个OID操作。 (11) can initiate the operation of an OID.
   (12)不能释放分配的相关资源,和Filter Module相关的资源最好放在FilterDetach例程里面来释放。 (12) can not release allocated resources, the best resources Filter Module on FilterDetach the routines inside to release.
   (13)如果有用于发送和接收的定时器那么要停止它。 (13) If there are for transmitting and receiving the timer to stop it.
 
   当成功停止发送和接收操作后就必须完成暂停操作。 When must complete successfully stopped sending and receiving operations after suspending operations.暂停操作的完成可以是同步的也可以是异步的。 The completion of the pausing operation can be synchronous or asynchronous.
   若返回值是NDIS_STATUS_SUCCESS则,是同步。 If return value is NDIS_STATUS_SUCCESS to the synchronization.
   若是异步,则返回NDIS_STATUS_PENDING。 If asynchronous, the return NDIS_STATUS_PENDING.那么还必须调用NdisFPauseComplete函数。 You must also call NdisFPauseComplete function.
 
   暂停操作完成了以后,Filter Module进入了Paused状态。 Suspend the operation is complete, Filter Module into the Paused state.这里它有如下的约束: Here it has the following constraints:
 
   (1)不能发起任何接收指示,但可以传递底层驱动发来的接收指示。 (1) can not initiate any receiving instructions, but can be passed to the underlying driver to receive instructions.
   (2)需要立即调用NdisFReturnNetBufferLists返回底层驱动的接收指示给NDIS,如果需要可以在返回之前复制和排队这些接收指示。 (2) the need to immediately call NdisFReturnNetBufferLists Back underlying driver receives instructions to NDIS, if necessary before returning replication and queuing receive instructions.
   (3)不能引发任何新的发送指示。 (3) can not lead to any new send instructions.
   (4)需要立即调用NdisFSendNetBufferListsComplete完成那些在FilterSendNetBufferLists中收到的发送请求,并为每一个NET_BUFFER_LIST设置NDIS_STATUS_PAUSED返回状态。 (4) the need to immediately call NdisFSendNetBufferListsComplete complete those received in FilterSendNetBufferLists, send a request and state for each NET_BUFFER_LIST set NDIS_STATUS_PAUSED return.
   (5)这时可以使用NdisFIndicateStatus发起状态指示。 (5) can use NdisFIndicateStatus initiation state instructions.
   (6)可以在FilterStatus中进行状态指示处理。 (6) may be in the state in FilterStatus instruction processing.
   (8)可以在FilterOidRequest里面处理OID请求。 (8) can FilterOidRequest inside to handle the OID the request.
   (8)可以发起一个OID请求。 (8) can be initiated by an OID request.
 
 
   在Filter Module进行Pausing状态时NDIS不会发起其它PnP操作,比如:附加、分离、重启。 NDIS Filter Module Pausing state will not initiate the other PnP operations, such as: attached, detached, restart.只有当Filter Module进入了Paused状态后NDIS才能对它进行分离和重启操作。 Only when The Filter Module into the Paused state NDIS and it could be separated and restart operations.
 ***************************************************************/  ************************************************** ************* /
NDIS_STATUS  NDIS_STATUS
FilterPause(  FilterPause (
        IN  NDIS_HANDLE                     FilterModuleContext,  IN NDIS_HANDLE FilterModuleContext,
        IN  PNDIS_FILTER_PAUSE_PARAMETERS   PauseParameters  IN PNDIS_FILTER_PAUSE_PARAMETERS PauseParameters
        )  )
  
{  {
    PMS_FILTER          pFilter = (PMS_FILTER)(FilterModuleContext);  PMS_FILTER pFilter = (PMS_FILTER) (FilterModuleContext);
    NDIS_STATUS         Status;  NDIS_STATUS Status;
    BOOLEAN               bFalse = FALSE;  BOOLEAN bFalse = FALSE;
  
    UNREFERENCED_PARAMETER(PauseParameters);  UNREFERENCED_PARAMETER (PauseParameters);
      
    DEBUGP(DL_TRACE, ("===>NDISLWF FilterPause: FilterInstance %p
", FilterModuleContext));  DEBUGP (DL_TRACE, ("===> NDISLWF FilterPause: FilterInstance% p  n", FilterModuleContext));
  
       
    FILTER_ASSERT(pFilter->State == FilterRunning);   FILTER_ASSERT (pFilter-> State == FilterRunning);
      
    FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse);  FILTER_ACQUIRE_LOCK (& pFilter-> Lock, bFalse);
    pFilter->State = FilterPausing;  pFilter-> State = FilterPausing;
    FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse);  FILTER_RELEASE_LOCK (& pFilter-> Lock, bFalse);
  
  
    Status = NDIS_STATUS_SUCCESS;      Status = NDIS_STATUS_SUCCESS;
  
    pFilter->State = FilterPaused;  pFilter-> State = FilterPaused;
      
    DEBUGP(DL_TRACE, ("<===FilterPause:  Status %x
", Status));  DEBUGP (DL_TRACE, ("<=== FilterPause: Status% x  n", Status));
    return Status;  return Status;
}  }
  
  
  
  
/*************************************************************** / ************************************************* **************
  FilterRestart函数的功能: Function of function FilterRestart:
   在Restarting状态下,一个Filter Driver必须为一个Filter Module完成重启发送和接收数据时 Restarting state, a Filter Driver must complete restart to send and receive data, a Filter Module
   所需要的所有准备工作。 Need all the preparation work.
 
   Restart is complete Restart is complete
    当Filter Module在Restarting状态下并且完成所有发送和接收所需要的准备工作时,Filter Module就进入了Running状态。 When the the Filter Module Restarting state and complete the preparatory work needed in all send and receive, Filter Module into the Running state.
 
要启动一个Paused状态的Filter Module,如果有FilterSetModuleOptions就先调用它,接着调用FilterRestart。 Filter Module, you want to start a Paused state if there FilterSetModuleOptions, first calling it then calls FilterRestart.
 
  当Filter Module在Restarting状态下,它可以: When the Filter Module Restarting state, it can:
  (1)完成任何正常的发送和接收所需要的准备工作。 (1) completion of any of the normal transmission and reception of the preparatory work needed.
  (2)可读写Filter Module的配置参数。 (2) to read and write the Filter Module configuration parameter.
  (3)可以接收网络数据指示,拷贝和排队数据稍后只是给上层驱动或者丢弃数据。 (3) can receive network data indicate, copy and queuing data later just to the upper drive or discard data.
  (4)不能发起任何新的接收指示。 (4) can not initiate any new receiving instructions.
  (5)应该立即调用NdisFSendNetBufferListsComplete例程来拒绝FilterSendNetBufferLists传来的发送的请求。 (5) should be called immediately NdisFSendNetBufferListsComplete routines to reject the request sent FilterSendNetBufferLists coming.应该设置每一个NET_BUFFER_LIST的完成状态为NDIS_STATUS_PAUSED Should set each NET_BUFFER_LIST completion status for NDIS_STATUS_PAUSED it
                (6)可以使用NdisFIndicateStatus例程进行状态指示。 (6) can be used to NdisFIndicateStatus routines status indication.
  (8)可以控制OID请求操作。 (8) can control OID requested operation.
  (8)不能发起任何新的发送请求。 (8) can not initiate any new send request.
  (9)应该调用NdisFReturnNetBufferLists返回所有新的接收指示。 (9) should be called NdisFReturnNetBufferLists returns all new receive instructions.如果需要的话可以在接收指示返回之前拷贝它们。 If need be receiving instructions before returning to copy them.
  (10)可以制作OID请求发送给下层驱动设置或查询配置信息。 (10) can be produced OID to send the request to the lower driver set or query configuration information.
  (11)可以在FilterStatus中控制状态指示。 (11) can be controlled in FilterStatus status indication.
  (12)返回时指示 NDIS_STATUS_SUCCESS 或失败状态,如果不Filter Module不能启动返回了失败,而它又是一个Mandatory的Filter Driver 那个 NDIS将会结束这个驱动栈 (12) return to indicate NDIS_STATUS_SUCCESS or failure status, if not Filter Module can not start to return failed, and it is also a Mandatory Filter Driver NDIS will be the end of the driver stack
在一个Filter Driver完成对发送和接收的重启后必须指示完成这个重启操作。 Must be instructed to complete the restart operation after the restart to send and receive in a Filter Driver.
Filter Driver的重启操作的完成可以是同步也可以是异步的,同步时返回 NDIS_STATUS_SUCCESS 异步时返回NDIS_STATUS_PENDING。 The Filter Driver reboot the completion of the operation can be synchronized can also asynchronous synchronization return NDIS_STATUS_SUCCESS asynchronous return NDIS_STATUS_PENDING.如果返回的是 NDIS_STATUS_PENDING 就必须调用NdisFRestartComplete 例程在重启操作完成后。 If the return is NDIS_STATUS_PENDING must call the the NdisFRestartComplete routines in the restart operation.
在这种情况下,驱动需要传递给NdisFRestartComplete 一个固定状态(标识重启结果的成功或失败状态)。 In this case, the driving need to pass NdisFRestartComplete the fixed state (success or failure status) identifies the restart results.
 
重启操作完成Filter Module就进入了 Running状态,恢得一切正常的发送和接收外理。 Restart operation is complete Filter Module into the Running state, the recovery was all normal send and receive outside the grounds.
在Filter Driver的FilterRestart例程执行的时候NDIS不会发起任即插即用操作,如附加,分离,暂停请求等等。 NDIS will not initiate any plug-and-play operation when performed in the Filter Driver FilterRestart routines, such as additional separation suspend request. Ndis可以在Filter Module进入Running状态后发起一个暂停请求。 Ndis Filter Module into the Running state to initiate a suspend request.
***************************************************************/  ************************************************** ************* /
NDIS_STATUS  NDIS_STATUS
FilterRestart(  FilterRestart (
    IN  NDIS_HANDLE                     FilterModuleContext,  IN NDIS_HANDLE FilterModuleContext,
    IN  PNDIS_FILTER_RESTART_PARAMETERS RestartParameters  IN PNDIS_FILTER_RESTART_PARAMETERS RestartParameters
    )  )
  
{  {
    NDIS_STATUS     Status;  NDIS_STATUS Status;
    PMS_FILTER      pFilter = (PMS_FILTER)FilterModuleContext; // BUGBUG, the cast may be wrong  PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext; / / BUGBUG, the cast may be wrong
    NDIS_HANDLE     ConfigurationHandle = NULL;  NDIS_HANDLE ConfigurationHandle = NULL;
  
  
    PNDIS_RESTART_GENERAL_ATTRIBUTES NdisGeneralAttributes;  PNDIS_RESTART_GENERAL_ATTRIBUTES NdisGeneralAttributes;
    PNDIS_RESTART_ATTRIBUTES         NdisRestartAttributes;  PNDIS_RESTART_ATTRIBUTES NdisRestartAttributes;
    NDIS_CONFIGURATION_OBJECT        ConfigObject;  NDIS_CONFIGURATION_OBJECT ConfigObject;
      
    DEBUGP(DL_TRACE, ("===>FilterRestart:   FilterModuleContext %p
", FilterModuleContext));  DEBUGP (DL_TRACE, ("===> FilterRestart: FilterModuleContext% p  n", FilterModuleContext));
      
    FILTER_ASSERT(pFilter->State == FilterPaused);  FILTER_ASSERT (pFilter-> State == FilterPaused);
  
    ConfigObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;  ConfigObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
    ConfigObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;  ConfigObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
    ConfigObject.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);  ConfigObject.Header.Size = sizeof (NDIS_CONFIGURATION_OBJECT);
    ConfigObject.NdisHandle = FilterDriverHandle;  ConfigObject.NdisHandle = FilterDriverHandle;
    ConfigObject.Flags = 0;  ConfigObject.Flags = 0;
      
    Status = NdisOpenConfigurationEx(&ConfigObject, &ConfigurationHandle);  Status = NdisOpenConfigurationEx (& ConfigObject, & ConfigurationHandle);
    if (Status != NDIS_STATUS_SUCCESS)  if (Status! = NDIS_STATUS_SUCCESS)
    {          {
          
#if 0  # If 0
        //  / /
        // The code is here just to demonstrate how to call NDIS to write an eventlog. If drivers need to write   / / The code is here just to demonstrate how to call NDIS to write an eventlog. If drivers need to write
        // an event log.  / / An event log.
        //  / /
        PWCHAR              ErrorString = L"Ndislwf";  PWCHAR ErrorString = L "Ndislwf";
          
        DEBUGP(DL_WARN, ("FilterRestart: Cannot open configuration.
"));  DEBUGP (DL_WARN, ("FilterRestart: Cannot open configuration.  N"));
        NdisWriteEventLogEntry(FilterDriverObject,  NdisWriteEventLogEntry (FilterDriverObject,
                                EVENT_NDIS_DRIVER_FAILURE,  EVENT_NDIS_DRIVER_FAILURE,
                                0,  0,
                                1,  1,
                                &ErrorString,  & ErrorString,
                                sizeof(Status),  sizeof (Status),
                                &Status);  & Status);
#endif                                  # Endif
                                  
    }  }
  
  
    if (Status == NDIS_STATUS_SUCCESS)  if (Status == NDIS_STATUS_SUCCESS)
    {  {
        NdisCloseConfiguration(ConfigurationHandle);  NdisCloseConfiguration (ConfigurationHandle);
    }  }
  
    NdisRestartAttributes = RestartParameters->RestartAttributes;  NdisRestartAttributes = RestartParameters-> RestartAttributes;
  
    
    if (NdisRestartAttributes != NULL)  if (NdisRestartAttributes! = NULL)
    {  {
        PNDIS_RESTART_ATTRIBUTES   NextAttributes;  PNDIS_RESTART_ATTRIBUTES NextAttributes;
          
        ASSERT(NdisRestartAttributes->Oid == OID_GEN_MINIPORT_RESTART_ATTRIBUTES);  ASSERT (NdisRestartAttributes-> Oid == OID_GEN_MINIPORT_RESTART_ATTRIBUTES);
      
        NdisGeneralAttributes = (PNDIS_RESTART_GENERAL_ATTRIBUTES)NdisRestartAttributes->Data;  NdisGeneralAttributes = (PNDIS_RESTART_GENERAL_ATTRIBUTES) NdisRestartAttributes-> Data;
      
        NdisGeneralAttributes->LookaheadSize = 128;  NdisGeneralAttributes-> LookaheadSize = 128;
  
        NextAttributes = NdisRestartAttributes->Next;  NextAttributes = NdisRestartAttributes-> Next;
  
        while (NextAttributes != NULL)  while (NextAttributes! = NULL)
        {  {
  
            NextAttributes = NextAttributes->Next;  NextAttributes = NextAttributes-> Next;
        }  }
      
    }  }
  
     
    pFilter->State = FilterRunning;   pFilter-> State = FilterRunning;
  
  
    Status = NDIS_STATUS_SUCCESS;  Status = NDIS_STATUS_SUCCESS;
      
    if (Status != NDIS_STATUS_SUCCESS)  if (Status! = NDIS_STATUS_SUCCESS)
    {  {
        pFilter->State = FilterPaused;  pFilter-> State = FilterPaused;
    }  }
      
      
    DEBUGP(DL_TRACE, ("<===FilterRestart:  FilterModuleContext %p, Status %x
", FilterModuleContext, Status));  DEBUGP (DL_TRACE, ("<=== FilterRestart: FilterModuleContext% p, Status% x  n", FilterModuleContext, Status));
    return Status;  return Status;
}  }
  
  
  
/**************************************************************   / ************************************************* *************
FilterDetach函数的功能: Function of function FilterDetach:
   Detach状态:当Filter Driver从一个驱动栈上分离一个Filter Module时,将发生该事件。 Detach state: When separating a Filter Module Filter Driver from a driver on the stack, the event will take place.
   在驱动栈上分离一个过滤模块时,NDIS会暂停这个驱动栈。 Separation of a filter module in the driver stack, NDIS will suspend the driver stack.这意味着NDIS已经使过滤模块进入 This means NDIS filter module into
   了Parse状态。 The Parse state.即FilterPause函数先被调用了。 That FilterPause functions be called first.
 
   在这个例程中释放和这个过滤模块相关的环境上下文和其它资源。 In this routine to release the associated environmental context and the filtering module and other resources.这个过程不能失败。 This process can not fail.
   当FilterDetach函数返回以后,NDIS会重新启动被暂停的驱动栈。 After when FilterDetach function returns, NDIS will restart the is suspended driver stack.
    
   参数说明: Parameter Description:
    FilterDriverContext  它由NdisFRegisterFilterDriver的FilterDriverContext来指定。 By NdisFRegisterFilterDriver the FilterDriverContext FilterDriverContext it to be specified.
 ************************************************************/  ************************************************** ********** /
VOID  VOID
FilterDetach(  FilterDetach (
        IN  NDIS_HANDLE     FilterModuleContext  IN NDIS_HANDLE FilterModuleContext
        )  )
  
{  {
    PMS_FILTER                  pFilter = (PMS_FILTER)FilterModuleContext;  PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext;
    BOOLEAN                      bFalse = FALSE;  BOOLEAN bFalse = FALSE;
  
  
    DEBUGP(DL_TRACE, ("===>FilterDetach:    FilterInstance %p
", FilterModuleContext));  DEBUGP (DL_TRACE, ("===> FilterDetach: FilterInstance% p  n", FilterModuleContext));
  
    
    FILTER_ASSERT(pFilter->State == FilterPaused);  FILTER_ASSERT (pFilter-> State == FilterPaused);
          
     
    if (pFilter->FilterName.Buffer != NULL)  if (pFilter-> FilterName.Buffer! = NULL)
    {  {
        FILTER_FREE_MEM(pFilter->FilterName.Buffer);  FILTER_FREE_MEM (pFilter-> FilterName.Buffer);
    }  }
  
  
    FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);  FILTER_ACQUIRE_LOCK (& FilterListLock, bFalse);
    RemoveEntryList(&pFilter->FilterModuleLink);  RemoveEntryList (& pFilter-> FilterModuleLink);
    FILTER_RELEASE_LOCK(&FilterListLock, bFalse);  FILTER_RELEASE_LOCK (& FilterListLock, bFalse);
  
  
    FILTER_FREE_MEM(pFilter);  FILTER_FREE_MEM (pFilter);
  
    
    DEBUGP(DL_TRACE, ("<===FilterDetach Successfully
"));  DEBUGP (DL_TRACE, ("<=== FilterDetach Successfully  n"));
      
    return;  return;
}  }
  
  
  
  
/************************************************************** / ************************************************* *************
 系统只会在调用FilterDetach()分离了所有和本Filter Driver相关的Filter Module以后,才会调用FilterUnload例程。 The system only after the separation of the Filter Driver Filter Module FilterDetach () is called, will call FilterUnload routine.
****************************************************************/  ************************************************** ************** /
VOID  VOID
FilterUnload(  FilterUnload (
        IN  PDRIVER_OBJECT      DriverObject  IN PDRIVER_OBJECT DriverObject
        )  )
  
{  {
#if DBG      # If DBG
    BOOLEAN               bFalse = FALSE;  BOOLEAN bFalse = FALSE;
#endif  # Endif
  
    UNREFERENCED_PARAMETER(DriverObject);  UNREFERENCED_PARAMETER (DriverObject);
  
    DEBUGP(DL_TRACE, ("===>FilterUnload
"));  DEBUGP (DL_TRACE, ("===> FilterUnload  n"));
      
     
    FilterDeregisterDevice();  FilterDeregisterDevice ();
    NdisFDeregisterFilterDriver(FilterDriverHandle);  NdisFDeregisterFilterDriver (FilterDriverHandle);
      
#if DBG      # If DBG
    FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);  FILTER_ACQUIRE_LOCK (& FilterListLock, bFalse);
    ASSERT(IsListEmpty(&FilterModuleList));  ASSERT (IsListEmpty (& FilterModuleList));
  
    FILTER_RELEASE_LOCK(&FilterListLock, bFalse);  FILTER_RELEASE_LOCK (& FilterListLock, bFalse);
      
#endif      # Endif
      
    FILTER_FREE_LOCK(&FilterListLock);  FILTER_FREE_LOCK (& FilterListLock);
      
    DEBUGP(DL_TRACE, ("<===FilterUnload
"));  DEBUGP (DL_TRACE, ("<=== FilterUnload  n"));
  
    return;  return;
      
}  }
  
  
  
/*************************************************************** / ************************************************* **************
 FilterOidRequest函数的功能: Function of function FilterOidRequest:
  Filter Module可以在Runnig状态、Restarting状态、Paused状态和Pauseing状态进行OID的控制和处理。 Filter Module can the the Runnig status, Restarting state, Paused state and Pauseing state control and treatment of the OID.
  Filter Driver可以处理上层驱动引发的OID请求,NDIS调用Filter Driver的FilterOidRequest例程来处理OID请求,Filter Driver需要调用NdisFOidRequest例程来转发请求给下层驱动。 Filter Driver can handle the upper drive OID requests triggered, NDIS calls the Filter Driver FilterOidRequest routines to handle the OID request, Filter Driver needs call NdisFOidRequest routine to forward the request to the lower driver.
 
  Filter Driver可以从FilterOidRequest同步和异步完成一个OID请求,分别返回NDIS_STATS_SUCCESS和NDIS_STATUS_PENDING即可。 The Filter Driver From FilterOidRequest synchronous and asynchronous complete an OID request, respectively to return NDIS_STATS_SUCCESS NDIS_STATUS_PENDING can. FilterOidRequest可以用同步的直接完成一个OID请求并返回一个错误状态。 FilterOidRequest can sync directly to complete an OID request and returns an error status.
 
  如果FilterOidRequest返回NDIS_STATUS_PENDING,就必须在OID请求完成后调用 If FilterOidRequest return NDIS_STATUS_PENDING, it must call the OID request complete
  NdisFOidRequestComplete来通知上层驱动求请求完成。 NdisFOidRequestComplete to notify the upper drive demand request is complete.在这种情况下,请求的结果通过 In this case, the result of the request by
  NdisFOidRequestComplete的OidRequest参数返回给上层驱动,并通过Status参数返回请求完成的最终状态。 The the OidRequest parameters of NdisFOidRequestComplete return to the upper-driven, and Status parameter returns the final status of the request is complete.
    
 
  如果FilterOidRequest返回NDIS_STATUS_SUCCESS,通过FilterOidRequest的OidRequest参数返回一个查询结果到上层。 If FilterOidRequest return NDIS_STATUS_SUCCESS, return to the results of a query to the upper through FilterOidRequest OidRequest parameters.这时不调用 NdisFOidRequestComplete例程。 This time not call NdisFOidRequestComplete routine.
 
 
  要转发OID请求到下层驱动,Filter Driver必须调用NdisFOidRequest。 The forwarding OID request to the lower driver, Filter Driver must call NdisFOidRequest.如果一个OID请求不能被转发到下层驱动应该当立即返回。 If an OID request can not be forwarded to the next lower driver should when to return immediately.要完成一个请求且不转发可以直接返回NDIS_STATUS_SUCCESS或其它错误状态或返回 NDIS_STATUS_PENDING 后调用NdisFOidRequestComplete。 To complete a request not forwarded the direct return NDIS_STATUS_SUCCESS or other error status or return call NdisFOidRequestComplete after NDIS_STATUS_PENDING.
 
 
  如果NdisFOidRequest返回NDIS_STATUS_PENDING,NDIS在OID请求完成后调用FilterOidRequestComplete来通知求请求完成在这种情况下,请求的结果通过NdisFOidRequestComplete的OidRequest参数返回给上层驱动,并通过 Status 参数返回请求完成的最终状态。 If NdisFOidRequest return NDIS_STATUS_PENDING, NDIS OID request complete notice seeking requests completed in this case, the result of the request through NdisFOidRequestComplete the OidRequest parameters returned to the upper drive to call FilterOidRequestComplete to, and through the Status parameter to return the request to complete the final state.
    
 
  如果 NdisFOidRequest返回NDIS_STATUS_SUCCESS,通过NdisFOidRequest的OidRequest参数返回一个查询结果到上层。 If NdisFOidRequest return NDIS_STATUS_SUCCESS, return a query result to the upper through NdisFOidRequest OidRequest parameters.这时不调用FilterOidRequestComplete例程。 This time not call FilterOidRequestComplete routine.
  一个Filter Driver可以调用NdisFOidRequest引发OID请求在Restarting、Running、Pausing和Paused 状态。 A Filter Driver can call NdisFOidRequest the the triggered OID requests in Restarting, Running, Pausing and Paused state.
   
  注意:Filter Driver必须跟踪这个请求确保不在FilterOidRequestComplete中调用NdisFOidRequestComplete(因为请求是自己引发的不能传到上层)。 Note: Filter Driver must track the request ensure the is not FilterOidRequestComplete call NdisFOidRequestComplete (because the request is not spread to the upper induced).
 ****************************************************************/  ************************************************** ************** /
NDIS_STATUS  NDIS_STATUS
FilterOidRequest(IN  NDIS_HANDLE   FilterModuleContext,IN  PNDIS_OID_REQUEST   Request)  FilterOidRequest (IN NDIS_HANDLE FilterModuleContext, IN PNDIS_OID_REQUEST Request)
  
{  {
    PMS_FILTER              pFilter = (PMS_FILTER)FilterModuleContext;  PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext;
    NDIS_STATUS             Status;  NDIS_STATUS Status;
    PNDIS_OID_REQUEST       ClonedRequest=NULL;  PNDIS_OID_REQUEST ClonedRequest = NULL;
    BOOLEAN                 bSubmitted = FALSE;  BOOLEAN bSubmitted = FALSE;
    PFILTER_REQUEST_CONTEXT Context;  PFILTER_REQUEST_CONTEXT Context;
    BOOLEAN               bFalse = FALSE;  BOOLEAN bFalse = FALSE;
  
      
    DEBUGP(DL_TRACE, ("===>FilterOidRequest: Request %p.
", Request));  DEBUGP (DL_TRACE, ("===> FilterOidRequest: Request% p.  N", Request));
  
    do  do
    {  {
        Status = NdisAllocateCloneOidRequest(pFilter->FilterHandle,  Status = NdisAllocateCloneOidRequest (pFilter-> FilterHandle,
                                            Request,  Request,
                                            FILTER_TAG,  FILTER_TAG,
                                            &ClonedRequest);  & ClonedRequest);
        if (Status != NDIS_STATUS_SUCCESS)  if (Status! = NDIS_STATUS_SUCCESS)
        {  {
            DEBUGP(DL_WARN, ("FilerOidRequest: Cannot Clone Request
"));  DEBUGP (DL_WARN, ("FilerOidRequest: Cannot Clone Request  n"));
            break;  break;
        }  }
  
        Context = (PFILTER_REQUEST_CONTEXT)(&ClonedRequest->SourceReserved[0]);  Context = (PFILTER_REQUEST_CONTEXT) (& ClonedRequest-> SourceReserved [0]);
        *Context = Request;  * Context = Request;
  
        bSubmitted = TRUE;  bSubmitted = TRUE;
  
         
        ClonedRequest->RequestId = Request->RequestId;  ClonedRequest-> RequestId = Request-> RequestId;
  
        pFilter->PendingOidRequest = ClonedRequest;  pFilter-> PendingOidRequest = ClonedRequest;
  
  
//Filter Driver可以调用NdisFOidRequest引发一个OID查询和设置请求给下层驱动。 / / Filter Driver can call NdisFOidRequest the trigger query and set an OID request to the lower driver.
        Status = NdisFOidRequest(pFilter->FilterHandle, ClonedRequest);  Status = NdisFOidRequest (pFilter-> FilterHandle, ClonedRequest);
  
        if (Status != NDIS_STATUS_PENDING)  if (Status! = NDIS_STATUS_PENDING)
        {  {
  
            FilterOidRequestComplete(pFilter, ClonedRequest, Status);  FilterOidRequestComplete (pFilter, ClonedRequest, Status);
            Status = NDIS_STATUS_PENDING;  Status = NDIS_STATUS_PENDING;
        }   }
  
          
    }while (bFalse);  } While (bFalse);
  
    if (bSubmitted == FALSE)  if (bSubmitted == FALSE)
    {  {
        switch(Request->RequestType)  switch (Request-> RequestType)
        {  {
            case NdisRequestMethod:  case NdisRequestMethod:
                Request->DATA.METHOD_INFORMATION.BytesRead = 0;  Request-> DATA.METHOD_INFORMATION.BytesRead = 0;
                Request->DATA.METHOD_INFORMATION.BytesNeeded = 0;   Request-> DATA.METHOD_INFORMATION.BytesNeeded = 0;
                Request->DATA.METHOD_INFORMATION.BytesWritten = 0;   Request-> DATA.METHOD_INFORMATION.BytesWritten = 0;
                break;  break;
  
            case NdisRequestSetInformation:  case NdisRequestSetInformation:
                Request->DATA.SET_INFORMATION.BytesRead = 0;  Request-> DATA.SET_INFORMATION.BytesRead = 0;
                Request->DATA.SET_INFORMATION.BytesNeeded = 0;   Request-> DATA.SET_INFORMATION.BytesNeeded = 0;
                break;  break;
  
            case NdisRequestQueryInformation:  case NdisRequestQueryInformation:
            case NdisRequestQueryStatistics:  case NdisRequestQueryStatistics:
            default:  default:
                Request->DATA.QUERY_INFORMATION.BytesWritten = 0;  Request-> DATA.QUERY_INFORMATION.BytesWritten = 0;
                Request->DATA.QUERY_INFORMATION.BytesNeeded = 0;   Request-> DATA.QUERY_INFORMATION.BytesNeeded = 0;
                break;  break;
        }  }
  
    }  }
    DEBUGP(DL_TRACE, ("<===FilterOidRequest: Status %8x.
", Status));  DEBUGP (DL_TRACE, ("<=== FilterOidRequest: Status% 8x.  N", Status));
  
    return Status;  return Status;
  
}  }
  
  
  
/************************************************************* / ************************************************* ************
 FilterCancelOidRequest函数的功能: Function of function FilterCancelOidRequest:
  NDIS调用FilterCancelOidRequest来取消一个OID请求,当NDIS调用FilterCancelOidRequest时, An OID request to NDIS to call FilterCancelOidRequest to cancel when the NDIS call FilterCancelOidRequest,
  Filter Driver应该尽可能快的调用NdisFCancelOidRequest。 Filter Driver should call as soon as possible NdisFCancelOidRequest.
 *************************************************************/  ************************************************** *********** /
VOID  VOID
FilterCancelOidRequest(  FilterCancelOidRequest (
    IN  NDIS_HANDLE             FilterModuleContext,  IN NDIS_HANDLE FilterModuleContext,
    IN  PVOID                   RequestId  IN PVOID RequestId
    )  )
{  {
    PMS_FILTER                          pFilter = (PMS_FILTER)FilterModuleContext;  PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext;
    PNDIS_OID_REQUEST                   Request = NULL;  PNDIS_OID_REQUEST Request = NULL;
    PFILTER_REQUEST_CONTEXT             Context;  PFILTER_REQUEST_CONTEXT Context;
    PNDIS_OID_REQUEST                   OriginalRequest = NULL;  PNDIS_OID_REQUEST OriginalRequest = NULL;
    BOOLEAN               bFalse = FALSE;  BOOLEAN bFalse = FALSE;
       
    FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse);  FILTER_ACQUIRE_LOCK (& pFilter-> Lock, bFalse);
      
    Request = pFilter->PendingOidRequest;  Request = pFilter-> PendingOidRequest;
  
    if (Request != NULL)  if (Request! = NULL)
    {  {
        Context = (PFILTER_REQUEST_CONTEXT)(&Request->SourceReserved[0]);  Context = (PFILTER_REQUEST_CONTEXT) (& Request-> SourceReserved [0]);
      
        OriginalRequest = (*Context);  OriginalRequest = (* Context);
    }  }
  
    if ((OriginalRequest != NULL) && (OriginalRequest->RequestId == RequestId))  if ((OriginalRequest! = NULL) && (OriginalRequest-> RequestId == RequestId))
    {  {
        FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse);  FILTER_RELEASE_LOCK (& pFilter-> Lock, bFalse);
          
        NdisFCancelOidRequest(pFilter->FilterHandle, RequestId);  NdisFCancelOidRequest (pFilter-> FilterHandle, RequestId);
    }  }
    else  else
    {  {
        FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse);  FILTER_RELEASE_LOCK (& pFilter-> Lock, bFalse);
    }  }
          
  
}  }
  
      
VOID  VOID
FilterOidRequestComplete(  FilterOidRequestComplete (
        IN  NDIS_HANDLE         FilterModuleContext,  IN NDIS_HANDLE FilterModuleContext,
        IN  PNDIS_OID_REQUEST   Request,  IN PNDIS_OID_REQUEST Request,
        IN  NDIS_STATUS         Status  IN NDIS_STATUS Status
        )  )
  
{  {
    PMS_FILTER                          pFilter = (PMS_FILTER)FilterModuleContext;  PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext;
    PNDIS_OID_REQUEST                   OriginalRequest;  PNDIS_OID_REQUEST OriginalRequest;
    PFILTER_REQUEST_CONTEXT             Context;  PFILTER_REQUEST_CONTEXT Context;
    BOOLEAN               bFalse = FALSE;  BOOLEAN bFalse = FALSE;
      
    DEBUGP(DL_TRACE, ("===>FilterOidRequestComplete, Request %p.
", Request));  DEBUGP (DL_TRACE, ("===> FilterOidRequestComplete, Request% p.  N", Request));
  
    Context = (PFILTER_REQUEST_CONTEXT)(&Request->SourceReserved[0]);  Context = (PFILTER_REQUEST_CONTEXT) (& Request-> Source
文章导航