Windows storage classification / stop rawdogging NVMes on Microsoft pp #7

Open
opened 2026-05-14 19:19:55 +00:00 by vxfemboy · 0 comments
vxfemboy commented 2026-05-14 19:19:55 +00:00 (Migrated from github.com)

why Windows users keep killing their SSDs

On Linux and macOS, wipedicks actually knows what it's plowing into. Linux reads /sys/class/block/<dev>/queue/rotational; macOS shells out to diskutil info -plist and parses the SolidState key. Both refuse to multi-pass overwrite SSDs/NVMes — because flash storage doesn't enjoy repeat performances. The Flash Translation Layer remaps your writes to fresh NAND, your "secure overwrite" leaves the original data sitting smug in over-provisioned cells, and every pass burns program/erase cycles off the drive's lifespan.

On Windows it's the bad old days. drive::classify returns DriveKind::Unknown for everything, drive::resolve_block_device returns None, and the tool happily blasts an NVMe like a $5 hooker. No refusal. No warning. No mercy. Some poor Windows user is out there grinding their Samsung 990 Pro into dust thinking they're being safe.

What Needs Penetrating

Two functions in src/drive.rs need real Windows implementations. They currently live in the #[cfg(not(any(target_os = "linux", target_os = "macos")))] fallback bunkers:

  1. resolve_block_device(path) — map a file path to its underlying physical disk so the SSD check has something to slap.
  2. classify(dev_path) — return DriveKind::Nvme / Sata / Rotational / Unknown for that disk.

Two Positions to Try (Pick One)

Position A: Shell Out to PowerShell (basic missionary, no new deps)

Get-PhysicalDisk | Select-Object FriendlyName, MediaType, BusType | ConvertTo-Json

Returns MediaType (SSD / HDD / Unspecified) and BusType (NVMe / SATA / SAS / ...). Resolve a path's drive letter via Get-Partition / Get-Disk. Parse the JSON, classify, done. Matches what drive.rs already does for macOS — shells out to diskutil. Consistent, lazy in the best way.

Position B: Native DeviceIoControl (the hard way, no protection)

DeviceIoControl(IOCTL_STORAGE_QUERY_PROPERTY, ...) with:

  • StorageDeviceSeekPenaltyProperty → the IncursSeekPenalty bit tells you HDD vs SSD
  • StorageAdapterPropertyBusType distinguishes NVMe from SATA

Pulls in the windows-sys crate but means no PowerShell process at runtime. Faster, more "real Rust", more code.

Either's fine. The project already shells out to diskutil / nvme / hdparm on other platforms, so Option A is the consistent first pass and probably what should land.

Acceptance Criteria (How You Know You Finished)

  • Pointing wipedicks at an NVMe physical drive on Windows (\\.\PhysicalDrive0 and friends) refuses with the same tone as Linux/NVMe — explain FTL + PE wear, point user at the right native tool. Windows doesn't have a single canonical cryptographic-erase command; mentioning vendor tools (Samsung Magician, Intel SSD Toolbox, etc.) and ATA Secure Erase is the right move. cipher /w:C:\ is NOT the answer (it's another overwrite, equally useless on flash).
  • A file living on an SSD triggers the one-time "file-on-flash" warning (warn_file_on_flash in drive.rs).
  • Spinning rust (MediaType: HDD, BusType: SATA, IncursSeekPenalty: true) proceeds without ceremony.
  • The Windows job in .github/workflows/ci.yml stays green — fmt + clippy + build + test.
  • The #[cfg_attr(not(any(target_os = "linux", target_os = "macos")), allow(dead_code))] line on DriveKind in drive.rs gets removed, because every variant is now actually constructed on Windows.

