Note that there are some explanatory texts on larger screens.

plurals
  1. PONDIS filter driver' FilterReceiveNetBufferLists handler isn't called
    primarykey
    data
    text
    <p>I am developing an NDIS filter driver, and I fount its <code>FilterReceiveNetBufferLists</code> is never called (the network is blocked) under certain condition (like open Wireshark or click the "Interface List" button of it). But When I start the capturing, the <code>FilterReceiveNetBufferLists</code> get to be normal (network restored), this is so strange. </p> <p>I found that when I mannually return <code>NDIS_STATUS_FAILURE</code> for the <code>NdisFOidRequest</code> function in an OID originating place of WinPcap driver (BIOCQUERYOID &amp; BIOCSETOID switch branch of NPF_IoControl), then driver won't block the network (Also the winpcap can't work). </p> <p><strong>Is there something wrong with the <code>NdisFOidRequest</code> call?</strong> </p> <p>The DeviceIO routine in Packet.c that originates OID requests:</p> <pre><code>case BIOCQUERYOID: case BIOCSETOID: TRACE_MESSAGE(PACKET_DEBUG_LOUD, "BIOCSETOID - BIOCQUERYOID"); // // gain ownership of the Ndis Handle // if (NPF_StartUsingBinding(Open) == FALSE) { // // MAC unbindind or unbound // SET_FAILURE_INVALID_REQUEST(); break; } // Extract a request from the list of free ones RequestListEntry = ExInterlockedRemoveHeadList(&amp;Open-&gt;RequestList, &amp;Open-&gt;RequestSpinLock); if (RequestListEntry == NULL) { // // Release ownership of the Ndis Handle // NPF_StopUsingBinding(Open); SET_FAILURE_NOMEM(); break; } pRequest = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement); // // See if it is an Ndis request // OidData = Irp-&gt;AssociatedIrp.SystemBuffer; if ((IrpSp-&gt;Parameters.DeviceIoControl.InputBufferLength == IrpSp-&gt;Parameters.DeviceIoControl.OutputBufferLength) &amp;&amp; (IrpSp-&gt;Parameters.DeviceIoControl.InputBufferLength &gt;= sizeof(PACKET_OID_DATA)) &amp;&amp; (IrpSp-&gt;Parameters.DeviceIoControl.InputBufferLength &gt;= sizeof(PACKET_OID_DATA) - 1 + OidData-&gt;Length)) { TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "BIOCSETOID|BIOCQUERYOID Request: Oid=%08lx, Length=%08lx", OidData-&gt;Oid, OidData-&gt;Length); // // The buffer is valid // NdisZeroMemory(&amp;pRequest-&gt;Request, sizeof(NDIS_OID_REQUEST)); pRequest-&gt;Request.Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST; pRequest-&gt;Request.Header.Revision = NDIS_OID_REQUEST_REVISION_1; pRequest-&gt;Request.Header.Size = NDIS_SIZEOF_OID_REQUEST_REVISION_1; if (FunctionCode == BIOCSETOID) { pRequest-&gt;Request.RequestType = NdisRequestSetInformation; pRequest-&gt;Request.DATA.SET_INFORMATION.Oid = OidData-&gt;Oid; pRequest-&gt;Request.DATA.SET_INFORMATION.InformationBuffer = OidData-&gt;Data; pRequest-&gt;Request.DATA.SET_INFORMATION.InformationBufferLength = OidData-&gt;Length; } else { pRequest-&gt;Request.RequestType = NdisRequestQueryInformation; pRequest-&gt;Request.DATA.QUERY_INFORMATION.Oid = OidData-&gt;Oid; pRequest-&gt;Request.DATA.QUERY_INFORMATION.InformationBuffer = OidData-&gt;Data; pRequest-&gt;Request.DATA.QUERY_INFORMATION.InformationBufferLength = OidData-&gt;Length; } NdisResetEvent(&amp;pRequest-&gt;InternalRequestCompletedEvent); if (*((PVOID *) pRequest-&gt;Request.SourceReserved) != NULL) { *((PVOID *) pRequest-&gt;Request.SourceReserved) = NULL; } // // submit the request // pRequest-&gt;Request.RequestId = (PVOID) NPF6X_REQUEST_ID; ASSERT(Open-&gt;AdapterHandle != NULL); Status = NdisFOidRequest(Open-&gt;AdapterHandle, &amp;pRequest-&gt;Request); //Status = NDIS_STATUS_FAILURE; } else { // // Release ownership of the Ndis Handle // NPF_StopUsingBinding(Open); // // buffer too small // SET_FAILURE_BUFFER_SMALL(); break; } if (Status == NDIS_STATUS_PENDING) { NdisWaitEvent(&amp;pRequest-&gt;InternalRequestCompletedEvent, 1000); Status = pRequest-&gt;RequestStatus; } // // Release ownership of the Ndis Handle // NPF_StopUsingBinding(Open); // // Complete the request // if (FunctionCode == BIOCSETOID) { OidData-&gt;Length = pRequest-&gt;Request.DATA.SET_INFORMATION.BytesRead; TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "BIOCSETOID completed, BytesRead = %u", OidData-&gt;Length); } else { if (FunctionCode == BIOCQUERYOID) { OidData-&gt;Length = pRequest-&gt;Request.DATA.QUERY_INFORMATION.BytesWritten; if (Status == NDIS_STATUS_SUCCESS) { // // check for the stupid bug of the Nortel driver ipsecw2k.sys v. 4.10.0.0 that doesn't set the BytesWritten correctly // The driver is the one shipped with Nortel client Contivity VPN Client V04_65.18, and the MD5 for the buggy (unsigned) driver // is 3c2ff8886976214959db7d7ffaefe724 *ipsecw2k.sys (there are multiple copies of this binary with the same exact version info!) // // The (certified) driver shipped with Nortel client Contivity VPN Client V04_65.320 doesn't seem affected by the bug. // if (pRequest-&gt;Request.DATA.QUERY_INFORMATION.BytesWritten &gt; pRequest-&gt;Request.DATA.QUERY_INFORMATION.InformationBufferLength) { TRACE_MESSAGE2(PACKET_DEBUG_LOUD, "Bogus return from NdisRequest (query): Bytes Written (%u) &gt; InfoBufferLength (%u)!!", pRequest-&gt;Request.DATA.QUERY_INFORMATION.BytesWritten, pRequest-&gt;Request.DATA.QUERY_INFORMATION.InformationBufferLength); Status = NDIS_STATUS_INVALID_DATA; } } TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "BIOCQUERYOID completed, BytesWritten = %u", OidData-&gt;Length); } } ExInterlockedInsertTailList(&amp;Open-&gt;RequestList, &amp;pRequest-&gt;ListElement, &amp;Open-&gt;RequestSpinLock); if (Status == NDIS_STATUS_SUCCESS) { SET_RESULT_SUCCESS(sizeof(PACKET_OID_DATA) - 1 + OidData-&gt;Length); } else { SET_FAILURE_INVALID_REQUEST(); } break; </code></pre> <p><strong>Three Filter OID routines:</strong></p> <pre><code>_Use_decl_annotations_ NDIS_STATUS NPF_OidRequest( NDIS_HANDLE FilterModuleContext, PNDIS_OID_REQUEST Request ) { POPEN_INSTANCE Open = (POPEN_INSTANCE) FilterModuleContext; NDIS_STATUS Status; PNDIS_OID_REQUEST ClonedRequest=NULL; BOOLEAN bSubmitted = FALSE; PFILTER_REQUEST_CONTEXT Context; BOOLEAN bFalse = FALSE; TRACE_ENTER(); do { Status = NdisAllocateCloneOidRequest(Open-&gt;AdapterHandle, Request, NPF6X_ALLOC_TAG, &amp;ClonedRequest); if (Status != NDIS_STATUS_SUCCESS) { TRACE_MESSAGE(PACKET_DEBUG_LOUD, "FilerOidRequest: Cannot Clone Request\n"); break; } Context = (PFILTER_REQUEST_CONTEXT)(&amp;ClonedRequest-&gt;SourceReserved[0]); *Context = Request; bSubmitted = TRUE; // // Use same request ID // ClonedRequest-&gt;RequestId = Request-&gt;RequestId; Open-&gt;PendingOidRequest = ClonedRequest; Status = NdisFOidRequest(Open-&gt;AdapterHandle, ClonedRequest); if (Status != NDIS_STATUS_PENDING) { NPF_OidRequestComplete(Open, ClonedRequest, Status); Status = NDIS_STATUS_PENDING; } }while (bFalse); if (bSubmitted == FALSE) { switch(Request-&gt;RequestType) { case NdisRequestMethod: Request-&gt;DATA.METHOD_INFORMATION.BytesRead = 0; Request-&gt;DATA.METHOD_INFORMATION.BytesNeeded = 0; Request-&gt;DATA.METHOD_INFORMATION.BytesWritten = 0; break; case NdisRequestSetInformation: Request-&gt;DATA.SET_INFORMATION.BytesRead = 0; Request-&gt;DATA.SET_INFORMATION.BytesNeeded = 0; break; case NdisRequestQueryInformation: case NdisRequestQueryStatistics: default: Request-&gt;DATA.QUERY_INFORMATION.BytesWritten = 0; Request-&gt;DATA.QUERY_INFORMATION.BytesNeeded = 0; break; } } TRACE_EXIT(); return Status; } //------------------------------------------------------------------- _Use_decl_annotations_ VOID NPF_CancelOidRequest( NDIS_HANDLE FilterModuleContext, PVOID RequestId ) { POPEN_INSTANCE Open = (POPEN_INSTANCE) FilterModuleContext; PNDIS_OID_REQUEST Request = NULL; PFILTER_REQUEST_CONTEXT Context; PNDIS_OID_REQUEST OriginalRequest = NULL; BOOLEAN bFalse = FALSE; FILTER_ACQUIRE_LOCK(&amp;Open-&gt;OIDLock, bFalse); Request = Open-&gt;PendingOidRequest; if (Request != NULL) { Context = (PFILTER_REQUEST_CONTEXT)(&amp;Request-&gt;SourceReserved[0]); OriginalRequest = (*Context); } if ((OriginalRequest != NULL) &amp;&amp; (OriginalRequest-&gt;RequestId == RequestId)) { FILTER_RELEASE_LOCK(&amp;Open-&gt;OIDLock, bFalse); NdisFCancelOidRequest(Open-&gt;AdapterHandle, RequestId); } else { FILTER_RELEASE_LOCK(&amp;Open-&gt;OIDLock, bFalse); } } //------------------------------------------------------------------- _Use_decl_annotations_ VOID NPF_OidRequestComplete( NDIS_HANDLE FilterModuleContext, PNDIS_OID_REQUEST Request, NDIS_STATUS Status ) { POPEN_INSTANCE Open = (POPEN_INSTANCE) FilterModuleContext; PNDIS_OID_REQUEST OriginalRequest; PFILTER_REQUEST_CONTEXT Context; BOOLEAN bFalse = FALSE; TRACE_ENTER(); Context = (PFILTER_REQUEST_CONTEXT)(&amp;Request-&gt;SourceReserved[0]); OriginalRequest = (*Context); // // This is an internal request // if (OriginalRequest == NULL) { TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Status= %p", Status); NPF_InternalRequestComplete(Open, Request, Status); TRACE_EXIT(); return; } FILTER_ACQUIRE_LOCK(&amp;Open-&gt;OIDLock, bFalse); ASSERT(Open-&gt;PendingOidRequest == Request); Open-&gt;PendingOidRequest = NULL; FILTER_RELEASE_LOCK(&amp;Open-&gt;OIDLock, bFalse); // // Copy the information from the returned request to the original request // switch(Request-&gt;RequestType) { case NdisRequestMethod: OriginalRequest-&gt;DATA.METHOD_INFORMATION.OutputBufferLength = Request-&gt;DATA.METHOD_INFORMATION.OutputBufferLength; OriginalRequest-&gt;DATA.METHOD_INFORMATION.BytesRead = Request-&gt;DATA.METHOD_INFORMATION.BytesRead; OriginalRequest-&gt;DATA.METHOD_INFORMATION.BytesNeeded = Request-&gt;DATA.METHOD_INFORMATION.BytesNeeded; OriginalRequest-&gt;DATA.METHOD_INFORMATION.BytesWritten = Request-&gt;DATA.METHOD_INFORMATION.BytesWritten; break; case NdisRequestSetInformation: OriginalRequest-&gt;DATA.SET_INFORMATION.BytesRead = Request-&gt;DATA.SET_INFORMATION.BytesRead; OriginalRequest-&gt;DATA.SET_INFORMATION.BytesNeeded = Request-&gt;DATA.SET_INFORMATION.BytesNeeded; break; case NdisRequestQueryInformation: case NdisRequestQueryStatistics: default: OriginalRequest-&gt;DATA.QUERY_INFORMATION.BytesWritten = Request-&gt;DATA.QUERY_INFORMATION.BytesWritten; OriginalRequest-&gt;DATA.QUERY_INFORMATION.BytesNeeded = Request-&gt;DATA.QUERY_INFORMATION.BytesNeeded; break; } (*Context) = NULL; NdisFreeCloneOidRequest(Open-&gt;AdapterHandle, Request); NdisFOidRequestComplete(Open-&gt;AdapterHandle, OriginalRequest, Status); TRACE_EXIT(); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload