Why my IRP_MJ_READ fails

Hi,

I have a filesystem filter driver in which I build and roll down buffered synchronous IRP_MJ_READ request, it is rolled during dispatch of IRP_MJ_READ request. My IRP_MJ_READ fails if I roll it down from the paging i/o, though it works fine from non paged i/o. What can be the reason?

I have seen several discussions about issues with dealing memory mapped files in this thread but none of them mention issues about reading data from paging i/o.

Thank you,
Roman

Your information is a little lacking in completeness. Are you using a worker thread? Are you capable of handling paging IO at IRQLs higher than PASSIVE_LEVEL? Redirecting paging IO is a complicated and dangerous task at the file system level. It is rather easy in the storage stack except for IRQLs.
“Roman Kudinov” wrote in message news:xxxxx@ntfsd…
Hi,

I have a filesystem filter driver in which I build and roll down buffered synchronous IRP_MJ_READ request, it is rolled during dispatch of IRP_MJ_READ request. My IRP_MJ_READ fails if I roll it down from the paging i/o, though it works fine from non paged i/o. What can be the reason?

I have seen several discussions about issues with dealing memory mapped files in this thread but none of them mention issues about reading data from paging i/o.

Thank you,
Roman

>buffered synchronous IRP_MJ_READ request

Read/Write requests obey the device object flag. Usually MS’s FSD use neither buffered nor direct IO.

What can be the reason?

If you issue a request for a file for which you receive paging IO, then the reason may be that IRP_MJ_CLEANUP has been send for this file, so you receive STATUS_FILE_CLOSED.


Slava Imameyev, xxxxx@hotmail.com

“Roman Kudinov” wrote in message news:xxxxx@ntfsd…
Hi,

I have a filesystem filter driver in which I build and roll down buffered synchronous IRP_MJ_READ request, it is rolled during dispatch of IRP_MJ_READ request. My IRP_MJ_READ fails if I roll it down from the paging i/o, though it works fine from non paged i/o. What can be the reason?

I have seen several discussions about issues with dealing memory mapped files in this thread but none of them mention issues about reading data from paging i/o.

Thank you,
Roman

Hi David,

No, I do not use a worker thread. When I say fails, I mean the underlying driver returns an error, the error code is 0xc000000d, below you can find the code snippets.

I develop decryption/decompression filter driver - it handles read i/o only. It simply filters IRP_MJ_READ, IRP_MJ_DIRECTORY_CONTROL, IRP_MJ_QUERY_INFORMATION (the latter two to modify file size).

During handling of IRP_MJ_READ the filter builds own IRP, rolls it down, decrypts/decompresses the data, fills the output buffer in the original IRP and completes it. Everything works fine if the paged i/o is passed through, but if I process paging i/o the same to non-paging i/o the driver fails.

I searched the archive and have a suspicion that paging i/o should use MDL, is it right?

the dispatch hander of IRP_MJ_READ looks like this:

NTSTATUS
ReadDispatch (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP OriginalIrp
)
{
//
PIO_STACK_LOCATION OriginalIrpSp = NULL;

NTSTATUS status;
ULONG BufferLength;
PVOID Buffer = NULL;
UINT ReturnedLength;

ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));

if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
{
OriginalIrp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
OriginalIrp->IoStatus.Information = 0;

IoCompleteRequest( OriginalIrp, IO_NO_INCREMENT );

return STATUS_INVALID_DEVICE_REQUEST;
}

if( OriginalIrp->Flags & IRP_PAGING_IO)
{
//Skip paging reads
return PassThrough(DeviceObject, OriginalIrp);
}

OriginalIrpSp = IoGetCurrentIrpStackLocation(OriginalIrp);

BufferLength = OriginalIrpSp->Parameters.Read.Length;

Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferLength, 0);
if (!Buffer)
{
return STATUS_INSUFFICIENT_RESOURCES;
}

status = ReadFile(DeviceObject,
OriginalIrpSp->FileObject,
BufferLength,
OriginalIrpSp->Parameters.Read.ByteOffset,
Buffer, &ReturnedLength);

-------------cut-----------
}

