static VOID KfcRead(PFILE_OBJECT FileObject,
PLARGE_INTEGER Offset,
ULONG Length,
PMDL Mdl,
PIO_STATUS_BLOCK IoStatusBlock)
{
PIRP irp;
KEVENT event;
PIO_STACK_LOCATION ioStackLocation;
PDEVICE_OBJECT fsdDevice = IoGetRelatedDeviceObject(FileObject);//获得与文件对象相关联的设备对象
//
// Set up the event we'll use.
//
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
//
// Allocate and build the IRP we'll be sending to the FSD.
//
irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
if (!irp)
{
//
// Allocation failed, presumably due to memory allocation failure.
//
IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
IoStatusBlock->Information = 0;
}
irp->MdlAddress = Mdl;
irp->UserEvent = &event;
irp->UserIosb = IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject= FileObject;
irp->RequestorMode = KernelMode;
//
// Indicate that this is a READ operation.
//
irp->Flags = IRP_READ_OPERATION;
//
// Set up the next I/O stack location. These are the parameters
// that will be passed to the underlying driver.
//
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_READ;
ioStackLocation->MinorFunction = 0;
ioStackLocation->DeviceObject = fsdDevice;
ioStackLocation->FileObject = FileObject;
//
// We use a completion routine to keep the I/O Manager from doing
// "cleanup" on our IRP - like freeing our MDL.
//
IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);
ioStackLocation->Parameters.Read.Length = Length;
ioStackLocation->Parameters.Read.ByteOffset = *Offset;
//
// Send it on. Ignore the return code.
//
(void) IoCallDriver(fsdDevice, irp);
//
// Wait for the I/O to complete.
//
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
//
// Done. Return results are in the io status block.
//
return;
}
问题:以上函数static VOID KfcRead()这个函数发出去IRP后,读取到的文件的内容存在哪里的?
Depending on whether the underlying device driver sets up the target device object's Flags with DO_BUFFERED_IO or with DO_DIRECT_IO, data is transferred into one of the following:
The buffer at Irp->AssociatedIrp.SystemBuffer if the driver uses buffered I/O.
The buffer described by the MDL at Irp->MdlAddress if the underlying device driver uses direct I/O (DMA or PIO).