passing outgoing NBL to user

Hi all,
I’m trying to pass outgoing NBL from a NDIS filter driver to a user mode program (via IRP using METHOD_IN_DIRECT ). I realized that I can only pass 1 MDL at once. But an NBL chain(NetBufferLists) consists of 1 or more NBLs, each NBL in the chain consists of 1 or more NBs, and each NB consists of 1 or more MDLs. How can I send them all using 1 IRP. If I need to go through all the MDLs separately, then how can I collect all these MDLs into an NBL chain in the receive path, as it was in the original NBL.
Maybe I need to encapsulate all NetBufferLists in 1MDL. Then how to do it.

How do you think you are going to “pass” an MDL to user mode at all?

You can’t combine MDLs. Each MDL describes a contiguous virtual space.

I have already done this by copying all the contents of the mdl. but it turned out that with small packages my driver is fixed, but not with large ones. I think the Windows developers have thought about this and there is such a feature - NetBufferList encapsulation in one MDL for sending via IRP. Thank you

Mr. Tim_Roberts. You said.
“You can’t combine MDLs. Each MDL describes a contiguous virtual space.”
In this case, I don’t understand the second picture from
https://learn.microsoft.com/en-us/windows-hardware/drivers/network/net-buffer-structure
Can I copy to the temporary buffer the integrated content off all MDLs and create new one MDL :
RtlCopyMemory (myBuffer,
MmGetMdlVrtualAddress(NET_BUFFER_FIRST_MDL(pNB)+NET_BUFFER_DATA_OFFSET(pNB),
NET_BUFFER_DATA_LENGTH(pNB))
then attach it to the already cloned NB (from the same NBL) and to send the new NBL with the one MDL I created

That image does not show combining several MDLs into a single MDL. It shows “chaining” MDLs together.

Certainly you can copy the contents of several MDLs into a single newly allocated MDL. However, you best make sure you fully understand the memory ownership rules in NDIS. I do not know them. Who is going to clean up your memory? Are you allowed/required to clean up the memory of the NBLs you are combining? It’s not trivial.

Thanks for the answer. Mr. Tim_Roberts. I clone all NBLs and complete the originals. I think the owner of the original requests will complete all original NBLs and clear everything.
Before completion, I decrement the ChildRefCount of the original NBLs, assign zero to ParentNetBufferList of cloned NBLs and assign zero to MdlChains of all NBs inside cloned NBLs. So I separate the clone from its parent. And copying all the original MDLs of the original NBLs into a temporary buffer. After that, when I receive an IRP from the user (DeviceIoControl), I create a new MDL, copy that buffer to that MDL, and connect to the previously queued cloned network buffers.
NBLs->NBs->MDL.
The only difference between original NBLs and cloned NBLs is that cloned NBLs only have one combined MDL instead of many original MDLs.
And the second. If you say that the image does not show the merging of several MDLs into one MDL, then what does this mean?
RTLCopyMemory (
my buffer
MmGetMdlVrtualAddress(
NET_BUFFER_FIRST_MDL(pNB)+NET_BUFFER_DATA_OFFSET(pNB),
NET_BUFFER_DATA_LENGTH(pNB))
Is this mistake?

Mr. Tim_Roberts. The second question I already solved. Now I am copying the contents off all MDLs separatory to one big buffer for allocating the new big MDL. Do not look to the second question. But, please, read the first part of my message.