/*++

    Copyright (c) Microsoft Corporation.  All rights reserved.

Rule Name:

    IoAllocateFree

Domain:

    wdm

Rule ID:

    Not Applicable

Description:

    A driver should use IoFreeIrp only on Irps it previously allocated with IoAllocateIrp.

Help Link:

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

--*/

#include "slic_base.h"

state
{
    enum {initial,allocated} irp_state = initial;             
}
watch IoAllocateIrp.exit.$return;

IoAllocateIrp.exit[guard $return]
{
    if($return!=NULL)
    {
        irp_state = allocated;
    }
    else
    {
       halt;
    }
}


[IoCsqInsertIrp,
IoCsqInsertIrpEx].entry[guard $2]
{
    halt;
}


[ExInterlockedInsertHeadList
,ExInterlockedInsertTailList
,ExInterlockedPushEntryList
,ExfInterlockedInsertHeadList
,ExfInterlockedInsertTailList
,ExfInterlockedPushEntryList].entry 
{
    halt;
}

[InsertHeadList
,InsertTailList].entry
{
    halt;
}

[RemoveHeadList,sdv_containing_record].entry
{
    halt;
}




IoFreeIrp.entry[guard $1]
{
    if(irp_state != allocated)
    {
        abort "A driver should only call $fname if IoAllocateIrp was called.";
    }
    else
    {
        halt;
    }
}

[sdv_RunStartDevice
,fun_IRP_MJ_CLEANUP
,fun_IRP_MJ_CLOSE
,fun_IRP_MJ_CREATE
,fun_IRP_MJ_DEVICE_CONTROL
,fun_IRP_MJ_FILE_SYSTEM_CONTROL
,fun_IRP_MJ_FLUSH_BUFFERS
,fun_IRP_MJ_INTERNAL_DEVICE_CONTROL
,fun_IRP_MJ_LOCK_CONTROL
,fun_IRP_MJ_QUERY_INFORMATION
,fun_IRP_MJ_READ
,fun_IRP_MJ_SET_INFORMATION
,fun_IRP_MJ_SYSTEM_CONTROL
,fun_IRP_MJ_WRITE
,fun_IRP_MJ_PNP
,fun_IRP_MJ_POWER
,sdv_RunRemoveDevice].exit
{
    if(irp_state == allocated&&$return!=STATUS_PENDING)
    {
    	abort "The driver needs to call IoFreeIrp in this case.";
    }
}


[fun_DriverStartIo
,fun_DriverUnload].exit
{
    if(irp_state == allocated)
    {
    	abort "The driver needs to call IoFreeIrp in this case.";
    }

}
