FltPerformAsynchronousIo does not use the MDL in the callBackData

I am trying to generate IO in a minifilter using FltPerformAsynchronousIo and provide an MDL in the callBackData. I see that the system ignores the MDL and only uses the buffer within the callBackData. Does anyone knows how can I perform Async IO using an MDL?

Please post your code.

Hi Cristian,
We checked the code and saw that when using FltPerformSynchronousIo, the kernel uses our MDL and not allocate a new one. Only with Asynchronous IO the kernel allocates a new one.
Here are the relevant parts from the code (I removed the error checking here but the original code checks the return codes and it’s ok).

NTSTATUS status;

status = FltAllocateCallbackData(TargetInstance, TargetFileObject, &data );

pVirtualAddr = (uint8_t *) MmAllocateMappingAddress ( totalLen + (PAGE_SIZE), ‘1pam’);

pMdl = IoAllocateMdl ( pVirtualAddr + firstPageOffset, totalLen, FALSE, FALSE, NULL/*, pIrp*/);

pCombinedMdlPfnArray = MmGetMdlPfnArray (pMdl);
for ( i=first ; i <= last ; ++i)
ULONG skipPages = sgl->segments[i].offset / PAGE_SIZE;
pSrcMdl = (PMDL) sgl->segments[i].base;
pSrcMdlPfnArray = MmGetMdlPfnArray ( pSrcMdl) + skipPages;
srcMdlVa = (uint8_t *)oczcache_os_iomem_get_address(pSrcMdl) + sgl->segments[i].offset;

pages = ADDRESS_AND_SIZE_TO_SPAN_PAGES( srcMdlVa, sgl->segments[i].len );
RtlCopyMemory( pCombinedMdlPfnArray, pSrcMdlPfnArray, sizeof(PFN_NUMBER)*pages);
pCombinedMdlPfnArray += pages;

pMdl->MdlFlags |= MDL_PAGES_LOCKED;

mappedAddr = MmMapLockedPagesWithReservedMapping( pVirtualAddr, ‘1pam’, pMdl, MmCached);

pMdl->MappedSystemVa = mappedAddr;

data->Iopb->Parameters.Read.MdlAddress = pMdl; // These parameters are set for both read and write.(union)
data->Iopb->Parameters.Write.WriteBuffer = MmGetMdlVirtualAddress(pMdl);

data->RequestorMode = KernelMode;
data->Iopb->IrpFlags = IRP_NOCACHE;
data->Iopb->MajorFunction = callback_info->majorFunction;
data->Iopb->MinorFunction = IRP_MN_MDL;
data->Iopb->Parameters.Write.ByteOffset.QuadPart = callback_info->lba * callback_info->logical_block_size;
data->Iopb->Parameters.Write.Length = callback_info->vaddrlen;
data->Iopb->IrpFlags |= IRP_WRITE_OPERATION;
data->Iopb->OperationFlags |= SL_WRITE_THROUGH;

status = FltPerformAsynchronousIo (Data, AsyncCompletion, (PVOID)pCallbackInfo);