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...\n")); 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.\n")); 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.\n")); DEBUGP (DL_WARN, ("MSFilter: Register device for the filter driver failed. \ N"));
break; break;
} }
} }
while(bFalse); while (bFalse);
DEBUGP(DL_TRACE, ("<===DriverEntry, Status = %8x\n", 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\n")); 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\n")); 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\n", 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.\n")); 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.\n")); 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.\n")); 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\n", 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\n", 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\n", 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\n", 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.\n")); 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\n", 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\n", 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\n")); 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\n")); 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\n")); 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.\n", 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\n")); 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.\n", 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.\n", Request)); DEBUGP (DL_TRACE, ("===> FilterOidRequestComplete, Request% p. \ N", Request));
Context = (PFILTER_REQUEST_CONTEXT)(&Request->SourceReserved[0]); Context = (PFILTER_REQUEST_CONTEXT) (& Request-> SourceReserved [0]);
OriginalRequest = (*Context); OriginalRequest = (* Context);
if (OriginalRequest == NULL) if (OriginalRequest == NULL)
{ {
filterInternalRequestComplete(pFilter, Request, Status); filterInternalRequestComplete (pFilter, Request, Status);
return; return;
} }
FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse); FILTER_ACQUIRE_LOCK (& pFilter-> Lock, bFalse);
ASSERT(pFilter->PendingOidRequest == Request); ASSERT (pFilter-> PendingOidRequest == Request);
pFilter->PendingOidRequest = NULL; pFilter-> PendingOidRequest = NULL;
FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse); FILTER_RELEASE_LOCK (& pFilter-> Lock, bFalse);
switch(Request->RequestType) switch (Request-> RequestType)
{ {
case NdisRequestMethod: case NdisRequestMethod:
OriginalRequest->DATA.METHOD_INFORMATION.OutputBufferLength = Request->DATA.METHOD_INFORMATION.OutputBufferLength; OriginalRequest-> DATA.METHOD_INFORMATION.OutputBufferLength = Request-> DATA.METHOD_INFORMATION.OutputBufferLength;
OriginalRequest->DATA.METHOD_INFORMATION.BytesRead = Request->DATA.METHOD_INFORMATION.BytesRead; OriginalRequest-> DATA.METHOD_INFORMATION.BytesRead = Request-> DATA.METHOD_INFORMATION.BytesRead;
OriginalRequest->DATA.METHOD_INFORMATION.BytesNeeded = Request->DATA.METHOD_INFORMATION.BytesNeeded; OriginalRequest-> DATA.METHOD_INFORMATION.BytesNeeded = Request-> DATA.METHOD_INFORMATION.BytesNeeded;
OriginalRequest->DATA.METHOD_INFORMATION.BytesWritten = Request->DATA.METHOD_INFORMATION.BytesWritten; OriginalRequest-> DATA.METHOD_INFORMATION.BytesWritten = Request-> DATA.METHOD_INFORMATION.BytesWritten;
break; break;
case NdisRequestSetInformation: case NdisRequestSetInformation:
OriginalRequest->DATA.SET_INFORMATION.BytesRead = Request->DATA.SET_INFORMATION.BytesRead; OriginalRequest-> DATA.SET_INFORMATION.BytesRead = Request-> DATA.SET_INFORMATION.BytesRead;
OriginalRequest->DATA.SET_INFORMATION.BytesNeeded = Request->DATA.SET_INFORMATION.BytesNeeded; OriginalRequest-> DATA.SET_INFORMATION.BytesNeeded = Request-> DATA.SET_INFORMATION.BytesNeeded;
break; break;
case NdisRequestQueryInformation: case NdisRequestQueryInformation:
case NdisRequestQueryStatistics: case NdisRequestQueryStatistics:
default: default:
OriginalRequest->DATA.QUERY_INFORMATION.BytesWritten = Request->DATA.QUERY_INFORMATION.BytesWritten; OriginalRequest-> DATA.QUERY_INFORMATION.BytesWritten = Request-> DATA.QUERY_INFORMATION.BytesWritten;
OriginalRequest->DATA.QUERY_INFORMATION.BytesNeeded = Request->DATA.QUERY_INFORMATION.BytesNeeded; OriginalRequest-> DATA.QUERY_INFORMATION.BytesNeeded = Request-> DATA.QUERY_INFORMATION.BytesNeeded;
break; break;
} }
(*Context) = NULL; (* Context) = NULL;
NdisFreeCloneOidRequest(pFilter->FilterHandle, Request); NdisFreeCloneOidRequest (pFilter-> FilterHandle, Request);
/* / *
如果FilterOidRequest返回NDIS_STATUS_PENDING,就必须在OID请求完成后调用NdisFOidRequestComplete 来通知上层驱动求请求完成。 If FilterOidRequest return NDIS_STATUS_PENDING, you must complete the OID request call NdisFOidRequestComplete to notify the upper drive demand request is complete.在这种情况下,请求的结果通过NdisFOidRequestComplete的OidRequest参数返回给上层驱动,并通过Status参数返回请求完成的最终状态。 In this case, the result of the request through NdisFOidRequestComplete OidRequest parameters return to the upper-driven, and through the Status parameter to return the request to complete the final state.
要转发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或其它错误状态 To complete a request not forwarded directly to return NDIS_STATUS_SUCCESS or other error status
或返回NDIS_STATUS_PENDING后调用NdisFOidRequestComplete。 The or return NDIS_STATUS_PENDING call NdisFOidRequestComplete.
*/ * /
NdisFOidRequestComplete(pFilter->FilterHandle, OriginalRequest, Status); NdisFOidRequestComplete (pFilter-> FilterHandle, OriginalRequest, Status);
DEBUGP(DL_TRACE, ("<===FilterOidRequestComplete.\n")); DEBUGP (DL_TRACE, ("<=== FilterOidRequestComplete. \ N"));
} }
/************************************************************* / ************************************************* ************
FilterStatus函数的功能: Function of functions FilterStatus:
当下层驱动报告状态的时候 NDIS会调用它。 NDIS will call it when the lower drive report.此外,Filter Driver还可以自己引发一个状态指示。 , Filter Driver can lead to a status indication.
当下层驱动调用一个状态指示例程时(NdisMIndicateStatusEx或NdisFIndicateStats),NDIS When the lower drive call a status indication routine (NdisMIndicateStatusEx or NdisFIndicateStats), NDIS
会调用Filter Driver的FilterStatus例程。 Call the Filter Driver FilterStatus routine.
Filter Driver在FilterStatus中调用NdisFIndicateStatus传递一个状态指示给上层驱动。 Filter Driver called in FilterStatus NdisFIndicateStatus pass a status indication to the upper drive.此外,还可以过滤状态指示(不用调用 NdisFIndicateStatus)或在调用 NdisFIndicateStatus之前修改状态信息。 In addition, you can also filter status indicator (do not call NdisFIndicateStatus) or modify the status information before calling NdisFIndicateStatus.
Filter Driver要自己引发一个状态报告,可以在NDIS未调用 FilterStatus的情况下调用NdisFIndicateStatus。 Filter Driver To trigger a status report, can call NdisFIndicateStatus NDIS not call FilterStatus.在这种情况下,Filter Driver要设置 SourceHandle 成员为 FilteAttech 参数提供的NdisFilterHandle句柄。 In this case, Filter Driver To set the NdisFilterHandle handle SourceHandle the members FilteAttech parameters.
如果一个状态指示是一个OID请求相关的(下层请求一个 OID 下层要做相应的状态指示),那么状态的DestinationHandle和RequestId成员要设置成上层的OID请求包携带的数据。 If a status indication is an OID request (lower request an OID lower to do the appropriate state instructions), then the state DestinationHandle and RequestId members want to set as the upper OID request packets carrying data.
Filter Driver调用NdisFIndicateStatus后NDIS会调用相邻上层的状态指示函数(ProtocolStatusEx或FilterStatus)。 Filter Driver the call NdisFIndicateStatus after NDIS will call the the adjacent upper state indicator function the (ProtocolStatusEx, or FilterStatus).
****************************************************************/ ************************************************** ************** /
VOID VOID
FilterStatus( FilterStatus (
IN NDIS_HANDLE FilterModuleContext, IN NDIS_HANDLE FilterModuleContext,
IN PNDIS_STATUS_INDICATION StatusIndication IN PNDIS_STATUS_INDICATION StatusIndication
) )
{ {
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext; PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext;
#if DBG # If DBG
BOOLEAN bFalse = FALSE; BOOLEAN bFalse = FALSE;
#endif # Endif
DEBUGP(DL_TRACE, ("===>FilterStaus, IndicateStatus = %8x.\n", StatusIndication->StatusCode)); DEBUGP (DL_TRACE, ("===> FilterStaus, IndicateStatus =% 8x. \ N", StatusIndication-> StatusCode));
#if DBG # If DBG
FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse); FILTER_ACQUIRE_LOCK (& pFilter-> Lock, bFalse);
ASSERT(pFilter->bIndicating == FALSE); ASSERT (pFilter-> bIndicating == FALSE);
pFilter->bIndicating = TRUE; pFilter-> bIndicating = TRUE;
FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse); FILTER_RELEASE_LOCK (& pFilter-> Lock, bFalse);
#endif # Endif
NdisFIndicateStatus(pFilter->FilterHandle, StatusIndication); NdisFIndicateStatus (pFilter-> FilterHandle, StatusIndication);
#if DBG # If DBG
FILTER_ACQUIRE_LOCK(&pFilter->Lock, bFalse); FILTER_ACQUIRE_LOCK (& pFilter-> Lock, bFalse);
ASSERT(pFilter->bIndicating == TRUE); ASSERT (pFilter-> bIndicating == TRUE);
pFilter->bIndicating = FALSE; pFilter-> bIndicating = FALSE;
FILTER_RELEASE_LOCK(&pFilter->Lock, bFalse); FILTER_RELEASE_LOCK (& pFilter-> Lock, bFalse);
#endif # Endif
DEBUGP(DL_TRACE, ("<===FilterStaus.\n")); DEBUGP (DL_TRACE, ("<=== FilterStaus. \ N"));
} }
/* / *
Filter Driver提供FilterPnpEventNotify来接收NDIS传递的PnP和电源管理事件 The Filter Driver provides FilterPnpEventNotify to receive NDIS pass PnP and power management events
*/ * /
VOID VOID
FilterDevicePnPEventNotify( FilterDevicePnPEventNotify (
IN NDIS_HANDLE FilterModuleContext, IN NDIS_HANDLE FilterModuleContext,
IN PNET_DEVICE_PNP_EVENT NetDevicePnPEvent IN PNET_DEVICE_PNP_EVENT NetDevicePnPEvent
) )
{ {
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext; PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext;
NDIS_DEVICE_PNP_EVENT DevicePnPEvent = NetDevicePnPEvent->DevicePnPEvent; NDIS_DEVICE_PNP_EVENT DevicePnPEvent = NetDevicePnPEvent-> DevicePnPEvent;
#if DBG # If DBG
BOOLEAN bFalse = FALSE; BOOLEAN bFalse = FALSE;
#endif # Endif
DEBUGP(DL_TRACE, ("===>FilterDevicePnPEventNotify: NetPnPEvent = %p.\n", NetDevicePnPEvent)); DEBUGP (DL_TRACE, ("===> FilterDevicePnPEventNotify: NetPnPEvent =% p. \ N", NetDevicePnPEvent));
switch (DevicePnPEvent) switch (DevicePnPEvent)
{ {
case NdisDevicePnPEventQueryRemoved: case NdisDevicePnPEventQueryRemoved:
case NdisDevicePnPEventRemoved: case NdisDevicePnPEventRemoved:
case NdisDevicePnPEventSurpriseRemoved: case NdisDevicePnPEventSurpriseRemoved:
case NdisDevicePnPEventQueryStopped: case NdisDevicePnPEventQueryStopped:
case NdisDevicePnPEventStopped: case NdisDevicePnPEventStopped:
case NdisDevicePnPEventPowerProfileChanged: case NdisDevicePnPEventPowerProfileChanged:
case NdisDevicePnPEventFilterListChanged: case NdisDevicePnPEventFilterListChanged:
break; break;
default: default:
DEBUGP(DL_ERROR, ("FilterDevicePnPEventNotify: Invalid event.\n")); DEBUGP (DL_ERROR, ("FilterDevicePnPEventNotify: Invalid event. \ N"));
FILTER_ASSERT(bFalse); FILTER_ASSERT (bFalse);
break; break;
} }
//Filter Driver要下层驱动转发收到的事件,转发事件要用到NdisFDevicePnPEventNotify例程 / / Filter Driver To lower driving forward the event received and forwarded events use to NdisFDevicePnPEventNotify routine
NdisFDevicePnPEventNotify(pFilter->FilterHandle, NetDevicePnPEvent); NdisFDevicePnPEventNotify (pFilter-> FilterHandle, NetDevicePnPEvent);
DEBUGP(DL_TRACE, ("<===FilterDevicePnPEventNotify\n")); DEBUGP (DL_TRACE, ("<=== FilterDevicePnPEventNotify \ n"));
} }
/* / *
Filter Driver提供了FilterNetPnpEvent例程来处理网络Pnp和电源管理事件通知。 The Filter Driver FilterNetPnpEvent routines to handle network the Pnp and the power management event notification.
*/ * /
NDIS_STATUS NDIS_STATUS
FilterNetPnPEvent( FilterNetPnPEvent (
IN NDIS_HANDLE FilterModuleContext, IN NDIS_HANDLE FilterModuleContext,
IN PNET_PNP_EVENT_NOTIFICATION NetPnPEventNotification IN PNET_PNP_EVENT_NOTIFICATION NetPnPEventNotification
) )
{ {
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext; PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS; NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
//Filter Driver需要转发网络PnP和电源管理事件给上层驱动。 / / Filter Driver network PnP and power management events need to be forwarded to the upper drive.转发这些事件是通NdisFNetPnpEvent来完成的。 Forwarding these events through NdisFNetPnpEvent to complete.
Status = NdisFNetPnPEvent(pFilter->FilterHandle, NetPnPEventNotification); Status = NdisFNetPnPEvent (pFilter-> FilterHandle, NetPnPEventNotification);
return Status; return Status;
} }
/************************************************************** / ************************************************* *************
FilterSendNetBufferListsComplete函数的功能: Function of function FilterSendNetBufferListsComplete:
NDIS调用 FilterSendNetBufferListsComplete 把发送的结构和数据返还给 Filter Driver。 The NDIS invoked FilterSendNetBufferListsComplete send the structure and the data is returned to the Filter Driver. NDIS可以收集多次NdisFSendNetBufferLists发送的结构和数据形成一个单链表传递给FilterSendNetBufferListsComplete。 NDIS can form a single linked list structure and data collection of several NdisFSendNetBufferLists sent passed to FilterSendNetBufferListsComplete.除非到NDIS调用FilterSendNetBufferListsComplete,否则一个发送请求的当前状态总是未知的。 Unless the NDIS call FilterSendNetBufferListsComplete, or send a request always unknown.
一个过滤驱动是不能在NDIS调用FilterSendNetBufferListsComplete返回结构之前对NET_BUFFER_LIST和其关联的数据做检查的。 A filter driver can not return structures in NDIS call FilterSendNetBufferListsComplete is of NET_BUFFER_LIST and its associated data check. FilterSendNetBufferListsComplete要完成一个发送请求完成后的任何必要的后继处理。 FilterSendNetBufferListsComplete to complete a transmission request is completed any necessary subsequent processing.当NDIS调用FilterSendNetBufferListsComplete时,Filter Driver就重新获地对结构及结构相关资源的所有权。 In the NDIS call FilterSendNetBufferListsComplete, Filter Driver regain ownership of the land on the structure and structural resources.可以在 FilterSendNetBufferListsComplete中释放相关的资源和准备下一个NdisFSendNetBufferLists调用。 Released in FilterSendNetBufferListsComplete related resources and ready to to under a NdisFSendNetBufferLists call.
NDIS总是按照过滤驱动调用NdisFSendNetBufferLists提交的顺序传递给下层驱动,但是回返FilterSendNetBufferListsComplete 的顺序则是任意的。 NDIS always pass the filter driver the call NdisFSendNetBufferLists submit the order to the lower drive but the return FilterSendNetBufferListsComplete order is arbitrary. Filter Driver可以请求一个回环发送请求,只要把NdisFSendNetBufferLists的SendFlags设置成NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK就行了。 The Filter Driver may request a loopback sends a request, as long as the the NdisFSendNetBufferLists the SendFlags to set into NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK the line. NDIS会引发一个包含发送数据的接收包指示。 The NDIS will lead a send data receiver package directions.
一个Filter Driver应该对自己引发的发送请求保持跟踪并确保在完成时不调用NdisFSendNetBufferComplete例程。 A Filter Driver should be triggered send requests to keep track and ensure completion call NdisFSendNetBufferComplete routine.
**************************************************************/ ************************************************** ************ /
VOID VOID
FilterSendNetBufferListsComplete( FilterSendNetBufferListsComplete (
IN NDIS_HANDLE FilterModuleContext, IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists, IN PNET_BUFFER_LIST NetBufferLists,
IN ULONG SendCompleteFlags IN ULONG SendCompleteFlags
) )
{ {
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext; PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext;
ULONG NumOfSendCompletes = 0; ULONG NumOfSendCompletes = 0;
BOOLEAN DispatchLevel; BOOLEAN DispatchLevel;
PNET_BUFFER_LIST CurrNbl; PNET_BUFFER_LIST CurrNbl;
DEBUGP(DL_TRACE, ("===>SendNBLComplete, NetBufferList: %p.\n", NetBufferLists)); DEBUGP (DL_TRACE, ("===> SendNBLComplete, NetBufferList:% p. \ N", NetBufferLists));
if (pFilter->TrackSends) if (pFilter-> TrackSends)
{ {
CurrNbl = NetBufferLists; CurrNbl = NetBufferLists;
while (CurrNbl) while (CurrNbl)
{ {
NumOfSendCompletes++; NumOfSendCompletes + +;
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl); CurrNbl = NET_BUFFER_LIST_NEXT_NBL (CurrNbl);
} }
DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendCompleteFlags); DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL (SendCompleteFlags);
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_ACQUIRE_LOCK (& pFilter-> Lock, DispatchLevel);
pFilter->OutstandingSends -= NumOfSendCompletes; pFilter-> OutstandingSends - = NumOfSendCompletes;
FILTER_LOG_SEND_REF(2, pFilter, PrevNbl, pFilter->OutstandingSends); FILTER_LOG_SEND_REF (2, pFilter, PrevNbl, pFilter-> OutstandingSends);
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_RELEASE_LOCK (& pFilter-> Lock, DispatchLevel);
} }
NdisFSendNetBufferListsComplete(pFilter->FilterHandle, NetBufferLists, SendCompleteFlags); NdisFSendNetBufferListsComplete (pFilter-> FilterHandle, NetBufferLists, SendCompleteFlags);
DEBUGP(DL_TRACE, ("<===SendNBLComplete.\n")); DEBUGP (DL_TRACE, ("<=== SendNBLComplete. \ N"));
} }
/************************************************************* / ************************************************* ************
FilterSendNetBufferLists函数的功能: Function of functions FilterSendNetBufferLists:
NDIS调用一个Filter Driver的FilterSendNetBufferLists例程来过滤上层驱动的发送请求。 NDIS call the Filter Driver FilterSendNetBufferLists routine to filter the upper drive sends a request. Filter Driver不能改变其它驱动传来的NET_BUFFER_LIST结构中的SourceHandle成员的值。 Filter Driver can not change the value of the other drivers coming NET_BUFFER_LIST structure in the SourceHandle members.它可以过滤数据并发送过滤的数据到下层驱动。 It can filter the data and send the data of the filter to the lower drive.
对每一个提交到FilterSendNetBufferLists的NDIS_BUFFER_LIST,我们可做下面的操作。 For each submitted to FilterSendNetBufferLists NDIS_BUFFER_LIST, we can do the following operations.
1)可以把缓冲区通过 NdisFSendBufferLists 传递给下层驱动,NDIS 保证上下文空间对FilterDriver的有效性。 1) can be put buffer by NdisFSendBufferLists in passing to the lower driver, NDIS to ensure the validity of the context the space FilterDriver the.过滤驱动可以在发送前修改缓冲区的内容。 The filter driver can modify the contents of the buffer before sending.可以像处理自己引发的发送请求的缓冲区一样处理这个缓冲区。 Like like a buffer to deal with their own triggered by sending a request to deal with this buffer.
2)可以调用 NdisFSendNetBufferListsComplete 拒绝传递这个包 2) can call NdisFSendNetBufferListsComplete refuse to pass this package
3)排队缓冲区内容到本地的供以后处理。 3) to the local queuing buffer content for later processing.例如要在一定超时后处理或要接收到特定包后才处理等。 For example, after a certain timeout processing or to be received to a specific package before processing.如果支持这种处理方式就要支持取消请求的操作。 If you support this approach is necessary to support the operation of the cancellation request.
4)可以拷贝缓冲区并引发一个发送请求。 4) copy buffer and trigger a send request.它类似自己引发一个发送请求,但必须先调用 NdisFSendNetBufferComplete返回上层驱动的缓冲区。 It is similar to its own to trigger a send request, but must call NdisFSendNetBufferComplete return to the upper drive buffer.
发送请求在驱动栈继续完成,当一个微端口驱动调用NdisMSendNetBufferListsComplete完成一个发送请求时,NDIS会调用微端口 Send a request to complete driver stack when a miniport driver calls NdisMSendNetBufferListsComplete completion of a send request, NDIS calls the miniport
驱动之上最近的Filter Driver的FilterSendNetBufferLists例程。 Drive above the the Filter Driver FilterSendNetBufferLists routine.
在一个发送操作完成后,Filter Driver可以做在FilterSendNetBufferLists中所有修改的相反操作。 After a send operation to complete, Filter Driver the opposite operation can be done in FilterSendNetBufferLists modified. FilterSendNetBufferListsComplete返回一个NET_BUFFER_LIST结构的单链表和发送请求的最终状态给上层的驱动。 The final state of the single FilterSendNetBufferListsComplete return a NET_BUFFER_LIST structure linked list and send the request to the upper drive.当最顶层的 Filter Module的FilterSendNetBufferListsComplete被调用完成后NDIS会调用引发发送请求的协议驱动的ProtocolSendNetBufferListsComplete。 When the the topmost Filter Module FilterSendNetBufferListsComplete is after the call completes NDIS will call the initiator sends a request to the protocol driver ProtocolSendNetBufferListsComplete.如果Filter Driver不提供FilterSendNetBufferLists它还是可以引发一个发送操作的,但它必须提供一个FilterSendNetBufferListsComplete并且不能在这个例程里把这个事件传递给上层驱动。 Filter Driver does not provide FilterSendNetBufferLists it can still lead to a send operation, but it must provide a FilterSendNetBufferListsComplete and can not be in this routine, this event is passed to the upper drive.
一个Filter Driver可以传递或过滤一个上层驱动的回环请求,要传递一个回环请求,NDIS会设置FilterSendNetBufferLists的SendFlags参数为NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK,Filter Driver在调用NdisFSendNetBufferLists时把这个标记传给它即可。 Loopback request, you can pass a Filter Driver or filter an upper drive to pass a loopback request, NDIS will to set FilterSendNetBufferLists SendFlags parameters for NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK Filter Driver call NdisFSendNetBufferLists this tag and pass it can.在回环请求的情况下NDIS会指示一个包含发送数据的接收包。 NDIS will indicate a received packet contains the transmission data in the case of loopback request.
通常情况下,如果一个Filter Driver修改的任何行为不是NDIS提供的标准服务,那么它应该当自己为NDIS提供相应的服务。 Under normal circumstances, if a Filter Driver modify any behavior not NDIS standard services provided, then it should provide the necessary services for NDIS.例如,如果一个Filter Driver修改了一个硬件地址请求,就必须处理直接到这个新地址回环包。 For example, if a Filter Driver modify a hardware address request, it must be processed directly into this new address loopback packet.在这种情况下, 因为Filter Driver已经更改了地址NDIS是不能提供一个回环服务的。 In this case, since the Filter Driver has changed the address NDIS is not to provide a loopback services.
还有就是如果Filter Driver设置了混杂模式那它就不能传递额外的数据给上层接收。 Filter Driver set promiscuous mode there is that it can not pass the additional data to the upper receiver.
**************************************************************/ ************************************************** ************ /
VOID VOID
FilterSendNetBufferLists( FilterSendNetBufferLists (
IN NDIS_HANDLE FilterModuleContext, IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists, IN PNET_BUFFER_LIST NetBufferLists,
IN NDIS_PORT_NUMBER PortNumber, IN NDIS_PORT_NUMBER PortNumber,
IN ULONG SendFlags IN ULONG SendFlags
) )
{ {
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext; PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext;
PNET_BUFFER_LIST CurrNbl; PNET_BUFFER_LIST CurrNbl;
BOOLEAN DispatchLevel; BOOLEAN DispatchLevel;
BOOLEAN bFalse = FALSE; BOOLEAN bFalse = FALSE;
DEBUGP(DL_TRACE, ("===>SendNetBufferList: NBL = %p.\n", NetBufferLists)); DEBUGP (DL_TRACE, ("===> SendNetBufferList: NBL =% p. \ N", NetBufferLists));
do do
{ {
DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags); DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL (SendFlags);
#if DBG # If DBG
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_ACQUIRE_LOCK (& pFilter-> Lock, DispatchLevel);
if (pFilter->State != FilterRunning) if (pFilter-> State! = FilterRunning)
{ {
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_RELEASE_LOCK (& pFilter-> Lock, DispatchLevel);
CurrNbl = NetBufferLists; CurrNbl = NetBufferLists;
while (CurrNbl) while (CurrNbl)
{ {
NET_BUFFER_LIST_STATUS(CurrNbl) = NDIS_STATUS_PAUSED; NET_BUFFER_LIST_STATUS (CurrNbl) = NDIS_STATUS_PAUSED;
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl); CurrNbl = NET_BUFFER_LIST_NEXT_NBL (CurrNbl);
} }
NdisFSendNetBufferListsComplete(pFilter->FilterHandle, NdisFSendNetBufferListsComplete (pFilter-> FilterHandle,
NetBufferLists, NetBufferLists,
DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0); DispatchLevel? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL: 0);
break; break;
} }
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_RELEASE_LOCK (& pFilter-> Lock, DispatchLevel);
#endif # Endif
/******************************************************/ / ************************************************* * /
//在这里添加我们的代码 / / Add our code here
/******************************************************/ / ************************************************* * /
if (pFilter->TrackSends) if (pFilter-> TrackSends)
{ {
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_ACQUIRE_LOCK (& pFilter-> Lock, DispatchLevel);
CurrNbl = NetBufferLists; CurrNbl = NetBufferLists;
while (CurrNbl) while (CurrNbl)
{ {
pFilter->OutstandingSends++; pFilter-> OutstandingSends + +;
FILTER_LOG_SEND_REF(1, pFilter, CurrNbl, pFilter->OutstandingSends); FILTER_LOG_SEND_REF (1, pFilter, CurrNbl, pFilter-> OutstandingSends);
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl); CurrNbl = NET_BUFFER_LIST_NEXT_NBL (CurrNbl);
} }
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_RELEASE_LOCK (& pFilter-> Lock, DispatchLevel);
} }
NdisFSendNetBufferLists(pFilter->FilterHandle, NetBufferLists, PortNumber, SendFlags); NdisFSendNetBufferLists (pFilter-> FilterHandle, NetBufferLists, PortNumber, SendFlags);
} }
while (bFalse); while (bFalse);
DEBUGP(DL_TRACE, ("<===SendNetBufferList. \n")); DEBUGP (DL_TRACE, ("<=== SendNetBufferList. \ N"));
} }
/************************************************************* / ************************************************* ************
FilterReturnNetBufferLists函数的功能: Function of functions FilterReturnNetBufferLists:
如果Filter Driver设置了NdisFIndicateReceiveNetBufferLists的状态为NDIS_STATUS_SUCCESS, NDIS通过驱动的FilterReturnNetBufferLists If Filter Driver to set NdisFIndicateReceiveNetBufferLists the state of NDIS_STATUS_SUCCESS, NDIS driven FilterReturnNetBufferLists
返回指示数据。 Return indicating data.在这种情况下 Filter Driver失去了对NET_BUFFER_LIST的所有权,直到FilterReturnNetBufferLists被调用。 In this case, Filter Driver loses ownership to NET_BUFFER_LIST be invoked until FilterReturnNetBufferLists.
Filter Driver调用NdisFIndicateNetBufferLists 传递接收指示给驱动栈上的上层驱动,如果上层驱动保留了对缓冲区(NET_BUFFER_LIST)的所有权,NDIS会调用Filter Driver的FilterReturnNetBufferLists 例程。 The Filter Driver calls NdisFIndicateNetBufferLists pass receiver instructions to the driver stack on the upper drive the upper drive retains ownership of the buffer (NET_BUFFER_LIST), NDIS will to call Filter Driver FilterReturnNetBufferLists routine.
在FilterReturnNetBufferLists中应该撤消在接收路径上(如在 FilterReciveNetBufferLists中做的一些处理)的操作。 The in FilterReturnNetBufferLists should undo the operation on the receive path (as do some processing in FilterReciveNetBufferLists).当最底层的Filter Module完成对缓冲区(NET_BUFFER_LIST)的处理后,NDIS把缓冲区返回给微端口驱动。 When the bottom of the Filter Module completed on after the buffer (NET_BUFFER_LIST), processing, NDIS buffer returned to the miniport driver.如果FilterReceiveNetBufferLists的ReceiveFlags没有设置NDIS_RECEIVE_FLAGS_RESOURCES标记, FilterDriver调用NdisFReturnNetBufferList返回这个缓冲区数据,如果设置了FilterReceiveNetBufferLists直接返回时就把缓冲区返还给了下层微端口驱动。 If FilterReceiveNetBufferLists of ReceiveFlags no set NDIS_RECEIVE_FLAGS_RESOURCES mark, FilterDriver invoked NdisFReturnNetBufferList return this buffer data set FilterReceiveNetBufferLists returned directly put the buffer returned to the lower miniport driver.
***************************************************************/ ************************************************** ************* /
VOID VOID
FilterReturnNetBufferLists( FilterReturnNetBufferLists (
IN NDIS_HANDLE FilterModuleContext, IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists, IN PNET_BUFFER_LIST NetBufferLists,
IN ULONG ReturnFlags IN ULONG ReturnFlags
) )
{ {
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext; PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext;
PNET_BUFFER_LIST CurrNbl = NULL; PNET_BUFFER_LIST CurrNbl = NULL;
UINT NumOfNetBufferLists = 0; UINT NumOfNetBufferLists = 0;
BOOLEAN DispatchLevel; BOOLEAN DispatchLevel;
ULONG Ref; ULONG Ref;
DEBUGP(DL_TRACE, ("===>ReturnNetBufferLists, NetBufferLists is %p.\n", NetBufferLists)); DEBUGP (DL_TRACE, ("===> ReturnNetBufferLists, NetBufferLists is% p. \ N", NetBufferLists));
if (pFilter->TrackReceives) if (pFilter-> TrackReceives)
{ {
while (CurrNbl) while (CurrNbl)
{ {
NumOfNetBufferLists ++; NumOfNetBufferLists + +;
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl); CurrNbl = NET_BUFFER_LIST_NEXT_NBL (CurrNbl);
} }
} }
NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReturnFlags); NdisFReturnNetBufferLists (pFilter-> FilterHandle, NetBufferLists, ReturnFlags);
if (pFilter->TrackReceives) if (pFilter-> TrackReceives)
{ {
DispatchLevel = NDIS_TEST_RETURN_AT_DISPATCH_LEVEL(ReturnFlags); DispatchLevel = NDIS_TEST_RETURN_AT_DISPATCH_LEVEL (ReturnFlags);
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_ACQUIRE_LOCK (& pFilter-> Lock, DispatchLevel);
pFilter->OutstandingRcvs -= NumOfNetBufferLists; pFilter-> OutstandingRcvs - = NumOfNetBufferLists;
Ref = pFilter->OutstandingRcvs; Ref = pFilter-> OutstandingRcvs;
FILTER_LOG_RCV_REF(3, pFilter, NetBufferLists, Ref); FILTER_LOG_RCV_REF (3, pFilter, NetBufferLists, Ref);
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_RELEASE_LOCK (& pFilter-> Lock, DispatchLevel);
} }
DEBUGP(DL_TRACE, ("<===ReturnNetBufferLists.\n")); DEBUGP (DL_TRACE, ("<=== ReturnNetBufferLists. \ N"));
} }
/*************************************************************** / ************************************************* **************
FilterReceiveNetBufferLists函数的功能: Function of functions FilterReceiveNetBufferLists:
Filter Driver调用 NdisFIndicateReceiveNetBufferLists来指示发送数据。 The Filter Driver calls NdisFIndicateReceiveNetBufferLists to indicate the transmission data.这个函数通过NET_BUFFER_LIST结构给上层驱动指示数据。 The instructions to the upper drive function through NET_BUFFER_LIST structure data. Filter Driver可以从池中分配这个结构。 Filter Driver can be allocated from the pool structure.如果Filter Driver设置了NdisFIndicateReceiveNetBufferLists的状态为 NDIS_STATUS_SUCCESS, NDIS通过驱动的FilterReturnNetBufferLists返回指示数据。 If Filter Driver to set NdisFIndicateReceiveNetBufferLists the state NDIS_STATUS_SUCCESS, NDIS through the drive FilterReturnNetBufferLists return instruction data.在这种情况下Filter Driver失去了对NET_BUFFER_LIST的所有权直到FilterReturnNetBufferLists被调用。 In this case, Filter Driver lost the the ownership right NET_BUFFER_LIST be invoked until FilterReturnNetBufferLists.如果Filter Driver在调用NdisFIndicateReceiveNetBufferLists时设置ReceiveFlags为NDIS_RECEIVE_FLAGS_RESOURCES,在函数返回后Filter Driver会立即恢复对NET_BUFFER_LIST的所有权,这时Filter Driver必须立即处理这个NET_BUFFER_LIST的返回,因为NDIS在这种情况下是不会调用FilterReturnNetBufferLists返回NET_BUFFER_LIST结构的。 If Filter Driver in to set ReceiveFlags call NdisFIndicateReceiveNetBufferLists, the NDIS_RECEIVE_FLAGS_RESOURCES Filter Driver after the function returns immediately restore ownership of NET_BUFFER_LIST, when Filter Driver must be dealt with immediately NET_BUFFER_LIST return, because NDIS in this case does not call FilterReturnNetBufferLists return NET_BUFFER_LIST structure.
注意: 一个Filter Driver应该跟踪自己引发的接收指示确保它在FilterReturnNetBufferLists Note: a Filter Driver should track their triggered by receiving instructions to ensure that it is in FilterReturnNetBufferLists
中不调用NdisFReturnNetBufferLists。 Do not call NdisFReturnNetBufferLists.
***************************************************************/ ************************************************** ************* /
VOID VOID
FilterReceiveNetBufferLists( FilterReceiveNetBufferLists (
IN NDIS_HANDLE FilterModuleContext, IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists, IN PNET_BUFFER_LIST NetBufferLists,
IN NDIS_PORT_NUMBER PortNumber, IN NDIS_PORT_NUMBER PortNumber,
IN ULONG NumberOfNetBufferLists, IN ULONG NumberOfNetBufferLists,
IN ULONG ReceiveFlags IN ULONG ReceiveFlags
) )
{ {
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext; PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext;
BOOLEAN DispatchLevel; BOOLEAN DispatchLevel;
ULONG Ref; ULONG Ref;
BOOLEAN bFalse = FALSE; BOOLEAN bFalse = FALSE;
#if DBG # If DBG
ULONG ReturnFlags; ULONG ReturnFlags;
#endif # Endif
DEBUGP(DL_TRACE, ("===>ReceiveNetBufferList: NetBufferLists = %p.\n", NetBufferLists)); DEBUGP (DL_TRACE, ("===> ReceiveNetBufferList: NetBufferLists =% p. \ N", NetBufferLists));
do do
{ {
DispatchLevel = NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags); DispatchLevel = NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL (ReceiveFlags);
#if DBG # If DBG
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_ACQUIRE_LOCK (& pFilter-> Lock, DispatchLevel);
if (pFilter->State != FilterRunning) if (pFilter-> State! = FilterRunning)
{ {
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_RELEASE_LOCK (& pFilter-> Lock, DispatchLevel);
if (NDIS_TEST_RECEIVE_CAN_PEND(ReceiveFlags)) if (NDIS_TEST_RECEIVE_CAN_PEND (ReceiveFlags))
{ {
ReturnFlags = 0; ReturnFlags = 0;
if (NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags)) if (NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL (ReceiveFlags))
{ {
NDIS_SET_RETURN_FLAG(ReturnFlags, NDIS_RETURN_FLAGS_DISPATCH_LEVEL); NDIS_SET_RETURN_FLAG (ReturnFlags, NDIS_RETURN_FLAGS_DISPATCH_LEVEL);
} }
NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReturnFlags); NdisFReturnNetBufferLists (pFilter-> FilterHandle, NetBufferLists, ReturnFlags);
} }
break; break;
} }
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_RELEASE_LOCK (& pFilter-> Lock, DispatchLevel);
#endif # Endif
ASSERT(NumberOfNetBufferLists >= 1); ASSERT (NumberOfNetBufferLists> = 1);
/*--------------------------------------------------------------------------------------*/ / * ------------------------------------------------ -------------------------------------- * /
//在这里添加我们的代码 / / Add our code here
/*---------------------------------------------------------------------------------------*/ / * ------------------------------------------------ --------------------------------------- * /
if (pFilter->TrackReceives) if (pFilter-> TrackReceives)
{ {
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_ACQUIRE_LOCK (& pFilter-> Lock, DispatchLevel);
pFilter->OutstandingRcvs += NumberOfNetBufferLists; pFilter-> OutstandingRcvs + = NumberOfNetBufferLists;
Ref = pFilter->OutstandingRcvs; Ref = pFilter-> OutstandingRcvs;
FILTER_LOG_RCV_REF(1, pFilter, NetBufferLists, Ref); FILTER_LOG_RCV_REF (1, pFilter, NetBufferLists, Ref);
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_RELEASE_LOCK (& pFilter-> Lock, DispatchLevel);
} }
/************************************************************ / ************************************************* ***********
调用 NdisFIndicateReceiveNetBufferLists来指示发送数据。 Call NdisFIndicateReceiveNetBufferLists to indicate the transmission data.
如果Filter Driver设置了NdisFIndicateReceiveNetBufferLists的状态为NDIS_STATUS_SUCCESS, NDIS通过驱动的FilterReturnNetBufferLists 返回指示数据。 If Filter Driver to set NdisFIndicateReceiveNetBufferLists the state NDIS_STATUS_SUCCESS, NDIS through the drive FilterReturnNetBufferLists return instruction data.
如果Filter Driver设置了NdisFIndicateReceiveNetBufferLists的ReceiveFlags值为 If The Filter Driver to set NdisFIndicateReceiveNetBufferLists the ReceiveFlags value
NDIS_RECEIVE_FLAGS_RESOURCES,那么在函数返回后Filter Driver会立即恢复对 NDIS_RECEIVE_FLAGS_RESOURCES, then the function returns Filter Driver will be resumed immediately on
NET_BUFFER_LIST的所有权,这时Filter Driver必须立即处理这个NET_BUFFER_LIST的返回。 NET_BUFFER_LIST ownership, then Filter Driver must immediately deal with the return NET_BUFFER_LIST.
在这种情况下是不会调用FilterReturnNetBufferLists返回NET_BUFFER_LIST结构的。 In this case, will not call FilterReturnNetBufferLists to return NET_BUFFER_LIST structure.
************************************************************/ ************************************************** ********** /
NdisFIndicateReceiveNetBufferLists( NdisFIndicateReceiveNetBufferLists (
pFilter->FilterHandle, pFilter-> FilterHandle,
NetBufferLists, NetBufferLists,
PortNumber, PortNumber,
NumberOfNetBufferLists, NumberOfNetBufferLists,
ReceiveFlags); ReceiveFlags);
if (NDIS_TEST_RECEIVE_CANNOT_PEND(ReceiveFlags) && pFilter->TrackReceives) if (NDIS_TEST_RECEIVE_CANNOT_PEND (ReceiveFlags) && pFilter-> TrackReceives)
{ {
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_ACQUIRE_LOCK (& pFilter-> Lock, DispatchLevel);
pFilter->OutstandingRcvs -= NumberOfNetBufferLists; pFilter-> OutstandingRcvs - = NumberOfNetBufferLists;
Ref = pFilter->OutstandingRcvs; Ref = pFilter-> OutstandingRcvs;
FILTER_LOG_RCV_REF(2, pFilter, NetBufferLists, Ref); FILTER_LOG_RCV_REF (2, pFilter, NetBufferLists, Ref);
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); FILTER_RELEASE_LOCK (& pFilter-> Lock, DispatchLevel);
} }
} while (bFalse); } While (bFalse);
DEBUGP(DL_TRACE, ("<===ReceiveNetBufferList: Flags = %8x.\n", ReceiveFlags)); DEBUGP (DL_TRACE, ("<=== ReceiveNetBufferList: Flags =% 8x. \ N", ReceiveFlags));
} }
/************************************************************** / ************************************************* *************
FilterCancelSendNetBufferLists函数的功能: Function of functions FilterCancelSendNetBufferLists:
过滤驱动调用NDIS_SET_NET_BUFFER_LIST_CANCEL_ID宏为每一个NET_BUFFER_LIST标记一个取消Id。 The filter driver calling NDIS_SET_NET_BUFFER_LIST_CANCEL_ID macro for each NET_BUFFER_LIST mark a canceled Id.
在为网络数据分配取消ID之前,必须先调用NdisGenratePartialCanceId获得取消ID的高字节。 Prior to cancel the ID for the network data distribution, you must first call NdisGenratePartialCanceId to cancel ID high byte.
这是为了确保不是驱动不会把一个取消ID分配给两个驱动驱动通常在DriverEntry调用 This is in order to ensure not drive will not put a canceled ID assigned to two drivers drive usually DriverEntry call
NdisGenratePartialCanceld,但是驱动可以在不同的时间多次调用它来获得多个取消ID。 NdisGenratePartialCanceld, but the driver can many times at different times to call it to get multiple cancel ID.
要取消被标记过取消ID且正在传输的数据,驱动可以调用NdisFCancelSendNetBufferLists例程 To cancel cancel ID is marked and the data being transferred, the drive can call NdisFCancelSendNetBufferLists routine
来完成。 To complete.要获得取消ID可以用NDIS_GET_NET_BUFFER_LIST_CANCEL_ID宏来完成。 To get to cancel ID can be used NDIS_GET_NET_BUFFER_LIST_CANCEL_ID macro.
如果一个Filter Driver对所有发送的NET_BUFFER_LIST标记了相同的取消ID那它可以用一个 A Filter Driver the same cancellation mark all the NET_BUFFER_LIST send ID it with a
NdisFCancelSendNetBufferLists来取消所有的发送请求。 NdisFCancelSendNetBufferLists to cancel all send requests.如果把一部发送请求的NET_BUFFER_LIST标记相同的取消ID那么就可以调用一次NdisFCancelSendNetBufferLists来取消这部分发送请求。 Send a request NET_BUFFER_LIST marker cancel ID then you can call the time NdisFCancelSendNetBufferLists to cancel this part of the send request.
在实现这个功能时NDIS会调用下层驱动的取消发送功能。 NDIS will achieve this function calls the lower drive cancel sending.中断正在执行的发送任务后,下层驱动会 The lower drive will interrupt the sending task being performed,
调用发送完成全程(如:NdisMSendNetBufferListComplete)返回指定的NET_BUFFER_LIST结构并指定 返回状态为 NDIS_STATUS_CANCELLED, NDIS依次调用Filter Driver的FilterSendNetBufferListsComplete例程。 Call to send will finish (eg: NdisMSendNetBufferListComplete), return specified NET_BUFFER_LIST structure and specify return NDIS_STATUS_CANCELLED, NDIS turn call the Filter Driver FilterSendNetBufferListsComplete routine.在FilterSendNetBufferListsComplete中要用NDIS_SET_NET_BUFFER_LIST_CANCEL_ID设置取消的NET_BUFFER_LIST NDIS_SET_NET_BUFFER_LIST_CANCEL_ID the setting cancel the NET_BUFFER_LIST use FilterSendNetBufferListsComplete in
的取消ID 为 NULL,这样是为了防止这个ID,在 NET_BUFFER_LIST被再次分配时使用。 Cancellation ID is NULL, this is in order to prevent this ID NET_BUFFER_LIST is again assigned to use.
上层驱动在取消一个未完成的发送请求时也必须对这个发送请求的 NET_BUFFER_LIST结构设定取消ID。 The upper drive cancel an unfinished send request must cancel this the sending request NET_BUFFER_LIST structure set ID.
NDIS会传递给Filter Driver的FilterCancelSendNetBufferLists一个取消ID来取消发送请求的 NDIS will pass to Filter Driver FilterCancelSendNetBufferLists an to cancel ID to cancel sending request
NET_BUFFER_LIST发送。 NET_BUFFER_LIST sent. FilterCanCelSendNetBufferLists下执行下列操作。 FilterCanCelSendNetBufferLists Perform the following procedure.
1)遍历 Filter Driver的发送队列,用 NDIS_GET_NET_BUFFER_LSIT_CANCEL_ID获得队列中NET_BUFFER_LIST的取消ID与FilterCancelSendBufferLists的取消ID比较。 1) traversal Filter Driver transmit queue, cancel ID with NDIS_GET_NET_BUFFER_LSIT_CANCEL_ID to get queue NET_BUFFER_LIST cancel ID FilterCancelSendBufferLists of the comparison.
2)移除队列中取消 ID 和 FilterCancelSentBufferLists中取消ID相同的元素。 2) Remove canceled the ID and FilterCancelSentBufferLists cancel the same ID elements in the queue.
3)调用 NdisFSendNetBufferListsComplete来完成这些NET_BUFFER_LIST并设定返回状 3) call NdisFSendNetBufferListsComplete to complete these NET_BUFFER_LIST and set the return-like
态为NDIS_STATUS_CANCELLED。 State is NDIS_STATUS_CANCELLED.
4)调用NdisFCancelSendNetBufferLists传递取消发送请求给下层驱动。 4) call NdisFCancelSendNetBufferLists passing cancel sending the request to the lower driver.传递取消ID给下层驱动就Filter Driver取消自己引发的发关请求一样。 Passed to cancel the ID to the lower drive Filter Driver cancel their hair off requests triggered.
*************************************************************/ ************************************************** *********** /
VOID VOID
FilterCancelSendNetBufferLists( FilterCancelSendNetBufferLists (
IN NDIS_HANDLE FilterModuleContext, IN NDIS_HANDLE FilterModuleContext,
IN PVOID CancelId IN PVOID CancelId
) )
{ {
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext; PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext;
NdisFCancelSendNetBufferLists(pFilter->FilterHandle,CancelId); NdisFCancelSendNetBufferLists (pFilter-> FilterHandle, CancelId);
} }
/************************************************************** / ************************************************* *************
FilterSetModuleOptions函数的功能: Function of functions FilterSetModuleOptions:
必须要在初始化时为驱动注册FilterSetModuleOptions例程,驱动可以在这个例程中初始化 Initialization must-driven routines of registration FilterSetModuleOptions, drive initialization routine
NDIS_FILTER_PARTIAL_CHARACTERISTICS结构来调用NdisSetOptionalHandlers来完成必变。 To call NdisSetOptionalHandlers NDIS_FILTER_PARTIAL_CHARACTERISTICS structure to complete must change.
这个例程如果存在那么在调用Filter Driver的FilterRestart例程之前调用它。 This routine if there is then called before the call Filter Driver FilterRestart routine.
***************************************************************/ ************************************************** ************* /
NDIS_STATUS NDIS_STATUS
FilterSetModuleOptions( FilterSetModuleOptions (
IN NDIS_HANDLE FilterModuleContext IN NDIS_HANDLE FilterModuleContext
) )
{ {
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext; PMS_FILTER pFilter = (PMS_FILTER) FilterModuleContext;
NDIS_FILTER_PARTIAL_CHARACTERISTICS OptionalHandlers; NDIS_FILTER_PARTIAL_CHARACTERISTICS OptionalHandlers;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS; NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
BOOLEAN bFalse = FALSE; BOOLEAN bFalse = FALSE;
if (bFalse) if (bFalse)
{ {
UINT i; UINT i;
pFilter->CallsRestart++; pFilter-> CallsRestart + +;
i = pFilter->CallsRestart % 8; i = pFilter-> CallsRestart% 8;
pFilter->TrackReceives = TRUE; pFilter-> TrackReceives = TRUE;
pFilter->TrackSends = TRUE; pFilter-> TrackSends = TRUE;
NdisMoveMemory(&OptionalHandlers, &DefaultChars, sizeof(OptionalHandlers)); NdisMoveMemory (& OptionalHandlers, & DefaultChars, sizeof (OptionalHandlers));
OptionalHandlers.Header.Type = NDIS_OBJECT_TYPE_FILTER_PARTIAL_CHARACTERISTICS; OptionalHandlers.Header.Type = NDIS_OBJECT_TYPE_FILTER_PARTIAL_CHARACTERISTICS;
OptionalHandlers.Header.Size = sizeof(OptionalHandlers); OptionalHandlers.Header.Size = sizeof (OptionalHandlers);
switch (i) switch (i)
{ {
case 0: case 0:
OptionalHandlers.ReceiveNetBufferListsHandler = NULL; OptionalHandlers.ReceiveNetBufferListsHandler = NULL;
pFilter->TrackReceives = FALSE; pFilter-> TrackReceives = FALSE;
break; break;
case 1: case 1:
OptionalHandlers.ReturnNetBufferListsHandler = NULL; OptionalHandlers.ReturnNetBufferListsHandler = NULL;
pFilter->TrackReceives = FALSE; pFilter-> TrackReceives = FALSE;
break; break;
case 2: case 2:
OptionalHandlers.SendNetBufferListsHandler = NULL; OptionalHandlers.SendNetBufferListsHandler = NULL;
pFilter->TrackSends = FALSE; pFilter-> TrackSends = FALSE;
break; break;
case 3: case 3:
OptionalHandlers.SendNetBufferListsCompleteHandler = NULL; OptionalHandlers.SendNetBufferListsCompleteHandler = NULL;
pFilter->TrackSends = FALSE; pFilter-> TrackSends = FALSE;
break; break;
case 4: case 4:
OptionalHandlers.ReceiveNetBufferListsHandler = NULL; OptionalHandlers.ReceiveNetBufferListsHandler = NULL;
OptionalHandlers.ReturnNetBufferListsHandler = NULL; OptionalHandlers.ReturnNetBufferListsHandler = NULL;
break; break;
case 5: case 5:
OptionalHandlers.SendNetBufferListsHandler = NULL; OptionalHandlers.SendNetBufferListsHandler = NULL;
OptionalHandlers.SendNetBufferListsCompleteHandler = NULL; OptionalHandlers.SendNetBufferListsCompleteHandler = NULL;
break; break;
case 6: case 6:
OptionalHandlers.ReceiveNetBufferListsHandler = NULL; OptionalHandlers.ReceiveNetBufferListsHandler = NULL;
OptionalHandlers.ReturnNetBufferListsHandler = NULL; OptionalHandlers.ReturnNetBufferListsHandler = NULL;
OptionalHandlers.SendNetBufferListsHandler = NULL; OptionalHandlers.SendNetBufferListsHandler = NULL;
OptionalHandlers.SendNetBufferListsCompleteHandler = NULL; OptionalHandlers.SendNetBufferListsCompleteHandler = NULL;
break; break;
case 8: case 8:
break; break;
} }
Status = NdisSetOptionalHandlers(pFilter->FilterHandle, (PNDIS_DRIVER_OPTIONAL_HANDLERS)&OptionalHandlers ); Status = NdisSetOptionalHandlers (pFilter-> FilterHandle, (PNDIS_DRIVER_OPTIONAL_HANDLERS) & OptionalHandlers);
} }
return Status; return Status;
} }
NDIS_STATUS NDIS_STATUS
filterDoInternalRequest( filterDoInternalRequest (
IN PMS_FILTER FilterModuleContext, IN PMS_FILTER FilterModuleContext,
IN NDIS_REQUEST_TYPE RequestType, IN NDIS_REQUEST_TYPE RequestType,
IN NDIS_OID Oid, IN NDIS_OID Oid,
IN PVOID InformationBuffer, IN PVOID InformationBuffer,
IN ULONG InformationBufferLength, IN ULONG InformationBufferLength,
IN ULONG OutputBufferLength, OPTIONAL IN ULONG OutputBufferLength, OPTIONAL
IN ULONG MethodId, OPTIONAL IN ULONG MethodId, OPTIONAL
OUT PULONG pBytesProcessed OUT PULONG pBytesProcessed
) )
{ {
FILTER_REQUEST FilterRequest; FILTER_REQUEST FilterRequest;
PNDIS_OID_REQUEST NdisRequest = &FilterRequest.Request; PNDIS_OID_REQUEST NdisRequest = & FilterRequest.Request;
NDIS_STATUS Status; NDIS_STATUS Status;
BOOLEAN bFalse; BOOLEAN bFalse;
bFalse = FALSE; bFalse = FALSE;
NdisZeroMemory(NdisRequest, sizeof(NDIS_OID_REQUEST)); NdisZeroMemory (NdisRequest, sizeof (NDIS_OID_REQUEST));
NdisInitializeEvent(&FilterRequest.ReqEvent); NdisInitializeEvent (& FilterRequest.ReqEvent);
NdisRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST; NdisRequest-> Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;
NdisRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1; NdisRequest-> Header.Revision = NDIS_OID_REQUEST_REVISION_1;
NdisRequest->Header.Size = sizeof(NDIS_OID_REQUEST); NdisRequest-> Header.Size = sizeof (NDIS_OID_REQUEST);
NdisRequest->RequestType = RequestType; NdisRequest-> RequestType = RequestType;
switch (RequestType) switch (RequestType)
{ {
case NdisRequestQueryInformation: case NdisRequestQueryInformation:
NdisRequest->DATA.QUERY_INFORMATION.Oid = Oid; NdisRequest-> DATA.QUERY_INFORMATION.Oid = Oid;
NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer =InformationBuffer; NdisRequest-> DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;
NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength; NdisRequest-> DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;
break; break;
case NdisRequestSetInformation: case NdisRequestSetInformation:
NdisRequest->DATA.SET_INFORMATION.Oid = Oid; NdisRequest-> DATA.SET_INFORMATION.Oid = Oid;
NdisRequest->DATA.SET_INFORMATION.InformationBuffer =InformationBuffer; NdisRequest-> DATA.SET_INFORMATION.InformationBuffer = InformationBuffer;
NdisRequest->DATA.SET_INFORMATION.InformationBufferLength =InformationBufferLength; NdisRequest-> DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength;
break; break;
case NdisRequestMethod: case NdisRequestMethod:
NdisRequest->DATA.METHOD_INFORMATION.Oid = Oid; NdisRequest-> DATA.METHOD_INFORMATION.Oid = Oid;
NdisRequest->DATA.METHOD_INFORMATION.MethodId = MethodId; NdisRequest-> DATA.METHOD_INFORMATION.MethodId = MethodId;
NdisRequest->DATA.METHOD_INFORMATION.InformationBuffer = InformationBuffer; NdisRequest-> DATA.METHOD_INFORMATION.InformationBuffer = InformationBuffer;
NdisRequest->DATA.METHOD_INFORMATION.InputBufferLength = InformationBufferLength; NdisRequest-> DATA.METHOD_INFORMATION.InputBufferLength = InformationBufferLength;
NdisRequest->DATA.METHOD_INFORMATION.OutputBufferLength = OutputBufferLength; NdisRequest-> DATA.METHOD_INFORMATION.OutputBufferLength = OutputBufferLength;
break; break;
default: default:
FILTER_ASSERT(bFalse); FILTER_ASSERT (bFalse);
break; break;
} }
NdisRequest->RequestId = (PVOID)FILTER_REQUEST_ID; NdisRequest-> RequestId = (PVOID) FILTER_REQUEST_ID;
Status = NdisFOidRequest(FilterModuleContext->FilterHandle,NdisRequest); Status = NdisFOidRequest (FilterModuleContext-> FilterHandle, NdisRequest);
if (Status == NDIS_STATUS_PENDING) if (Status == NDIS_STATUS_PENDING)
{ {
NdisWaitEvent(&FilterRequest.ReqEvent, 0); NdisWaitEvent (& FilterRequest.ReqEvent, 0);
Status = FilterRequest.Status; Status = FilterRequest.Status;
} }
if (Status == NDIS_STATUS_SUCCESS) if (Status == NDIS_STATUS_SUCCESS)
{ {
if (RequestType == NdisRequestSetInformation) if (RequestType == NdisRequestSetInformation)
{ {
*pBytesProcessed = NdisRequest->DATA.SET_INFORMATION.BytesRead; * PBytesProcessed = NdisRequest-> DATA.SET_INFORMATION.BytesRead;
} }
if (RequestType == NdisRequestQueryInformation) if (RequestType == NdisRequestQueryInformation)
{ {
*pBytesProcessed = NdisRequest->DATA.QUERY_INFORMATION.BytesWritten; * PBytesProcessed = NdisRequest-> DATA.QUERY_INFORMATION.BytesWritten;
} }
if (RequestType == NdisRequestMethod) if (RequestType == NdisRequestMethod)
{ {
*pBytesProcessed = NdisRequest->DATA.METHOD_INFORMATION.BytesWritten; * PBytesProcessed = NdisRequest-> DATA.METHOD_INFORMATION.BytesWritten;
} }
if (RequestType == NdisRequestMethod) if (RequestType == NdisRequestMethod)
{ {
if (*pBytesProcessed > OutputBufferLength) if (* pBytesProcessed> OutputBufferLength)
{ {
*pBytesProcessed = OutputBufferLength; * PBytesProcessed = OutputBufferLength;
} }
} }
else else
{ {
if (*pBytesProcessed > InformationBufferLength) if (* pBytesProcessed> InformationBufferLength)
{ {
*pBytesProcessed = InformationBufferLength; * PBytesProcessed = InformationBufferLength;
} }
} }
} }
return (Status); return (Status);
} }
VOID VOID
filterInternalRequestComplete( filterInternalRequestComplete (
IN NDIS_HANDLE FilterModuleContext, IN NDIS_HANDLE FilterModuleContext,
IN PNDIS_OID_REQUEST NdisRequest, IN PNDIS_OID_REQUEST NdisRequest,
IN NDIS_STATUS Status IN NDIS_STATUS Status
) )
{ {
PFILTER_REQUEST FilterRequest; PFILTER_REQUEST FilterRequest;
UNREFERENCED_PARAMETER(FilterModuleContext); UNREFERENCED_PARAMETER (FilterModuleContext);
FilterRequest = CONTAINING_RECORD(NdisRequest, FILTER_REQUEST, Request); FilterRequest = CONTAINING_RECORD (NdisRequest, FILTER_REQUEST, Request);
FilterRequest->Status = Status; FilterRequest-> Status = Status;
NdisSetEvent(&FilterRequest->ReqEvent); NdisSetEvent (& FilterRequest-> ReqEvent);
} }
~~~
- 前言
- Visual Studio 11开发指南(1) Visual Studio 11简介与新特性
- Visual Studio 11开发指南(2) Visual Studio 11放弃宏处理
- Visual Studio 11开发指南(3)Visual Studio 11开发SharePoint 2011程序
- Visual Studio 11开发指南(4)Visual Studio 11编程语言发展
- Visual Studio 11开发指南(5)Visual Studio 11 IDE增强
- Visual Studio 11开发指南(6)Visual Studio 11平台改进
- Visual Studio 11开发指南(7)NET 4.5的改善
- Visual Studio 11开发指南(8)Visual C++ 11新特色
- Visual Studio 11开发指南(9)Visual C++ 新功能体验
- Visual Studio 11开发指南(10)Visual C++11 IDE 新功能体验
- Visual Studio 11开发指南(11)Visual Studio 11调试游戏
- Visual Studio 11开发指南(12)Visual Studio 11可视化多核多线程编程的行为
- Visual Studio 11开发指南(13)C++11语言新特性
- Visual Studio 11开发指南(14)C++11---C++/ CX设计
- Visual Studio 11开发指南(15)C++11单元测试
- Visual Studio 11开发指南(16)C++11更新-多线程和异步操作管理
- Visual Studio 11开发指南(17)C++11更新- Lambda表达式
- Visual Studio 11开发指南(18)C++11更新-自动矢量器使用
- Visual Studio 11开发指南(19)C++11更新-并行模式库和代理库
- 在 C++ 中使用 PPL 进行异步编程
- 基于VisualStudio11开发Windows8的Metro sample讲解(1)MessageBox
- Visual C++ 11 中新的并发功能
- 基于Windows8与Visual Studio2012开发内核隐藏注册表
- 基于VC++2012在Windows8上实现文件隐藏
- 实现诺基亚 lumia Windows phone 的手机通话记录截取
- 最短代码实现windows8下的下载器-下载安装执行一体化
- 用Visual studio2012在Windows8上开发内核驱动监视线程创建
- 用Visual studio2012在Windows8上开发内核驱动监视进程创建
- 基于Windows8与Visual Studio2012实现杀毒通用模块
- 用Visual studio2012在Windows8上开发内核中隐藏进程
- 用Visual studio11在Windows8上开发内核枚举注册表
- 用Visual studio11在Windows8上开发内核驱动隐藏注册表
- 用Visual studio11在Windows8上开发驱动实现注册表监控和过滤
- 用Visual studio11在Windows8上开发驱动实现内存填0杀进程
- 【CSDN2012年度博客之星】喜欢本博客的读者,投票赠送《visual C++2010开发权威指南》电子稿--感谢支持 ~(截至到2012年12月30日)
- 今天在清华图书馆看到我的杰作,感慨万千,而我要归零一切 !
- use Visual studio2012 developing kernel driver monitor thread creation on Windows8
- To kernel driver monitoring process developed in Windows8 create using Visual studio2012
- Under Windows8 kernel mode development NDIS application-NDIS Filter explain
- use Visual studio2012 development kernel to hidden process on Windows8