/*++

    Copyright (c) Microsoft Corporation.  All rights reserved.

Rule Name:

    NdisAllocateGenericObject

Domain:

    ndis

Rule ID:

    Not Applicable

Description:

    This rule checks that NdisAllocateGenericObject and NdisFreeGenericObject are called 
    in alternate order. The ultimate goal is to make sure all GenericObjects are freed
    when MiniportHaltEx ends.

    The rule uses three different states. state changes when a GenericObject is allocated or freed.
    If a GenericObject is still allocated when the MiniportHaltEx exits, then the rule will fail. 
    
    Related Rule:

Help Link:

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

--*/




#include "slic_base.h"

state{
   enum {initial, set, not_set} s = initial;
}
watch NdisAllocateGenericObject.exit.$return;

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

NdisFreeGenericObject.exit[guard $1]
{
    if ( s == not_set)
    {
        abort "Freeing a generic object that was not allocated.";
    }
  
    s = not_set;
}

[sdv_MINIPORT_HALT,
sdv_FILTER_DETACH,
sdv_PROTOCOL_UNBIND_ADAPTER_EX].exit
{
    if (s == set) 
    {
        abort "You are halting the miniport but still have some generic object allocated.";
    }
}
