Help in how to send an IRP_MJ_READ/IRP_MJ_READ

Hi,

I will be very appreciated for any help.

I would like to issue a normal read/write/directory control irps to the file
object.
Seems, I do not understand the mechanism well enough, because
the system crashes with DRIVER_LEFT_LOCKED_PAGES_IN_PROGRESS
in the NTFS.SYS.

I am allocating a read buffer from the non-paged pool and
calling the following routine for synchronous read:

NTSTATUS
ReadFile (
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset
)
{
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
KEVENT Event;
NTSTATUS Status;

KeInitializeEvent(&Event, SynchronizationEvent, FALSE);

Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (Irp == NULL) {
return(STATUS_INSUFFICIENT_RESOURCES);
}

Irp->UserBuffer = Buffer;

Irp->UserEvent = &Event;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = KernelMode;
Irp->Flags = IRP_READ_OPERATION;

IrpSp = IoGetNextIrpStackLocation(Irp);

IrpSp->MajorFunction = IRP_MJ_READ;
IrpSp->MinorFunction = 0;

IrpSp->DeviceObject = DeviceObject;
IrpSp->FileObject = FileObject;

IrpSp->Parameters.Read.Length = Length;
IrpSp->Parameters.Read.ByteOffset = *ByteOffset;

IoSetCompletionRoutine(Irp, IrpComplete, 0, TRUE, TRUE, TRUE);

Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING) {
KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
Status = IoStatusBlock->Status;
}

return(Status);
}

And the completion routine looks like

NTSTATUS
IrpComplete (
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
)
{
*Irp->UserIosb = Irp->IoStatus;

KeSetEvent(Irp->UserEvent, 0, FALSE);

IoFreeIrp(Irp);

return(STATUS_MORE_PROCESSING_REQUIRED);
}

What am I doing wrong in this code?

If I will use MDL, instead of raw buffer who is responsible for freeing it?

Thank you very much in advance.

Regards,
Leonid.

I’m almost certain that this is because NTFS decided to post the IRP, and
wrapping the buffer in an MDL - which the I/O manager would usually free, but in
your case the IRP is never completed and the I/O manager would never free the
MDL.
If you allocate an MDL you are responsible for freeing it. NTFS would
usually allocate an MDL around your buffer if you don’t have an MDL (as would
FAT - See FatLockUserBuffer)

Leonid Zhigunov wrote:

Hi,

I will be very appreciated for any help.

I would like to issue a normal read/write/directory control irps to the file
object.
Seems, I do not understand the mechanism well enough, because
the system crashes with DRIVER_LEFT_LOCKED_PAGES_IN_PROGRESS
in the NTFS.SYS.

I am allocating a read buffer from the non-paged pool and
calling the following routine for synchronous read:

NTSTATUS
ReadFile (
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset
)
{
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
KEVENT Event;
NTSTATUS Status;

KeInitializeEvent(&Event, SynchronizationEvent, FALSE);

Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (Irp == NULL) {
return(STATUS_INSUFFICIENT_RESOURCES);
}

Irp->UserBuffer = Buffer;

Irp->UserEvent = &Event;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = KernelMode;
Irp->Flags = IRP_READ_OPERATION;

IrpSp = IoGetNextIrpStackLocation(Irp);

IrpSp->MajorFunction = IRP_MJ_READ;
IrpSp->MinorFunction = 0;

IrpSp->DeviceObject = DeviceObject;
IrpSp->FileObject = FileObject;

IrpSp->Parameters.Read.Length = Length;
IrpSp->Parameters.Read.ByteOffset = *ByteOffset;

IoSetCompletionRoutine(Irp, IrpComplete, 0, TRUE, TRUE, TRUE);

Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING) {
KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
Status = IoStatusBlock->Status;
}

return(Status);
}

And the completion routine looks like

