在驱动中处理irp
一旦你得到IRP,你就拥有了这个IRP. 你就能够使用它做任何你想要的事情。 如果你处理它,当你处理完时你就必须要么完成它,要么把它向下传给另外的驱动。如果你把它传给其他的驱动,你就必须忘记它。你传递给的驱动现在负责完成它。
这个例子过滤驱动,我们地实现有些不同,在我们提供irp给例子驱动后,它想要处理参数。
这样,我们必须要捕获完成时并停止它。因为我们知道底层驱动将会完成它。所以,我们设置我们自己的completion routine, 我们就能停止它。下面就是我们的实现代码。
pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
PIO_COMPLETION_ROUTINE) ExampleFilter_CompletionRoutine, NULL,
TRUE, TRUE, TRUE);
/*
* IoCallDriver() simply calls the
* appropriate entry point in the driver object associated
* with the device object. This is
* how drivers are basically "chained" together, they must know
* that there are lower driver so they
* can perform the appropriate action and send down the IRP.
*
* They do not have to send the IRP down
* they could simply process it completely themselves if they wish.
*/
NtStatus = IoCallDriver(
pExampleFilterDeviceContext->pNextDeviceInChain, Irp);
/*
* Please note that our
* implementation here is a simple one. We do not take into account
* PENDING IRP's oranything complicated. We assume that once we get
* to this locaiton the IRP has alreadybeen completed and our completetion
* routine was called or it wasn't completed and we are still able
* to complete it here.
* Our completetion routine makes sure that the IRP is still valid here.
*
*/
if(NT_SUCCESS(NtStatus)
{ /*
* Data was read?
*/
if(Irp->IoStatus.Information)
{
/*
* Our filter device is dependent upon the compliation settings of
* how we compiled example.sys
* That means we need to dynamically figure out if we're
* using Direct, Buffered or Neither.
*/
if(DeviceObject->Flags & DO_BUFFERED_IO)
{
DbgPrint("ExampleFilter_Read - Use Buffered I/O \r\n");
/*
* Implementation for Buffered I/O
*/
pReadDataBuffer = (PCHAR)Irp->AssociatedIrp.SystemBuffer;
if(pReadDataBuffer
&& pIoStackIrp->Parameters.Read.Length > 0)
{
ExampleFilter_FixNullString(pReadDataBuffer,
(UINT)Irp->IoStatus.Information);
}
}
else
{
if(DeviceObject->Flags
& DO_DIRECT_IO)
{
DbgPrint("ExampleFilter_Read - Use Direct I/O \r\n");
/*
* Implementation for Direct I/O
*/
if(pIoStackIrp && Irp->MdlAddress)
{
pReadDataBuffer = MmGetSystemAddressForMdlSafe(
Irp->MdlAddress, NormalPagePriority);
if(pReadDataBuffer &&
pIoStackIrp->Parameters.Read.Length)
{
ExampleFilter_FixNullString(pReadDataBuffer,
(UINT)Irp->IoStatus.Information);
}
}
}
else
{
DbgPrint("ExampleFilter_Read - Use Neither I/O \r\n");
/* Implementation for Neither I/O
*/
__try {
if(pIoStackIrp->Parameters.Read.Length >
0 && Irp->UserBuffer)
{
ProbeForWrite(Irp->UserBuffer,
IoStackIrp->Parameters.Read.Length,
TYPE_ALIGNMENT(char));
pReadDataBuffer = Irp->UserBuffer;
ExampleFilter_FixNullString(pReadDataBuffer,
(UINT)Irp->IoStatus.Information);
}
} __except( EXCEPTION_EXECUTE_HANDLER ) {
NtStatus = GetExceptionCode();
}
}
}
}
}