/*++

    Copyright (c) Microsoft Corporation.  All rights reserved.

Rule Name:

    IrpProcessingComplete

Domain:

    wdm

Rule ID:

    Not Applicable

Description:

    This rule specifices that if a dispatch routine returns
    STATUS_SUCCESS, the IRP must have been completed by the driver
    it self or a lower driver.

Help Link:

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

--*/


#include "slic_base.h"

state {
    int lower_driver_pends = 0;
    int done = 0;
} with guard(sdv_main,sdv_irp) 

[SDV_RunDispatchFunction].exit [guard $2]
{
    if (!done && $return == STATUS_SUCCESS) {
       abort "The dispatch routine returned STATUS_SUCCESS, but IRP is not completed by driver or lower driver.";
    }
}

[RemoveHeadList,sdv_containing_record].entry
{
    done = 1;
}

[PoCallDriver,IoCallDriver].exit[guard $2] 
{
    if ( $return == STATUS_PENDING
       ) {
        lower_driver_pends = 1;
    }
    else {
        done = 1;
    }
}

[KeWaitForSingleObject, KeWaitForMultipleObjects,KeWaitForMutexObject].entry
{
     if ( lower_driver_pends == 1
         ) {
             done = 1;
     }
}

[IoCompleteRequest,IofCompleteRequest].entry[guard $1]
{
    done = 1;
}

sdv_stub_WmiIrpProcessed.entry [guard $1] {
    done = 1;
}
