我正在使用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 ,这是我应该使用的吗?感谢。
答案 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 = ...