How to replace the original MDL passed by lazy writer by a new MDL during a paging IO call

Dear Sirs,

I have run into a problem to replace the MDL passed by the lazy writer
during a call to my file system filter driver. I have follow the exact
recommendation thru some research done by myself but still getting crash on
my target system.

Here is the scenarios:

Target system: XP Pro + SP2
Lazy writer call FS for a paging IO with a MDL set to length = 64K:
Irp write length = 64KB also.

code fragment:

BaseAddress = (ULONG) MmGetMdlVirtualAddress(pSourceMdl);
// BaseAddress = 0
ulByteCount = MmGetMdlByteCount(pSourceMdl);
// ulByteCount = 64KB
pNewBuf = (PCHAR) ExAllocatePool(NonPagedPool, ulByteCount);
// Error checking…

pNewMdl = IoAllocateMdl((PVOID)pNewBuf, ulByteCount, FALSE, FALSE, NULL);
// Error Checking…
//pNewMdl = IoAllocateMdl((PVOID)pNewBuf, ulByteCount, FALSE, FALSE, pIrp);
// Same result as above…

MmBuildMdlForNonPagedPool(pNewMdl);
// do some content change but no change on the size…

IoCopyCurrentIrpStackLocationToNext(pIrp);
KeInitializeEvent(&kWaitEvent, NotificationEvent, FALSE);
IoSetCompletionRoutine(pIrp, WriteCompletionCallBackRoutine, &WriteContext,
TRUE, TRUE, TRUE);
// Call the next driver in the stack
status = IoCallDriver(VolumnDevice, pIrp);

// Crash => kernel Stack shows BugCheck during IoBuildPartialMdl…

***Remarks: In my completion routine I did free the MDL which was create by
me and restore the original MDL pointer back to the Irp … Because I have a
write context struction pointer passed to the completion routine.

My reason for this approach is that I ran into a unknown behavior of the
system when I directly modify the memory by getting the mapped virtual
address using “MmGetSystemAddressForMdlSafe(pSourceMdl, NormalPagePriority)”
after the modification I pass down the request to the lower device from the
device stack and in return from the lower device I restore the content of
the orginal state and call “IoCompleteRequest”. My thought was before I
tell the caller the Irp is done the caller will not access and change the
content of the MDL physical memory content, however, that assumption was
wrong … The caller did change some of the content unexpectly… I don’t
know why please help …

Thanks a lot !

-henry

// Crash => kernel Stack shows BugCheck during IoBuildPartialMdl…

This is a well known problem - just set Irp->UserBuffer to MmGetMdlVirtualAddress( YourMdl );
FSDs use the Irp->UserBuffer value for building partial MDLs, you can easily find this code in FAT’s source code.
The Irp->UserBuffer value is NULL in case of request generated by the system because MDLs used by Modified/Mapped Page Writers are not associated with any virtual range, but your MDL was associated with a valid virtual range.


Slava Imameyev, xxxxx@hotmail.com

“Chun Tai” wrote in message news:xxxxx@ntfsd…
Dear Sirs,

I have run into a problem to replace the MDL passed by the lazy writer during a call to my file system filter driver. I have follow the exact recommendation thru some research done by myself but still getting crash on my target system.

Here is the scenarios:

Target system: XP Pro + SP2
Lazy writer call FS for a paging IO with a MDL set to length = 64K:
Irp write length = 64KB also.

code fragment:

BaseAddress = (ULONG) MmGetMdlVirtualAddress(pSourceMdl);
// BaseAddress = 0
ulByteCount = MmGetMdlByteCount(pSourceMdl);
// ulByteCount = 64KB

pNewBuf = (PCHAR) ExAllocatePool(NonPagedPool, ulByteCount);
// Error checking…

pNewMdl = IoAllocateMdl((PVOID)pNewBuf, ulByteCount, FALSE, FALSE, NULL);
// Error Checking…
//pNewMdl = IoAllocateMdl((PVOID)pNewBuf, ulByteCount, FALSE, FALSE, pIrp);
// Same result as above…

MmBuildMdlForNonPagedPool(pNewMdl);
// do some content change but no change on the size…

IoCopyCurrentIrpStackLocationToNext(pIrp);
KeInitializeEvent(&kWaitEvent, NotificationEvent, FALSE);
IoSetCompletionRoutine(pIrp, WriteCompletionCallBackRoutine, &WriteContext, TRUE, TRUE, TRUE);
// Call the next driver in the stack
status = IoCallDriver(VolumnDevice, pIrp);