NTSTATUS
IrpComplete (
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
)
{
*Irp->UserIosb = Irp->IoStatus;

KeSetEvent(Irp->UserEvent, 0, FALSE);

IoFreeIrp(Irp);

return(STATUS_MORE_PROCESSING_REQUIRED);
}

What am I doing wrong in this code?

If I will use MDL, instead of raw buffer who is responsible for freeing it?

Thank you very much in advance.

Regards,
Leonid.


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


Kind regards, Dejan M. MVP for DDK
http://www.alfasp.com E-mail: xxxxx@alfasp.com
Alfa Transparent File Encryptor - Transparent file encryption services.
Alfa File Protector - File protection and hiding library for Win32 developers.
Alfa File Monitor - File monitoring library for Win32 developers.

Thank you, Dejan.

“Dejan Maksimovic” wrote in message news:xxxxx@ntfsd…
>
>
> I’m almost certain that this is because NTFS decided to post the IRP,
and
> wrapping the buffer in an MDL - which the I/O manager would usually free,
but in
> your case the IRP is never completed and the I/O manager would never free
the
> MDL.
> If you allocate an MDL you are responsible for freeing it. NTFS would
> usually allocate an MDL around your buffer if you don’t have an MDL (as
would
> FAT - See FatLockUserBuffer)
>
> Leonid Zhigunov wrote:
>
> > Hi,
> >
> > I will be very appreciated for any help.
> >
> > I would like to issue a normal read/write/directory control irps to the
file
> > object.
> > Seems, I do not understand the mechanism well enough, because
> > the system crashes with DRIVER_LEFT_LOCKED_PAGES_IN_PROGRESS
> > in the NTFS.SYS.
> >
> > I am allocating a read buffer from the non-paged pool and
> > calling the following routine for synchronous read:
> >
> > NTSTATUS
> > ReadFile (
> > IN PDEVICE_OBJECT DeviceObject,
> > IN PFILE_OBJECT FileObject,
> > IN PIO_STATUS_BLOCK IoStatusBlock,
> > IN PVOID Buffer,
> > IN ULONG Length,
> > IN PLARGE_INTEGER ByteOffset
> > )
> > {
> > PIRP Irp;
> > PIO_STACK_LOCATION IrpSp;
> > KEVENT Event;
> > NTSTATUS Status;
> >
> > KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
> >
> > Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
> > if (Irp == NULL) {
> > return(STATUS_INSUFFICIENT_RESOURCES);
> > }
> >
> > Irp->UserBuffer = Buffer;
> >
> > Irp->UserEvent = &Event;
> > Irp->UserIosb = IoStatusBlock;
> > Irp->Tail.Overlay.Thread = PsGetCurrentThread();
> > Irp->Tail.Overlay.OriginalFileObject = FileObject;
> > Irp->RequestorMode = KernelMode;
> > Irp->Flags = IRP_READ_OPERATION;
> >
> > IrpSp = IoGetNextIrpStackLocation(Irp);
> >
> > IrpSp->MajorFunction = IRP_MJ_READ;
> > IrpSp->MinorFunction = 0;
> >
> > IrpSp->DeviceObject = DeviceObject;
> > IrpSp->FileObject = FileObject;
> >
> > IrpSp->Parameters.Read.Length = Length;
> > IrpSp->Parameters.Read.ByteOffset = *ByteOffset;
> >
> > IoSetCompletionRoutine(Irp, IrpComplete, 0, TRUE, TRUE, TRUE);
> >
> > Status = IoCallDriver(DeviceObject, Irp);
> > if (Status == STATUS_PENDING) {
> > KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
> > Status = IoStatusBlock->Status;
> > }
> >
> > return(Status);
> > }
> >
> > And the completion routine looks like
> >
> > NTSTATUS
> > IrpComplete (
> > PDEVICE_OBJECT DeviceObject,
> > PIRP Irp,
> > PVOID Context
> > )
> > {
> > *Irp->UserIosb = Irp->IoStatus;
> >
> > KeSetEvent(Irp->UserEvent, 0, FALSE);
> >
> > IoFreeIrp(Irp);
> >
> > return(STATUS_MORE_PROCESSING_REQUIRED);
> > }
> >
> > What am I doing wrong in this code?
> >
> > If I will use MDL, instead of raw buffer who is responsible for freeing
it?
> >
> > Thank you very much in advance.
> >
> > Regards,
> > Leonid.
> >
> > —
> > You are currently subscribed to ntfsd as: xxxxx@alfasp.com
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
>
> –
> Kind regards, Dejan M. MVP for DDK
> http://www.alfasp.com E-mail: xxxxx@alfasp.com
> Alfa Transparent File Encryptor - Transparent file encryption services.
> Alfa File Protector - File protection and hiding library for Win32
developers.
> Alfa File Monitor - File monitoring library for Win32 developers.
>
>
>
>
>
>

Leonid,

Dejan’s analysis is correct. If you wish to circumvent this, I’d suggest
building the MDL directly. Since the buffer is from non-paged pool, you can
call IoAllocateMdl and MmBuildMdlForNonPagedPool. Set Irp->MdlAddress to
point to your MDL. Of course, you still want to set Irp->UserBuffer.

In your completion routine call IoFreeMdl on the MDL you allocated earlier.
This will resolve your problem and be efficient.

Regards,

Tony

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

-----Original Message-----
From: Leonid Zhigunov [mailto:xxxxx@progate.spb.ru]
Sent: Tuesday, April 22, 2003 6:28 AM
To: File Systems Developers
Subject: [ntfsd] Help in how to send an IRP_MJ_READ/IRP_MJ_READ

Hi,

I will be very appreciated for any help.

I would like to issue a normal read/write/directory control irps to the file
object.
Seems, I do not understand the mechanism well enough, because
the system crashes with DRIVER_LEFT_LOCKED_PAGES_IN_PROGRESS
in the NTFS.SYS.

I am allocating a read buffer from the non-paged pool and
calling the following routine for synchronous read:

NTSTATUS
ReadFile (
IN PDEVICE_OBJECT DeviceObject,
IN PFILE_OBJECT FileObject,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset
)
{
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
KEVENT Event;
NTSTATUS Status;

KeInitializeEvent(&Event, SynchronizationEvent, FALSE);

Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (Irp == NULL) {
return(STATUS_INSUFFICIENT_RESOURCES);
}

Irp->UserBuffer = Buffer;

Irp->UserEvent = &Event;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = KernelMode;
Irp->Flags = IRP_READ_OPERATION;

IrpSp = IoGetNextIrpStackLocation(Irp);

IrpSp->MajorFunction = IRP_MJ_READ;
IrpSp->MinorFunction = 0;

IrpSp->DeviceObject = DeviceObject;
IrpSp->FileObject = FileObject;

IrpSp->Parameters.Read.Length = Length;
IrpSp->Parameters.Read.ByteOffset = *ByteOffset;

IoSetCompletionRoutine(Irp, IrpComplete, 0, TRUE, TRUE, TRUE);

Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING) {
KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
Status = IoStatusBlock->Status;
}

return(Status);
}

And the completion routine looks like

NTSTATUS
IrpComplete (
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
)
{
*Irp->UserIosb = Irp->IoStatus;

KeSetEvent(Irp->UserEvent, 0, FALSE);

IoFreeIrp(Irp);

return(STATUS_MORE_PROCESSING_REQUIRED);
}

What am I doing wrong in this code?

If I will use MDL, instead of raw buffer who is responsible for freeing it?

Thank you very much in advance.

Regards,
Leonid.


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

>I will be very appreciated for any help.

I would like to issue a normal read/write/directory control irps to the file
object.
Seems, I do not understand the mechanism well enough, because
the system crashes with DRIVER_LEFT_LOCKED_PAGES_IN_PROGRESS
in the NTFS.SYS.

I am allocating a read buffer from the non-paged pool and
calling the following routine for synchronous read:

