I/O 验证

驱动程序验证程序有两个级别的 I/O 验证:

  • 选择 I/O 验证时,级别 1 I/O 验证 始终处于活动状态。

  • 每当在 Windows XP 及更高版本中选择 I/O 验证时,级别 2 I/O 验证 始终处于活动状态。

另请参阅:在 Windows 7 及更高版本的 Windows 操作系统中增强的 I/O 验证,选择“I/O 验证”时,将自动激活增强的 I/O 验证。 它不可用或需要将其选为单独的选项。

级别 1 I/O 验证

启用级别 1 I/O 验证后,将从特殊池分配通过 IoAllocateIrp 获取的所有 IRP ,并跟踪其使用。

此外,驱动程序验证程序检查无效的 I/O 调用,包括:

  • 尝试释放类型不IO_TYPE_IRP的 IRP

  • 将无效设备对象传递到 IoCallDriver

  • 将 IRP 传递到 IoCompleteRequest ,其中包含无效状态或仍具有取消例程集

  • 通过调用驱动程序调度例程更改 IRQL

  • 尝试释放与线程关联的 IRP

  • 将设备对象传递给已包含已初始化计时器的 IoInitializeTimer

  • 将无效缓冲区传递到 IoBuildAsynchronousFsdRequestIoBuildDeviceIoControlRequest

  • 将 I/O 状态块传递到 IRP,当此 I/O 状态块在已取消部署太远的堆栈上分配时

  • 将事件对象传递到 IRP,当此事件对象在已取消部署太远的堆栈上分配时

由于特殊 IRP 池的大小有限,因此 I/O 验证在一次仅在一个驱动程序上使用时最有效。

I/O 验证级别 1 失败会导致发出 bug 检查0xC9。 此 bug 检查的第一个参数指示发生了冲突。 有关完整参数列表,请参阅 Bug 检查0xC9 (DRIVER_VERIFIER_IOMANAGER_VIOLATION)。

级别 2 I/O 验证

I/O 验证级别 2 错误以不同的方式显示:在蓝屏、故障转储文件中和内核调试器中。

在蓝屏上,这些错误由消息 IO 系统验证错误和字符串 WDM DRIVER ERRORXXX 指出,其中 XXX 是 I/O 错误代码。

在故障转储文件中,大多数错误都由 消息 BugCheck 0xC9(DRIVER_VERIFIER_IOMANAGER_VIOLATION)以及 I/O 错误代码记录。 在这种情况下,I/O 错误代码显示为 bug 检查的第一个参数0xC9。 其余部分由消息 Bug 检查0xC4(DRIVER_VERIFIER_DETECTED_VIOLATION)以及驱动程序验证程序错误代码记录。 在这种情况下,驱动程序验证程序错误代码显示为 bug 检查的第一个参数0xC4。

在内核调试器(KD 或 WinDbg)中,这些错误由消息 WDM DRIVER ERROR 和描述性文本字符串记录。 当内核调试器处于活动状态时,可以忽略级别 2 错误并恢复系统操作。 (无法进行任何其他 bug 检查。

蓝屏、故障转储文件和内核调试器也显示其他信息。 有关大多数 I/O 验证级别 2 错误消息的完整说明,请参阅 bug 检查0xC9。 有关其余部分,请参阅 bug 检查0xC4

从 Window Vista 开始,I/O 验证选项将检查以下驱动程序错误:

从 Windows 7 开始,I/O 验证选项将检查以下驱动程序错误:

  • 尝试通过调用 ExFreePool 来释放 IRP。 必须使用 IoFreeIrp 释放 IRP

此外,可以使用此选项检测另一个常见的驱动程序 bug - 重新初始化删除锁。 删除锁数据结构应在设备扩展内分配。 这可确保 I/O 管理器仅在删除设备对象时释放保存IO_REMOVE_LOCK结构的内存。 如果驱动程序执行以下三个步骤,那么在步骤 2 之后,应用程序或驱动程序仍保留对 Device1 的引用:

在步骤 2 之后,应用程序或驱动程序仍保留对 Device1 的引用。 即使删除了此设备,应用程序或驱动程序仍可将请求发送到 Device1。 因此,在 I/O 管理器删除 Device1 之前,重复使用与新删除锁相同的内存是不安全的。 当另一个线程尝试获取锁时重新初始化同一锁可能会导致锁损坏,驱动程序和整个系统的结果不可预知。

在 Windows 7 及更高版本的 Windows 操作系统中,选择“I/O 验证”时, 将自动激活增强的 I/O 验证

激活此选项

可以使用驱动程序验证程序管理器或Verifier.exe命令行为一个或多个驱动程序激活 I/O 验证功能。 有关详细信息,请参阅 “选择驱动程序验证程序选项”。

  • 在命令行。

    在命令行中,I/O 验证选项由 位 4 (0x10) 表示。 若要激活 I/O 验证,请使用标志值0x10或向标志值添加0x10。 例如:

    verifier /flags 0x10 /driver MyDriver.sys
    

    下一次启动后,该功能将处于活动状态。

    还可以通过将 /volatile 参数添加到命令来激活和停用 I/O 验证,而无需重新启动计算机。 例如:

    verifier /volatile /flags 0x10 /adddriver MyDriver.sys
    

    此设置立即生效,但在关闭或重新启动计算机时会丢失。 有关详细信息,请参阅 “使用易失性设置”。

    标准设置中还包括 I/O 验证功能。 例如:

    verifier /standard /driver MyDriver.sys
    
  • 使用驱动程序验证程序管理器

    1. 选择“ 创建自定义设置”(面向代码开发人员), 然后单击“ 下一步”。
    2. 从完整列表中选择单个设置。
    3. 选择(检查) I/O 验证

    标准设置中还包括 I/O 验证功能。 若要使用此功能,请在驱动程序验证程序管理器中,单击“ 创建标准设置”。