Getting BSOD from NDIS LWF driver

Hi All,
Currently i am facing a BSOD issue in the LAPTOP OS Version: windows 7 .
Windbg analysis:

STACK_COMMAND: .bugcheck ; kb

FOLLOWUP_IP:
NWLWF!FilterSendNetBufferLists+7fe [c:\users\rajendra\desktop\hfn_ibm\engine\cust\netif\nwlwf\filter.c @ 2184]
fffff880`03d6369e 0fb718 movzx ebx,word ptr [rax]

FAULTING_SOURCE_CODE:
2180: pFilter->FilterHandle,
2181: NDF_GET_NBL_QUEUE_HEAD( &PacketSendQueue ),
2182: PortNumber,
2183: SendFlags

2184: );
2185: }
2186:
2187: //
2188: // Complete Blocked Packets
2189: //

SYMBOL_NAME: NWLWF!FilterSendNetBufferLists+7fe

FOLLOWUP_NAME: MachineOwner

IMAGE_NAME: NWLWF.sys

BUCKET_ID: WRONG_SYMBOLS

After windbg analysis I got that below section is giving BSOD issue which is used in FilterSendNetBufferLists()

if( NDF_GET_NBL_QUEUE_HEAD( &PacketSendQueue ) )
{

NdisFSendNetBufferLists(
pFilter->FilterHandle,
NDF_GET_NBL_QUEUE_HEAD( &PacketSendQueue ),
PortNumber,
SendFlags
);
}

Please help me to solve this issue.

Rajendra

xxxxx@gmail.com wrote:

Currently i am facing a BSOD issue in the LAPTOP OS Version: windows 7 .
Windbg analysis:

Why didn’t you show us the registers? When you pick and choose nuggets
from the analysis output, inevitably you will decide to throw out some
piece of information we need. You didn’t even show us what the bugcheck
code was.

The same thing is true of your source code. You’ve deleted anything
that could possibly lead to an answer.

After windbg analysis I got that below section is giving BSOD issue which is used in FilterSendNetBufferLists()

if( NDF_GET_NBL_QUEUE_HEAD( &PacketSendQueue ) )
{

NdisFSendNetBufferLists(
pFilter->FilterHandle,
NDF_GET_NBL_QUEUE_HEAD( &PacketSendQueue ),
PortNumber,
SendFlags
);
}

It’s dereferencing a pointer, and the only pointer dereference I see
here is the pFilter->. However, the instruction is fetching a 16-bit
value, and the FilterHandle should be a 64-bit value. Where is
NDF_GET_NBL_QUEUE_HEAD?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,

I did not delete any code.

I am sending the complete analysis of windbg.

ADDITIONAL_DEBUG_TEXT:
Use ‘!findthebuild’ command to search for the target build information.
If the build information is available, run ‘!findthebuild -s ; .reload’ to set symbol path and load symbols.

MODULE_NAME: NWLWF

FAULTING_MODULE: fffff80003c4d000 nt

DEBUG_FLR_IMAGE_TIMESTAMP: 547726f2

READ_ADDRESS: 0000000000000000

CURRENT_IRQL: 0

FAULTING_IP:
NWLWF!FilterSendNetBufferLists+7fe [c:\users\rajendra\desktop\hfn_ibm\engine\cust\netif\nwlwf\filter.c @ 2184]
fffff880`03d6369e 0fb718 movzx ebx,word ptr [rax]

CUSTOMER_CRASH_COUNT: 2

DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT

BUGCHECK_STR: 0xD1

LAST_CONTROL_TRANSFER: from fffff80003cc2169 to fffff80003cc2bc0

STACK_TEXT:
fffff880073b9ef8 fffff80003cc2169 : 000000000000000a 0000000000000000 0000000000000002 0000000000000000 : nt+0x75bc0
fffff880073b9f00 000000000000000a : 0000000000000000 0000000000000002 0000000000000000 fffff88003d6369e : nt+0x75169
fffff880073b9f08 0000000000000000 : 0000000000000002 0000000000000000 fffff88003d6369e fffffa8004ed8a50 : 0xa

STACK_COMMAND: .bugcheck ; kb