Leonid,

Here’s a sample from my code that I use to do this.

Rick Cadruvi…

=======================================================================

status_nt = STATUS_UNSUCCESSFUL;
for (;:wink:
{
KeInitializeEvent (&waitevent, NotificationEvent, FALSE);

irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ,
(PDEVICE_OBJECT) *filehandle,
realbuf, iosize, &offset,
&waitevent, &iosb);
if (irp == NULL) break;

iomdl = IoAllocateMdl (realbuf, iosize, FALSE, FALSE, irp);
if (iomdl == NULL) break;

MmBuildMdlForNonPagedPool (iomdl);

status_nt = IoCallDriver ((PDEVICE_OBJECT) *filehandle, irp);
if (status_nt == STATUS_PENDING)
KeWaitForSingleObject (&waitevent, Executive, KernelMode, FALSE, NULL);
status_nt = iosb.Status;

break;
}

Thank you very much to everyone who answered me.
Now everything works ok.

Regards,
Leonid.

“Leonid Zhigunov” wrote in message
news:xxxxx@ntfsd…
>
> Hi,
>
> I will be very appreciated for any help.
>
> I would like to issue a normal read/write/directory control irps to the
file
> object.
> Seems, I do not understand the mechanism well enough, because
> the system crashes with DRIVER_LEFT_LOCKED_PAGES_IN_PROGRESS
> in the NTFS.SYS.
>
> I am allocating a read buffer from the non-paged pool and
> calling the following routine for synchronous read:
>
> NTSTATUS
> ReadFile (
> IN PDEVICE_OBJECT DeviceObject,
> IN PFILE_OBJECT FileObject,
> IN PIO_STATUS_BLOCK IoStatusBlock,
> IN PVOID Buffer,
> IN ULONG Length,
> IN PLARGE_INTEGER ByteOffset
> )
> {
> PIRP Irp;
> PIO_STACK_LOCATION IrpSp;
> KEVENT Event;
> NTSTATUS Status;
>
>
> KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
>
> Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
> if (Irp == NULL) {
> return(STATUS_INSUFFICIENT_RESOURCES);
> }
>
> Irp->UserBuffer = Buffer;
>
> Irp->UserEvent = &Event;
> Irp->UserIosb = IoStatusBlock;
> Irp->Tail.Overlay.Thread = PsGetCurrentThread();
> Irp->Tail.Overlay.OriginalFileObject = FileObject;
> Irp->RequestorMode = KernelMode;
> Irp->Flags = IRP_READ_OPERATION;
>
> IrpSp = IoGetNextIrpStackLocation(Irp);
>
> IrpSp->MajorFunction = IRP_MJ_READ;
> IrpSp->MinorFunction = 0;
>
> IrpSp->DeviceObject = DeviceObject;
> IrpSp->FileObject = FileObject;
>
> IrpSp->Parameters.Read.Length = Length;
> IrpSp->Parameters.Read.ByteOffset = *ByteOffset;
>
> IoSetCompletionRoutine(Irp, IrpComplete, 0, TRUE, TRUE, TRUE);
>
> Status = IoCallDriver(DeviceObject, Irp);
> if (Status == STATUS_PENDING) {
> KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
> Status = IoStatusBlock->Status;
> }
>
> return(Status);
> }
>
> And the completion routine looks like
>
> NTSTATUS
> IrpComplete (
> PDEVICE_OBJECT DeviceObject,
> PIRP Irp,
> PVOID Context
> )
> {
> *Irp->UserIosb = Irp->IoStatus;
>
> KeSetEvent(Irp->UserEvent, 0, FALSE);
>
> IoFreeIrp(Irp);
>
> return(STATUS_MORE_PROCESSING_REQUIRED);
> }
>
> What am I doing wrong in this code?
>
> If I will use MDL, instead of raw buffer who is responsible for freeing
it?
>
> Thank you very much in advance.
>
> Regards,
> Leonid.
>
>
>
>
>