Bluescreen when calling NdisFSendNetBufferLists

Hi,
I want to send the packets from an NDIS 6 LWF. Here the packets just include an Ethernet Header and some data. The following is the procedures:

  1. Call NdisAllocateNetBufferListPool to allocate a pool
  2. Data encapsulation- set the attributes of Ethernet Header(src, dst mac address and Ethernet type)
  3. Allocate a MDL
  4. Copy the data to the MDL using NdisMoveMemory()
  5. Allocate Net_buffer_list and netbuffer — NdisAllocateNetBufferAndNetBufferList(…MDL.)
  6. Set the source handle of net_buffer_list, and then call NdisFSendNetBufferLists to send the list.
    I have tested that pool, mdl, and net_buffer_list are not NULL, however, I get blue screen when calling the NdisFSendNetBufferLists.
    I write the codes reference to the NdisProt sample[http://msdn.microsoft.com/en-us/library/dd163321.aspx]. So, I want to know are there some important details to which I should pay attention? I will post my codes if necessary.
    Thanks in advance.

When you “allocated a MDL” what did you provide as the VirtualAddress
parameter? Where did the virtual memory that you are using come from? Is it
page locked?

Are you using a debugger? my guess is that you aren’t since you said that
you got a BSOD. You really need to use WinDbg to be successful at this stage
of development.

Good luck!

Thomas F. Divine
http://www.pcausa.com


From:
Sent: Saturday, January 16, 2010 10:51 PM
To: “Windows System Software Devs Interest List”
Subject: [ntdev] Bluescreen when calling NdisFSendNetBufferLists

> Hi,
> I want to send the packets from an NDIS 6 LWF. Here the packets just
> include an Ethernet Header and some data. The following is the procedures:
> 1. Call NdisAllocateNetBufferListPool to allocate a pool
> 2. Data encapsulation- set the attributes of Ethernet Header(src, dst mac
> address and Ethernet type)
> 3. Allocate a MDL
> 4. Copy the data to the MDL using NdisMoveMemory()
> 5. Allocate Net_buffer_list and netbuffer —
> NdisAllocateNetBufferAndNetBufferList(…MDL.)
> 6. Set the source handle of net_buffer_list, and then call
> NdisFSendNetBufferLists to send the list.
> I have tested that pool, mdl, and net_buffer_list are not NULL, however, I
> get blue screen when calling the NdisFSendNetBufferLists.
> I write the codes reference to the NdisProt
> sample[http://msdn.microsoft.com/en-us/library/dd163321.aspx]. So, I want
> to know are there some important details to which I should pay attention?
> I will post my codes if necessary.
> Thanks in advance.
>
>
>
> —
> NTDEV is sponsored by OSR
>
> 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

My codes:
1.//Allocate buffer for Ethernet Header and some data
pWriteBuf = (PUCHAR)NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle,BufferSize,FILTER_ALLOC_TAG, LowPoolPriority);
NdisZeroMemory(pWriteBuf,BufferSize);
pEthHeader = (PTESTPROV_ETH_HEADER)pWriteBuf;
2.// allocate MDL and initialize it
pEthFrameNew = (PUCHAR)pWriteBuf + BufferSize;//Bytes following the pWriteBuf
pMdl = NdisAllocateMdl(pFilter->FilterHandle,
pEthFrameNew,
BufferSize);
//So the pEthFrameNew is the virtual address of the MDL, is it OK?
3. Yes, I use winDbg, but I am not familiar with that.
4.Thanks

You really should get familiar with WinDbg! If you don’t, then folks on this
list will may ignore you. In fact, messages that start with “I gotta
bluescreen…” hint that the writer is too lazy to develop drivers properly
and is using the list as a substitute for doing their homework.

A common mistake is to ignore the fact that FilterSendNetBufferListsComplete
must be modified to handle the packets that you send differently from
packets that enter the filter at FilterSendNetBufferLists. In
FilterSendNetBufferListsComplete packets that entered the driver at
FilterSendNetBufferLists must be returned to the sender by calling
NdisFSendNetBufferListsComplete. HOWEVER, you must NOT call
NdisFSendNetBufferListsComplete for your own packets; you would be
“returning” a packet that the higher level never actually sent - and this
can cause a crash of course. In NdisFSendNetBufferListsComplete for your own
packets you simply free (or better - recycle) the resources that you
allocated for the send.

Perhaps this is an issue that you have overlooked.

Good luck,

Thomas F. Divine
http://www.pcausa.com


From:
Sent: Saturday, January 16, 2010 11:21 PM
To: “Windows System Software Devs Interest List”
Subject: RE:[ntdev] Bluescreen when calling NdisFSendNetBufferLists

> My codes:
> 1.//Allocate buffer for Ethernet Header and some data
> pWriteBuf =
> (PUCHAR)NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle,BufferSize,FILTER_ALLOC_TAG,
> LowPoolPriority);
> NdisZeroMemory(pWriteBuf,BufferSize);
> pEthHeader = (PTESTPROV_ETH_HEADER)pWriteBuf;
> 2.// allocate MDL and initialize it
> pEthFrameNew = (PUCHAR)pWriteBuf + BufferSize;//Bytes following the
> pWriteBuf
> pMdl = NdisAllocateMdl(pFilter->FilterHandle,
> pEthFrameNew,
> BufferSize);
> //So the pEthFrameNew is the virtual address of the MDL, is it OK?
> 3. Yes, I use winDbg, but I am not familiar with that.
> 4.Thanks
>
> —
> NTDEV is sponsored by OSR
>
> 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

Dear Thomas,
I think you are right. But I am confused with the function FilterSendNetBufferListsComplete(). Usually, this function simply calls NdisFSendNetBufferListsComplete function to return a linked list of NET_BUFFER_LIST structures to an overlying driver. Here are the codes in original LWF sample:
VOID
FilterSendNetBufferListsComplete(…){

NdisFSendNetBufferListsComplete(pFilter->FilterHandle, NetBufferLists, SendCompleteFlags);
}
But now, we should consider the data generated by my own, as you said, it should not call NdisFSendNetBufferListsComplete, because the overlying driver never sent this data. So we just free this buffer list for simple by calling NdisFreeNetBufferList .
The question is, should I distinguish between the data sent from higher level and the data of my own, because My filter should take care of these two situations. Thanks.

Leyond

And how? because I get “Bad pool caller” error message if I simply Free the NetBufferList I Allocated. I find it hard to handle this.

Your asked: “…should I distinguish between the data sent from higher level
and the data of my own, because My filter should take care of these two
situations.”

Answer: You must. I thought I made that clear in my previous reply.

am not sure that calling NdisFreeNetBufferList is sufficient. Basically
you must look at the items you allocated for the send. You must free each of
them when you are dome with them.

Thomas


From:
Sent: Sunday, January 17, 2010 2:25 AM
To: “Windows System Software Devs Interest List”
Subject: RE:[ntdev] Bluescreen when calling NdisFSendNetBufferLists

> Dear Thomas,
> I think you are right. But I am confused with the function
> FilterSendNetBufferListsComplete(). Usually, this function simply calls
> NdisFSendNetBufferListsComplete function to return a linked list of
> NET_BUFFER_LIST structures to an overlying driver. Here are the codes in
> original LWF sample:
> VOID
> FilterSendNetBufferListsComplete(…){
> …
> NdisFSendNetBufferListsComplete(pFilter->FilterHandle, NetBufferLists,
> SendCompleteFlags);
> }
> But now, we should consider the data generated by my own, as you said, it
> should not call NdisFSendNetBufferListsComplete, because the overlying
> driver never sent this data. So we just free this buffer list for simple
> by calling NdisFreeNetBufferList .
> The question is, should I distinguish between the data sent from higher
> level and the data of my own, because My filter should take care of these
> two situations. Thanks.
>
> Leyond
>
> —
> NTDEV is sponsored by OSR
>
> 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 have added a note on NDIS.com to make a suggestion for this. See the topic “Common Error in Sending or Indicating Custom Packets from a NDIS Filter Driver” at:

http://www.ndis.com/ndis-general/default.htm

Good luck,

Thomas F. Divine
http://www.pcausa.com

I have added a note on NDIS.com to make a suggestion for this. See:

http://www.ndis.com/ndis-general/default.htm#CommonSendDesignError

Good luck,

Thomas F. Divine
http://www.pcausa.com


From:
Sent: Sunday, January 17, 2010 2:25 AM
To: “Windows System Software Devs Interest List”
Subject: RE:[ntdev] Bluescreen when calling NdisFSendNetBufferLists

