scsi/windows: correct IOCTL_STORAGE_RESET_DEVICE to 0x002D5004

The dual-model Windows audit (Sonnet) caught that the prior 'fix' (0x002DD000)
was also wrong: that decodes to the OBSOLETE RESET_BUS code (function 0x400,
R|W access) which class drivers reject. Canonical ntddstor.h:
  IOCTL_STORAGE_RESET_DEVICE = CTL_CODE(0x2D, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS)
  = (0x2D<<16)|(1<<14)|(0x401<<2)|0 = 0x002D5004.

Only affects the best-effort drive-reset recovery path (return value is
discarded); the normal read/unlock/rip path never calls it, so this does not
change normal Windows operation. Verified correct-by-construction; the
AlignmentMask finding is deferred to rc4 (benign on USB optical bridges,
needs a real Windows SCSI-HBA rig to validate).
This commit is contained in:
Matthew Jackson
2026-06-22 15:53:45 -07:00
parent fa8913800c
commit e9108e8b6b
+9 -7
View File
@@ -214,13 +214,15 @@ impl SptiTransport {
/// Opens the device, sends IOCTL_STORAGE_RESET_DEVICE to reset
/// the USB/SCSI bus, then closes. Same concept as SG_SCSI_RESET on Linux.
pub fn reset(device: &Path) -> Result<()> {
// CTL_CODE(IOCTL_STORAGE_BASE=0x2D, 0x0400, METHOD_BUFFERED=0,
// FILE_READ_ACCESS|FILE_WRITE_ACCESS=3)
// = (0x2D<<16) | (3<<14) | (0x0400<<2) | 0 = 0x002DD000.
// The earlier literal 0x002D1004 decoded to function 0x401 with the
// access bits cleared — not IOCTL_STORAGE_RESET_DEVICE, so
// DeviceIoControl would fail ERROR_INVALID_FUNCTION instead of resetting.
const IOCTL_STORAGE_RESET_DEVICE: u32 = 0x002D_D000;
// ntddstor.h: IOCTL_STORAGE_RESET_DEVICE
// = CTL_CODE(IOCTL_STORAGE_BASE=0x2D, 0x0401, METHOD_BUFFERED=0, FILE_READ_ACCESS=1)
// = (0x2D<<16) | (1<<14) | (0x0401<<2) | 0
// = 0x002D0000 | 0x4000 | 0x1004 = 0x002D5004.
// Two earlier values were wrong: 0x002D1004 (function 0x401 but access
// bits cleared) and 0x002DD000 (function 0x400 + R|W access — that's the
// OBSOLETE RESET_BUS code class drivers reject). Both made DeviceIoControl
// fail ERROR_INVALID_FUNCTION, silently skipping the reset.
const IOCTL_STORAGE_RESET_DEVICE: u32 = 0x002D_5004;
let dev_str = device.to_str().ok_or_else(|| Error::DeviceNotFound {
path: device.display().to_string(),