Surprise! Your device is gone. What should your driver do
Surprise removal occurs when the user removes a device from the system without notifying the operating system to prepare the device for removal. When this happens, the PnP Manager sends a surprise-remove IRP (IRP_MN_SURPRISE_REMOVAL) to the driver for the device.
If your driver registers for device interfaces or Windows Management Instrumentation (WMI), it must handle surprise removal and clean up properly in its surprise-remove handler. Why? Device interfaces and WMI both use the device instance path as a way to create a unique identifier. If your device is surprise-removed while there is an outstanding file handle, the device remains in the surprise-removed state until the handle is closed. When the device is enumerated again, it will have the same instance path as the first instance. If the first instance is still in the surprise-removed state, the instance path is no longer unique and registration of a device interface or WMI will fail.
What should you do?
- In your driver's surprise-remove IRP handler (IRP_MN_SURPRISE_REMOVAL), set all of your device interface states to FALSE and deregister from WMI. Do not postpone these actions until you receive a remove-device IRP (IRP_MN_REMOVE_DEVICE).
- Remember that your driver can receive a remove-device IRP without a previous surprise-remove IRP, so perform these actions in your remove-device handler as well.
The following pseudocode shows how to implement this tip:
DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension
…
switch(minorFunction) {
case IRP_MN_SURPRISE_REMOVAL:
IoSetDeviceInterfaceState(&pDevExt->InterfaceLink, FALSE);
IoWMIRegistrationControl(DeviceObject, WMI_ACTION_DEREGISTER);
pDevExt->SurpriseRemoved = TRUE;
…
break;
case IRP_MN_REMOVE_DEVICE:
if (pDevExt->SurpriseRemoved == FALSE) {
IoSetDeviceInterfaceState(&pDevExt->InterfaceLink, FALSE);
IoWMIRegistrationControl(DeviceObject, WMI_ACTION_DEREGISTER);
}
RtlFreeUnicodeString(&pDevExt->InterfaceLink);
…
break;
}
…
}
For more information:
Setting Removal-Related Device Capabilities" in Hardware Design for Surprise Removal