> Dear Thomas,
> I think you are right. But I am confused with the function
> FilterSendNetBufferListsComplete(). Usually, this function simply calls
> NdisFSendNetBufferListsComplete function to return a linked list of
> NET_BUFFER_LIST structures to an overlying driver. Here are the codes in
> original LWF sample:
> VOID
> FilterSendNetBufferListsComplete(…){
> …
> NdisFSendNetBufferListsComplete(pFilter->FilterHandle, NetBufferLists,
> SendCompleteFlags);
> }
> But now, we should consider the data generated by my own, as you said, it
> should not call NdisFSendNetBufferListsComplete, because the overlying
> driver never sent this data. So we just free this buffer list for simple
> by calling NdisFreeNetBufferList .
> The question is, should I distinguish between the data sent from higher
> level and the data of my own, because My filter should take care of these
> two situations. Thanks.
>
> Leyond
>
> —
> NTDEV is sponsored by OSR
>
> 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

Dear Thomas, thanks for your suggestion.
Totally I allocated three kinds of resources: Pool, MDL and BufferList. I used windbg to find that inappropriate resources management causes the blue screen when calling FilterSendNetBufferListsComplete(). I am wondering should I call NdisFreeMDL() to free Mdl before calling NdisFreeNetBufferList()? Here are the codes:

if(pFilter->IsMyPacket == 1){
//get the pool and free it
PoolHandle = NdisGetPoolFromNetBufferList(NetBufferLists);
if(PoolHandle != NULL)
NdisFreeNetBufferPool(PoolHandle);
NdisFreeNetBufferList(NetBufferLists);
pFilter->IsMyPacket = 0;
}else{
NdisFSendNetBufferListsComplete(pFilter->FilterHandle, NetBufferLists, SendCompleteFlags);
}

And the BEBUG message:

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: 00000004, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, value 0 = read operation, 1 = write operation
Arg4: 8dc4e46f, address which referenced memory

FOLLOWUP_IP:
ndislwf!FilterSendNetBufferListsComplete+136 [c:\users\leyond\desktop\filter_sendpacket\src\filter\filter.c @ 1084]
9a9a41e6 8b4d0c mov ecx,dword ptr [ebp+0Ch]

FAULTING_SOURCE_CODE:
1080: //get the pool and free it
1081: PoolHandle = NdisGetPoolFromNetBufferList(NetBufferLists);
1082: if(PoolHandle != NULL)
1083: NdisFreeNetBufferPool(PoolHandle);

1084: NdisFreeNetBufferList(NetBufferLists);
1085: pFilter->IsMyPacket = 0;
1086: }else{
1087: NdisFSendNetBufferListsComplete(pFilter->FilterHandle, NetBufferLists, SendCompleteFlags);
1088: }
1089: FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);

SYMBOL_STACK_INDEX: 5

SYMBOL_NAME: ndislwf!FilterSendNetBufferListsComplete+136

FOLLOWUP_NAME: MachineOwner


Obviously, I didn’t free these resources in an appropriate way. So, could you give more detail suggestions. I really need your help, thanks.

Leyond

I am totally confused by your snippet.

Why this?

NdisFreeNetBufferPool(PoolHandle);

Here you are destroying the pool (or perhaps someone else’s pool).

In filter drivers pools should be allocated exactly once in FilterAttach and
freed once when the pool is no longer needed - sometime after FilterDetach.

How do you determine IsMyPacket in your completion routine? I would have
thought you might use NdisGetPoolFromPacket and then compare it to the pool
handle that you allocated in FilterAttach.

You need to do some careful reading and perhaps look at the filter sample in
the WDK.

Good luck,

Thomas F. Divine


From:
Sent: Monday, January 18, 2010 4:08 AM
To: “Windows System Software Devs Interest List”
Subject: RE:[ntdev] Bluescreen when calling NdisFSendNetBufferLists

> Dear Thomas, thanks for your suggestion.
> Totally I allocated three kinds of resources: Pool, MDL and BufferList. I
> used windbg to find that inappropriate resources management causes the
> blue screen when calling FilterSendNetBufferListsComplete(). I am
> wondering should I call NdisFreeMDL() to free Mdl before calling
> NdisFreeNetBufferList()? Here are the codes:
> ---------------------------------
> if(pFilter->IsMyPacket == 1){
> //get the pool and free it
> PoolHandle = NdisGetPoolFromNetBufferList(NetBufferLists);
> if(PoolHandle != NULL)
> NdisFreeNetBufferPool(PoolHandle);
> NdisFreeNetBufferList(NetBufferLists);
> pFilter->IsMyPacket = 0;
> }else{
> NdisFSendNetBufferListsComplete(pFilter->FilterHandle,
> NetBufferLists, SendCompleteFlags);
> }
> -------------------------
> And the BEBUG message:
> --------------------------
> DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
> An attempt was made to access a pageable (or completely invalid) address
> at an
> interrupt request level (IRQL) that is too high. This is usually
> caused by drivers using improper addresses.
> If kernel debugger is available get stack backtrace.
> Arguments:
> Arg1: 00000004, memory referenced
> Arg2: 00000002, IRQL
> Arg3: 00000001, value 0 = read operation, 1 = write operation
> Arg4: 8dc4e46f, address which referenced memory
> …
> FOLLOWUP_IP:
> ndislwf!FilterSendNetBufferListsComplete+136
> [c:\users\leyond\desktop\filter_sendpacket\src\filter\filter.c @ 1084]
> 9a9a41e6 8b4d0c mov ecx,dword ptr [ebp+0Ch]
>
> FAULTING_SOURCE_CODE:
> 1080: //get the pool and free it
> 1081: PoolHandle = NdisGetPoolFromNetBufferList(NetBufferLists);
> 1082: if(PoolHandle != NULL)
> 1083: NdisFreeNetBufferPool(PoolHandle);
>> 1084: NdisFreeNetBufferList(NetBufferLists);
> 1085: pFilter->IsMyPacket = 0;
> 1086: }else{
> 1087: NdisFSendNetBufferListsComplete(pFilter->FilterHandle,
> NetBufferLists, SendCompleteFlags);
> 1088: }
> 1089: FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
>
>
> SYMBOL_STACK_INDEX: 5
>
> SYMBOL_NAME: ndislwf!FilterSendNetBufferListsComplete+136
>
> FOLLOWUP_NAME: MachineOwner
>
> -----------------------
> Obviously, I didn’t free these resources in an appropriate way. So, could
> you give more detail suggestions. I really need your help, thanks.
>
> Leyond
>
> —
> NTDEV is sponsored by OSR
>
> 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

In your completion routine you must find something to differentiate between
pass-through packets and your own private packets.

To make this determination you need to put something in the NBL Context
member. That something could just be a flag, or it could be a more
sophisticated structure that includes second-level completion function
pointers.

I hope this gives you the clue you need.

Don’t forget to make sure that pools are allocated exactly once in
FilterAttach and freed exactly once sometime after FilterDetach (on the
final dereference to the filter memory…).

Good luck,

Thomas F. Divine
http://www.pcausa.com


From:
Sent: Monday, January 18, 2010 4:08 AM
To: “Windows System Software Devs Interest List”
Subject: RE:[ntdev] Bluescreen when calling NdisFSendNetBufferLists

> Dear Thomas, thanks for your suggestion.
> Totally I allocated three kinds of resources: Pool, MDL and BufferList. I
> used windbg to find that inappropriate resources management causes the
> blue screen when calling FilterSendNetBufferListsComplete(). I am
> wondering should I call NdisFreeMDL() to free Mdl before calling
> NdisFreeNetBufferList()? Here are the codes:
> ---------------------------------
> if(pFilter->IsMyPacket == 1){
> //get the pool and free it
> PoolHandle = NdisGetPoolFromNetBufferList(NetBufferLists);
> if(PoolHandle != NULL)
> NdisFreeNetBufferPool(PoolHandle);
> NdisFreeNetBufferList(NetBufferLists);
> pFilter->IsMyPacket = 0;
> }else{
> NdisFSendNetBufferListsComplete(pFilter->FilterHandle,
> NetBufferLists, SendCompleteFlags);
> }
> -------------------------
> And the BEBUG message:
> --------------------------
> DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
> An attempt was made to access a pageable (or completely invalid) address
> at an
> interrupt request level (IRQL) that is too high. This is usually
> caused by drivers using improper addresses.
> If kernel debugger is available get stack backtrace.
> Arguments:
> Arg1: 00000004, memory referenced
> Arg2: 00000002, IRQL
> Arg3: 00000001, value 0 = read operation, 1 = write operation
> Arg4: 8dc4e46f, address which referenced memory
> …
> FOLLOWUP_IP:
> ndislwf!FilterSendNetBufferListsComplete+136
> [c:\users\leyond\desktop\filter_sendpacket\src\filter\filter.c @ 1084]
> 9a9a41e6 8b4d0c mov ecx,dword ptr [ebp+0Ch]
>
> FAULTING_SOURCE_CODE:
> 1080: //get the pool and free it
> 1081: PoolHandle = NdisGetPoolFromNetBufferList(NetBufferLists);
> 1082: if(PoolHandle != NULL)
> 1083: NdisFreeNetBufferPool(PoolHandle);
>> 1084: NdisFreeNetBufferList(NetBufferLists);
> 1085: pFilter->IsMyPacket = 0;
> 1086: }else{
> 1087: NdisFSendNetBufferListsComplete(pFilter->FilterHandle,
> NetBufferLists, SendCompleteFlags);
> 1088: }
> 1089: FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
>
>
> SYMBOL_STACK_INDEX: 5
>
> SYMBOL_NAME: ndislwf!FilterSendNetBufferListsComplete+136
>
> FOLLOWUP_NAME: MachineOwner
>
> -----------------------
> Obviously, I didn’t free these resources in an appropriate way. So, could
> you give more detail suggestions. I really need your help, thanks.
>
> Leyond
>
> —
> NTDEV is sponsored by OSR
>
> 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

One useful means to differentiate between ‘internally generated’ vs.
external NBLs is to have more than one pool. The allocation pool from which
the NBL came is a public property of the NBL. You can easily compare that
to the pool used to allocate ‘internal’ packets when packets are returned
and thus dispatch to the correct handling.

Of course, Thomas’ suggestion regarding the Context member takes into
account that most solutions need far more information about the internal
operation than just the binary fact that it is internal (or not).

Cheers,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Thomas F. Divine
Sent: Monday, January 18, 2010 10:26 AM
To: Windows System Software Devs Interest List
Subject: Re: RE:[ntdev] Bluescreen when calling NdisFSendNetBufferLists

In your completion routine you must find something to differentiate between
pass-through packets and your own private packets.

To make this determination you need to put something in the NBL Context
member. That something could just be a flag, or it could be a more
sophisticated structure that includes second-level completion function
pointers.

I hope this gives you the clue you need.

Don’t forget to make sure that pools are allocated exactly once in
FilterAttach and freed exactly once sometime after FilterDetach (on the
final dereference to the filter memory…).

Good luck,

Thomas F. Divine
http://www.pcausa.com


From:
Sent: Monday, January 18, 2010 4:08 AM
To: “Windows System Software Devs Interest List”
Subject: RE:[ntdev] Bluescreen when calling NdisFSendNetBufferLists

> Dear Thomas, thanks for your suggestion.
> Totally I allocated three kinds of resources: Pool, MDL and BufferList. I
> used windbg to find that inappropriate resources management causes the
> blue screen when calling FilterSendNetBufferListsComplete(). I am
> wondering should I call NdisFreeMDL() to free Mdl before calling
> NdisFreeNetBufferList()? Here are the codes:
> ---------------------------------
> if(pFilter->IsMyPacket == 1){
> //get the pool and free it
> PoolHandle = NdisGetPoolFromNetBufferList(NetBufferLists);
> if(PoolHandle != NULL)
> NdisFreeNetBufferPool(PoolHandle);
> NdisFreeNetBufferList(NetBufferLists);
> pFilter->IsMyPacket = 0;
> }else{
> NdisFSendNetBufferListsComplete(pFilter->FilterHandle,
> NetBufferLists, SendCompleteFlags);
> }
> -------------------------
> And the BEBUG message:
> --------------------------
> DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
> An attempt was made to access a pageable (or completely invalid) address
> at an
> interrupt request level (IRQL) that is too high. This is usually
> caused by drivers using improper addresses.
> If kernel debugger is available get stack backtrace.
> Arguments:
> Arg1: 00000004, memory referenced
> Arg2: 00000002, IRQL
> Arg3: 00000001, value 0 = read operation, 1 = write operation
> Arg4: 8dc4e46f, address which referenced memory
> …
> FOLLOWUP_IP:
> ndislwf!FilterSendNetBufferListsComplete+136
> [c:\users\leyond\desktop\filter_sendpacket\src\filter\filter.c @ 1084]
> 9a9a41e6 8b4d0c mov ecx,dword ptr [ebp+0Ch]
>
> FAULTING_SOURCE_CODE:
> 1080: //get the pool and free it
> 1081: PoolHandle = NdisGetPoolFromNetBufferList(NetBufferLists);
> 1082: if(PoolHandle != NULL)
> 1083: NdisFreeNetBufferPool(PoolHandle);
>> 1084: NdisFreeNetBufferList(NetBufferLists);
> 1085: pFilter->IsMyPacket = 0;
> 1086: }else{
> 1087: NdisFSendNetBufferListsComplete(pFilter->FilterHandle,
> NetBufferLists, SendCompleteFlags);
> 1088: }
> 1089: FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
>
>
> SYMBOL_STACK_INDEX: 5
>
> SYMBOL_NAME: ndislwf!FilterSendNetBufferListsComplete+136
>
> FOLLOWUP_NAME: MachineOwner
>
> -----------------------
> Obviously, I didn’t free these resources in an appropriate way. So, could
> you give more detail suggestions. I really need your help, thanks.
>
> Leyond
>
> —
> NTDEV is sponsored by OSR
>
> 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


