/*++

    Copyright (c) Microsoft Corporation.  All rights reserved.

Rule Name:

    NdisAllocateMemoryWithTagPriority_Cleanup

Domain:

    ndis

Rule ID:

    Not Applicable

Description:

    This rule checks that NdisAllocateMemoryWithTagPriority and NdisFreeMemoryWithTagPriority or NdisFreeMemory
    are called in alternate order. The ultimate goal is to make sure all memory allocated is freed
    when the initialization functions fails.

    The rule uses three different states. state changes when memory is allocated or freed.
    If memory is still allocated when the Initialization functions fails this rule will report a defect.
    
    Related Rule:

Help Link:

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

--*/



#include "slic_base.h"

state{
   enum {initial, allocated, free} s = initial;
}
watch NdisAllocateMemoryWithTagPriority.exit.$return;

NdisAllocateMemoryWithTagPriority.exit[guard $return]
{  
    if ($return != 0)
    {
        s = allocated;
    }
}

[NdisFreeMemoryWithTagPriority].exit[guard $2]
{
    if ( s == free)
    {
        abort "Freeing memory that was not allocated.";
    }
  
    s = free;
}

[NdisFreeMemory].exit[guard $1]
{
    if ( s == free)
    {
        abort "Freeing memory that was not allocated.";
    }
  
    s = free;
}



[sdv_MINIPORT_HALT,
sdv_FILTER_DETACH,
sdv_PROTOCOL_UNBIND_ADAPTER_EX].exit
{
    if (s==allocated)
    {
        abort "$fname is failing but the driver has memory allocated using NdisAllocateMemoryWithTagPriority that is not freed.";
    }
}