NTSTATUS
ReadFile (
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject,
IN ULONG Length,
IN LARGE_INTEGER ByteOffset,
OUT PVOID Buffer,
OUT PULONG ReturnedLength,
IN BOOLEAN Paging)
{
PIRP NewIrp = NULL;
PIO_STACK_LOCATION NewIrpSp = NULL;
IO_STATUS_BLOCK ioStatusBlock;
KEVENT event;
NTSTATUS status;

UNREFERENCED_PARAMETER(Paging);

*ReturnedLength = 0;

///////// Creating our own IRP >>
KeInitializeEvent( &event, SynchronizationEvent, FALSE );
ioStatusBlock.Status = STATUS_SUCCESS;
ioStatusBlock.Information = 0;

NewIrp = IoAllocateIrp( ((PFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject->StackSize, FALSE );
if (NewIrp == NULL)
{
DbgPrint(“ReadFile:ERROR:IRP not created\n”);
return STATUS_INSUFFICIENT_RESOURCES;
}

/* if (TRUE == Paging) {
NewIrp->Flags |= IRP_PAGING_IO;
}*/

NewIrp->Tail.Overlay.Thread = PsGetCurrentThread();
NewIrp->RequestorMode = KernelMode;
NewIrp->UserIosb = &ioStatusBlock;
NewIrp->UserEvent = NULL;
NewIrp->Flags = IRP_SYNCHRONOUS_API;
NewIrpSp = IoGetNextIrpStackLocation( NewIrp );
NewIrpSp->MajorFunction = IRP_MJ_READ;
NewIrpSp->MinorFunction = IRP_MN_NORMAL;
NewIrpSp->FileObject = FileObject;
NewIrp->UserBuffer = Buffer; // This is Buffer of our new IRP

IoSetCompletionRoutine( NewIrp,
ReaderCompletionRoutine,
&event,
TRUE,
TRUE,
TRUE );

NewIrpSp->Parameters.Read.Length = Length;
NewIrpSp->Parameters.Read.ByteOffset = ByteOffset;

status = IoCallDriver( ((PFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, NewIrp );

if (STATUS_PENDING == status)
{
DbgPrint(“ReadFile: pending status\n”);
KeWaitForSingleObject( &event,
Executive,
KernelMode,
FALSE,
NULL );
}

return ioStatusBlock.Status;
}

“David J. Craig” ???/??? ? ??? ???: news:xxxxx@ntfsd…
Your information is a little lacking in completeness. Are you using a worker thread? Are you capable of handling paging IO at IRQLs higher than PASSIVE_LEVEL? Redirecting paging IO is a complicated and dangerous task at the file system level. It is rather easy in the storage stack except for IRQLs.
“Roman Kudinov” wrote in message news:xxxxx@ntfsd…
Hi,

I have a filesystem filter driver in which I build and roll down buffered synchronous IRP_MJ_READ request, it is rolled during dispatch of IRP_MJ_READ request. My IRP_MJ_READ fails if I roll it down from the paging i/o, though it works fine from non paged i/o. What can be the reason?

I have seen several discussions about issues with dealing memory mapped files in this thread but none of them mention issues about reading data from paging i/o.

Thank you,
Roman

>NewIrp->UserBuffer = Buffer; // This is Buffer of our new IRP

This is called neither IO method, not “buffered” as you wrote.

have a suspicion that paging i/o should use MDL, is it right?

Yes.

If you read my previous answer you will give up attempts to issue non paging read request from Paging IO path. Because a FO which backs a data segment may be in a cleanup state, i.e. IRP_MJ_CLEANUP has been received, and FSD will reject all non Paged IO read/write requests for this FO.


Slava Imameyev, xxxxx@hotmail.com

“Roman Kudinov” wrote in message news:xxxxx@ntfsd…
Hi David,

No, I do not use a worker thread. When I say fails, I mean the underlying driver returns an error, the error code is 0xc000000d, below you can find the code snippets.

I develop decryption/decompression filter driver - it handles read i/o only. It simply filters IRP_MJ_READ, IRP_MJ_DIRECTORY_CONTROL, IRP_MJ_QUERY_INFORMATION (the latter two to modify file size).

During handling of IRP_MJ_READ the filter builds own IRP, rolls it down, decrypts/decompresses the data, fills the output buffer in the original IRP and completes it. Everything works fine if the paged i/o is passed through, but if I process paging i/o the same to non-paging i/o the driver fails.

I searched the archive and have a suspicion that paging i/o should use MDL, is it right?

the dispatch hander of IRP_MJ_READ looks like this:

NTSTATUS
ReadDispatch (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP OriginalIrp
)
{
//
PIO_STACK_LOCATION OriginalIrpSp = NULL;

NTSTATUS status;
ULONG BufferLength;
PVOID Buffer = NULL;
UINT ReturnedLength;

ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));

if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
{
OriginalIrp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
OriginalIrp->IoStatus.Information = 0;

IoCompleteRequest( OriginalIrp, IO_NO_INCREMENT );

return STATUS_INVALID_DEVICE_REQUEST;
}

if( OriginalIrp->Flags & IRP_PAGING_IO)
{
//Skip paging reads
return PassThrough(DeviceObject, OriginalIrp);
}

OriginalIrpSp = IoGetCurrentIrpStackLocation(OriginalIrp);

BufferLength = OriginalIrpSp->Parameters.Read.Length;

Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferLength, 0);
if (!Buffer)
{
return STATUS_INSUFFICIENT_RESOURCES;
}

status = ReadFile(DeviceObject,
OriginalIrpSp->FileObject,
BufferLength,
OriginalIrpSp->Parameters.Read.ByteOffset,
Buffer, &ReturnedLength);

-------------cut-----------
}

NTSTATUS
ReadFile (
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject,
IN ULONG Length,
IN LARGE_INTEGER ByteOffset,
OUT PVOID Buffer,
OUT PULONG ReturnedLength,
IN BOOLEAN Paging)
{
PIRP NewIrp = NULL;
PIO_STACK_LOCATION NewIrpSp = NULL;
IO_STATUS_BLOCK ioStatusBlock;
KEVENT event;
NTSTATUS status;

UNREFERENCED_PARAMETER(Paging);

ReturnedLength = 0;

///////// Creating our own IRP >>
KeInitializeEvent( &event, SynchronizationEvent, FALSE );
ioStatusBlock.Status = STATUS_SUCCESS;
ioStatusBlock.Information = 0;

NewIrp = IoAllocateIrp( ((PFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject->StackSize, FALSE );
if (NewIrp == NULL)
{
DbgPrint(“ReadFile:ERROR:IRP not created\n”);
return STATUS_INSUFFICIENT_RESOURCES;
}

/
if (TRUE == Paging) {
NewIrp->Flags |= IRP_PAGING_IO;
}*/

NewIrp->Tail.Overlay.Thread = PsGetCurrentThread();
NewIrp->RequestorMode = KernelMode;
NewIrp->UserIosb = &ioStatusBlock;
NewIrp->UserEvent = NULL;
NewIrp->Flags = IRP_SYNCHRONOUS_API;
NewIrpSp = IoGetNextIrpStackLocation( NewIrp );
NewIrpSp->MajorFunction = IRP_MJ_READ;
NewIrpSp->MinorFunction = IRP_MN_NORMAL;
NewIrpSp->FileObject = FileObject;
NewIrp->UserBuffer = Buffer; // This is Buffer of our new IRP

IoSetCompletionRoutine( NewIrp,
ReaderCompletionRoutine,
&event,
TRUE,
TRUE,
TRUE );

NewIrpSp->Parameters.Read.Length = Length;
NewIrpSp->Parameters.Read.ByteOffset = ByteOffset;

status = IoCallDriver( ((PFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, NewIrp );

if (STATUS_PENDING == status)
{
DbgPrint(“ReadFile: pending status\n”);
KeWaitForSingleObject( &event,
Executive,
KernelMode,
FALSE,
NULL );
}

return ioStatusBlock.Status;
}

“David J. Craig” ???/??? ? ??? ???: news:xxxxx@ntfsd…
Your information is a little lacking in completeness. Are you using a worker thread? Are you capable of handling paging IO at IRQLs higher than PASSIVE_LEVEL? Redirecting paging IO is a complicated and dangerous task at the file system level. It is rather easy in the storage stack except for IRQLs.
“Roman Kudinov” wrote in message news:xxxxx@ntfsd…
Hi,

I have a filesystem filter driver in which I build and roll down buffered synchronous IRP_MJ_READ request, it is rolled during dispatch of IRP_MJ_READ request. My IRP_MJ_READ fails if I roll it down from the paging i/o, though it works fine from non paged i/o. What can be the reason?

I have seen several discussions about issues with dealing memory mapped files in this thread but none of them mention issues about reading data from paging i/o.

Thank you,
Roman

>My IRP_MJ_READ fails if I roll it down from the paging i/o, though it works
fine

from non paged i/o. What can be the reason?

Paging IO paths are executing on APC_LEVEL, where you cannot use ZwXxxFile and
IoBuildSynchronousFsdRequest or IoBuildDeviceIoControlRequest.

Use IoAllocateIrp or IoBuildAsynchronousFsdRequest instead.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

We use IoBuildAsycnronoususFsdRequest for building IRP.

The problem was that it is necessary to initialize MDL field of IRP
properly.

But now I get another problem - after I call IoCallDriver with my IRP I get
the infinite recursion. I.e. I get another IRP_MJ_READ which seems to be
initated by the underlying driver in response to my IRP…

I am completely in stuck.

Thank you,
Roman

“Maxim S. Shatskih” ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ
ÓÌÅÄÕÀÝÅÅ: news:xxxxx@ntfsd…
> >My IRP_MJ_READ fails if I roll it down from the paging i/o, though it
works
> fine
> >from non paged i/o. What can be the reason?
>
> Paging IO paths are executing on APC_LEVEL, where you cannot use ZwXxxFile
and
> IoBuildSynchronousFsdRequest or IoBuildDeviceIoControlRequest.
>
> Use IoAllocateIrp or IoBuildAsynchronousFsdRequest instead.
>
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>

So you take an IRP with the IRP_PAGING_IO bit set and then issue an IRP without the IRP_PAGING_IO bit set?

That’s the equivalent of converting the paging I/O to user I/O. The user I/O is satisfied from the cache, which isn’t present, so the OS issues a paging I/O.

At a minimum you have to satisfy your paging I/O operations using non-cached I/O operations. The area in which your operating - performing I/O during paging I/O operations can be rather complex anyway, so I’m not sure why you’re complicating it by using a different IRP and a different type of I/O.

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Roman Kudinov
Sent: Thursday, September 21, 2006 5:16 AM
To: ntfsd redirect
Subject: Re:[ntfsd] Why my IRP_MJ_READ fails

We use IoBuildAsycnronoususFsdRequest for building IRP.

The problem was that it is necessary to initialize MDL field of IRP
properly.

But now I get another problem - after I call IoCallDriver with my IRP I get
the infinite recursion. I.e. I get another IRP_MJ_READ which seems to be
initated by the underlying driver in response to my IRP…

I am completely in stuck.

Thank you,
Roman

“Maxim S. Shatskih” ???/??? ? ???
???: news:xxxxx@ntfsd…
> >My IRP_MJ_READ fails if I roll it down from the paging i/o, though it
works
> fine
> >from non paged i/o. What can be the reason?
>
> Paging IO paths are executing on APC_LEVEL, where you cannot use ZwXxxFile
and
> IoBuildSynchronousFsdRequest or IoBuildDeviceIoControlRequest.
>
> Use IoAllocateIrp or IoBuildAsynchronousFsdRequest instead.
>
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>


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

Look at this example code we using in our driver.

NTSTATUS OwnRead(
IN PDEVICE_OBJECT NextDeviceObject,
IN PFILE_OBJECT FileObject,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset,
IN KPROCESSOR_MODE requestorMode

)
//////////////////////////////////////////////////////////////////////////
// sends IRP_MJ_READ for read data from file
// in this function not implemented using of Fast IO routines
//////////////////////////////////////////////////////////////////////////
{
NTSTATUS status;
LARGE_INTEGER fileOffset = {0,0};
KEVENT event;
PIRP irp = NULL;
PIO_STACK_LOCATION irpSp = NULL;
PFAST_IO_DISPATCH fastIoDispatch = NULL;
ULONG keyValue = 0;

if (!NextDeviceObject || !FileObject || !IoStatusBlock || !Buffer){
return STATUS_INVALID_PARAMETER;
}

//
// capture ByteOffset parameter if it is present.
//

if (ARGUMENT_PRESENT( ByteOffset )) {
fileOffset = *ByteOffset;
}

if (requestorMode != KernelMode)
{
//Validate offset
if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING)
{
//
// The file was opened without intermediate
buffering enabled.
// Check that the Buffer is properly aligned, and
that the
// length is an integral number of the block size.
//

if ((NextDeviceObject->SectorSize &&
(Length & (NextDeviceObject->SectorSize -
1))) ||
(ULONG_PTR) Buffer &
NextDeviceObject->AlignmentRequirement)
{

//
// Check for sector sizes that are not a
power of two.
//

if ((NextDeviceObject->SectorSize &&
Length %
NextDeviceObject->SectorSize) ||
(ULONG_PTR) Buffer &
NextDeviceObject->AlignmentRequirement)
{
ASSERT( FALSE );
return STATUS_INVALID_PARAMETER;
}
}

//
// If a ByteOffset parameter was specified, ensure
that it
// is a valid argument.
//

if (ARGUMENT_PRESENT( ByteOffset ))
{
if (NextDeviceObject->SectorSize &&
(fileOffset.LowPart &
(NextDeviceObject->SectorSize - 1)))
{
ASSERT( FALSE );
return STATUS_INVALID_PARAMETER;
}
}
}

}

//
// Get the address of the driver object’s Fast I/O dispatch
structure.
//

fastIoDispatch = NextDeviceObject->DriverObject->FastIoDispatch;

//
// Make a special check here to determine whether this is a
synchronous
// I/O operation. If it is, then wait here until the file is owned
by
// the current thread.
//

if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{

if (/*!ARGUMENT_PRESENT( ByteOffset ) || */ /*!!!*/
(fileOffset.LowPart ==
FILE_USE_FILE_POINTER_POSITION &&
fileOffset.HighPart == -1))
{
fileOffset = FileObject->CurrentByteOffset;
}

//
// Turbo read support. If the file is currently cached on
this
// file object, then call the Cache Manager directly via
FastIoRead
// and try to successfully complete the request here. Note
if
// FastIoRead returns FALSE or we get an I/O error, we
simply
// fall through and go the “long way” and create an Irp.
//

if (FileObject->PrivateCacheMap)
{

IO_STATUS_BLOCK localIoStatus;

ASSERT(fastIoDispatch &&
fastIoDispatch->FastIoRead);

//
// Negative file offsets are illegal.
//

if (fileOffset.HighPart < 0) {

return STATUS_INVALID_PARAMETER;
}

if (fastIoDispatch->FastIoRead( FileObject,
&fileOffset,
Length,
TRUE,
keyValue,
Buffer,
&localIoStatus,
NextDeviceObject )

&&

((localIoStatus.Status == STATUS_SUCCESS) ||
(localIoStatus.Status ==
STATUS_BUFFER_OVERFLOW) ||
(localIoStatus.Status ==
STATUS_END_OF_FILE)))
{

__try {
*IoStatusBlock = localIoStatus;
}__except( EXCEPTION_EXECUTE_HANDLER ) {
localIoStatus.Status =
GetExceptionCode();
localIoStatus.Information = 0;
}

return localIoStatus.Status;
}
}

}

//
// Negative file offsets are illegal.
//
if (fileOffset.HighPart < 0) {
return STATUS_INVALID_PARAMETER;
}

// Set the file object to the Not-Signaled state
KeInitializeEvent( &event, NotificationEvent, FALSE );

//
IoStatusBlock->Status = STATUS_SUCCESS;
IoStatusBlock->Information = 0;

// Allocate and initialize the I/O Request Packet (IRP) for this
operation.
irp = IoAllocateIrp( NextDeviceObject->StackSize, FALSE );
if (irp == NULL) {
// An IRP could not be allocated. Cleanup and return an
appropriate error status code
return STATUS_INSUFFICIENT_RESOURCES;
}
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.AuxiliaryBuffer = (PVOID) NULL;
irp->RequestorMode = KernelMode;
irp->PendingReturned = FALSE;
irp->Cancel = FALSE;
irp->CancelRoutine = (PDRIVER_CANCEL) NULL;

// Fill in the service independent parameters in the IRP.
irp->MdlAddress = NULL;
irp->UserIosb = IoStatusBlock;
irp->UserEvent = NULL;
irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
irp->Overlay.AsynchronousParameters.UserApcContext = NULL;

//
// Get a pointer to the stack location for the first driver. This
will be
// used to pass the original function codes and parameters. Note
that
// setting the major function here also sets:
//
// MinorFunction = 0;
// Flags = 0;
// Control = 0;
//
irpSp = IoGetNextIrpStackLocation( irp );
irpSp->MajorFunction = IRP_MJ_READ;
irpSp->MinorFunction = IRP_MN_NORMAL;
irpSp->FileObject = FileObject;

//
// Now determine whether this device expects to have data buffered
to it
// or whether it performs direct I/O.

irp->AssociatedIrp.SystemBuffer = (PVOID) NULL;
irp->MdlAddress = (PMDL) NULL;

if (NextDeviceObject->Flags & DO_BUFFERED_IO) {
if (Length) {
irp->AssociatedIrp.SystemBuffer = Buffer;
}
}else if (NextDeviceObject->Flags & DO_DIRECT_IO) {
//
// This is a direct I/O operation. Allocate an MDL and
invoke the
// memory management routine to lock the buffer into memory.
This
// is done using an exception handler that will perform
cleanup if
// the operation fails. Note that no MDL is allocated, nor
is any
// memory probed or locked if the length of the request was
zero.
//
irp->Flags = 0;
irp->MdlAddress;
if (Length) {
__try {
//
// Allocate an MDL, charging quota for it,
and hang it off of
// the IRP. Probe and lock the pages
associated with the
// caller’s buffer for write access and fill
in the MDL with
// the PFNs of those pages.
//
irp->MdlAddress = IoAllocateMdl( Buffer,
Length, FALSE, TRUE, irp );
if (irp->MdlAddress == NULL) {
IoFreeIrp(irp);
return STATUS_INSUFFICIENT_RESOURCES
;
}
MmProbeAndLockPages( irp->MdlAddress,
KernelMode, IoWriteAccess );
}__except(EXCEPTION_EXECUTE_HANDLER) {
IoFreeIrp(irp);
return GetExceptionCode();
}
}
}else {
// Pass the address of the user’s buffer so the driver has
access to
// it. It is now the driver’s responsibility to do
everything.
irp->Flags = 0;
irp->UserBuffer = Buffer;
}

// If this read operation is supposed to be performed with caching
disabled
// set the disable flag in the IRP so no caching is performed.

if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) {
irp->Flags |= IRP_NOCACHE | IRP_READ_OPERATION |
IRP_DEFER_IO_COMPLETION;
} else {
irp->Flags |= IRP_READ_OPERATION | IRP_DEFER_IO_COMPLETION;
}

// Copy the caller’s parameters to the service-specific portion of
the
// IRP.
irpSp->Parameters.Read.Length = Length;
irpSp->Parameters.Read.Key = 0;
irpSp->Parameters.Read.ByteOffset = fileOffset;

IoSetCompletionRoutine( irp,
OwnReadWriteCompletion,
&event,
TRUE,
TRUE,
TRUE );

status = IoCallDriver( NextDeviceObject, irp );

if (STATUS_PENDING == status) {

KeWaitForSingleObject( &event,
Executive,
KernelMode,
FALSE,
NULL );
}

return IoStatusBlock->Status;
}

Andrey Gunko
soft Xpansion GmbH & Co.KG
Programmer
Powered by eKnow-how
Konigsallee 45 D-44789 Bochum Tel: +49 234 2984171 Fax: +49 234
2984172 Internet: [www.maus-soft.com]

|-----Original Message-----
|From: xxxxx@lists.osr.com [mailto:bounce-263408-
|xxxxx@lists.osr.com] On Behalf Of Roman Kudinov
|Sent: Thursday, September 21, 2006 3:16 PM
|To: Windows File Systems Devs Interest List
|Subject: Re:[ntfsd] Why my IRP_MJ_READ fails
|
|We use IoBuildAsycnronoususFsdRequest for building IRP.
|
|The problem was that it is necessary to initialize MDL field of IRP
|properly.
|
|But now I get another problem - after I call IoCallDriver with my IRP I get
|the infinite recursion. I.e. I get another IRP_MJ_READ which seems to be
|initated by the underlying driver in response to my IRP…
|
|I am completely in stuck.
|
|
|Thank you,
|Roman
|
|
|“Maxim S. Shatskih” ???/??? ? ???
|???: news:xxxxx@ntfsd…
|> >My IRP_MJ_READ fails if I roll it down from the paging i/o, though it
|works
|> fine
|> >from non paged i/o. What can be the reason?
|>
|> Paging IO paths are executing on APC_LEVEL, where you cannot use
|ZwXxxFile
|and
|> IoBuildSynchronousFsdRequest or IoBuildDeviceIoControlRequest.
|>
|> Use IoAllocateIrp or IoBuildAsynchronousFsdRequest instead.
|>
|> Maxim Shatskih, Windows DDK MVP
|> StorageCraft Corporation
|> xxxxx@storagecraft.com
|> http://www.storagecraft.com
|>
|>
|
|
|
|—
|Questions? First check the IFS FAQ at
|https://www.osronline.com/article.cfm?id=17
|
|You are currently subscribed to ntfsd as: xxxxx@maus.donetsk.ua
|To unsubscribe send a blank email to xxxxx@lists.osr.com

> The problem was that it is necessary to initialize MDL field o IRP

properly.

Do you create a Paging IO request?


Slava Imameyev, xxxxx@hotmail.com

“Roman Kudinov” wrote in message news:xxxxx@ntfsd…
> We use IoBuildAsycnronoususFsdRequest for building IRP.
>
> The problem was that it is necessary to initialize MDL field of IRP
> properly.
>
> But now I get another problem - after I call IoCallDriver with my IRP I
> get
> the infinite recursion. I.e. I get another IRP_MJ_READ which seems to be
> initated by the underlying driver in response to my IRP…
>
> I am completely in stuck.
>
>
> Thank you,
> Roman
>
>
> “Maxim S. Shatskih” ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ
> ÓÌÅÄÕÀÝÅÅ: news:xxxxx@ntfsd…
>> >My IRP_MJ_READ fails if I roll it down from the paging i/o, though it
> works
>> fine
>> >from non paged i/o. What can be the reason?
>>
>> Paging IO paths are executing on APC_LEVEL, where you cannot use
>> ZwXxxFile
> and
>> IoBuildSynchronousFsdRequest or IoBuildDeviceIoControlRequest.
>>
>> Use IoAllocateIrp or IoBuildAsynchronousFsdRequest instead.
>>
>> Maxim Shatskih, Windows DDK MVP
>> StorageCraft Corporation
>> xxxxx@storagecraft.com
>> http://www.storagecraft.com
>>
>>
>
>
>

This is modified NtReadFile code from MS.
Do you pay MS for using their code and publishing it?
And it is wrong to lock an MDL buffer in the IRP, it has been already locked
by the caller or can’t be locked because MDL describes non paged buffer. And
many other redundant checks.


Slava Imameyev, xxxxx@hotmail.com

“Gunko Andrey” wrote in message news:xxxxx@ntfsd…
Look at this example code we using in our driver.

NTSTATUS OwnRead(
IN PDEVICE_OBJECT NextDeviceObject,
IN PFILE_OBJECT FileObject,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset,
IN KPROCESSOR_MODE requestorMode

)
//////////////////////////////////////////////////////////////////////////
// sends IRP_MJ_READ for read data from file
// in this function not implemented using of Fast IO routines
//////////////////////////////////////////////////////////////////////////
{
NTSTATUS status;
LARGE_INTEGER fileOffset = {0,0};
KEVENT event;
PIRP irp = NULL;
PIO_STACK_LOCATION irpSp = NULL;
PFAST_IO_DISPATCH fastIoDispatch = NULL;
ULONG keyValue = 0;

if (!NextDeviceObject || !FileObject || !IoStatusBlock || !Buffer){
return STATUS_INVALID_PARAMETER;
}

//
// capture ByteOffset parameter if it is present.
//

if (ARGUMENT_PRESENT( ByteOffset )) {
fileOffset = ByteOffset;
}

if (requestorMode != KernelMode)
{
//Validate offset
if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING)
{
//
// The file was opened without intermediate
buffering enabled.
// Check that the Buffer is properly aligned, and
that the
// length is an integral number of the block size.
//

if ((NextDeviceObject->SectorSize &&
(Length & (NextDeviceObject->SectorSize -
1))) ||
(ULONG_PTR) Buffer &
NextDeviceObject->AlignmentRequirement)
{

//
// Check for sector sizes that are not a
power of two.
//

if ((NextDeviceObject->SectorSize &&
Length %
NextDeviceObject->SectorSize) ||
(ULONG_PTR) Buffer &
NextDeviceObject->AlignmentRequirement)
{
ASSERT( FALSE );
return STATUS_INVALID_PARAMETER;
}
}

//
// If a ByteOffset parameter was specified, ensure
that it
// is a valid argument.
//

if (ARGUMENT_PRESENT( ByteOffset ))
{
if (NextDeviceObject->SectorSize &&
(fileOffset.LowPart &
(NextDeviceObject->SectorSize - 1)))
{
ASSERT( FALSE );
return STATUS_INVALID_PARAMETER;
}
}
}

}

//
// Get the address of the driver object’s Fast I/O dispatch
structure.
//

fastIoDispatch = NextDeviceObject->DriverObject->FastIoDispatch;

//
// Make a special check here to determine whether this is a
synchronous
// I/O operation. If it is, then wait here until the file is owned
by
// the current thread.
//

if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{

if (/
!ARGUMENT_PRESENT( ByteOffset ) || / /!!!*/
(fileOffset.LowPart ==
FILE_USE_FILE_POINTER_POSITION &&
fileOffset.HighPart == -1))
{
fileOffset = FileObject->CurrentByteOffset;
}

//
// Turbo read support. If the file is currently cached on
this
// file object, then call the Cache Manager directly via
FastIoRead
// and try to successfully complete the request here. Note
if
// FastIoRead returns FALSE or we get an I/O error, we
simply
// fall through and go the “long way” and create an Irp.
//

if (FileObject->PrivateCacheMap)
{

IO_STATUS_BLOCK localIoStatus;

ASSERT(fastIoDispatch &&
fastIoDispatch->FastIoRead);

//
// Negative file offsets are illegal.
//

if (fileOffset.HighPart < 0) {

return STATUS_INVALID_PARAMETER;
}

if (fastIoDispatch->FastIoRead( FileObject,
&fileOffset,
Length,
TRUE,
keyValue,
Buffer,
&localIoStatus,
NextDeviceObject )

&&

((localIoStatus.Status == STATUS_SUCCESS) ||
(localIoStatus.Status ==
STATUS_BUFFER_OVERFLOW) ||
(localIoStatus.Status ==
STATUS_END_OF_FILE)))
{

try {
*IoStatusBlock = localIoStatus;
}
except( EXCEPTION_EXECUTE_HANDLER ) {
localIoStatus.Status =
GetExceptionCode();
localIoStatus.Information = 0;
}

return localIoStatus.Status;
}
}

}

//
// Negative file offsets are illegal.
//
if (fileOffset.HighPart < 0) {
return STATUS_INVALID_PARAMETER;
}

// Set the file object to the Not-Signaled state
KeInitializeEvent( &event, NotificationEvent, FALSE );

//
IoStatusBlock->Status = STATUS_SUCCESS;
IoStatusBlock->Information = 0;

// Allocate and initialize the I/O Request Packet (IRP) for this
operation.
irp = IoAllocateIrp( NextDeviceObject->StackSize, FALSE );
if (irp == NULL) {
// An IRP could not be allocated. Cleanup and return an
appropriate error status code
return STATUS_INSUFFICIENT_RESOURCES;
}
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.AuxiliaryBuffer = (PVOID) NULL;
irp->RequestorMode = KernelMode;
irp->PendingReturned = FALSE;
irp->Cancel = FALSE;
irp->CancelRoutine = (PDRIVER_CANCEL) NULL;

// Fill in the service independent parameters in the IRP.
irp->MdlAddress = NULL;
irp->UserIosb = IoStatusBlock;
irp->UserEvent = NULL;
irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
irp->Overlay.AsynchronousParameters.UserApcContext = NULL;

//
// Get a pointer to the stack location for the first driver. This
will be
// used to pass the original function codes and parameters. Note
that
// setting the major function here also sets:
//
// MinorFunction = 0;
// Flags = 0;
// Control = 0;
//
irpSp = IoGetNextIrpStackLocation( irp );
irpSp->MajorFunction = IRP_MJ_READ;
irpSp->MinorFunction = IRP_MN_NORMAL;
irpSp->FileObject = FileObject;

//
// Now determine whether this device expects to have data buffered
to it
// or whether it performs direct I/O.

irp->AssociatedIrp.SystemBuffer = (PVOID) NULL;
irp->MdlAddress = (PMDL) NULL;

if (NextDeviceObject->Flags & DO_BUFFERED_IO) {
if (Length) {
irp->AssociatedIrp.SystemBuffer = Buffer;
}
}else if (NextDeviceObject->Flags & DO_DIRECT_IO) {
//
// This is a direct I/O operation. Allocate an MDL and
invoke the
// memory management routine to lock the buffer into memory.
This
// is done using an exception handler that will perform
cleanup if
// the operation fails. Note that no MDL is allocated, nor
is any
// memory probed or locked if the length of the request was
zero.
//
irp->Flags = 0;
irp->MdlAddress;
if (Length) {
__try {
//
// Allocate an MDL, charging quota for it,
and hang it off of
// the IRP. Probe and lock the pages
associated with the
// caller’s buffer for write access and fill
in the MDL with
// the PFNs of those pages.
//
irp->MdlAddress = IoAllocateMdl( Buffer,
Length, FALSE, TRUE, irp );
if (irp->MdlAddress == NULL) {
IoFreeIrp(irp);
return STATUS_INSUFFICIENT_RESOURCES
;
}
MmProbeAndLockPages( irp->MdlAddress,
KernelMode, IoWriteAccess );
}__except(EXCEPTION_EXECUTE_HANDLER) {
IoFreeIrp(irp);
return GetExceptionCode();
}
}
}else {
// Pass the address of the user’s buffer so the driver has
access to
// it. It is now the driver’s responsibility to do
everything.
irp->Flags = 0;
irp->UserBuffer = Buffer;
}

// If this read operation is supposed to be performed with caching
disabled
// set the disable flag in the IRP so no caching is performed.

if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) {
irp->Flags |= IRP_NOCACHE | IRP_READ_OPERATION |
IRP_DEFER_IO_COMPLETION;
} else {
irp->Flags |= IRP_READ_OPERATION | IRP_DEFER_IO_COMPLETION;
}

// Copy the caller’s parameters to the service-specific portion of
the
// IRP.
irpSp->Parameters.Read.Length = Length;
irpSp->Parameters.Read.Key = 0;
irpSp->Parameters.Read.ByteOffset = fileOffset;

IoSetCompletionRoutine( irp,
OwnReadWriteCompletion,
&event,
TRUE,
TRUE,
TRUE );

status = IoCallDriver( NextDeviceObject, irp );

if (STATUS_PENDING == status) {

KeWaitForSingleObject( &event,
Executive,
KernelMode,
FALSE,
NULL );
}

return IoStatusBlock->Status;
}

Andrey Gunko
soft Xpansion GmbH & Co.KG
Programmer
Powered by eKnow-how
Konigsallee 45 D-44789 Bochum Tel: +49 234 2984171 Fax: +49 234
2984172 Internet: [www.maus-soft.com]

|-----Original Message-----
|From: xxxxx@lists.osr.com [mailto:bounce-263408-
|xxxxx@lists.osr.com] On Behalf Of Roman Kudinov
|Sent: Thursday, September 21, 2006 3:16 PM
|To: Windows File Systems Devs Interest List
|Subject: Re:[ntfsd] Why my IRP_MJ_READ fails
|
|We use IoBuildAsycnronoususFsdRequest for building IRP.
|
|The problem was that it is necessary to initialize MDL field of IRP
|properly.
|
|But now I get another problem - after I call IoCallDriver with my IRP I get
|the infinite recursion. I.e. I get another IRP_MJ_READ which seems to be
|initated by the underlying driver in response to my IRP…
|
|I am completely in stuck.
|
|
|Thank you,
|Roman
|
|
|“Maxim S. Shatskih” ñîîáùèë/ñîîáùèëà â íîâîñòÿõ
|ñëåäóþùåå: news:xxxxx@ntfsd…
|> >My IRP_MJ_READ fails if I roll it down from the paging i/o, though it
|works
|> fine
|> >from non paged i/o. What can be the reason?
|>
|> Paging IO paths are executing on APC_LEVEL, where you cannot use
|ZwXxxFile
|and
|> IoBuildSynchronousFsdRequest or IoBuildDeviceIoControlRequest.
|>
|> Use IoAllocateIrp or IoBuildAsynchronousFsdRequest instead.
|>
|> Maxim Shatskih, Windows DDK MVP
|> StorageCraft Corporation
|> xxxxx@storagecraft.com
|> http://www.storagecraft.com
|>
|>
|
|
|
|—
|Questions? First check the IFS FAQ at
|https://www.osronline.com/article.cfm?id=17
|
|You are currently subscribed to ntfsd as: xxxxx@maus.donetsk.ua
|To unsubscribe send a blank email to xxxxx@lists.osr.com

Yes, Paging IO

Thanks,
Roman

“Slava Imameyev” ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ
ÓÌÅÄÕÀÝÅÅ: news:xxxxx@ntfsd…
> > The problem was that it is necessary to initialize MDL field o IRP
> > properly.
>
> Do you create a Paging IO request?
>
> –
> Slava Imameyev, xxxxx@hotmail.com
>
>
> “Roman Kudinov” wrote in message news:xxxxx@ntfsd…
> > We use IoBuildAsycnronoususFsdRequest for building IRP.
> >
> > The problem was that it is necessary to initialize MDL field of IRP
> > properly.
> >
> > But now I get another problem - after I call IoCallDriver with my IRP I
> > get
> > the infinite recursion. I.e. I get another IRP_MJ_READ which seems to be
> > initated by the underlying driver in response to my IRP…
> >
> > I am completely in stuck.
> >
> >
> > Thank you,
> > Roman
> >
> >
> > “Maxim S. Shatskih” ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ
> > ÓÌÅÄÕÀÝÅÅ: news:xxxxx@ntfsd…
> >> >My IRP_MJ_READ fails if I roll it down from the paging i/o, though it
> > works
> >> fine
> >> >from non paged i/o. What can be the reason?
> >>
> >> Paging IO paths are executing on APC_LEVEL, where you cannot use
> >> ZwXxxFile
> > and
> >> IoBuildSynchronousFsdRequest or IoBuildDeviceIoControlRequest.
> >>
> >> Use IoAllocateIrp or IoBuildAsynchronousFsdRequest instead.
> >>
> >> Maxim Shatskih, Windows DDK MVP
> >> StorageCraft Corporation
> >> xxxxx@storagecraft.com
> >> http://www.storagecraft.com
> >>
> >>
> >
> >
> >
>
>
>

>So you take an IRP with the IRP_PAGING_IO bit set and then issue an IRP
without the IRP_PAGING_IO bit set?

No, I create and roll a paging IO IRP as well

At a minimum you have to satisfy your paging I/O operations using
non-cached I/O operations. The area in which your operating - performing
I/O during >paging I/O operations can be rather complex anyway, so I’m not
sure why you’re complicating it by using a different IRP and a different
type of I/O.

I develop a decompression filter driver, so I need to read custom data
amount to perform decompression, that’s why I roll down my own IRP’s.

I get paging IRP, generate a set of own paging IRP’s, decompress data
returned by them, fill the buffer in the original IRP and complete it.

Tony

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

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com]
On Behalf Of Roman Kudinov
Sent: Thursday, September 21, 2006 5:16 AM
To: ntfsd redirect
Subject: Re:[ntfsd] Why my IRP_MJ_READ fails

