/*++

    Copyright (c) Microsoft Corporation.  All rights reserved.

Rule Name:

    SignalEventInCompletion3

Domain:

    wdm

Rule ID:

    Not Applicable

Description:

    KeSetEvent needs to be called in the completion routine when Irp->PendingReturned is TRUE and processing a async. irp.
    In this case the completion routine will not be called.

Help Link:

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

--*/

#include "slic_base.h"

state 
{
    enum {notsignaled,signaled,initialized} SignalState = initialized;
} 
watch KeInitializeEvent.entry.$1;


KeInitializeEvent.exit[guard $1]
{
    if($3)
    {
        halt;
    }
    else
    {
        
        SignalState=notsignaled;
    }
}
IoSetCompletionRoutineEx.entry
{
    if(((!$5) || (!$6) || (!$7)) && SignalState==notsignaled && ($2==sdv_irp))
    {
        abort "KeSetEvent needs to be called in the completion routine when Irp->PendingReturned is TRUE and processing a async. irp. In this case the completion routine may not be called in all cases.";
    }
    else
    {
        halt;
    }
}

IoSetCompletionRoutine.entry
{
    if(((!$4) || (!$5) || (!$6)) && SignalState==notsignaled && ($1==sdv_irp))
    {
        abort "KeSetEvent needs to be called in the completion routine when Irp->PendingReturned is TRUE and processing a async. irp.In this case the completion routine may not be called in all cases.";
    }
    else
    {
        halt;
    }
}