NTDEV is sponsored by OSR

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

Dear Thomas,
I have read the filter sample in the WDK again, and you will find that Filter driver pool isn’t allocated in FilterAttach(). According to your suggestion, I add a variable named SendNetBufferListPool to the struct of MS_FILTER,

//
// Define the filter struct
//
typedef struct _MS_FILTER
{

NDIS_HANDLE SendNetBufferListPool;

}MS_FILTER, * PMS_FILTER;

And I try to initialize this handle in FilterAttach()

NDIS_STATUS
FilterAttach(
IN NDIS_HANDLE NdisFilterHandle,
IN NDIS_HANDLE FilterDriverContext,
IN PNDIS_FILTER_ATTACH_PARAMETERS AttachParameters
){

//Allocate Send NetBufferList Pool
NdisZeroMemory(&PoolParameters, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS));

PoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
PoolParameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
PoolParameters.Header.Size = sizeof(PoolParameters);
PoolParameters.ProtocolId = NDIS_PROTOCOL_ID_IPX ;
PoolParameters.ContextSize = sizeof(NPROT_SEND_NETBUFLIST_RSVD);
PoolParameters.fAllocateNetBuffer = TRUE;
PoolParameters.PoolTag = FILTER_ALLOC_TAG;

pFilter->SendNetBufferListPool = NdisAllocateNetBufferListPool(
NdisFilterHandle,
&PoolParameters);
if (pFilter->SendNetBufferListPool == NULL)
{
DEBUGP(DL_TEST, (“CreateBinding: failed to alloc”
" send net buffer list pool\n"));

Status = NDIS_STATUS_RESOURCES;
break;
}

}

But the debug message shows that “Fail to allocate sent net buffer list pool”. Is there anything I ignore in this part? However, It is successful if I allocate the pool in my own function. Thanks very much.
Leyond

Looks OK to me. Only difference between your initialization and mine is that
I use NDIS_PROTOCOL_ID_DEFAULT

Good luck,

Thomas F. Divine


From:
Sent: Tuesday, January 19, 2010 8:18 AM
To: “Windows System Software Devs Interest List”
Subject: RE:[ntdev] Bluescreen when calling NdisFSendNetBufferLists

> Dear Thomas,
> I have read the filter sample in the WDK again, and you will find that
> Filter driver pool isn’t allocated in FilterAttach(). According to your
> suggestion, I add a variable named SendNetBufferListPool to the struct of
> MS_FILTER,
> ----------------------------------
> //
> // Define the filter struct
> //
> typedef struct _MS_FILTER
> {
> …
> NDIS_HANDLE SendNetBufferListPool;
> …
> }MS_FILTER, * PMS_FILTER;
> ---------------------------------
> And I try to initialize this handle in FilterAttach()
> --------------------------------
> NDIS_STATUS
> FilterAttach(
> IN NDIS_HANDLE NdisFilterHandle,
> IN NDIS_HANDLE FilterDriverContext,
> IN PNDIS_FILTER_ATTACH_PARAMETERS AttachParameters
> ){
> …
> //Allocate Send NetBufferList Pool
> NdisZeroMemory(&PoolParameters,
> sizeof(NET_BUFFER_LIST_POOL_PARAMETERS));
>
> PoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
> PoolParameters.Header.Revision =
> NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
> PoolParameters.Header.Size = sizeof(PoolParameters);
> PoolParameters.ProtocolId = NDIS_PROTOCOL_ID_IPX ;
> PoolParameters.ContextSize = sizeof(NPROT_SEND_NETBUFLIST_RSVD);
> PoolParameters.fAllocateNetBuffer = TRUE;
> PoolParameters.PoolTag = FILTER_ALLOC_TAG;
>
> pFilter->SendNetBufferListPool = NdisAllocateNetBufferListPool(
> NdisFilterHandle,
> &PoolParameters);
> if (pFilter->SendNetBufferListPool == NULL)
> {
> DEBUGP(DL_TEST, (“CreateBinding: failed to alloc”
> " send net buffer list pool\n"));
>
> Status = NDIS_STATUS_RESOURCES;
> break;
> }
> …
> }
> -------------------------------
> But the debug message shows that “Fail to allocate sent net buffer list
> pool”. Is there anything I ignore in this part? However, It is successful
> if I allocate the pool in my own function. Thanks very much.
> Leyond
>
> —
> NTDEV is sponsored by OSR
>
> 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

