How roll my IRP for paging IO?

I have got ryo.zip,and I can roll my IRP for normal IO(read/write).It works very fine.
But,If I want to roll my IRP for paging IO,it will DRIVER_IRQL_NOT_LESS_OR_EQUAL.
The difference (my roll IRP for normal IO,my roll IRP for paging IO) is just:
if (bPagingIO)
Irp->Flags = Irp->Flags | IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO;

This is my all code,somebody can explain it?thank you.

NTSTATUS MyReadData(
IN PDEVICE_OBJECT pDevObj,
IN PFILE_OBJECT FileObject,
IN ULONG nOffset,
IN PVOID pBuffer,
IN ULONG nReadLength,
IN BOOLS bPagingIO,
OUT PULONG pRetLength
)
{
NTSTATUS status;
PMDL pMdl;
ULONG nRetLength = 0;
LARGE_INTEGER FileOffset;

FileOffset.QuadPart = nOffset;
FileOffset.LowPart = nOffset;

pMdl = IoAllocateMdl(pBuffer, nReadLength, FALSE, FALSE, NULL);
if(pMdl == NULL)
return STATUS_INSUFFICIENT_RESOURCES;

MmBuildMdlForNonPagedPool(pMdl);
status = MyReadWriteData(pDevObj,IRP_MJ_READ, FileObject, FileOffset, pMdl,

nReadLength,bPagingIO, &nRetLength);

IoFreeMdl(pMdl);
*pRetLength = nRetLength;

return status;
}

NTSTATUS MyReadWriteData(
IN PDEVICE_OBJECT pDevObj,
IN UCHAR MajorFunction,
IN PFILE_OBJECT FileObject,
IN LARGE_INTEGER offset,
IN PMDL pMdl,
IN ULONG nLength,
IN BOOLS bPagingIO,
OUT PULONG pRetLength
)
{
PIRP Irp;
KEVENT event;
PIO_STACK_LOCATION pIrpStack;
IO_STATUS_BLOCK iostatus;
PDEVICE_EXTENSION pDevExt;
PDEVICE_OBJECT pFsdDevObj;
pDevExt= (PDEVICE_EXTENSION) pDevObj->DeviceExtension;
pFsdDevObj=pDevExt-> pBelowDeviceObject;//the pFsdDevObj is just below mine

KeInitializeEvent(&event, NotificationEvent, FALSE);

Irp = IoAllocateIrp(pFsdDevObj->StackSize, FALSE);
if(!Irp)
return STATUS_INSUFFICIENT_RESOURCES;

Irp->MdlAddress = pMdl;
Irp->UserEvent = NULL;
Irp->UserIosb = &iostatus;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = KernelMode;
if (MajorFunction == IRP_MJ_READ)
Irp->Flags = IRP_READ_OPERATION;
else
Irp->Flags = IRP_WRITE_OPERATION;
if (bPagingIO)
Irp->Flags = Irp->Flags | IRP_NOCACHE | IRP_PAGING_IO |

IRP_SYNCHRONOUS_PAGING_IO;

pIrpStack = IoGetNextIrpStackLocation(Irp);
pIrpStack->MajorFunction = MajorFunction;
pIrpStack->MinorFunction = 0;
pIrpStack->DeviceObject = pFsdDevObj;
pIrpStack->FileObject = FileObject;

if(MajorFunction == IRP_MJ_READ)
{
pIrpStack->Parameters.Read.Length = nLength;
pIrpStack->Parameters.Read.ByteOffset = offset;
}
else
{
pIrpStack->Parameters.Write.Length = nLength;
pIrpStack->Parameters.Write.ByteOffset = offset;
}

IoSetCompletionRoutine(Irp, MyFreeIrpCommonCompletion, &event, TRUE, TRUE, TRUE);

NTSTATUS status = IoCallDriver(pFsdDevObj, Irp);
if(status == STATUS_PENDING)
{
KeWaitForSingleObject( &event,
Executive,
KernelMode,
TRUE,
0);
status = iostatus.Status;
}

if(NT_SUCCESS(status))
{
*pRetLength = iostatus.Information;
}
else
{
KdPrint((“\r\nReadWriteData Error:%x”, status));
}

return status;
}