We use IoBuildAsycnronoususFsdRequest for building IRP.

The problem was that it is necessary to initialize MDL field of IRP
properly.

But now I get another problem - after I call IoCallDriver with my IRP I get
the infinite recursion. I.e. I get another IRP_MJ_READ which seems to be
initated by the underlying driver in response to my IRP…

I am completely in stuck.

Thank you,
Roman

“Maxim S. Shatskih” ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ
ÓÌÅÄÕÀÝÅÅ: news:xxxxx@ntfsd…
> >My IRP_MJ_READ fails if I roll it down from the paging i/o, though it
works
> fine
> >from non paged i/o. What can be the reason?
>
> Paging IO paths are executing on APC_LEVEL, where you cannot use ZwXxxFile
and
> IoBuildSynchronousFsdRequest or IoBuildDeviceIoControlRequest.
>
> Use IoAllocateIrp or IoBuildAsynchronousFsdRequest instead.
>
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>


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

> Yes, Paging IO

So, you send the Paging IO read and receive another recursive read request.
Is this request for the same file or for a paging file? If for the paging
file and you can see the page fault handler on the stack then this is a
processing of a page fault generated while processing your paging IO
request. Page faults are allowed when processing paging requests for files
which are not paging files.


Slava Imameyev, xxxxx@hotmail.com