Dear Thomas,
I change the value of ProtocolId to NDIS_PROTOCOL_ID_DEFAULT, and it doesn’t work either.
I will appreciate if you could send me a copy of LWF sample which you have modified successfully. My Email address: feixianyexin@163.com
Thanks.
Leyond

Sorry, Leynod. I am a dirty-rotten Capitalist. Big parts of a man-year are
in some of the simplest drivers, so I can’t send one to you.

Good luck,

Thomas F. Divine


From:
Sent: Tuesday, January 19, 2010 9:37 PM
To: “Windows System Software Devs Interest List”
Subject: RE:[ntdev] Bluescreen when calling NdisFSendNetBufferLists

> Dear Thomas,
> I change the value of ProtocolId to NDIS_PROTOCOL_ID_DEFAULT, and it
> doesn’t work either.
> I will appreciate if you could send me a copy of LWF sample which you have
> modified successfully. My Email address: feixianyexin@163.com
> Thanks.
> Leyond
>
> —
> NTDEV is sponsored by OSR
>
> 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

Dear Thomas,
It doesn’t matter. Thanks all the same.
Leyond

Leyond,

Below is the initial part of the FilterAttach code from a working NDIS 6 LWF
that injects packets up or down the stack. It is loosely based on the WDK
filter sample.

I hope this helps…

Thomas

