过滤驱动与IRP处理方式
我们关系这个IRP的处理结果 就用这个
a.Pending完成例程
IoCopyCurrentIrpStackLocationToNext +完成例程
Pending完成例程
KEVENT event;
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
CompRoutine,
&event,
TRUE,
TRUE,
TRUE
);
status = IoCallDriver(DeviceObject, Irp);
if (status == STATUS_PENDING)
{
status = KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL
);
ASSERT(NT_SUCCESS(status));
status = Irp->IoStatus.Status;
}
回调例程
NTSTATUS
CompRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
PKEVENT event = Context;
Irp->UserIosb->Status = Irp->IoStatus.Status;
Irp->UserIosb->Information = Irp->IoStatus.Information;
KeSetEvent(event ,
IO_NO_INCREMENT, FALSE);
//IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
b.忽略直接下发
IoSkipCurrentIrpStackLocation,下层设备拿到的IO_STACKLOCATION 和当前的一样
对IRP没有任何改动的时候,比如放行:
PDEVICE_EXTENSION deviceExtension;
IoSkipCurrentIrpStackLocation(Irp);
//拿到保存在设备扩展里的下层设备
deviceExtension =
(PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
//下发
return IoCallDriver(
deviceExtension->TargetDeviceObject,
Irp);
c.结束IRP不下发
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation (Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
d.手动构建IRP
IoAllocateIrp
IoGetNextIrpStackLocation
IoAllocateIrp /IoBuildDeviceIoControlRequest
IoGetNextIrpStackLocation
//例子:
//强制删除文件
//Sfilter里查询文件名字
错误的下发:
下发后就没有访问这个IRP的权限了 必须等待 和设置完成例程
例程中必须返回STATUS_MORE_PROCESSING_REQUIRED
// Forward request to next driver
IoCopyCurrentIrpStackLocationToNext( Irp );
// Send the IRP down
status = IoCallDriver( nextDevice, Irp );
// The following is an error because this driver
// no longer owns the IRP.
If (status == STATUS_PENDING)
{
IoMarkIrpPending( Irp );//错误,无权操作Irp了
}
// Return the lower driver’s status
return status;