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

Dal*_*ale 6 c c++ driver kmdf wdf

我在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,这是我应该使用的吗?谢谢.

Ser*_*bry 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 = ...
Run Code Online (Sandbox Code Playgroud)