从IRQL发送IOCTL = DISPATCH_LEVEL(KbFilter / KMDF)

时间:2009-10-03 07:35:34

标签: c++ c driver kmdf wdf

我正在使用WDK中的KbFilter示例,尝试在由KbFilter_ServiceCallback调用的函数中发送IOCTL,因此在DISPATCH_LEVEL处执行。该函数只需要发送一个IOCTL并返回,不等待输出缓冲区被填充,因此它可以是异步,激发和遗忘。

我目前正在使用WDF函数 WdfIoTargetFormatRequestForIoctl WdfRequestSend 尝试在DISPATCH_LEVEL发送并且什么也没得到。对WdfRequestSend的调用是成功的,但似乎没有收到IOCTL。

使用 WdfIoTargetSendIoctlSynchronously 或WDM模式 IoBuildDeviceIoControlRequest()和IoCallDriver()需要PASSIVE_LEVEL,我知道在PASSIVE_LEVEL中调用它们的唯一方法是创建一个单独的在PASSIVE_LEVEL运行的线程,通过缓冲区或队列传递指令,与自旋锁和信号量同步。

有人可以告诉我是否有更简单的方法将IOCTL传递给我的过滤器下面的驱动程序,或者当您需要在更高的IRQL上执行操作时,线程/队列是否接近正常模式?在什么情况下我可以使用 KeRaiseIrql ,这是我应该使用的吗?感谢。

1 个答案:

答案 0 :(得分:5)

使用IoAllocateIrp和IoCallDriver。它们可以在IRQL< = DISPATCH_LEVEL。

运行

你不能降低你的IRQL(除非是你提出它)。 KeRaiseIrql仅用于引发IRQL。如果调用者指定NewIrql> = CurrentIrql,则对KeRaiseIrql的调用有效。

小心:您的IOCTL是否应该在DISPATCH_LEVEL?

以下是代码段:

PIRP Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);

Irp->Tail.Overlay.Thread  = PsGetCurrentThread(); 
Irp->RequestorMode        = KernelMode; 
Irp->IoStatus.Status      = STATUS_NOT_SUPPORTED; 
Irp->IoStatus.Information = 0; 

PIO_STACK_LOCATION stack  = IoGetNextIrpStackLocation(Irp); 
stack->MajorFunction      = IRP_MJ_DEVICE_CONTROL; 
stack->Parameters.DeviceIoControl.IoControlCode = ...