6

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

我目前正在使用 WDF 函数WdfIoTargetFormatRequestForIoctlWdfRequestSend尝试在 DISPATCH_LEVEL 发送,但一无所获。对 WdfRequestSend 的调用成功,但似乎未收到 IOCTL。

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

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

4

1 回答 1

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 = ...
于 2009-10-05T07:07:59.230 回答