NTSTATUS MyFreeIrpCommonCompletion (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID pContext
)
{

UNREFERENCED_PARAMETER( DeviceObject );

ASSERT( NULL != Irp->UserIosb );
*Irp->UserIosb = Irp->IoStatus;

PKEVENT SynchronizingEvent = (PKEVENT)pContext;
KeSetEvent( SynchronizingEvent, IO_NO_INCREMENT, FALSE );

IoFreeIrp( Irp );

return STATUS_MORE_PROCESSING_REQUIRED;
}

You must set the Irp->UserBuffer. FSDs use this field when call
IoBuildPartialMdl
Add
Irp->UserBuffer = pBuffer or Irp->UserBuffer = MmGetMdlVirtualAddress(
pMdl )

Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntfsd...
>I have got ryo.zip,and I can roll my IRP for normal IO(read/write).It works
>very fine.
> But,If I want to roll my IRP for paging IO,it will
> DRIVER_IRQL_NOT_LESS_OR_EQUAL.
> The difference (my roll IRP for normal IO,my roll IRP for paging IO) is
> just:
> if (bPagingIO)
> Irp->Flags = Irp->Flags | IRP_NOCACHE | IRP_PAGING_IO |
> IRP_SYNCHRONOUS_PAGING_IO;
>
> This is my all code,somebody can explain it?thank you.
>
> NTSTATUS MyReadData(
> IN PDEVICE_OBJECT pDevObj,
> IN PFILE_OBJECT FileObject,
> IN ULONG nOffset,
> IN PVOID pBuffer,
> IN ULONG nReadLength,
> IN BOOLS bPagingIO,
> OUT PULONG pRetLength
> )
> {
> NTSTATUS status;
> PMDL pMdl;
> ULONG nRetLength = 0;
> LARGE_INTEGER FileOffset;
>
> FileOffset.QuadPart = nOffset;
> FileOffset.LowPart = nOffset;
>
> pMdl = IoAllocateMdl(pBuffer, nReadLength, FALSE, FALSE, NULL);
> if(pMdl == NULL)
> return STATUS_INSUFFICIENT_RESOURCES;
>
> MmBuildMdlForNonPagedPool(pMdl);
> status = MyReadWriteData(pDevObj,IRP_MJ_READ, FileObject, FileOffset,
> pMdl,
>
> nReadLength,bPagingIO, &nRetLength);
>
> IoFreeMdl(pMdl);
> *pRetLength = nRetLength;
>
> return status;
> }
>
>
> NTSTATUS MyReadWriteData(
> IN PDEVICE_OBJECT pDevObj,
> IN UCHAR MajorFunction,
> IN PFILE_OBJECT FileObject,
> IN LARGE_INTEGER offset,
> IN PMDL pMdl,
> IN ULONG nLength,
> IN BOOLS bPagingIO,
> OUT PULONG pRetLength
> )
> {
> PIRP Irp;
> KEVENT event;
> PIO_STACK_LOCATION pIrpStack;
> IO_STATUS_BLOCK iostatus;
> PDEVICE_EXTENSION pDevExt;
> PDEVICE_OBJECT pFsdDevObj;
> pDevExt= (PDEVICE_EXTENSION) pDevObj->DeviceExtension;
> pFsdDevObj=pDevExt-> pBelowDeviceObject;//the pFsdDevObj is just below
> mine
>
> KeInitializeEvent(&event, NotificationEvent, FALSE);
>
> Irp = IoAllocateIrp(pFsdDevObj->StackSize, FALSE);
> if(!Irp)
> return STATUS_INSUFFICIENT_RESOURCES;
>
> Irp->MdlAddress = pMdl;
> Irp->UserEvent = NULL;
> Irp->UserIosb = &iostatus;
> Irp->Tail.Overlay.Thread = PsGetCurrentThread();
> Irp->Tail.Overlay.OriginalFileObject = FileObject;
> Irp->RequestorMode = KernelMode;
> if (MajorFunction == IRP_MJ_READ)
> Irp->Flags = IRP_READ_OPERATION;
> else
> Irp->Flags = IRP_WRITE_OPERATION;
> if (bPagingIO)
> Irp->Flags = Irp->Flags | IRP_NOCACHE | IRP_PAGING_IO |
>
> IRP_SYNCHRONOUS_PAGING_IO;
>
> pIrpStack = IoGetNextIrpStackLocation(Irp);
> pIrpStack->MajorFunction = MajorFunction;
> pIrpStack->MinorFunction = 0;
> pIrpStack->DeviceObject = pFsdDevObj;
> pIrpStack->FileObject = FileObject;
>
> if(MajorFunction == IRP_MJ_READ)
> {
> pIrpStack->Parameters.Read.Length = nLength;
> pIrpStack->Parameters.Read.ByteOffset = offset;
> }
> else
> {
> pIrpStack->Parameters.Write.Length = nLength;
> pIrpStack->Parameters.Write.ByteOffset = offset;
> }
>
> IoSetCompletionRoutine(Irp, MyFreeIrpCommonCompletion, &event, TRUE, TRUE,
> TRUE);
>
> NTSTATUS status = IoCallDriver(pFsdDevObj, Irp);
> if(status == STATUS_PENDING)
> {
> KeWaitForSingleObject( &event,
> Executive,
> KernelMode,
> TRUE,
> 0);
> status = iostatus.Status;
> }
>
> if(NT_SUCCESS(status))
> {
> *pRetLength = iostatus.Information;
> }
> else
> {
> KdPrint(("\r\nReadWriteData Error:%x", status));
> }
>
> return status;
> }
>
>
> NTSTATUS MyFreeIrpCommonCompletion (
> IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp,
> IN PVOID pContext
> )
> {
>
> UNREFERENCED_PARAMETER( DeviceObject );
>
> ASSERT( NULL != Irp->UserIosb );
> *Irp->UserIosb = Irp->IoStatus;
>
> PKEVENT SynchronizingEvent = (PKEVENT)pContext;
> KeSetEvent( SynchronizingEvent, IO_NO_INCREMENT, FALSE );
>
> IoFreeIrp( Irp );
>
> return STATUS_MORE_PROCESSING_REQUIRED;
> }
>

