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;
}