Hi,
I want to send my own packet in the filter driver. Here are my procedures?
- Allocate NetBufferListPool in FilterAttach function--- NdisAllocateNetBufferListPool
- Create local buffer for my own data packet
- Create an MDL and allocate the NetBuffer and NetBufferList using NdisAllocateNetBufferAndNetBufferList()
- Send this NetBufferList-- NdisFSendNetBufferLists
- Call NdisFreeNetBufferList to free the netbufferlist when NDIS calling the FilterSendNetBufferListsComplete function to complete a send request
- Finally Call NdisFreeNetBufferListPool to free the pool when FilterDetach
However,something goes wrong when calling NdisFreeNetBufferListPool:
** Fatal System Error: 0x000000d1
(0x00000004,0x00000002,0x00000001,0x8F83446F)
BugCheck D1, {4, 2, 1, 8f83446f}
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.
..
CURRENT_IRQL: 2
FAULTING_IP:
ndis!NdisFreeNetBufferPool+52
8f83446f 897104 mov dword ptr [ecx+4],esi
DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT
BUGCHECK_STR: 0xD1
PROCESS_NAME: dllhost.exe
I did free the NBL before freeing the pool. So, are there any details I should pay attention to if I want to send my own packet in the filter driver? Thanks very much.
Leyond
Your numbered procedures seem reasonable. To track down a bug like this:
A. Make sure you are running with driver verifier enabled.
B. Check that the NBL Pool handle is correct (set breakpoints to verify that it is the same value you got back from allocate).
C. Check that you aren't accidentally double-freeing the NBL Pool (set breakpoints to verify you only free once).
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of feixianyexin@163.com
Sent: Thursday, March 04, 2010 10:05 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] To Free NetBufferListPool
Hi,
I want to send my own packet in the filter driver. Here are my procedures?
- Allocate NetBufferListPool in FilterAttach function--- NdisAllocateNetBufferListPool
- Create local buffer for my own data packet
- Create an MDL and allocate the NetBuffer and NetBufferList using NdisAllocateNetBufferAndNetBufferList()
- Send this NetBufferList-- NdisFSendNetBufferLists
- Call NdisFreeNetBufferList to free the netbufferlist when NDIS calling the FilterSendNetBufferListsComplete function to complete a send request
- Finally Call NdisFreeNetBufferListPool to free the pool when FilterDetach
However,something goes wrong when calling NdisFreeNetBufferListPool:
** Fatal System Error: 0x000000d1
(0x00000004,0x00000002,0x00000001,0x8F83446F)
BugCheck D1, {4, 2, 1, 8f83446f}
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.
..
CURRENT_IRQL: 2
FAULTING_IP:
ndis!NdisFreeNetBufferPool+52
8f83446f 897104 mov dword ptr [ecx+4],esi
DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT
BUGCHECK_STR: 0xD1
PROCESS_NAME: dllhost.exe
I did free the NBL before freeing the pool. So, are there any details I should pay attention to if I want to send my own packet in the filter driver? Thanks very much.
Leyond
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
To unsubscribe, visit the List Server section of OSR Online at ListServer/Forum
There are two NICs in my PC, and FilterAttach() will be executed twice, so NetBufferListPool will be also be allocated twice for each filter instance separately. I just use the wireless network interface card for testing, and it gets blue screen when I try to uninstall this filter driver. I am wondering FilterDetach() will be also executed twice to free the resources (including two pools)allocated in FilterAttach(), right?
Filter Attach will be called for each adapter that the filter binds to. Same
for Detach.
In your FilterAttach you create a filter module context of each filter
instance and pass it to NDIS using NdisFSetAttributes. This context is
passed back to you as FilterModuleContext in FilterDetach (and other
callbacks). Use the context to distinguish between filter module instances.
Thomas F. Divine
http://www.pcausa.com
From:
Sent: Friday, March 05, 2010 11:12 PM
To: “Windows System Software Devs Interest List”
Subject: RE:[ntdev] To Free NetBufferListPool
> There are two NICs in my PC, and FilterAttach() will be executed twice,
> so NetBufferListPool will be also be allocated twice for each filter
> instance separately. I just use the wireless network interface card for
> testing, and it gets blue screen when I try to uninstall this filter
> driver. I am wondering FilterDetach() will be also executed twice to free
> the resources (including two pools)allocated in FilterAttach(), right?
>
> —
> 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
1 Like
Hi, Thomas, I don’t understand how to use the context to distinguish between filter module instances. For example, there are two filter module instances in the FilterModuleList:
Link = FilterModuleList.Flink;
while (Link != &FilterModuleList)
{
pFilter = CONTAINING_RECORD(Link, MS_FILTER, FilterModuleLink);
//How can I dstinguish this pFilter instance is bound to the wireless NIC
Link = Link->Flink;
}
Now, I just want to use the wireless NIC for testing, for example: sending my own packet. So, how can i know which filter module instance is bound to the wireless adapter? As you said, If My code is like this in FilterDetach:
if(pFilter->SendNetBufferListPool !=NULL)
{
NdisFreeNetBufferPool(pFilter->SendNetBufferListPool);
pFilter->SendNetBufferListPool = NULL;
}
These two pools will be freed individually. So what do you think make this problem(DRIVER_IRQL_NOT_LESS_OR_EQUAL ) happen when I try to free the Pools.
Thanks
You may want to check if you have memory corruption in your codes. I ran into a similar problem days ago and it turned out I misused NET_BUFFER and its attached MDLs . The data ran out of boundary and corrupted pool information, leading to a BSOD when the pool was freed.
But just as reference. Your cause of the problem may be different from mine.
Yes, I think what you said is reasonable. Could you please help me check my codes. I just want to send a packet with only Ethernet Header and some unuseful data.
- Create an buffer for my data with size of 80
pWriteBuf = (PUCHAR)NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle,BufferSize,FILTER_ALLOC_TAG, LowPoolPriority);
NdisZeroMemory(pWriteBuf,BufferSize);
// Try to fill this buffer with some necessary data like Ethernet Header
pEthHeader = (PTESTPROV_ETH_HEADER)pWriteBuf;
- Fulfill the struct of TESTPROV_ETH_HEADER with Source mac address, etc.
- set the virtual address for MDL
pEthFrameNew = (PUCHAR)pWriteBuf + BufferSize;//Bytes following the pWriteBuf
- Crate an MDL:
pMdl = NdisAllocateMdl(pFilter->FilterHandle,
pEthFrameNew,
BufferSize);
- Copy the data to the MDL
NdisMoveMemory(pEthFrameNew,pEthHeader, BufferSize);
- Allocate and initialize a NBL:
pNetBufferList = NdisAllocateNetBufferAndNetBufferList(
pFilter->SendNetBufferListPool,
sizeof(FILTER_SEND_NETBUFLIST_RSVD), //Request control offset delta
0, // back fill size
pMdl,
0, // Data offset
BufferSize);
I have a test that, pMdl and pNetBuferList is not null. But as you said, maybe because of invalid usage of memory, Pool has been corrupted before it is freed. Could you please help check my codes, thanks.
Be sure to use a debugger.
Be sure to modify your send buffer list complete handler to handle your
injected packet differently from passthrough packets. You must not tell
higher-levels about completion of your injected packets; they did not send
the unexpected packet completion wil probably cause a crash.
Good luck,
Thomas F. Divine
From:
Sent: Sunday, March 07, 2010 7:22 AM
To: “Windows System Software Devs Interest List”
Subject: RE:[ntdev] To Free NetBufferListPool
> Yes, I think what you said is reasonable. Could you please help me check
> my codes. I just want to send a packet with only Ethernet Header and some
> unuseful data.
> 1. Create an buffer for my data with size of 80
> pWriteBuf =
> (PUCHAR)NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle,BufferSize,FILTER_ALLOC_TAG,
> LowPoolPriority);
> NdisZeroMemory(pWriteBuf,BufferSize);
> // Try to fill this buffer with some necessary data like Ethernet Header
> pEthHeader = (PTESTPROV_ETH_HEADER)pWriteBuf;
> 2. Fulfill the struct of TESTPROV_ETH_HEADER with Source mac address, etc.
> 3. set the virtual address for MDL
> pEthFrameNew = (PUCHAR)pWriteBuf + BufferSize;//Bytes following the
> pWriteBuf
> 4. Crate an MDL:
> pMdl = NdisAllocateMdl(pFilter->FilterHandle,
> pEthFrameNew,
> BufferSize);
> 5. Copy the data to the MDL
> NdisMoveMemory(pEthFrameNew,pEthHeader, BufferSize);
> 6. Allocate and initialize a NBL:
> pNetBufferList = NdisAllocateNetBufferAndNetBufferList(
> pFilter->SendNetBufferListPool,
> sizeof(FILTER_SEND_NETBUFLIST_RSVD),
> //Request control offset delta
> 0, // back fill size
> pMdl,
> 0, // Data offset
> BufferSize);
> ----
> I have a test that, pMdl and pNetBuferList is not null. But as you said,
> maybe because of invalid usage of memory, Pool has been corrupted before
> it is freed. Could you please help check my codes, 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
Yes, I use the SourceHandle of NetBufferList to distinguish between the NBLs.
if(NetBufferLists->SourceHandle == pFilter->FilterHandle)
{
FILTER_DEREF_SEND_NBL(NetBufferLists, DispatchLevel);
}else{
NdisFSendNetBufferListsComplete(pFilter->FilterHandle, NetBufferLists, SendCompleteFlags);
}
That is, If the SourceHandle of NBL is pFilterHandle, I just free it; if not, call NdisFSendNetBufferListsComplete to complete the sending request. Is it Ok? Or any suggestions?
I have done a tracking test, and find that the NBL will be freed if this NBL is my injected packets.
You may have several problems. So, lets deal with the obvious ones…
You allocate your packet memory like this:
pWriteBuf = (PUCHAR)NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle,BufferSize,FILTER_ALLOC_TAG, LowPoolPriority);
But then you allocate your MDL like this:
//now allocate MDL and initialize it
pEthFrameNew = (PUCHAR)pWriteBuf + BufferSize;//Bytes following the pWriteBuf
pMdl = NdisAllocateMdl(pFilter->FilterHandle,
pEthFrameNew,
BufferSize);
Think about what you have done! The pointer passed as the second argument to NdisAllocateMdl should point to the bginning of the memory that you have allocated. Instead, it points to the first byte AFTER the memory that you have allocated. Big problem there.
You may have a question about when to free things that you have allocated. The answer is simple: Whne they are no longer being referenced (used). In the case of a send operation the send operation the send is not completed until your FilterSendNetBufferListsComplete handler is called.
You must do some special handling in your FilterSendNetBufferListsComplete handler. For pass-through packet that were sent by a higher-level protocol you call NdisFSendNetBufferListsComplete to return the send NBL to the originator. However, you must not call NdisFSendNetBufferListsComplete for the packets that you send yourself. Instead, you must detect them and instead of calling NdisFSendNetBufferListsComplete you finally free the resources that you originally allocated when you initiated the send.
There may be other problems. Sorry…
Good luck,
Thomas F. Divine
http//www.pcausa.com
1 Like
Dear Thomas,
Thanks very much, I fix the problems with your kind help. 
Leyond