<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                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); } } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看