ZwReadFile may cause memory leak on w2k SP4?

I have a problem with ZwReadFile in my virtual disk driver.
To demonstrate this problem I will use ‘filedisk’ driver sources
(http://www.acc.umu.se/~bosse/).

Code of IRP_MJ_READ handler:

case IRP_MJ_READ:
system_buffer = (PUCHAR)
MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
if (system_buffer == NULL)
{
irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
irp->IoStatus.Information = 0;
break;
}
buffer = (PUCHAR) ExAllocatePool(PagedPool,
io_stack->Parameters.Read.Length);
if (buffer == NULL)
{
irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
irp->IoStatus.Information = 0;
break;
}
ZwReadFile(
device_extension->file_handle,
NULL,
NULL,
NULL,
&irp->IoStatus,
buffer,
io_stack->Parameters.Read.Length,
&io_stack->Parameters.Read.ByteOffset,
NULL
);
RtlCopyMemory(system_buffer, buffer,
io_stack->Parameters.Read.Length);
ExFreePool(buffer);
break;
This code works.

But change this code:

case IRP_MJ_READ:
system_buffer = (PUCHAR)
MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
if (system_buffer == NULL)
{
irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
irp->IoStatus.Information = 0;
break;
}

ZwReadFile(
device_extension->file_handle,
NULL,
NULL,
NULL,
&irp->IoStatus,
system_buffer, // <======
io_stack->Parameters.Read.Length,
&io_stack->Parameters.Read.ByteOffset,
NULL
);

break;

This code works on W2k SP0,1,2,3; XP sp0,1, but doesn’t work on
w2k SP4: system is going out of memory, it may hang or become very slow.
!vm command shows:
kd> !vm

*** Virtual Memory Usage ***
Physical Memory: 61114 ( 244456 Kb)
Page File: ??\C:\pagefile.sys
Current: 368640Kb Free Space: 331620Kb
Minimum: 368640Kb Maximum: 490496Kb
Available Pages: 29532 ( 118128 Kb)
ResAvail Pages: 41148 ( 164592 Kb)
Modified Pages: 797 ( 3188 Kb)
********** High Number Of Modified No Write Pages ********
Modified No Write Pages: 6984 ( 27936 Kb) <=====
NonPagedPool Usage: 3129 ( 12516 Kb)
NonPagedPool Max: 24374 ( 97496 Kb)

Thanks.

The second approach doesn’t work properly on any OS. It results in every
page that was read due to page fault immediately becomes dirty.
The reason is using ZwReadFile will result in creating another MDL that
describes the same buffer. While dirty bits from MDL that is used for paging
IO will be discarded, this additional MDL will mark the same physical pages
dirty. This confuses OS enough to create different problems like generating
paging write requests for the memory that was just fetched or create dirty
pages faster then they could be written out.

Alexei.

“Max Woo” wrote in message news:xxxxx@ntdev…
> I have a problem with ZwReadFile in my virtual disk driver.
> To demonstrate this problem I will use ‘filedisk’ driver sources
> (http://www.acc.umu.se/~bosse/).
>
> Code of IRP_MJ_READ handler:
>
> case IRP_MJ_READ:
> system_buffer = (PUCHAR)
> MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
> if (system_buffer == NULL)
> {
> irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
> irp->IoStatus.Information = 0;
> break;
> }
> buffer = (PUCHAR) ExAllocatePool(PagedPool,
> io_stack->Parameters.Read.Length);
> if (buffer == NULL)
> {
> irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
> irp->IoStatus.Information = 0;
> break;
> }
> ZwReadFile(
> device_extension->file_handle,
> NULL,
> NULL,
> NULL,
> &irp->IoStatus,
> buffer,
> io_stack->Parameters.Read.Length,
> &io_stack->Parameters.Read.ByteOffset,
> NULL
> );
> RtlCopyMemory(system_buffer, buffer,
> io_stack->Parameters.Read.Length);
> ExFreePool(buffer);
> break;
> This code works.
>
> But change this code:
>
> case IRP_MJ_READ:
> system_buffer = (PUCHAR)
> MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
> if (system_buffer == NULL)
> {
> irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
> irp->IoStatus.Information = 0;
> break;
> }
>
> ZwReadFile(
> device_extension->file_handle,
> NULL,
> NULL,
> NULL,
> &irp->IoStatus,
> system_buffer, // <======
> io_stack->Parameters.Read.Length,
> &io_stack->Parameters.Read.ByteOffset,
> NULL
> );
>
> break;
>
>
> This code works on W2k SP0,1,2,3; XP sp0,1, but doesn’t work on
> w2k SP4: system is going out of memory, it may hang or become very slow.
> !vm command shows:
> kd> !vm
>
> Virtual Memory Usage
> Physical Memory: 61114 ( 244456 Kb)
> Page File: ??\C:\pagefile.sys
> Current: 368640Kb Free Space: 331620Kb
> Minimum: 368640Kb Maximum: 490496Kb
> Available Pages: 29532 ( 118128 Kb)
> ResAvail Pages: 41148 ( 164592 Kb)
> Modified Pages: 797 ( 3188 Kb)
> **High Number Of Modified No Write Pages
> Modified No Write Pages: 6984 ( 27936 Kb) <=====
> NonPagedPool Usage: 3129 ( 12516 Kb)
> NonPagedPool Max: 24374 ( 97496 Kb)
>
>
> Thanks.
>
>
>
>
>
>
>