Can I use MmGetMdlPfnArray API to merge data buffer pointed by MDL in the filter driver which sits below Disk Class? Is it ok to use this API to get PFN array and read and modify the contents of it ?
Suppose I need to merge two buffers pointed by irp1->MdlAddr and irp2->MdlAddr. I will be doing the following
- Get PFN array of irp1->MdlAddr and irp2->MdlAddr, read the contents of it
- Allocate a new MDL with size of MDL1+MDL2
- Get the PFN array of newly allocated MDL and copy the contents of PFN array of MDL1 and MDL2 to newly allocated MDL.
Please let me know if MmGetMdlPfnArray can be used to perform the operation mentioned below.
Sample snippet to copy the source mdl “srcmdl” to newly allocated MDL “destmdl” (this is not for merging). This is just to copy the contents of srcmdl pointed by irp to newly allocated mdl.
PMDL srcmdl,destmdl;
PPFN_NUMBER mdlAddrArray, mdlDestAddrArray;
u32 mdlAddrArrayIndex, mdlDestAddrArrayIndex, page_offset, srcbytes ;
u32 noofentries=0;
PVOID srcVirtualAddress = NULL;
PIRP irp = NULL;
irp = WdfRequestWdmGetIrp(Request);
srcmdl = irp->MdlAddress;
/* Get PFN array of src mdl */
mdlAddrArray = MmGetMdlPfnArray(srcmdl);
page_offset = MmGetMdlByteOffset(srcmdl);
mdlAddrArrayIndex = 0;
/* Bytes described by MDL*/
srcbytes = MmGetMdlByteCount(srcmdl);
/* Calculate no of PFN entries */
noofentries = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(srcmdl), MmGetMdlByteCount(srcmdl));
/* Get the base virtual address described by MDL */
srcVirtualAddress = MmGetMdlVirtualAddress(srcmdl);
/* Allocate Target MDL */
destmdl = IoAllocateMdl(srcVirtualAddress, srcbytes, FALSE, FALSE, irp);
/* Get PFN array of dest mdl */
mdlDestAddrArray = MmGetMdlPfnArray(destmdl);
mdlDestAddrArrayIndex = 0;
while(noofentries)
{
mdlDestAddrArray[mdlDestAddrArrayIndex++] = (mdlAddrArray[mdlAddrArrayIndex++]) + page_offset;
page_offset = 0;
noofentries–;
}
DK