/*++

    Copyright (c) Microsoft Corporation.  All rights reserved.

Rule Name:

    UsbDeviceCreateFail

Domain:

    wdf

Rule ID:

    Not Applicable

Description:

   This rule verifies that the driver returns from EVT_WDF_DEVICE_PREPARE_HARDWARE
   with an error status if creation of a WDFUSBDEVICE fails.

    If the driver calls the WdfUsbTargetDeviceCreate DDI in 
    EvtDevicePrepareHardware, the driver is a USB driver. In order to perform 
    any usb specific operations, the creation of a WDFUSBDEVICE must have been successful.
    Hence, if this step fails and the driver does not report an error, the driver 
    has a defect.
    
    Rule diagnostics:
    If EVT_WDF_DEVICE_PREPARE_HARDWARE returns a success status while WdfUsbTargetDeviceCreate
    returns a failure, this rule reports a defect.


Help Link:

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

--*/




#include "slic_base.h"

state
{
    enum {CALLED, NOTCALLED} usbDevCreate=NOTCALLED;
}

select one 
{
  case fun_WDF_DEVICE_PREPARE_HARDWARE:
         [sdv_WdfUsbTargetDeviceCreate,
          WdfUsbTargetDeviceCreateWithParameters].entry
         {
	     usbDevCreate=CALLED;
	 }
		 
	 [sdv_WdfUsbTargetDeviceCreate,
      WdfUsbTargetDeviceCreateWithParameters].exit
         {
             if (NT_SUCCESS($return))
	     {
	         halt;
	     }
         } 
	 fun_WDF_DEVICE_PREPARE_HARDWARE.exit
	 { 
             if (NT_SUCCESS($return) && usbDevCreate==CALLED)
	     {
	         abort "$fname returning SUCCESS status while WDFUSBDEVICE creation failed.";
	     }
             else
             {
                 halt;
             }
	 }
} 