FOLLOWUP_IP:
NWLWF!FilterSendNetBufferLists+7fe [c:\users\rajendra\desktop\hfn_ibm\engine\cust\netif\nwlwf\filter.c @ 2184]
fffff880`03d6369e 0fb718 movzx ebx,word ptr [rax]

FAULTING_SOURCE_CODE:
2180: pFilter->FilterHandle,
2181: NDF_GET_NBL_QUEUE_HEAD( &PacketSendQueue ),
2182: PortNumber,
2183: SendFlags

2184: );
2185: }
2186:
2187: //
2188: // Complete Blocked Packets
2189: //

SYMBOL_NAME: NWLWF!FilterSendNetBufferLists+7fe

FOLLOWUP_NAME: MachineOwner

IMAGE_NAME: NWLWF.sys

BUCKET_ID: WRONG_SYMBOLS

Followup: MachineOwner

Is this enough for you or i will send more information to you.

Regards,
Rajendra

xxxxx@gmail.com wrote:

I did not delete any code.

You sent us almost no code at all. What does your
NDF_GET_NBL_QUEUE_HEAD macro look like? Where did pFilter come from?
Can you send us the whole function, without editing?

I am sending the complete analysis of windbg.

Are you using “!analyze -v”? Because there’s information I expect to
see that isn’t here.

However, in the end you are going to have to use the debugger to find
this. We can’t chase this down over email. You’re dereferencing a bad
pointer, and you need to figure out which pointer. If you disassembled
the assembly code leading up to the failure line, you could figure out
exactly which variable access is causing the crash.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,
I am using “!analyze -v”, as it came once in my customer laptop. So i am giving the minidump analysis.
What other information you need from me, can you please mention.
And I am sharing the code,
As per the code FilterHandle is of type PVOID
VOID
FilterSendNetBufferLists(
IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists,
IN NDIS_PORT_NUMBER PortNumber,
IN ULONG SendFlags
)
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PNET_BUFFER_LIST CurrNbl;
BOOLEAN DispatchLevel;
NDF_NBL_QUEUE_HEADER PacketSendQueue; // Packets to passthrough to lower-level miniport
NDF_NBL_QUEUE_HEADER NblDropQueue; // to return to higher-level protocol by send completion /*added new */
NDF_NBL_QUEUE_HEADER PacketCompleteQueue; // Packets to return to higher-level protocol by send completion
NDF_NBL_QUEUE_HEADER NblDelayQueue; // NBLs to passthrough to lower-level miniport /*added new */
ULONG NumberOfNetBufferLists = 0; // Diagnostic
PCASIM_SEND_FILTER_ACTION SendAction;

Ndf_DbgPrint(DL_TRACE, DBG_SEND, “===>SendNetBufferList: NBL = %p.\n”, NetBufferLists);

do
{
PNET_BUFFER_LIST pCurrentNetBufferList;
PNET_BUFFER_LIST pNextNetBufList;

DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags);

//
// Complete Immediately If In Invalid State
// ----------------------------------------
// Should never be given packets to send if not running…
//

NDF_ACQUIRE_SPIN_LOCK(&pFilter->Lock, DispatchLevel);

//
// If the filter is not in running state, fail the send
//
if (pFilter->State != FilterRunning)
{

NDF_RELEASE_SPIN_LOCK(&pFilter->Lock, DispatchLevel);

if( NetBufferLists != NULL )
{
CurrNbl = NetBufferLists;
while (CurrNbl)
{
NET_BUFFER_LIST_STATUS(CurrNbl) = NDIS_STATUS_PAUSED;
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
}

NdisFSendNetBufferListsComplete(pFilter->FilterHandle,
NetBufferLists,
DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0);
}

return;
}

NDF_RELEASE_SPIN_LOCK(&pFilter->Lock, DispatchLevel);

NDF_INIT_NBL_QUEUE_HEADER( &PacketSendQueue );
NDF_INIT_NBL_QUEUE_HEADER( &PacketCompleteQueue );
NDF_INIT_NBL_QUEUE_HEADER( &NblDropQueue );
NDF_INIT_NBL_QUEUE_HEADER( &NblDelayQueue );

PacketSendQueue.Head = NetBufferLists; // MAGIC!!! Ignore tail at this point

// if( IsListEmpty( &pFilter->W32NOpenList ) )
// {
// // Nothing to Do…
////DbgPrint("nothing to do ");
// goto PassthruThePacket;
// }

//count the number of netbufferlist
pCurrentNetBufferList = NetBufferLists;
while(pCurrentNetBufferList != NULL)
{

++NumberOfNetBufferLists;
pCurrentNetBufferList = NET_BUFFER_LIST_NEXT_NBL(pCurrentNetBufferList);

}

// Walk the List of NetBufferLists
// -------------------------------
// The NET_BUFFER_LIST passed into this routine can be the head
// of a singly-linked list containing multiple NET_BUFFER_LIST
// members.
//
pCurrentNetBufferList = NetBufferLists;

// Reinitialize the Packet Send Queue
NDF_INIT_NBL_QUEUE_HEADER( &PacketSendQueue );

while (pCurrentNetBufferList != NULL)
{
BOOLEAN bAcceptedSend = FALSE;
BOOLEAN Result;
PW32N_OPEN_CONTEXT pW32NOpenContext = NULL;
NDF_PACKET_METADATA MetaData;
ULONG nFilterAction;
PNET_BUFFER pCurrentNetBuffer, pNextNetBuffer; /* added new */
USHORT NumberOfNetBuffers = 0;

nFilterAction = REDIR_PASS_PACKET;
pW32NOpenContext = NULL;

//
// Locate the Next NetBufferList
//
pNextNetBufList = NET_BUFFER_LIST_NEXT_NBL (pCurrentNetBufferList);
NET_BUFFER_LIST_NEXT_NBL (pCurrentNetBufferList) = NULL;

pCurrentNetBuffer = NET_BUFFER_LIST_FIRST_NB( pCurrentNetBufferList );

ASSERT( pCurrentNetBuffer );

if( pCurrentNetBuffer == NULL )
break;

// Count the NetBuffers Chained to This NetBufferList
pNextNetBuffer = pCurrentNetBuffer;

while( pNextNetBuffer != NULL )
{
++NumberOfNetBuffers;
pNextNetBuffer = NET_BUFFER_NEXT_NB( pNextNetBuffer );
}

//
// Operate on the First NetBuffer in the Current NetBufferList
// -----------------------------------------------------------
// Get first MDL and data length from the first NB in the current NBL.
//
// Note that this implementation assumes that all NBs in a NBL are of
// the same protocol type, same network addresses. If the first NB
// matches the MetaData then the rest will as well.
//
Result = Ndf_GetMetaDataFromNetBuffer(
NET_BUFFER_LIST_FIRST_NB( pCurrentNetBufferList ),
FALSE,
FALSE,
pFilter->MediaType,
&MetaData
);

if( !Result)
{
//PAssthrough Send this netbufferList
NDF_INSERT_TAIL_NBL_QUEUE(&PacketSendQueue,pCurrentNetBufferList);

goto NextNBL;
}

if( Result )
{
//
// Determine Filter Action by Examining MetaData and Filter Rules
// --------------------------------------------------------------
// ATTENTION!!! If this function is successful it may return a non-NULL
// pointer in pW32NOpenContext. In this case the call will have added
// a reference to the W32N_OPEN_CONTEXT structure that must eventually
// be dereferenced.
//

nFilterAction = IMFilter_Handler(pFilter, &MetaData, &pW32NOpenContext, TRUE);
//nFilterAction = IMFilter_GetRedirectionAction( pFilter, &MetaData, &pW32NOpenContext, TRUE );

/*We are not using pW32NOpenContext */
/*
if( pW32NOpenContext == NULL )
{
//DbgPrint(" nFilterAction = REDIR_PASS_PACKET;");
nFilterAction = REDIR_PASS_PACKET;
}
*/
}

//
// Handle Based On IP Filter Action
//
if( nFilterAction == REDIR_PASS_PACKET )
{
Ndf_DbgPrint(DL_TRACE, DBG_SEND, “SendNetBufferList: Passing 0x%4.4X Packet\n”, MetaData.Link.Ether.EtherType );

// Passthrough Send This Packet
NDF_INSERT_TAIL_NBL_QUEUE( &PacketSendQueue, pCurrentNetBufferList );

goto NextNBL;
}
if( ( pW32NOpenContext!= NULL ) && ( nFilterAction & REDIR_READ_PACKET ) )
{
PPKT_LOG_RECORD pLogRec = NULL;

ASSERT( pW32NOpenContext ); // A “Must Have”!!!

Ndf_DbgPrint(DL_TRACE, DBG_SEND, “SendNetBufferList: Reading 0x%4.4X Packet Src/Dst: 0x%8.8X/0x%8.8X\n”,
MetaData.Link.Ether.EtherType,
(MetaData.Net.pIPv4Header)->ip_src.s_addr,
(MetaData.Net.pIPv4Header)->ip_dst.s_addr
);

// Make Log Records For The NetBufferList
pLogRec = IMFilter_MakeLogRecordFromSendNetBufferList(
pCurrentNetBufferList,
PortNumber,
nFilterAction,
pW32NOpenContext
);

if( pLogRec )
{
// Add The Log Record To The Log Record List
NDF_ACQUIRE_SPIN_LOCK( &pW32NOpenContext->m_PendingPktLogRecordListLock, FALSE );

InsertTailList(
&pW32NOpenContext->m_PendingPktLogRecordList,
(PLIST_ENTRY )pLogRec
);

NDF_RELEASE_SPIN_LOCK( &pW32NOpenContext->m_PendingPktLogRecordListLock, FALSE );
}
else
{
// Passthrough Send This Packet
NDF_INSERT_TAIL_NBL_QUEUE( &PacketSendQueue, pCurrentNetBufferList );
}
}

if( nFilterAction & REDIR_BLOCK_PACKET )
{
Ndf_DbgPrint(DL_TRACE, DBG_SEND, “SendNetBufferList: Blocking 0x%4.4X Packet Src/Dst: 0x%8.8X/0x%8.8X\n”,
MetaData.Link.Ether.EtherType,
(MetaData.Net.pIPv4Header)->ip_src.s_addr,
(MetaData.Net.pIPv4Header)->ip_dst.s_addr
);

// Complete This Send with Success
NET_BUFFER_LIST_STATUS(pCurrentNetBufferList) = NDIS_STATUS_SUCCESS;
NDF_INSERT_TAIL_NBL_QUEUE( &PacketCompleteQueue, pCurrentNetBufferList );
}
else
{
Ndf_DbgPrint(DL_TRACE, DBG_SEND, “SendNetBufferList: Passing 0x%4.4X Packet\n”, MetaData.Link.Ether.EtherType );

// Passthrough Send This Packet
NDF_INSERT_TAIL_NBL_QUEUE( &PacketSendQueue, pCurrentNetBufferList );
}

NextNBL:
if( pW32NOpenContext )
{
//
// Remove Extra Reference If Necessary
// -----------------------------------
// IMFilter_GetRedirectionAction may return a non-NULL pointer
// in pW32NOpenContext. If so, then it has also incremented the
// reference count. This extra reference must be removed here.
//
W32N_DerefOpenContext( pW32NOpenContext );
}

// Move to the Next NetBufferList
pCurrentNetBufferList = pNextNetBufList;
}

//PassthruThePacket:
//
// Send Passthrough Packets
//
if( NDF_GET_NBL_QUEUE_HEAD( &PacketSendQueue ) )
{

NdisFSendNetBufferLists(
pFilter->FilterHandle,
NDF_GET_NBL_QUEUE_HEAD( &PacketSendQueue ),
PortNumber,
SendFlags
);
}

//
// Complete Blocked Packets
//
if( NDF_GET_NBL_QUEUE_HEAD( &PacketCompleteQueue ) )
{
NdisFSendNetBufferListsComplete(
pFilter->FilterHandle,
NDF_GET_NBL_QUEUE_HEAD( &PacketCompleteQueue ),
DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0
);
}
}
while (FALSE);

// Process Pending Reads If Filter Send/Receive Handlers Installed
if( pFilter->FilterHandlersInstalled )
{
//
// Attempt to Process Any Pending Reads
//
IMFilter_ProcessPendingReadsOnFilter( pFilter );
}

Ndf_DbgPrint(DL_TRACE, DBG_SEND, “<===SendNetBufferList: NBL Count: %d; Status = %8x.\n”,
NumberOfNetBufferLists, Status
);
}

Might make sure that your logic never can put the same packet into multiple
queues.

Thomas

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Monday, March 30, 2015 7:59 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Getting BSOD from NDIS LWF driver

Hi Tim,
I am using “!analyze -v”, as it came once in my customer laptop. So i am
giving the minidump analysis.
What other information you need from me, can you please mention.
And I am sharing the code,
As per the code FilterHandle is of type PVOID VOID FilterSendNetBufferLists(
IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists,
IN NDIS_PORT_NUMBER PortNumber,
IN ULONG SendFlags
)
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PNET_BUFFER_LIST CurrNbl;
BOOLEAN DispatchLevel;
NDF_NBL_QUEUE_HEADER PacketSendQueue; // Packets to passthrough to
lower-level miniport
NDF_NBL_QUEUE_HEADER NblDropQueue; // to return to higher-level
protocol by send completion /*added new */
NDF_NBL_QUEUE_HEADER PacketCompleteQueue; // Packets to return to
higher-level protocol by send completion
NDF_NBL_QUEUE_HEADER NblDelayQueue; // NBLs to passthrough to
lower-level miniport /*added new */
ULONG NumberOfNetBufferLists = 0; // Diagnostic
PCASIM_SEND_FILTER_ACTION SendAction;

Ndf_DbgPrint(DL_TRACE, DBG_SEND, “===>SendNetBufferList: NBL = %p.\n”,
NetBufferLists);

do
{
PNET_BUFFER_LIST pCurrentNetBufferList;
PNET_BUFFER_LIST pNextNetBufList;

DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags);

//
// Complete Immediately If In Invalid State
// ----------------------------------------
// Should never be given packets to send if not running…
//

NDF_ACQUIRE_SPIN_LOCK(&pFilter->Lock, DispatchLevel);

//
// If the filter is not in running state, fail the send
//
if (pFilter->State != FilterRunning)
{

NDF_RELEASE_SPIN_LOCK(&pFilter->Lock, DispatchLevel);

if( NetBufferLists != NULL )
{
CurrNbl = NetBufferLists;
while (CurrNbl)
{
NET_BUFFER_LIST_STATUS(CurrNbl) = NDIS_STATUS_PAUSED;
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
}

NdisFSendNetBufferListsComplete(pFilter->FilterHandle,
NetBufferLists,
DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0);
}

return;
}

NDF_RELEASE_SPIN_LOCK(&pFilter->Lock, DispatchLevel);

NDF_INIT_NBL_QUEUE_HEADER( &PacketSendQueue );
NDF_INIT_NBL_QUEUE_HEADER( &PacketCompleteQueue );
NDF_INIT_NBL_QUEUE_HEADER( &NblDropQueue );
NDF_INIT_NBL_QUEUE_HEADER( &NblDelayQueue );

PacketSendQueue.Head = NetBufferLists; // MAGIC!!! Ignore tail at
this point

// if( IsListEmpty( &pFilter->W32NOpenList ) )
// {
// // Nothing to Do…
////DbgPrint("nothing to do ");
// goto PassthruThePacket;
// }

//count the number of netbufferlist
pCurrentNetBufferList = NetBufferLists;
while(pCurrentNetBufferList != NULL)
{

++NumberOfNetBufferLists;
pCurrentNetBufferList =
NET_BUFFER_LIST_NEXT_NBL(pCurrentNetBufferList);

}

// Walk the List of NetBufferLists
// -------------------------------
// The NET_BUFFER_LIST passed into this routine can be the head
// of a singly-linked list containing multiple NET_BUFFER_LIST
// members.
//
pCurrentNetBufferList = NetBufferLists;

// Reinitialize the Packet Send Queue
NDF_INIT_NBL_QUEUE_HEADER( &PacketSendQueue );

while (pCurrentNetBufferList != NULL)
{
BOOLEAN bAcceptedSend = FALSE;
BOOLEAN Result;
PW32N_OPEN_CONTEXT pW32NOpenContext = NULL;
NDF_PACKET_METADATA MetaData;
ULONG nFilterAction;
PNET_BUFFER pCurrentNetBuffer, pNextNetBuffer; /* added
new */
USHORT NumberOfNetBuffers = 0;

nFilterAction = REDIR_PASS_PACKET;
pW32NOpenContext = NULL;

//
// Locate the Next NetBufferList
//
pNextNetBufList = NET_BUFFER_LIST_NEXT_NBL (pCurrentNetBufferList);
NET_BUFFER_LIST_NEXT_NBL (pCurrentNetBufferList) = NULL;

pCurrentNetBuffer = NET_BUFFER_LIST_FIRST_NB( pCurrentNetBufferList
);

ASSERT( pCurrentNetBuffer );

if( pCurrentNetBuffer == NULL )
break;

// Count the NetBuffers Chained to This NetBufferList
pNextNetBuffer = pCurrentNetBuffer;

while( pNextNetBuffer != NULL )
{
++NumberOfNetBuffers;
pNextNetBuffer = NET_BUFFER_NEXT_NB( pNextNetBuffer );
}

//
// Operate on the First NetBuffer in the Current NetBufferList
// -----------------------------------------------------------
// Get first MDL and data length from the first NB in the current
NBL.
//
// Note that this implementation assumes that all NBs in a NBL are
of
// the same protocol type, same network addresses. If the first NB
// matches the MetaData then the rest will as well.
//
Result = Ndf_GetMetaDataFromNetBuffer(
NET_BUFFER_LIST_FIRST_NB( pCurrentNetBufferList ),
FALSE,
FALSE,
pFilter->MediaType,
&MetaData
);

if( !Result)
{
//PAssthrough Send this netbufferList

NDF_INSERT_TAIL_NBL_QUEUE(&PacketSendQueue,pCurrentNetBufferList);

goto NextNBL;
}

if( Result )
{
//
// Determine Filter Action by Examining MetaData and Filter
Rules
//

// ATTENTION!!! If this function is successful it may return a
non-NULL
// pointer in pW32NOpenContext. In this case the call will have
added
// a reference to the W32N_OPEN_CONTEXT structure that must
eventually
// be dereferenced.
//

nFilterAction = IMFilter_Handler(pFilter, &MetaData,
&pW32NOpenContext, TRUE);
//nFilterAction = IMFilter_GetRedirectionAction(
pFilter, &MetaData, &pW32NOpenContext, TRUE );

/*We are not using pW32NOpenContext */
/*
if( pW32NOpenContext == NULL )
{
//DbgPrint(" nFilterAction =
REDIR_PASS_PACKET;");
nFilterAction = REDIR_PASS_PACKET;
}
*/
}

//
// Handle Based On IP Filter Action
//
if( nFilterAction == REDIR_PASS_PACKET )
{
Ndf_DbgPrint(DL_TRACE, DBG_SEND, “SendNetBufferList: Passing
0x%4.4X Packet\n”, MetaData.Link.Ether.EtherType );

// Passthrough Send This Packet
NDF_INSERT_TAIL_NBL_QUEUE( &PacketSendQueue,
pCurrentNetBufferList );

goto NextNBL;
}
if( ( pW32NOpenContext!= NULL ) && ( nFilterAction &
REDIR_READ_PACKET ) )
{
PPKT_LOG_RECORD pLogRec = NULL;

ASSERT( pW32NOpenContext ); // A “Must Have”!!!

Ndf_DbgPrint(DL_TRACE, DBG_SEND, “SendNetBufferList: Reading
0x%4.4X Packet Src/Dst: 0x%8.8X/0x%8.8X\n”,
MetaData.Link.Ether.EtherType,
(MetaData.Net.pIPv4Header)->ip_src.s_addr,
(MetaData.Net.pIPv4Header)->ip_dst.s_addr
);

// Make Log Records For The NetBufferList
pLogRec = IMFilter_MakeLogRecordFromSendNetBufferList(
pCurrentNetBufferList,
PortNumber,
nFilterAction,
pW32NOpenContext
);

if( pLogRec )
{
// Add The Log Record To The Log Record List
NDF_ACQUIRE_SPIN_LOCK(
&pW32NOpenContext->m_PendingPktLogRecordListLock, FALSE );

InsertTailList(
&pW32NOpenContext->m_PendingPktLogRecordList,
(PLIST_ENTRY )pLogRec
);

NDF_RELEASE_SPIN_LOCK(
&pW32NOpenContext->m_PendingPktLogRecordListLock, FALSE );
}
else
{
// Passthrough Send This Packet
NDF_INSERT_TAIL_NBL_QUEUE( &PacketSendQueue,
pCurrentNetBufferList );
}
}

if( nFilterAction & REDIR_BLOCK_PACKET )
{
Ndf_DbgPrint(DL_TRACE, DBG_SEND, “SendNetBufferList: Blocking
0x%4.4X Packet Src/Dst: 0x%8.8X/0x%8.8X\n”,
MetaData.Link.Ether.EtherType,
(MetaData.Net.pIPv4Header)->ip_src.s_addr,
(MetaData.Net.pIPv4Header)->ip_dst.s_addr
);

// Complete This Send with Success
NET_BUFFER_LIST_STATUS(pCurrentNetBufferList) =
NDIS_STATUS_SUCCESS;
NDF_INSERT_TAIL_NBL_QUEUE( &PacketCompleteQueue,
pCurrentNetBufferList );
}
else
{
Ndf_DbgPrint(DL_TRACE, DBG_SEND, “SendNetBufferList: Passing
0x%4.4X Packet\n”, MetaData.Link.Ether.EtherType );

// Passthrough Send This Packet
NDF_INSERT_TAIL_NBL_QUEUE( &PacketSendQueue,
pCurrentNetBufferList );
}

NextNBL:
if( pW32NOpenContext )
{
//
// Remove Extra Reference If Necessary
// -----------------------------------
// IMFilter_GetRedirectionAction may return a non-NULL pointer
// in pW32NOpenContext. If so, then it has also incremented the
// reference count. This extra reference must be removed here.
//
W32N_DerefOpenContext( pW32NOpenContext );
}

// Move to the Next NetBufferList
pCurrentNetBufferList = pNextNetBufList;
}

//PassthruThePacket:
//
// Send Passthrough Packets
//
if( NDF_GET_NBL_QUEUE_HEAD( &PacketSendQueue ) )
{

NdisFSendNetBufferLists(
pFilter->FilterHandle,
NDF_GET_NBL_QUEUE_HEAD( &PacketSendQueue ),
PortNumber,
SendFlags
);
}

//
// Complete Blocked Packets
//
if( NDF_GET_NBL_QUEUE_HEAD( &PacketCompleteQueue ) )
{
NdisFSendNetBufferListsComplete(
pFilter->FilterHandle,
NDF_GET_NBL_QUEUE_HEAD( &PacketCompleteQueue ),
DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0
);
}
}
while (FALSE);

// Process Pending Reads If Filter Send/Receive Handlers Installed
if( pFilter->FilterHandlersInstalled )
{
//
// Attempt to Process Any Pending Reads
//
IMFilter_ProcessPendingReadsOnFilter( pFilter );
}

Ndf_DbgPrint(DL_TRACE, DBG_SEND, “<===SendNetBufferList: NBL Count: %d;
Status = %8x.\n”,
NumberOfNetBufferLists, Status
);
}


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Hi Thomas,

I was waiting for your reply. Even I sent you the mail regarding the BSOD issue. We purchased the code from you. If it possible can you please look into this issue.

Regards,
Rajendra

Sorry.

It is looks like someone on your end has made further modifications (See
"/*added new */ comment). It’s your code now.

If you were an active PCAUSA customer with a current support agreement or
consulting agreement I would think that you would have contacted me directly
instead of posting this on NTDEV.

Good luck!

Thomas

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Monday, March 30, 2015 9:33 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Getting BSOD from NDIS LWF driver

Hi Thomas,

I was waiting for your reply. Even I sent you the mail regarding the BSOD
issue. We purchased the code from you. If it possible can you please look
into this issue.

Regards,
Rajendra


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

I looked up your records and see that you are from HandsFree Networks. And you were a PCAUSA customer in the past. Sorry for inferring that you weren’t.

Once you modify a PCAUSA sample you are on your own. The baseline sample (probably) works, but once you must debug the modification that you make to the baseline driver.

Good luck in your endeavor!

Thomas

xxxxx@gmail.com wrote:

I am using “!analyze -v”, as it came once in my customer laptop. So i am giving the minidump analysis.
What other information you need from me, can you please mention.
And I am sharing the code,

I think Thomas’ comment gives a clue. One question to answer is whether
nFilterAction is an enumeration or a bitmask. You have
if( nFilterAction == REDIR_PASS_PACKET )
but
if( … (nFilterAction & REDIR_READ_PACKET) )
and
if( nFilterAction & REDIR_BLOCK_PACKET )

However, look at the processing around line 230 or so. If pLogRec is
null, you insert the current list onto PacketSendQueue. In the very
next block, that same list is going to be added to either
PacketCompleteQueue or PacketSendQueue. Thus, it will definitely be on
two lists.

I SUSPECT that you need a “goto NextNBL” after this code:
// Passthrough Send This Packet
NDF_INSERT_TAIL_NBL_QUEUE( &PacketSendQueue,
pCurrentNetBufferList );


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.