您的设备不见了。您的驱动程序应该做什么?
用户从系统中移除设备而不通知操作系统准备移除的设备的操作称为意外删除。发生这种情况时,PnP 管理器将一个意外删除 IRP (IRP_MN_SURPRISE_REMOVAL) 发送到设备的驱动程序。
如果您的驱动程序注册设备接口或 Windows 管理规范 (WMI),那么它必须在其意外删除处理程序中正确地处理意外删除和清除。为什么?设备接口和 WMI 都使用设备实例路径作为创建唯一标识符的方法。如果在存在未决的文件句柄时设备被意外删除,那么设备保持意外删除状态,直到句柄被关闭。当设备被再次枚举时,它将拥有与第一个实例相同的实例路径。如果第一个实例仍然处于意外删除状态,那么实例路径不再唯一,并且设备接口或 WMI 的注册将会失败。
您应该做什么?
| • | 在驱动程序的意外删除 IRP 处理程序 (IRP_MN_SURPRISE_REMOVAL) 中,将所有设备接口状态设置为 FALSE 并从 WMI 取消注册。只有在接收到删除设备 IRP (IRP_MN_REMOVE_DEVICE) 后才能延迟这些操作。 |
| • | 请记住,您的驱动程序可以接收一个删除设备 IRP 而无需以前的意外删除 IRP,因此也可以在您的删除设备处理程序中执行这些操作。 |
下面的伪代码显示如何实现这个技巧:
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; } … }更多信息:
“设置与删除相关的设备功能”(在
“针对意外删除的硬件设计”中)
Windows XP 和硬件的意外删除
Windows DDK:
处理 IRP_MN_SURPRISE_REMOVAL 请求