/*++

    Copyright (c) Microsoft Corporation.  All rights reserved.

Rule Name:

    IoBuildSynchronousFsdRequestWaitTimeout

Domain:

    wdm

Rule ID:

    Not Applicable

Description:

    This rule warns that the driver will wait indefinitely until the lower driver returns, as the IRP's event is required to be signalled in the completion routine.

Help Link:

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

--*/


#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;
    }
}

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

[IoCallDriver,PoCallDriver].exit
{
    if($2==sdv_IoBuildSynchronousFsdRequest_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 IRP's event is required to be signalled in the completion routine.";
   }
   else
   {
       halt;
   }
}

