send MDL from network buffer to user via IRP

Hello.
Can I send MDLs from network buffer (FilterSendNetBufferLists procedure from NDIS filter driver) to user using IRP->MdlAddress without copying the entire Mdl.
Uncompleted (pending) Irp IrpFromUser->MdlAddress = pNB->NetBufferHeader.MdlChain;
IoCompleteRequest(IrpFromUser,IO_NO_INCREENT);
Thank you.

Can I send outgoing buffers from the NDIS network driver (from NET_BUFFER.MdlChain) to the user via Irp->MdlAddress. Is that enough, or should I also copy all mdl buffers. Where can I find an example doing something similar.

No. You’re not thinking about what you’re asking. When a request originates from user-mode, the user has specified a virtual address within its process. Assuming it is a direct I/O request, Irp->MdlAddress describes the physical pages of that user buffer. The “virtual address” within the MDL is the virtual address in that process. Those physical addresses are system-wide, but the virtual address is only valid within the originating process.

All the user process knows is the virtual address. If you just plop a new MDL into the IRP, the physical pages in that MDL have nothing to do with the user’s virtual address, and are probably not mapped into the other process at all. When the IRP is completed, the user is going to find that his buffer is unchanged, because those pages were not touched. And when the IRP is cleaned up, things probably explode because the fields are inconsistent.

Short answer, don’t do that. You must copy the bytes into the other process.

Thank You. Now I am trying to understand everything You wrote

Can I copy the contents of the MDL to system space memory and share that memory with the user

Could you please explain in more detail how to copy the bytes to another process. Do you mean the process in user mode, the originator of DeviceIoControl request.

As a driver, you just need to remember that a user-mode address is only valid when that process is the current process. Otherwise, you have the wrong page tables. You have two buffers to worry about: the buffer from your net packets, and the buffer from the monitoring application (which arrived via DeviceIoControl). The buffer from the net packets has probably already been mapped into kernel memory, and if the ioctl is Direct I/O, its buffer has also been mapped into kernel memory. When you have two kernel addresses, you can copy the data, and then complete the ioctl. As an overly general rule, you won’t use the MDL unless you’re doing DMA.

hank you Mr. Tim_Roberts. Until now, I couldn’t figure out why MdlAddress is a member of the Irp structure. Now I know that one of its uses is related to DMA. Now I have one more question. When I make an Irq request from a user program, at that time I don’t know the size of the buffer that the driver will return. I can provide a large field as the second buffer for the DeviceIoControl, but this is not a very good solution. Because of this, it will be better to allocate the buffer from the driver. Thank you

hank you Mr. Tim_Roberts. Until now, I couldn’t figure out why MdlAddress is a member of the Irp structure. Now I know that one of its uses is related to DMA. Now I have one more question. When I make an Irq request from a user program, at that time I don’t know the size of the buffer that the driver will return. I can provide a large field as the second buffer for the DeviceIoControl, but this is not a very good solution. Because of this, it will be better to allocate the buffer from inside the driver. Thank you

it will be better to allocate the buffer from inside the driver.

You might think so, but that’s not how it works. Just allocate a large buffer. I’m not sure why you think it’s “not a very good solution”. There’s no particular penalty, and there’s really no alternative. Remember, YOU have to adapt to the WINDOWS I/O system, not the other way around.

Thank You,mister