WDF Driver crash on Create

I have a crash in my WDF driver in a stress test when I try to deref the Device Extension.
After some debugging it appears that this is caused because on thread in the stress test is unloading the driver while the other still tries to open a handle to it. The device extension is already freed up and hence the call to get the device context returns a NULL pointer.

Questions:

  1. Shouldn’t the WDF framework disallow this from happening?
  2. Is the something that I need to do in my teardown path to prevent WDF from accepting/forwarding these extra creates?

The system will not unload the driver until all of the open handles have closed. However, if you have launched a separate thread, that’s something the operating system knows nothing about. It is your responsibility to signal the thread to end and make sure it dies before the unload is allowed to complete.

Likely you need to call WdfDeviceInitSetRemoveLockOptions(DeviceInit, WDF_REMOVE_LOCK_OPTION_ACQUIRE_FOR_IO).

The remove lock is allocated as part of WDM device object extension, and has the same life span as the device object itself.

If incoming I/O is through an file handle, the open handle will prevent the device from being removed and the crash won’t happen. However, there are some ill-behaved client driver that IoCallDriver(devobj) directly without taking consideration of target device’s pnp state. To protecte from such client drivers, KMDF driver can opt-in to aquire remove lock for I/O operation.

Once opt-in, when the target device is being removed, after WDF FxDevice is deleted and device context space is NULL, as long as the ill-behave client driver has an extra reference to the WDM device object and the devobj is still valid, the remove lock remains valid with a Removed flag set. When the client driver sends any I/O request to the target driver, the driver’s IRP dispatch routine, FxDevice::DispatchWithLock, try to acquire the remove lock first. The acquire will fail with STATUS_DELETE_PENDING, and DispatchWithLock will complete the IRP without touching FxDevice, thus avoid the crash.