Completing PAGING_IO read

Hi,

I’m working on a FSFD that modify certain files on read operations. To do
that, I intercept IRP_MJ_READ. I have no problems for non PAGING_IO reads.
But in PAGING_IO reads the computer crashes.

In the IRP_MJ_READ dispatch function for PAGING_IO, I create my own IRP and
get the file data from the lower driver. That works fine. After that, I
complete the original request as in the code below. What am I doing wrong?
Notice that I didn’t modified the original buffer. I’m just trying the
fragment.

// code fragment starts here

IoCallDriver(devExt->AttachedToDeviceObject, MyIrp);

KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);

/*
If I return here, using the INSUFFICIENT_RESOURCES status below,
and send the original IRP to the lower driver after return, everything is
OK.

ExFreePool(MyBuffer);
IoFreeIrp(MyIrp);
status = STATUS_INSUFFICIENT_RESOURCES;
return status;

but if I continue with the lower code, the computer crashes.
*/

Irp->IoStatus.Status = MyIrp->IoStatus.Status;
Irp->IoStatus.Information = NewLength;

NewOffset.QuadPart = OriginalOffset.QuadPart + NewLength;
pIrpStack->FileObject->CurrentByteOffset.QuadPart = NewOffset.QuadPart;

status = MyIrp->IoStatus.Status;

ExFreePool(MyBuffer);

IoFreeIrp(MyIrp);

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return status;

// code fragment ends here

Thanks, very much, in advance.

Daniel

Well, there are multiple bugs present in this code fragment. In
addition, it is quite possible that your problem is related to the code
you did not include in the fragment (you don’t show us how you construct
the MDL chain for your IRP, for example, and the rules for IRP cleanup
are different for paging I/O versus non-paging I/O operations).

(1) you return a truncated read to the memory manager. You’ve already
told it how big the file is (either directory or by answering its
inquiry as to file size) and now you are returning less than the full
amount of data. Hardly surprising, it isn’t happy.

(2) You update the byte offset in the file object for paging I/O. That
should cause application problems, not a memory manager issue, but it is
a bug.

My guess is that your MDL handling is screwed up. Of course, not
knowing what your specific crash is (I mean, is this a verifier crash,
an IRQL related problem, a memory corruption issue, a stack overflow, or
something else?) makes it difficult to suggest what your specific issue
is in this case.

My suggestion would be to look at the output from “!analyze -v” and
debug from there. Everyone I know who has been working with file
systems for very long is extremely gifted in the debugging department -
we have to be, to figure out why things don’t work the way we expected.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

Looking forward to seeing you at the next OSR File Systems class in Los
Angeles, CA October 24-27, 2005.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Daniel Casali
Sent: Wednesday, October 19, 2005 2:12 AM
To: ntfsd redirect
Subject: [ntfsd] Completing PAGING_IO read

Hi,

I’m working on a FSFD that modify certain files on read operations. To
do
that, I intercept IRP_MJ_READ. I have no problems for non PAGING_IO
reads.
But in PAGING_IO reads the computer crashes.

In the IRP_MJ_READ dispatch function for PAGING_IO, I create my own IRP
and
get the file data from the lower driver. That works fine. After that, I
complete the original request as in the code below. What am I doing
wrong?
Notice that I didn’t modified the original buffer. I’m just trying the
fragment.

// code fragment starts here

IoCallDriver(devExt->AttachedToDeviceObject, MyIrp);

KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);

/*
If I return here, using the INSUFFICIENT_RESOURCES status below,
and send the original IRP to the lower driver after return, everything
is
OK.

ExFreePool(MyBuffer);
IoFreeIrp(MyIrp);
status = STATUS_INSUFFICIENT_RESOURCES;
return status;

but if I continue with the lower code, the computer crashes.
*/

Irp->IoStatus.Status = MyIrp->IoStatus.Status;
Irp->IoStatus.Information = NewLength;

NewOffset.QuadPart = OriginalOffset.QuadPart + NewLength;
pIrpStack->FileObject->CurrentByteOffset.QuadPart = NewOffset.QuadPart;

status = MyIrp->IoStatus.Status;

ExFreePool(MyBuffer);

IoFreeIrp(MyIrp);

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return status;

// code fragment ends here

Thanks, very much, in advance.

Daniel


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@osr.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Tony,

Thanks, very much, for your comments. They are very useful.

I’ll test it as you suggested.

You said “and the rules for IRP cleanup are different for paging I/O versus
non-paging I/O operations”. Where can I find additional reading for this
specific issue?

Best regards.

Daniel

“Tony Mason” escribió en el mensaje news:xxxxx@ntfsd…
Well, there are multiple bugs present in this code fragment. In
addition, it is quite possible that your problem is related to the code
you did not include in the fragment (you don’t show us how you construct
the MDL chain for your IRP, for example, and the rules for IRP cleanup
are different for paging I/O versus non-paging I/O operations).

(1) you return a truncated read to the memory manager. You’ve already
told it how big the file is (either directory or by answering its
inquiry as to file size) and now you are returning less than the full
amount of data. Hardly surprising, it isn’t happy.

(2) You update the byte offset in the file object for paging I/O. That
should cause application problems, not a memory manager issue, but it is
a bug.

My guess is that your MDL handling is screwed up. Of course, not
knowing what your specific crash is (I mean, is this a verifier crash,
an IRQL related problem, a memory corruption issue, a stack overflow, or
something else?) makes it difficult to suggest what your specific issue
is in this case.

My suggestion would be to look at the output from “!analyze -v” and
debug from there. Everyone I know who has been working with file
systems for very long is extremely gifted in the debugging department -
we have to be, to figure out why things don’t work the way we expected.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

Looking forward to seeing you at the next OSR File Systems class in Los
Angeles, CA October 24-27, 2005.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Daniel Casali
Sent: Wednesday, October 19, 2005 2:12 AM
To: ntfsd redirect
Subject: [ntfsd] Completing PAGING_IO read

Hi,

I’m working on a FSFD that modify certain files on read operations. To
do
that, I intercept IRP_MJ_READ. I have no problems for non PAGING_IO
reads.
But in PAGING_IO reads the computer crashes.

In the IRP_MJ_READ dispatch function for PAGING_IO, I create my own IRP
and
get the file data from the lower driver. That works fine. After that, I
complete the original request as in the code below. What am I doing
wrong?
Notice that I didn’t modified the original buffer. I’m just trying the
fragment.

// code fragment starts here

IoCallDriver(devExt->AttachedToDeviceObject, MyIrp);

KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);

/
If I return here, using the INSUFFICIENT_RESOURCES status below,
and send the original IRP to the lower driver after return, everything
is
OK.

ExFreePool(MyBuffer);
IoFreeIrp(MyIrp);
status = STATUS_INSUFFICIENT_RESOURCES;
return status;

but if I continue with the lower code, the computer crashes.
/

Irp->IoStatus.Status = MyIrp->IoStatus.Status;
Irp->IoStatus.Information = NewLength;

NewOffset.QuadPart = OriginalOffset.QuadPart + NewLength;
pIrpStack->FileObject->CurrentByteOffset.QuadPart = NewOffset.QuadPart;

status = MyIrp->IoStatus.Status;

ExFreePool(MyBuffer);

IoFreeIrp(MyIrp);

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return status;

// code fragment ends here

Thanks, very much, in advance.

Daniel


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@osr.com
To unsubscribe send a blank email to xxxxx@lists.osr.com