“Roman Kudinov” wrote in message news:xxxxx@ntfsd…
> Yes, Paging IO
>
> Thanks,
> Roman
>
>
>
> “Slava Imameyev” ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ
> ÓÌÅÄÕÀÝÅÅ: news:xxxxx@ntfsd…
>> > The problem was that it is necessary to initialize MDL field o IRP
>> > properly.
>>
>> Do you create a Paging IO request?
>>
>> –
>> Slava Imameyev, xxxxx@hotmail.com
>>
>>
>> “Roman Kudinov” wrote in message news:xxxxx@ntfsd…
>> > We use IoBuildAsycnronoususFsdRequest for building IRP.
>> >
>> > The problem was that it is necessary to initialize MDL field of IRP
>> > properly.
>> >
>> > But now I get another problem - after I call IoCallDriver with my IRP I
>> > get
>> > the infinite recursion. I.e. I get another IRP_MJ_READ which seems to
>> > be
>> > initated by the underlying driver in response to my IRP…
>> >
>> > I am completely in stuck.
>> >
>> >
>> > Thank you,
>> > Roman
>> >
>> >
>> > “Maxim S. Shatskih” ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ ×
>> > ÎÏ×ÏÓÔÑÈ
>> > ÓÌÅÄÕÀÝÅÅ: news:xxxxx@ntfsd…
>> >> >My IRP_MJ_READ fails if I roll it down from the paging i/o, though it
>> > works
>> >> fine
>> >> >from non paged i/o. What can be the reason?
>> >>
>> >> Paging IO paths are executing on APC_LEVEL, where you cannot use
>> >> ZwXxxFile
>> > and
>> >> IoBuildSynchronousFsdRequest or IoBuildDeviceIoControlRequest.
>> >>
>> >> Use IoAllocateIrp or IoBuildAsynchronousFsdRequest instead.
>> >>
>> >> Maxim Shatskih, Windows DDK MVP
>> >> StorageCraft Corporation
>> >> xxxxx@storagecraft.com
>> >> http://www.storagecraft.com
>> >>
>> >>
>> >
>> >
>> >
>>
>>
>>
>
>
>

