Reporting Device Failures
There are three ways to report device failures:
When returning from device object callback functions, the driver can supply a return value for which NT_SUCCESS(status) equals FALSE.
The driver can call WdfDeviceSetFailed.
When returning from its EvtDriverDeviceAdd callback routine, a function driver can supply a return value for which NT_SUCCESS(status) equals FALSE. If a driver that is installed as a filter fails EvtDriverDeviceAdd, the operating system skips the filter device object and does not indicate a PnP error.
Each of the above methods results in the framework effectively removing the device. If the device's drivers are not supporting other devices on the system, the I/O manager unloads the drivers.
If a driver's device object callback function returns a value for which NT_SUCCESS(status) equals FALSE, the framework notifies the PnP manager, which then attempts to restart the device by requesting the bus driver to reenumerate its devices. Your driver will be reloaded, if it was unloaded.
If your driver calls WdfDeviceSetFailed, it supplies an input argument that determines whether the device will be restarted. The argument values are WdfDeviceFailedAttemptRestart and WdfDeviceFailedNoRestart.
UMDF Before UMDF 2.15 a UMDF driver must set this value to WdfDeviceFailedNoRestart. Starting in UMDF version 2.15, a UMDF driver can request that the underlying bus driver re-enumerate it by calling WdfDeviceSetFailed with FailedAction set to WdfDeviceFailedAttemptRestart. For more information, see WdfDeviceSetFailed.
For more information about these argument values, see WDF_DEVICE_FAILED_ACTION. Before a driver's device object callback function returns with a value for which NT_SUCCESS(status) equals FALSE, the callback function can prevent restarts by calling WdfDeviceSetFailed with an input argument of WdfDeviceFailedNoRestart. Otherwise, these callback functions do not have to call WdfDeviceSetFailed.
If, within a short period of time, several consecutive restart attempts fail (because the restarted driver again reports an error), the framework stops trying to restart the device.
If a bus driver's EvtDeviceD0Entry function returns a value for which NT_SUCCESS(status) equals FALSE, the framework might still call the EvtDeviceD0Entry functions of drivers associated with the bus driver's child devices.