// Crash => kernel Stack shows BugCheck during IoBuildPartialMdl…

***Remarks: In my completion routine I did free the MDL which was create by me and restore the original MDL pointer back to the Irp … Because I have a write context struction pointer passed to the completion routine.

My reason for this approach is that I ran into a unknown behavior of the system when I directly modify the memory by getting the mapped virtual address using “MmGetSystemAddressForMdlSafe(pSourceMdl, NormalPagePriority)” after the modification I pass down the request to the lower device from the device stack and in return from the lower device I restore the content of the orginal state and call “IoCompleteRequest”. My thought was before I tell the caller the Irp is done the caller will not access and change the content of the MDL physical memory content, however, that assumption was wrong … The caller did change some of the content unexpectly… I don’t know why please help …

Thanks a lot !

-henry

Slava,

It works now thanks for your help.

-henry

On Wed, Feb 13, 2008 at 8:51 PM, Slava Imameyev
wrote:

> // Crash => kernel Stack shows BugCheck during IoBuildPartialMdl…
>
> This is a well known problem - just set Irp->UserBuffer to MmGetMdlVirtualAddress(
> YourMdl );
> FSDs use the Irp->UserBuffer value for building partial MDLs, you can
> easily find this code in FAT’s source code.
> The Irp->UserBuffer value is NULL in case of request generated by the
> system because MDLs used by Modified/Mapped Page Writers are not
> associated with any virtual range, but your MDL was associated with a valid
> virtual range.
>
> –
> Slava Imameyev, xxxxx@hotmail.com
>
>
>
> “Chun Tai” wrote in message news:xxxxx@ntfsd…
> Dear Sirs,
>
> I have run into a problem to replace the MDL passed by the lazy writer
> during a call to my file system filter driver. I have follow the exact
> recommendation thru some research done by myself but still getting crash on
> my target system.
>
> Here is the scenarios:
>
> Target system: XP Pro + SP2
> Lazy writer call FS for a paging IO with a MDL set to length = 64K:
> Irp write length = 64KB also.
>
> code fragment:
>
> BaseAddress = (ULONG) MmGetMdlVirtualAddress(pSourceMdl);
> // BaseAddress = 0
> ulByteCount = MmGetMdlByteCount(pSourceMdl);
> // ulByteCount = 64KB
> pNewBuf = (PCHAR) ExAllocatePool(NonPagedPool, ulByteCount);
> // Error checking…
>
> pNewMdl = IoAllocateMdl((PVOID)pNewBuf, ulByteCount, FALSE, FALSE, NULL);
> // Error Checking…
> //pNewMdl = IoAllocateMdl((PVOID)pNewBuf, ulByteCount, FALSE, FALSE,
> pIrp);
> // Same result as above…
>
> MmBuildMdlForNonPagedPool(pNewMdl);
> // do some content change but no change on the size…
>
> IoCopyCurrentIrpStackLocationToNext(pIrp);
> KeInitializeEvent(&kWaitEvent, NotificationEvent, FALSE);
> IoSetCompletionRoutine(pIrp, WriteCompletionCallBackRoutine,
> &WriteContext, TRUE, TRUE, TRUE);
> // Call the next driver in the stack
> status = IoCallDriver(VolumnDevice, pIrp);
>
> // Crash => kernel Stack shows BugCheck during IoBuildPartialMdl…
>
> ***Remarks: In my completion routine I did free the MDL which was create
> by me and restore the original MDL pointer back to the Irp … Because I
> have a write context struction pointer passed to the completion routine.
>
>
> My reason for this approach is that I ran into a unknown behavior of the
> system when I directly modify the memory by getting the mapped virtual
> address using “MmGetSystemAddressForMdlSafe(pSourceMdl, NormalPagePriority)”
> after the modification I pass down the request to the lower device from the
> device stack and in return from the lower device I restore the content of
> the orginal state and call “IoCompleteRequest”. My thought was before I
> tell the caller the Irp is done the caller will not access and change the
> content of the MDL physical memory content, however, that assumption was
> wrong … The caller did change some of the content unexpectly… I don’t
> know why please help …
>
> Thanks a lot !
>
> -henry
>
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule debugging and file system seminars
> (including our new fs mini-filter seminar) visit:
> http://www.osr.com/seminars
>
> You are currently subscribed to ntfsd as: unknown lmsubst tag argument: ‘’
>
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>