WDM驱动StartDeviceWait规则合规:KeWaitForSingleObject替代方案咨询
解决WDM驱动StartDeviceWait规则违规问题
Static Driver Verifier提示驱动未通过StartDeviceWait规则,原因是在IRP_MN_START_DEVICE的处理上下文里调用了KeWaitForSingleObject。该规则的核心要求是:PnP启动设备的IRP处理不能阻塞,否则会导致系统PnP子系统死锁风险。
现有代码的问题点
当前Cam_Pnp处理IRP_MN_START_DEVICE时,同步调用Cam_SubmitIrpSynch下发IRP,而Cam_SubmitIrpSynch内部通过KeWaitForSingleObject等待事件触发,直接违反了StartDeviceWait规则。
替代方案:异步化IRP处理
核心思路是移除同步等待逻辑,改用完成例程异步处理后续流程,避免在PnP管理器的线程上下文里阻塞。
1. 修改IRP_MN_START_DEVICE的处理逻辑
将原同步调用替换为异步下发IRP并绑定完成例程:
case IRP_MN_START_DEVICE: IoMarkIrpPending(Irp); // 复制当前IRP栈到下一层 IoCopyCurrentIrpStackLocationToNext(Irp); // 设置完成例程,下层完成后触发后续处理 IoSetCompletionRoutine(Irp, Cam_StartDeviceCompletion, DeviceObject, TRUE, TRUE, TRUE); ntStatus = IoCallDriver(DeviceObject, Irp); // 如果下层立即完成IRP,手动触发完成例程 if (ntStatus != STATUS_PENDING) { Cam_StartDeviceCompletion(DeviceObject, Irp, DeviceObject); } // 标记IRP为Pending后返回该状态 return STATUS_PENDING;
2. 实现启动设备的完成例程
在完成例程中执行原同步逻辑里的后续操作,并最终完成IRP:
NTSTATUS Cam_StartDeviceCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) { NTSTATUS ntStatus = Irp->IoStatus.Status; PDEVICE_OBJECT devObj = (PDEVICE_OBJECT)Context; if (NT_SUCCESS(ntStatus)) { // 执行原同步逻辑里的Cam_PnpStartDevice Cam_PnpStartDevice(devObj, Irp); } // 设置IRP状态并完成请求 Irp->IoStatus.Status = ntStatus; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
3. 调整Cam_SubmitIrpSynch的使用(可选)
如果Cam_SubmitIrpSynch还要用于其他非PnP上下文场景,可以添加上下文判断,在启动设备IRP场景下禁用同步等待,或者拆分出异步版本的IRP提交函数。
规则本质说明
StartDeviceWait规则禁止在启动设备IRP上下文里等待,是因为PnP管理器处理设备启动时持有系统级PnP锁,此时阻塞会导致整个PnP子系统无法响应其他设备请求,引发系统级死锁。异步处理是唯一符合规范的解决方案。
内容的提问来源于stack exchange,提问作者Gary
相关产品推荐
相关产品推荐

