SCSI 验证

驱动程序验证程序的 SCSI 验证功能监视 SCSI 微型端口驱动程序与端口驱动程序之间的交互。 如果微型端口驱动程序误用例程、错误地响应来自端口驱动程序的请求,或花费过多时间响应请求,则会发出 bug 检查。

此驱动程序验证程序选项仅在 Windows XP 及更高版本中可用。

SCSI 验证检测到的冲突

SCSI 验证选项可以检测 SCSI 例程的多次误用。 也可以单独禁用某些检查。

当 SCSI 微型端口驱动程序提交以下冲突之一时,驱动程序验证程序将发出 bug 检查 0xF1。

  • 微型端口驱动程序将错误的参数传递给 ScsiPortInitialize

  • 微型端口驱动程序调用 ScsiPortStallExecution 并指定超过 0.1 秒的延迟,从而将处理器停止过长的时间。

  • 端口驱动程序调用微型端口驱动程序例程,微型端口驱动程序执行该例程的时间超过 0.5 秒。 (FindAdapter 例程是豁免的,并且 HwInitialize 例程允许 5 秒。)

  • 微型端口驱动程序多次完成请求。

  • 微型端口驱动程序完成 SRB 状态无效的例程。

  • 微型端口驱动程序调用 ScsiPortNotification 来请求 NextLuRequest,但未标记的请求仍处于活动状态。

  • 微型端口驱动程序将无效的虚拟地址传递给 ScsiPortGetPhysicalAddress。 (这通常意味着提供的地址不会映射到公共缓冲区。)

  • 总线重置保持期结束,但微型端口驱动程序仍有未完成的请求。

有关 bug 检查参数的完整列表,请参阅 bug 检查0xF1 (SCSI_VERIFIER_DETECTED_VIOLATION) 。

除了这些冲突之外,SCSI 验证还会监视微型端口驱动程序的内存访问,以用于不当使用。 微型端口驱动程序进行的两个常见内存冲突是在请求完成后访问 SRB 扩展,以及当微型端口驱动程序未指定 MapBuffer 时访问 SRB 的 DataBuffer

此类内存冲突通常会导致发出 bug 检查0xD1 (DRIVER_IRQL_NOT_LESS_OR_EQUAL) 。

激活此选项

激活 SCSI 验证选项的过程不同于激活其他驱动程序验证程序选项的过程。

激活 SCSI 验证

  1. 使用驱动程序验证程序管理器或Verifier.exe命令行,开始验证微型端口驱动程序。 由于 SCSI 验证不能作为选项提供,因此必须至少选择一个其他驱动程序验证程序选项。 有关详细信息 ,请参阅选择驱动程序验证程序选项选择要验证的驱动程序

  2. 使用 regedit.exe 打开注册表。 在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ScsiPort 项中,添加名为 “验证程序”的子项。 在该键中,添加名为 VerifyLevel 的REG_DWORD项。 分配给此条目的值将确定哪些 SCSI 验证测试将处于活动状态。 值0x1将提供最大验证。

  3. 重新启动计算机。

如果 VerifyLevel 值不存在,或等于 0xFFFFFFFF,则将禁用 SCSI 验证。

VerifyLevel 值中的单个位可用于精确控制将执行哪些测试。 零位 (0x1) 启用某些测试;bits 28、29、30 和 31 禁用某些测试。 因此,可以使用值 0x00000001 获取最大验证。

每个位的影响如下所示:

bit 效果

0

0x1

驱动程序验证程序将监视微型端口驱动程序的内存访问,并检查内存缓冲区的不当使用。

28

0x10000000

HwAdapterControl 例程完成时间超过 0.5 秒时,驱动程序验证程序不会发出 bug 检查。

29

0x20000000

当重置保留期结束且逻辑单元上仍有未完成的请求时,驱动程序验证程序不会发出 bug 检查。

30

0x40000000

当微型端口驱动程序使用 NextLuRequest 调用 ScsiPortNotification 时,驱动程序验证程序不会发出 bug 检查,而未标记的请求仍处于活动状态。

31

0x80000000

HwInitialize 例程需要 5 秒以上才能完成时,驱动程序验证程序不会发出 bug 检查。

在大多数情况下,建议的设置是0xD0000001。 这将启用所有 SCSI 验证程序 测试,但 HwAdapterControl 上的时间限制、 HwInitialize 上的时间限制和对逻辑单元的多个请求的禁令除外。 这三个测试通常过于严格。

如果附加了内核调试器,可以在启动周期后更改 SCSI 验证级别。 为此,请使用调试器命令:

kd> ed scsiport!SpVrfyLevel Level 

此命令允许设置 Level 的新值。 使用此方法,可以随时通过0x8000000) 更改高位 (0x10000000。 但是,如果要更改低位 (0x1) ,则必须在启动过程中 (内核调试器的初始断点) 执行此操作。

同样,如果要完全停用 SCSI 验证,则需要将 “级别 ”设置为在初始断点处0xFFFFFFFF。

注意 值 0xF0000000 将禁用所有测试,但仍会加载 SCSI 验证模块。 如果希望禁用验证,但打算在以后启用高位测试,请使用此值。 另一方面,0xFFFFFFFF值会阻止完全加载模块;如果在启动期间使用此值,则无法在不重新启动的情况下启用 SCSI 验证。

在不重新启动的情况下激活

通常,如果不在任何 Windows 操作系统上重启 (“重新启动”) 计算机,则无法激活或停用 SCSI 验证。 ScsiPort.sys驱动程序仅在加载 时读取 VerifyLevel 注册表项,这通常是在启动时。 但是,如果在添加注册表项时未加载ScsiPort.sys驱动程序,或者卸载并重新加载该驱动程序,则可以在 Windows XP 和更高版本的 Windows 上启用 SCSI 验证,而无需重新启动计算机。