yet another error:
You must unlock the MDL before calling IoFreeMdl.
MmUnlockPages( Mdl )


Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntfsd…
>I have got ryo.zip,and I can roll my IRP for normal IO(read/write).It works
>very fine.
> But,If I want to roll my IRP for paging IO,it will
> DRIVER_IRQL_NOT_LESS_OR_EQUAL.
> The difference (my roll IRP for normal IO,my roll IRP for paging IO) is
> just:
> if (bPagingIO)
> Irp->Flags = Irp->Flags | IRP_NOCACHE | IRP_PAGING_IO |
> IRP_SYNCHRONOUS_PAGING_IO;
>
> This is my all code,somebody can explain it?thank you.
>
> NTSTATUS MyReadData(
> IN PDEVICE_OBJECT pDevObj,
> IN PFILE_OBJECT FileObject,
> IN ULONG nOffset,
> IN PVOID pBuffer,
> IN ULONG nReadLength,
> IN BOOLS bPagingIO,
> OUT PULONG pRetLength
> )
> {
> NTSTATUS status;
> PMDL pMdl;
> ULONG nRetLength = 0;
> LARGE_INTEGER FileOffset;
>
> FileOffset.QuadPart = nOffset;
> FileOffset.LowPart = nOffset;
>
> pMdl = IoAllocateMdl(pBuffer, nReadLength, FALSE, FALSE, NULL);
> if(pMdl == NULL)
> return STATUS_INSUFFICIENT_RESOURCES;
>
> MmBuildMdlForNonPagedPool(pMdl);
> status = MyReadWriteData(pDevObj,IRP_MJ_READ, FileObject, FileOffset,
> pMdl,
>
> nReadLength,bPagingIO, &nRetLength);
>
> IoFreeMdl(pMdl);
> *pRetLength = nRetLength;
>
> return status;
> }
>
>
> NTSTATUS MyReadWriteData(
> IN PDEVICE_OBJECT pDevObj,
> IN UCHAR MajorFunction,
> IN PFILE_OBJECT FileObject,
> IN LARGE_INTEGER offset,
> IN PMDL pMdl,
> IN ULONG nLength,
> IN BOOLS bPagingIO,
> OUT PULONG pRetLength
> )
> {
> PIRP Irp;
> KEVENT event;
> PIO_STACK_LOCATION pIrpStack;
> IO_STATUS_BLOCK iostatus;
> PDEVICE_EXTENSION pDevExt;
> PDEVICE_OBJECT pFsdDevObj;
> pDevExt= (PDEVICE_EXTENSION) pDevObj->DeviceExtension;
> pFsdDevObj=pDevExt-> pBelowDeviceObject;//the pFsdDevObj is just below
> mine
>
> KeInitializeEvent(&event, NotificationEvent, FALSE);
>
> Irp = IoAllocateIrp(pFsdDevObj->StackSize, FALSE);
> if(!Irp)
> return STATUS_INSUFFICIENT_RESOURCES;
>
> Irp->MdlAddress = pMdl;
> Irp->UserEvent = NULL;
> Irp->UserIosb = &iostatus;
> Irp->Tail.Overlay.Thread = PsGetCurrentThread();
> Irp->Tail.Overlay.OriginalFileObject = FileObject;
> Irp->RequestorMode = KernelMode;
> if (MajorFunction == IRP_MJ_READ)
> Irp->Flags = IRP_READ_OPERATION;
> else
> Irp->Flags = IRP_WRITE_OPERATION;
> if (bPagingIO)
> Irp->Flags = Irp->Flags | IRP_NOCACHE | IRP_PAGING_IO |
>
> IRP_SYNCHRONOUS_PAGING_IO;
>
> pIrpStack = IoGetNextIrpStackLocation(Irp);
> pIrpStack->MajorFunction = MajorFunction;
> pIrpStack->MinorFunction = 0;
> pIrpStack->DeviceObject = pFsdDevObj;
> pIrpStack->FileObject = FileObject;
>
> if(MajorFunction == IRP_MJ_READ)
> {
> pIrpStack->Parameters.Read.Length = nLength;
> pIrpStack->Parameters.Read.ByteOffset = offset;
> }
> else
> {
> pIrpStack->Parameters.Write.Length = nLength;
> pIrpStack->Parameters.Write.ByteOffset = offset;
> }
>
> IoSetCompletionRoutine(Irp, MyFreeIrpCommonCompletion, &event, TRUE, TRUE,
> TRUE);
>
> NTSTATUS status = IoCallDriver(pFsdDevObj, Irp);
> if(status == STATUS_PENDING)
> {
> KeWaitForSingleObject( &event,
> Executive,
> KernelMode,
> TRUE,
> 0);
> status = iostatus.Status;
> }
>
> if(NT_SUCCESS(status))
> {
> *pRetLength = iostatus.Information;
> }
> else
> {
> KdPrint((“\r\nReadWriteData Error:%x”, status));
> }
>
> return status;
> }
>
>
> NTSTATUS MyFreeIrpCommonCompletion (
> IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp,
> IN PVOID pContext
> )
> {
>
> UNREFERENCED_PARAMETER( DeviceObject );
>
> ASSERT( NULL != Irp->UserIosb );
> *Irp->UserIosb = Irp->IoStatus;
>
> PKEVENT SynchronizingEvent = (PKEVENT)pContext;
> KeSetEvent( SynchronizingEvent, IO_NO_INCREMENT, FALSE );
>
> IoFreeIrp( Irp );
>
> return STATUS_MORE_PROCESSING_REQUIRED;
> }
>

thank you~slava~
It can works if I don’t call MmUnlockPages( pMdl );
If I call MmUnlockPages( pMdl ) before IoFreeMdl,it will bugcheck LIST_CORRUPT.

thank you~~

but it can’t resolve my question:
Use MmMapViewOfSection to write,I can’t hook the Paging Write!

> It can works if I don’t call MmUnlockPages( pMdl );

Yes, this is because you use a non paged pool. I conclude this from
MmBuildMdlForNonPagedPool .


Slava Imameyev, xxxxx@hotmail.com

wrote in message news:xxxxx@ntfsd…
> thank you~slava~
> It can works if I don’t call MmUnlockPages( pMdl );
> If I call MmUnlockPages( pMdl ) before IoFreeMdl,it will bugcheck
> LIST_CORRUPT.
>
> thank you~~
>
> but it can’t resolve my question:
> Use MmMapViewOfSection to write,I can’t hook the Paging Write!
>
>
>

yes,I use nonpaged,hehe,just for simple.
sorry for my stupid question,I should know your description is for paged pool.
hehe