设置DeviceObject的DO_DIRECT_IO标识后无法正确卸载驱动怎么解决
Windows驱动设置DO_DIRECT_IO后无法正常卸载的解决方案
DO_DIRECT_IO配置本身不会阻止设备对象的删除流程,你遇到的设备残留、驱动文件不卸载的核心原因是设备对象的内核引用计数未归零,IoDeleteDevice仅会将设备标记为待删除状态,要等所有引用释放后才会执行真正的销毁操作。你可以按照以下步骤排查修复:
- 修正Flags的赋值逻辑
你当前直接覆盖设备对象Flags的写法是错误的:DeviceObject->Flags = DO_DIRECT_IO会抹除IO管理器初始化设备时预设的其他标记位,干扰后续系统的资源清理逻辑。正确写法是按位追加标记:DeviceObject->Flags |= DO_DIRECT_IO; - 确保所有IRP处理完成再执行删除
卸载例程执行时首先要阻止新的IRP进入:在设备扩展中新增移除标记,所有新收到的IRP直接返回STATUS_DEVICE_REMOVED。同时统计当前正在处理的IRP数量,等待所有存量IRP全部完成、计数归零后再执行后续删除操作。
DO_DIRECT_IO模式下的读写IRP会关联MDL内存锁定记录,如果有未完成的挂起IRP,会持续持有设备对象的引用,导致设备无法销毁。 - 检查MDL资源泄漏
如果你自行调用IoAllocateMdl分配了MDL对象,需要先调用MmUnlockPages(如果执行过MmProbeAndLockPages),再调用IoFreeMdl释放MDL,不要依赖系统自动清理。如果是IO管理器随读写IRP传入的MDL,不需要你手动释放。 - 遵循正确的卸载流程
严格按照以下顺序执行卸载操作:- 标记设备为待移除,拒绝新IRP,等待存量IRP全部处理完成
- 调用
IoDeleteSymbolicLink删除创建的符号链接 - 若设备挂载了下层设备栈,先调用
IoDetachDevice解绑 - 最后调用
IoDeleteDevice删除设备对象
内容的提问来源于stack exchange,提问作者JsonFile191
相关产品推荐
相关产品推荐

