All,
I am trying to port a Ndis5 Win2K/XP IM driver to run on Vista as a Ndis6 Filter driver. Most of my code in the IM driver will be easily ported once I get a packet list that I can modify so I thought the best place to start was in the packet data path.
Since the WDK documentations says that you can’t modify any of the NET_BUFFER pointers that belong to a NET_BUFFER_LIST that didn’t originate from your driver, my first guess was to use the NdisAllocateCloneNetBufferList so I have a copy to modify before sending the list and buffers on its way to the next driver. While the WDK says that I should use this function, it isn’t used anywhere in the Ndis6 driver examples … nice.
Anyhow, my send and sendcomplete functions are shown below. I have not yet modified the receive path so the problem is definitely here. I don’t get any crashes or resource leak warnings, but the cloned NET_BUFFER_LIST is not well received by the lower portion of the Ndis stack. For example: when I ping a host on my local network, I get “PING: transmit failed, error code 1231.” as output. It sounds to me like the system is unable to get ARP packets out on the wire.
If there is a Ndis Guru out there that can give me some suggestions, I would greatly appreciate it.
//-------------------------------------------------------------------
// Filter the netbuffer send list
//-------------------------------------------------------------------
VOID FilterSendNetBufferLists(
IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists,
IN NDIS_PORT_NUMBER PortNumber,
IN ULONG SendFlags )
{
PFLT_ADAPTER FLTAdapter = ( PFLT_ADAPTER ) FilterModuleContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PNET_BUFFER_LIST CurrNbl = NetBufferLists;
PNET_BUFFER_LIST NextNbl;
PNET_BUFFER_LIST ClonedNbl;
PNET_BUFFER CurrNb;
PFLT_NBL_RSVD NblReserved;
ULONG NumOfNetBufferLists = 0;
ULONG NumOfNetBuffers = 0;
BOOLEAN DispatchLevel;
DEBUGP( DL_TRACE, ( “===>SendNetBufferLists:\n” ) );
while( CurrNbl != NULL )
{
NextNbl = NET_BUFFER_LIST_NEXT_NBL( CurrNbl );
ClonedNbl = NdisAllocateCloneNetBufferList(
CurrNbl,
FLTAdapter->SendNetBufferListPool,
FLTAdapter->SendNetBufferPool,
NDIS_CLONE_FLAGS_USE_ORIGINAL_MDLS );
ClonedNbl->ParentNetBufferList = CurrNbl;
NET_BUFFER_LIST_NEXT_NBL( CurrNbl ) = NULL;
NET_BUFFER_LIST_NEXT_NBL( ClonedNbl ) = NULL;
NumOfNetBuffers = 0;
CurrNb = NET_BUFFER_LIST_FIRST_NB( ClonedNbl );
while( CurrNb != NULL )
{
NumOfNetBuffers++;
CurrNb = NET_BUFFER_NEXT_NB( CurrNb );
}
DEBUGP( DL_TRACE, ( “SendNetBufferLists: processing %i net buffers\n”, NumOfNetBuffers ) );
NdisFSendNetBufferLists(
FLTAdapter->FilterHandle,
ClonedNbl,
PortNumber,
SendFlags );
NumOfNetBufferLists++;
CurrNbl = NextNbl;
}
DEBUGP( DL_TRACE, ( “SendNetBufferLists: NumOfNetBufferLists %i\n”, NumOfNetBufferLists ) );
DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL( SendFlags );
FILTER_ACQUIRE_LOCK( &FLTAdapter->Lock, DispatchLevel );
FLTAdapter->OutstandingSends += NumOfNetBufferLists;
FILTER_RELEASE_LOCK( &FLTAdapter->Lock, DispatchLevel );
DEBUGP( DL_TRACE, ( “<===SendNetBufferLists: Status %8x\n”, Status ) );
}
VOID FilterSendNetBufferListsComplete(
IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists,
IN ULONG SendCompleteFlags )
{
PFLT_ADAPTER FLTAdapter = ( PFLT_ADAPTER ) FilterModuleContext;
PNET_BUFFER_LIST CurrNbl = NetBufferLists;
PNET_BUFFER_LIST NextNbl;
PNET_BUFFER_LIST ParentNetBufferList;
PFLT_NBL_RSVD NblReserved;
ULONG NumOfNetBufferLists = 0;
BOOLEAN DispatchLevel;
DEBUGP( DL_TRACE, ( “===>SendNetBufferListsComplete:\n” ) );
while( CurrNbl != NULL )
{
NextNbl = NET_BUFFER_LIST_NEXT_NBL( CurrNbl );
ParentNetBufferList = CurrNbl->ParentNetBufferList;
CurrNbl->ParentNetBufferList = NULL;
NdisFreeCloneNetBufferList(
CurrNbl,
NDIS_CLONE_FLAGS_USE_ORIGINAL_MDLS );
NdisFSendNetBufferListsComplete(
FLTAdapter->FilterHandle,
ParentNetBufferList,
SendCompleteFlags );
NumOfNetBufferLists++;
CurrNbl = NextNbl;
}
DEBUGP( DL_TRACE, ( “SendNetBufferListsComplete: NumOfNetBufferLists %i\n”, NumOfNetBufferLists ) );
DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL( SendCompleteFlags );
FILTER_ACQUIRE_LOCK( &FLTAdapter->Lock, DispatchLevel );
FLTAdapter->OutstandingSends -= NumOfNetBufferLists;
FILTER_RELEASE_LOCK( &FLTAdapter->Lock, DispatchLevel );
DEBUGP( DL_TRACE, ( “<===SendNetBufferListsComplete:\n” ) );
}
Thanks in advance,
-Matthew