Thank you for the advise.
In addition there is one more issue: I send a request to read 1 sector of
data (2048 bytes on CDFS) but information field of status block is equal to
10 and subsequent IRP’s fail with a error code 0x00000011. All this finished
with STATUS_NO_MEMORY error…

“Slava Imameyev” ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ
ÓÌÅÄÕÀÝÅÅ: news:xxxxx@ntfsd…
> > Yes, Paging IO
>
> So, you send the Paging IO read and receive another recursive read
request.
> Is this request for the same file or for a paging file? If for the paging
> file and you can see the page fault handler on the stack then this is a
> processing of a page fault generated while processing your paging IO
> request. Page faults are allowed when processing paging requests for files
> which are not paging files.
>
> –
> Slava Imameyev, xxxxx@hotmail.com
>
>
> “Roman Kudinov” wrote in message news:xxxxx@ntfsd…
> > Yes, Paging IO
> >
> > Thanks,
> > Roman
> >
> >
> >
> > “Slava Imameyev” ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ × ÎÏ×ÏÓÔÑÈ
> > ÓÌÅÄÕÀÝÅÅ: news:xxxxx@ntfsd…
> >> > The problem was that it is necessary to initialize MDL field o IRP
> >> > properly.
> >>
> >> Do you create a Paging IO request?
> >>
> >> –
> >> Slava Imameyev, xxxxx@hotmail.com
> >>
> >>
> >> “Roman Kudinov” wrote in message
news:xxxxx@ntfsd…
> >> > We use IoBuildAsycnronoususFsdRequest for building IRP.
> >> >
> >> > The problem was that it is necessary to initialize MDL field of IRP
> >> > properly.
> >> >
> >> > But now I get another problem - after I call IoCallDriver with my IRP
I
> >> > get
> >> > the infinite recursion. I.e. I get another IRP_MJ_READ which seems to
> >> > be
> >> > initated by the underlying driver in response to my IRP…
> >> >
> >> > I am completely in stuck.
> >> >
> >> >
> >> > Thank you,
> >> > Roman
> >> >
> >> >
> >> > “Maxim S. Shatskih” ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ ×
> >> > ÎÏ×ÏÓÔÑÈ
> >> > ÓÌÅÄÕÀÝÅÅ: news:xxxxx@ntfsd…
> >> >> >My IRP_MJ_READ fails if I roll it down from the paging i/o, though
it
> >> > works
> >> >> fine
> >> >> >from non paged i/o. What can be the reason?
> >> >>
> >> >> Paging IO paths are executing on APC_LEVEL, where you cannot use
> >> >> ZwXxxFile
> >> > and
> >> >> IoBuildSynchronousFsdRequest or IoBuildDeviceIoControlRequest.
> >> >>
> >> >> Use IoAllocateIrp or IoBuildAsynchronousFsdRequest instead.
> >> >>
> >> >> Maxim Shatskih, Windows DDK MVP
> >> >> StorageCraft Corporation
> >> >> xxxxx@storagecraft.com
> >> >> http://www.storagecraft.com
> >> >>
> >> >>
> >> >
> >> >
> >> >
> >>
> >>
> >>
> >
> >
> >
>
>
>

CDFS is in the IFS Kit; you can build it from source and walk into it
with a debugger to see why you are observing this behavior.

0x00000011 is not an error code, it is a success code. After looking
(it isn’t a defined success code) I’m guessing you mean that the return
is 0xC0000011 (STATUS_END_OF_FILE).

From these two things, I’m curious - how big is the file you’re reading?
If you do a 2048 byte read of a 10 byte file opened for synchronous I/O,
you’ll get exactly the behavior you described - the first read will have
all the data in the file (10 bytes) and then each subsequent read will
fail (STATUS_END_OF_FILE.)

If you don’t want it to return STATUS_END_OF_FILE, when you open the
file, don’t specify synchronous I/O (FILE_SYNCHRONOUS_IO_ALERT or
FILE_SYNCHRONOUS_IO_NONALERT) - in which case the CurrentByteOffset
won’t be advanced and you can read the same 10 bytes each time.

Tony

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