/*++

    Copyright (c) Microsoft Corporation.  All rights reserved.

Rule Name:

    InitFreeDeviceCreate

Domain:

    wdf

Rule ID:

    Not Applicable

Description:

    A driver must call WdfDeviceInitFree instead of WdfDeviceCreate if an error occurs in one of the device object initialization functions 
    when allocating a WDFDEVICE_INIT stucture via WdfControlDeviceInitAllocate.

    Rule diagnostics:
    "A driver must call WdfDeviceInitFree instead of WdfDeviceCreate if an error occurs in one of the device initialization functions when 
        allocating a WDFDEVICE_INIT stucture via WdfControlDeviceInitAllocate."
 
        Related rules: InitFreeDeviceCallback,InitFreeDeviceCreate,InitFreeDeviceCreateType2,PdoInitFreeDeviceCreateType2,
    InitFreeDeviceCreateType4,PdoInitFreeDeviceCallback,PdoInitFreeDeviceCreate,PdoInitFreeDeviceCreateType4 and InitFreeDevice.  

Help Link:

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

--*/







#include "slic_base.h"

state{
     enum {FREENOTREQUIRED,FREEREQUIRED,FREECALLED} s1 = FREENOTREQUIRED;
	 
} 

watch sdv_WdfControlDeviceInitAllocate.exit.$return;


[sdv_WdfDeviceInitRegisterPnpStateChangeCallback
, sdv_WdfDeviceInitRegisterPowerStateChangeCallback
, sdv_WdfDeviceInitRegisterPowerPolicyStateChangeCallback
, sdv_WdfDeviceInitAssignName
, sdv_WdfDeviceInitAssignSDDLString
, sdv_WdfDeviceInitAssignWdmIrpPreprocessCallback
, sdv_WdfPdoInitAssignDeviceID
, sdv_WdfPdoInitAssignInstanceID
, sdv_WdfPdoInitAddHardwareID
, sdv_WdfPdoInitAddCompatibleID
, sdv_WdfPdoInitAddDeviceText
, sdv_WdfPdoInitAssignRawDevice
].exit [guard $1]
{
   if (!NT_SUCCESS($return))
   {
      s1=FREEREQUIRED;
   }
   
   
}




[sdv_WdfDeviceInitFree].entry[guard $1]
{
   if (s1==FREEREQUIRED)
   {
      s1=FREECALLED;
	  
   }
   
}

[sdv_WdfDeviceCreate].entry[guard *$1]
{
	if (s1==FREEREQUIRED||s1==FREECALLED) 
	{ 
	  abort "A driver must call WdfDeviceInitFree instead of WdfDeviceCreate if an error occurs in one of the device initialization functions when allocating a WDFDEVICE_INIT stucture via WdfControlDeviceInitAllocate.";
	}
	else
	{
		halt;
	}
	
}





 
