Windows驱动设备移除与竞争问题
2025-06-13
0
0
对于设备的IPR回调处理函数中,对于非IRP_MN_REMOVE_DEVICE请求做引用计数
if (!((majorFunction == IRP_MJ_PNP) && (minorFunction == IRP_MN_REMOVE_DEVICE))){
IncrementPendingActionCount(parentFdoExt);
}
这样在其设备移除IRP_MN_REMOVE_DEVICE时进行
/*
* Do an extra decrement on the pendingActionCount.
* This will cause the count to eventually go to -1
* (once all IO completes),
* at which time we'll continue.
*/
DecrementPendingActionCount(parentFdoExt);
KeWaitForSingleObject( &parentFdoExt->removeEvent,
Executive,
KernelMode,
FALSE,
NULL );
其中DecrementPendingActionCount为负数时,表示所有IRP已经完成,置事件完成后的IRP_MN_REMOVE_DEVICE
VOID DecrementPendingActionCount(PPARENT_FDO_EXT parentFdoExt)
{
ASSERT(parentFdoExt->pendingActionCount >= 0);
InterlockedDecrement(&parentFdoExt->pendingActionCount);
if (parentFdoExt->pendingActionCount < 0){
/*
* All pending actions have completed and we've gotten
* the REMOVE_DEVICE IRP.
* Set the removeEvent so we'll stop waiting on REMOVE_DEVICE.
*/
ASSERT((parentFdoExt->state == STATE_REMOVING) || (parentFdoExt->state == STATE_REMOVED));
KeSetEvent(&parentFdoExt->removeEvent, 0, FALSE);
}
}
这段代码和注释解释了一种在 Windows 驱动程序开发中处理 IRP(I/O Request Packet,输入/输出请求包)时的同步机制,特别是针对 PnP(即插即用)设备移除操作(IRP_MN_REMOVE_DEVICE
)的竞态条件防护。
代码功能解析:
条件判断:
if (!((majorFunction == IRP_MJ_PNP) && (minorFunction == IRP_MN_REMOVE_DEVICE)))
这个条件检查当前 IRP 不是 PnP 的REMOVE_DEVICE
请求。如果是其他类型的 IRP(如读、写、查询等),或者虽然是 PnP IRP 但不是移除设备操作,则进入分支。
PendingActionCount 的作用:
IncrementPendingActionCount(parentFdoExt)
对设备扩展(parentFdoExt
)中的PendingActionCount
计数器进行递增。
这个计数器用于跟踪当前正在处理的、尚未完成的非移除设备操作(如读写、配置等)的数量。
注释解释的竞态条件问题:
问题场景:
- 假设一个线程正在处理普通 IRP(如读写操作),此时突然收到
REMOVE_DEVICE
请求(设备移除)。 - 如果没有
PendingActionCount
的保护,REMOVE_DEVICE
可能会直接释放设备对象(Device Object)和设备扩展(Device Extension)的内存。 - 但此时另一个线程仍在执行读写操作,访问已释放的内存,导致崩溃或数据损坏。
- 假设一个线程正在处理普通 IRP(如读写操作),此时突然收到
解决方案:
- 对于所有非移除设备的 IRP,提前递增
PendingActionCount
,表示“有一个操作正在使用设备”。 - 当
REMOVE_DEVICE
请求到达时,必须等待PendingActionCount
降为 0(即所有操作完成)才能继续移除设备。 - 这确保了设备对象和扩展在不再被使用时才被释放。
- 对于所有非移除设备的 IRP,提前递增
关键点总结:
- 同步机制:
PendingActionCount
是一个引用计数器,用于防止设备在仍有操作未完成时被意外移除。 - 移除操作的特殊性:
REMOVE_DEVICE
是唯一不需要递增此计数器的操作,因为它的执行需要依赖其他操作完成后才能继续。 - PnP 设备管理:这是 Windows 驱动模型中即插即用功能的核心安全措施之一。
这种模式在驱动程序开发中非常常见,尤其是在处理动态设备插拔和资源释放时。
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936