test(scsi/windows): cross-check all FFI structs + constants vs SDK headers
Audited every #[repr(C)] struct and IOCTL/flag constant in scsi/windows.rs against the authoritative Windows SDK headers (ntddscsi.h, winioctl.h, devioctl.h, winnt.h, fileapi.h). All correct except the already-reverted ScsiPassThroughDirect packing. Add the missing regression guards: - StoragePropertyQuery layout (STORAGE_PROPERTY_QUERY: 0/4/8, size 12). - IOCTL/flag constants, with IOCTLs asserted against an independent CTL_CODE re-derivation (not a tautological literal) so a mistyped code is caught. Validated compiling via cargo xwin check --target x86_64-pc-windows-msvc.
This commit is contained in:
@@ -686,4 +686,59 @@ mod tests {
|
|||||||
assert_eq!(offset_of!(SptwbDirect, sense), 56);
|
assert_eq!(offset_of!(SptwbDirect, sense), 56);
|
||||||
assert_eq!(size_of::<SptwbDirect>(), 56 + K_SENSE_SIZE);
|
assert_eq!(size_of::<SptwbDirect>(), 56 + K_SENSE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cross-checked against `STORAGE_PROPERTY_QUERY` (winioctl.h):
|
||||||
|
/// `STORAGE_PROPERTY_ID PropertyId; STORAGE_QUERY_TYPE QueryType;
|
||||||
|
/// BYTE AdditionalParameters[1];`. Both enums are `int`-sized (4 bytes),
|
||||||
|
/// so PropertyId@0, QueryType@4, AdditionalParameters@8, size 12.
|
||||||
|
#[test]
|
||||||
|
fn storage_property_query_matches_sdk_layout() {
|
||||||
|
use std::mem::{offset_of, size_of};
|
||||||
|
assert_eq!(offset_of!(StoragePropertyQuery, PropertyId), 0);
|
||||||
|
assert_eq!(offset_of!(StoragePropertyQuery, QueryType), 4);
|
||||||
|
assert_eq!(offset_of!(StoragePropertyQuery, AdditionalParameters), 8);
|
||||||
|
assert_eq!(size_of::<StoragePropertyQuery>(), 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cross-checked against the Windows SDK headers. Each IOCTL is asserted
|
||||||
|
/// against an INDEPENDENT re-derivation of the `CTL_CODE` macro
|
||||||
|
/// (devioctl.h: `(DeviceType<<16) | (Access<<14) | (Function<<2) | Method`),
|
||||||
|
/// not just its literal — so a mistyped constant fails the derivation, not
|
||||||
|
/// a tautology. Flag/enum values cite their defining header.
|
||||||
|
#[test]
|
||||||
|
fn windows_ffi_constants_match_sdk() {
|
||||||
|
// CTL_CODE re-derivation. FILE_DEVICE_CONTROLLER=0x4,
|
||||||
|
// FILE_DEVICE_MASS_STORAGE=0x2D, METHOD_BUFFERED=0,
|
||||||
|
// FILE_ANY_ACCESS=0, FILE_READ_ACCESS=1, FILE_WRITE_ACCESS=2.
|
||||||
|
const fn ctl_code(dev: u32, func: u32, method: u32, access: u32) -> u32 {
|
||||||
|
(dev << 16) | (access << 14) | (func << 2) | method
|
||||||
|
}
|
||||||
|
// ntddscsi.h: CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, READ|WRITE)
|
||||||
|
assert_eq!(
|
||||||
|
IOCTL_SCSI_PASS_THROUGH_DIRECT,
|
||||||
|
ctl_code(0x4, 0x405, 0, 1 | 2)
|
||||||
|
);
|
||||||
|
// winioctl.h: CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, ANY)
|
||||||
|
assert_eq!(IOCTL_STORAGE_QUERY_PROPERTY, ctl_code(0x2D, 0x500, 0, 0));
|
||||||
|
// winioctl.h: CTL_CODE(IOCTL_STORAGE_BASE, 0x0401, METHOD_BUFFERED, READ)
|
||||||
|
assert_eq!(IOCTL_STORAGE_RESET_DEVICE, ctl_code(0x2D, 0x401, 0, 1));
|
||||||
|
|
||||||
|
// winioctl.h STORAGE_PROPERTY_ID / STORAGE_QUERY_TYPE enums.
|
||||||
|
assert_eq!(STORAGE_ADAPTER_PROPERTY, 1); // StorageAdapterProperty (Device=0, Adapter=1)
|
||||||
|
assert_eq!(PROPERTY_STANDARD_QUERY, 0); // PropertyStandardQuery
|
||||||
|
|
||||||
|
// ntddscsi.h SCSI_IOCTL_DATA_*.
|
||||||
|
assert_eq!(SCSI_IOCTL_DATA_OUT, 0);
|
||||||
|
assert_eq!(SCSI_IOCTL_DATA_IN, 1);
|
||||||
|
assert_eq!(SCSI_IOCTL_DATA_UNSPECIFIED, 2);
|
||||||
|
|
||||||
|
// winnt.h GENERIC_* / FILE_SHARE_* / FILE_ATTRIBUTE_*; fileapi.h OPEN_EXISTING.
|
||||||
|
assert_eq!(GENERIC_READ, 0x8000_0000);
|
||||||
|
assert_eq!(GENERIC_WRITE, 0x4000_0000);
|
||||||
|
assert_eq!(FILE_SHARE_READ, 0x1);
|
||||||
|
assert_eq!(FILE_SHARE_WRITE, 0x2);
|
||||||
|
assert_eq!(OPEN_EXISTING, 3);
|
||||||
|
assert_eq!(FILE_ATTRIBUTE_NORMAL, 0x80);
|
||||||
|
assert_eq!(INVALID_HANDLE_VALUE, -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user