NDIS_STATUS
FilterAttach(
IN NDIS_HANDLE NdisFilterHandle,
IN NDIS_HANDLE FilterDriverContext,
IN PNDIS_FILTER_ATTACH_PARAMETERS AttachParameters
)
{
PMS_FILTER pFilter = NULL;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PFL_NDIS_FILTER_LIST FilterHandleEntry;
NDIS_FILTER_ATTRIBUTES FilterAttributes;
ULONG Size;
NET_BUFFER_LIST_POOL_PARAMETERS PoolParameters;

Ndf_DbgPrint(DL_INFO, DBG_BIND, “===>FilterAttach: NdisFilterHandle
%p\n”, NdisFilterHandle);
do
{
if (FilterDriverContext != (NDIS_HANDLE)g_FilterDriverObject)
{
Status = NDIS_STATUS_INVALID_PARAMETER;
break;
}

if ((AttachParameters->MiniportMediaType != NdisMedium802_3)
&& (AttachParameters->MiniportMediaType != NdisMediumWan))
{
Ndf_DbgPrint(DL_ERROR, DBG_BIND, “Doesn’t support media type other
than NdisMedium802_3.\n”);

Status = NDIS_STATUS_INVALID_PARAMETER;
break;
}

Size = sizeof(MS_FILTER) +
AttachParameters->FilterModuleGuidName->Length +
AttachParameters->BaseMiniportInstanceName->Length +
AttachParameters->BaseMiniportName->Length;

pFilter = (PMS_FILTER)NDF_ALLOC_MEM_WITH_TAG(NdisFilterHandle, Size,
FILTER_ALLOC_TAG );
if (pFilter == NULL)
{
Ndf_DbgPrint(DL_WARNING, DBG_BIND, “Failed to allocate context
structure.\n”);
Status = NDIS_STATUS_RESOURCES;
break;
}

NdisZeroMemory(pFilter, sizeof(MS_FILTER));

pFilter->RefCount = 1; // Add Initial Reference
pFilter->FilterHandle = NdisFilterHandle;

//
// Allocate UserSendNetBufferListPool
//
NdisZeroMemory(&PoolParameters,
sizeof(NET_BUFFER_LIST_POOL_PARAMETERS));

PoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
PoolParameters.Header.Revision =
NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
PoolParameters.Header.Size = sizeof(PoolParameters);
PoolParameters.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
PoolParameters.ContextSize = sizeof(SEND_NETBUFLIST_RSVD);
PoolParameters.fAllocateNetBuffer = TRUE;
PoolParameters.PoolTag = FILTER_ALLOC_TAG;

pFilter->UserSendNetBufferListPool = NdisAllocateNetBufferListPool(
pFilter->FilterHandle,
&PoolParameters);

if (pFilter->UserSendNetBufferListPool == NULL)
{
Ndf_DbgPrint(DL_ERROR, DBG_BIND, “Failed to allocate send net
buffer list pool.\n”);

Status = NDIS_STATUS_RESOURCES;
break;
}

Dear Thomas,
It still doesn’t work. I post the codes of FilterAttach(). I think there must be something I ignored. Thanks for your kindly help.

NDIS_STATUS
FilterAttach(
IN NDIS_HANDLE NdisFilterHandle,
IN NDIS_HANDLE FilterDriverContext,
IN PNDIS_FILTER_ATTACH_PARAMETERS AttachParameters
)
{
PMS_FILTER pFilter = NULL;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NDIS_FILTER_ATTRIBUTES FilterAttributes;
ULONG Size;
BOOLEAN bFalse = FALSE;
NET_BUFFER_LIST_POOL_PARAMETERS PoolParameters;
DEBUGP(DL_TRACE, (“===>FilterAttach: NdisFilterHandle %p\n”, NdisFilterHandle));
do
{
ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject);
if (FilterDriverContext != (NDIS_HANDLE)FilterDriverObject)
{
Status = NDIS_STATUS_INVALID_PARAMETER;
break;
}

if ((AttachParameters->MiniportMediaType != NdisMedium802_3)
&& (AttachParameters->MiniportMediaType != NdisMediumWan))
{
DEBUGP(DL_ERROR, (“MSFilter: Doesn’t support media type other than NdisMedium802_3.\n”));

Status = NDIS_STATUS_INVALID_PARAMETER;
break;
}

Size = sizeof(MS_FILTER) +
AttachParameters->FilterModuleGuidName->Length +
AttachParameters->BaseMiniportInstanceName->Length +
AttachParameters->BaseMiniportName->Length;

pFilter = (PMS_FILTER)FILTER_ALLOC_MEM(NdisFilterHandle, Size);
if (pFilter == NULL)
{
DEBUGP(DL_WARN, (“MSFilter: Failed to allocate context structure.\n”));
Status = NDIS_STATUS_RESOURCES;
break;
}

NdisZeroMemory(pFilter, sizeof(MS_FILTER));

//
// Allocate UserSendNetBufferListPool
//
NdisZeroMemory(&PoolParameters, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS));
PoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
PoolParameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
PoolParameters.Header.Size = sizeof(PoolParameters);
PoolParameters.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
PoolParameters.ContextSize = sizeof(SEND_NETBUFLIST_RSVD);
PoolParameters.fAllocateNetBuffer = TRUE;
PoolParameters.PoolTag = FILTER_ALLOC_TAG;
pFilter->UserSendNetBufferListPool = NdisAllocateNetBufferListPool(
pFilter->FilterHandle,
&PoolParameters);
if (pFilter->UserSendNetBufferListPool == NULL)
{
DEBUGP(DL_ERROR, (“Failed to allocate send net buffer list pool.\n”));
Status = NDIS_STATUS_RESOURCES;
break;
}
NdisZeroMemory(&FilterAttributes, sizeof(NDIS_FILTER_ATTRIBUTES));
FilterAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1;
FilterAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES);
FilterAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES;
FilterAttributes.Flags = 0;
Status = NdisFSetAttributes(NdisFilterHandle,
pFilter,
&FilterAttributes);
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGP(DL_WARN, (“MSFilter: Failed to set attributes.\n”));
break;
}

pFilter->State = FilterPaused;
FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);
InsertHeadList(&FilterModuleList, &pFilter->FilterModuleLink);
FILTER_RELEASE_LOCK(&FilterListLock, bFalse);

}
while (bFalse);

if (Status != NDIS_STATUS_SUCCESS)
{
if (pFilter != NULL)
{
FILTER_FREE_MEM(pFilter);
}
}

DEBUGP(DL_TRACE, (“<===FilterAttach: Status %x\n”, Status));
return Status;
}

DEBUG message:
00000014 0.02387063 NDISLWF:
00000015 0.02387622 Failed to allocate send net buffer list pool.
00000016 0.02388181 NDISLWF:
00000017 0.02388795 <===FilterAttach: Status c000009a
00000018 1.55161953 NDISLWF:
00000019 1.55162990 ===>FilterAttach: NdisFilterHandle 8EECF008
00000020 1.55163991 NDISLWF:
00000021 1.55164552 Failed to allocate send net buffer list pool.
00000022 1.55165112 NDISLWF:
00000023 1.55165696 <===FilterAttach: Status c000009a