在以下示例中,驱动程序使用 ASSERT 宏检查驱动程序映像调试版本中的正确设备状态,但不检查同一驱动程序源的零售版本中的设备状态:
case IOCTL_WAIT_FOR_EVENT:
ASSERT((!Extension->WaitEventIrp));
Extension->WaitEventIrp = Irp;
IoMarkIrpPending(Irp);
status = STATUS_PENDING;
在调试驱动程序映像中,如果驱动程序已保留 IRP 挂起,系统将断言。 但是,在零售版本中,驱动程序不会检查此错误。 对同一 IOCTL 的两次调用会导致驱动程序失去对 IRP 的跟踪。
在多处理器系统上,此代码片段可能会导致其他问题。 假设在进入此例程时,您已拥有此 IRP 的所有权(即对其进行操作的权利)。 当例程将 Irp 指针保存在 Extension-WaitEventIrp> 的全局结构中时,另一个线程可以从该全局结构获取 IRP 地址,并在 IRP 上执行作。 为防止此问题,驱动程序应在保存 IRP 之前标记 IRP 挂起,并应同时包括对 IoMarkIrpPending 的调用和互锁序列中的分配。 取消 IRP 的例程可能也有必要。