Sending IOCTL from IRQL=DISPATCH_LEVEL (KbFilter/KMDF)
Asked Answered
W

1

6

I am using the KbFilter example in the WDK, trying to send an IOCTL in a function that is called by KbFilter_ServiceCallback and therefore is executed at DISPATCH_LEVEL. The function just has to send an IOCTL and return, am not waiting for an output buffer to be filled so it can be asynchronous, fire and forget.

I am currently using the WDF functions WdfIoTargetFormatRequestForIoctl and WdfRequestSend to try and send at DISPATCH_LEVEL and getting nothing. The call to WdfRequestSend is succeeding but the IOCTL doesn't appear to be received.

Using either of WdfIoTargetSendIoctlSynchronously or the WDM pattern IoBuildDeviceIoControlRequest() and IoCallDriver() requires PASSIVE_LEVEL and the only way I know to call these at PASSIVE_LEVEL is to create a separate thread that runs at PASSIVE_LEVEL and pass it instructions via a buffer or a queue, synchronized with a spinlock and semaphore.

Can someone tell me if there is an easier way to pass IOCTLs to the drivers below my filter, or is the thread/queue approach the normal pattern when you need to do things at a higher IRQL? Under what circumstances can I use KeRaiseIrql and is this what I should use? Thanks.

Whitt answered 3/10, 2009 at 7:35 Comment(0)
B
5

Use IoAllocateIrp and IoCallDriver. They can be run at IRQL <= DISPATCH_LEVEL.

You cannot lower your IRQL (unless it is you who raised it). KeRaiseIrql is used only to raise IRQL. A call to KeRaiseIrql is valid if the caller specifies NewIrql >= CurrentIrql.

Be careful: Is your IOCTL expected at DISPATCH_LEVEL?

Here is a code snippet:

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 = ...
Bega answered 5/10, 2009 at 7:7 Comment(4)
Thanks, how do I create the IOCTL request at dispatch level? IoAllocateIrp and IoCallDriver are both ok at dispatch level, but IoBuildDeviceIoControlRequest requires passive level.Whitt
actually msdn.microsoft.com/en-us/library/ms801530.aspx says it needs at least APC level, whereas osronline.com/DDKx/kmarch/k104_8ble.htm says it needs to be at passive level.. strangeWhitt
Thanks for the code, I am not really familiar with the WDM way, I will give it a tryWhitt
IoBuildDeviceIoControlRequest really does need to be invoked at PASSIVE_LEVEL. It marks various parts of the IRP based on your current thread, and the side effects of that may not be what you're looking for at raised IRQL.Kathie

© 2022 - 2024 — McMap. All rights reserved.