Search code examples
windowsdevice-driver

Delay execution of IRP_MN_SET_POWER


I am developing a Windows device-driver and need to delay execution of a system shutdown for about 10 secs. I am using following code inside DispatchPower() function of my driver:

NTSTATUS DispatchPower(
  __in  struct _DEVICE_OBJECT *DeviceObject,
  __in  struct _IRP *Irp
)
{

    switch(stack->MinorFunction)
    {
        case IRP_MN_SET_POWER:            
            delay_time.QuadPart = WDF_REL_TIMEOUT_IN_SEC(10);
            KeDelayExecutionThread(KernelMode, FALSE, &delay_time);
    }

}

But it seems KeDelayExecutionThread() returns immediately without waiting? Any suggestions?

Thanks,


Solution

  • Not certain, but here are some advices:

    1. Check the return value of KeDelayExecutionThread. According to the docs it seems that this function may return preliminary with either STATUS_ALERTED or STATUS_USER_APC. Well, since you're performing a non-alertable state this should not happen, but OTOH I don't quite understand what is the difference between STATUS_ALERTED and STATUS_USER_APC. Besides from this it may return you an error status, which may be informative.

    2. According to the docs you must run at IRQL <= APC_LEVEL. You should check your actual IRQL (KeGetCurrentIrql).

    3. Anyway, IMHO it's a pretty weird design to block a thread in the kernel-mode. Usually this hangs the whole system. If you want to delay the IRP processing you'd better return STATUS_PENDING in the dispatch routine, and then, via timer DPC complete this IRP.

    If you're not familiar with this read the MSDN about the following: KeInitializeDpc, KeInitializeTimer, KeSetTimer.