Out of Scope (Save It for a Separate Fuck)

  • Implementing --secure-erase delegation on Windows. Windows doesn't have a single canonical tool — the right answer depends on the drive vendor (Samsung Magician, Intel SSD Toolbox, Kingston SSD Manager, ...). Separate issue.
  • TCG Opal / sedutil-cli on Windows. Same reason.
  • Windows path-safety refusal (we don't ass-blast C:\Windows\System32 yet because the path-safety prefix list is Unix-style). Also a separate issue if anyone's brave enough.

Reference Material

  • Existing macOS classification to copy the pattern from: src/drive.rs:127-181
  • Existing Linux classification (the more involved one): src/drive.rs:54-181
  • TODO markers: src/drive.rs:19, src/drive.rs:152, src/drive.rs:225
  • The cfg-gate that needs to come off when the variants are alive on Windows: src/drive.rs:21

Want to take a swing? Grab the issue, plow ahead, send the PR. I'll review it like a horny code-review bottom.

8====D~~~

# why Windows users keep killing their SSDs On Linux and macOS, `wipedicks` actually knows what it's plowing into. Linux reads `/sys/class/block/<dev>/queue/rotational`; macOS shells out to `diskutil info -plist` and parses the `SolidState` key. Both refuse to multi-pass overwrite SSDs/NVMes — because flash storage doesn't enjoy repeat performances. The Flash Translation Layer remaps your writes to fresh NAND, your "secure overwrite" leaves the original data sitting smug in over-provisioned cells, and every pass burns program/erase cycles off the drive's lifespan. On Windows it's the bad old days. `drive::classify` returns `DriveKind::Unknown` for everything, `drive::resolve_block_device` returns `None`, and the tool happily blasts an NVMe like a $5 hooker. No refusal. No warning. No mercy. Some poor Windows user is out there grinding their Samsung 990 Pro into dust thinking they're being safe. ## What Needs Penetrating Two functions in `src/drive.rs` need real Windows implementations. They currently live in the `#[cfg(not(any(target_os = "linux", target_os = "macos")))]` fallback bunkers: 1. **`resolve_block_device(path)`** — map a file path to its underlying physical disk so the SSD check has something to slap. 2. **`classify(dev_path)`** — return `DriveKind::Nvme` / `Sata` / `Rotational` / `Unknown` for that disk. ## Two Positions to Try (Pick One) ### Position A: Shell Out to PowerShell (basic missionary, no new deps) ```powershell Get-PhysicalDisk | Select-Object FriendlyName, MediaType, BusType | ConvertTo-Json ``` Returns `MediaType` (`SSD` / `HDD` / `Unspecified`) and `BusType` (`NVMe` / `SATA` / `SAS` / ...). Resolve a path's drive letter via `Get-Partition` / `Get-Disk`. Parse the JSON, classify, done. Matches what `drive.rs` already does for macOS — shells out to `diskutil`. Consistent, lazy in the best way. ### Position B: Native `DeviceIoControl` (the hard way, no protection) `DeviceIoControl(IOCTL_STORAGE_QUERY_PROPERTY, ...)` with: - `StorageDeviceSeekPenaltyProperty` → the `IncursSeekPenalty` bit tells you HDD vs SSD - `StorageAdapterProperty` → `BusType` distinguishes NVMe from SATA Pulls in the `windows-sys` crate but means no PowerShell process at runtime. Faster, more "real Rust", more code. Either's fine. The project already shells out to `diskutil` / `nvme` / `hdparm` on other platforms, so **Option A is the consistent first pass** and probably what should land. ## Acceptance Criteria (How You Know You Finished) - [ ] Pointing wipedicks at an NVMe physical drive on Windows (`\\.\PhysicalDrive0` and friends) **refuses** with the same tone as Linux/NVMe — explain FTL + PE wear, point user at the right native tool. Windows doesn't have a single canonical cryptographic-erase command; mentioning vendor tools (Samsung Magician, Intel SSD Toolbox, etc.) and ATA Secure Erase is the right move. `cipher /w:C:\` is NOT the answer (it's another overwrite, equally useless on flash). - [ ] A file living on an SSD triggers the one-time "file-on-flash" warning (`warn_file_on_flash` in `drive.rs`). - [ ] Spinning rust (`MediaType: HDD`, `BusType: SATA`, `IncursSeekPenalty: true`) proceeds without ceremony. - [ ] The Windows job in `.github/workflows/ci.yml` stays green — fmt + clippy + build + test. - [ ] The `#[cfg_attr(not(any(target_os = "linux", target_os = "macos")), allow(dead_code))]` line on `DriveKind` in `drive.rs` gets **removed**, because every variant is now actually constructed on Windows. ## Out of Scope (Save It for a Separate Fuck) - Implementing `--secure-erase` delegation on Windows. Windows doesn't have a single canonical tool — the right answer depends on the drive vendor (Samsung Magician, Intel SSD Toolbox, Kingston SSD Manager, ...). Separate issue. - TCG Opal / `sedutil-cli` on Windows. Same reason. - Windows path-safety refusal (we don't ass-blast `C:\Windows\System32` yet because the path-safety prefix list is Unix-style). Also a separate issue if anyone's brave enough. ## Reference Material - Existing macOS classification to copy the pattern from: `src/drive.rs:127-181` - Existing Linux classification (the more involved one): `src/drive.rs:54-181` - TODO markers: `src/drive.rs:19`, `src/drive.rs:152`, `src/drive.rs:225` - The cfg-gate that needs to come off when the variants are alive on Windows: `src/drive.rs:21` --- Want to take a swing? Grab the issue, plow ahead, send the PR. I'll review it like a horny code-review bottom. 8====D~~~
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
vxfemboy/wipedicks#7
No description provided.