/*++

    Copyright (c) Microsoft Corporation.  All rights reserved.

Rule Name:

    IoBuildDeviceControlWaitTimeout

Domain:

    wdm

Rule ID:

    Not Applicable

Description:

    This rule warns that the driver will wait indefinitely until the lower driver returns, as the IRPs event is required to be signalled in the completion routine.
  
    KeWaitForSingleObject is called with no timeout value.

Help Link:

    https://go.microsoft.com/fwlink/?LinkId=507263

--*/


#include "slic_base.h"

state 
{
    enum {init,forwarded_and_pending} irp_state = init; 
    enum {initial,notsignalled,notsignaled_sync} event_state = initial; 
}
watch KeInitializeEvent.entry.$1;


KeInitializeEvent.entry[guard $1]
{
    if($3)
    {
        halt;
    }
    else
    {
        event_state=notsignalled;
    }
}

IoBuildDeviceIoControlRequest.exit[guard $8]
{
    if($return!=NULL&&event_state==notsignalled)
    {
        event_state=notsignaled_sync;
    }
    else
    {
        halt;
    }
}

[IoCallDriver,PoCallDriver].exit
{
    if($2==sdv_IoBuildDeviceIoControlRequest_irp&&$return==STATUS_PENDING&&event_state==notsignaled_sync)
    {
        irp_state = forwarded_and_pending;
    }
}

KeWaitForSingleObject.entry[guard $1]
{
   if(irp_state == forwarded_and_pending&&$5==NULL)
   {
      abort "KeWaitForSingleObject is called with no timeout value. The driver will wait indefinitely until the lower driver returns, as the IRPs event is required to be signalled in the completion routine.";
   }
   else
   {
       halt;
   }
}

