win-drives 0.1.0

Low-level access to Windows physical drives and harddisk volumes via NT APIs, with no_std support
#![cfg(feature = "std")]

use win_drives::HarddiskVolume;

#[test]
fn should_enumerate_volumes() {
    for drive in HarddiskVolume::enumerate() {
        println!("{:?}", drive);
    }
}

#[test]
fn volume_zero_has_valid_geometry() {
    let vol = HarddiskVolume::open(2)
        .expect("HarddiskVolume1 not accessible (run as Admin)");

    let bps = vol.bytes_per_sector();
    assert!(bps.is_power_of_two());
    assert!(matches!(bps, 512 | 1024 | 2048 | 4096));
    assert!(vol.cylinders() > 0);
    assert!(vol.tracks_per_cylinder() > 0);
    assert!(vol.sectors_per_track() > 0);
}

#[test]
fn volume_exposes_partition_info() {
    let vol = HarddiskVolume::open(1)
        .expect("HarddiskVolume1 not accessible");

    assert!(vol.size() > 0, "volume size must be > 0");

    let style = vol.partition_info.style();
    assert!(matches!(style,
        win_drives::PartitionStyle::Mbr
        | win_drives::PartitionStyle::Gpt
        | win_drives::PartitionStyle::Raw
    ));

    assert!(vol.partition_info.starting_offset() > 0);
}

#[test]
fn volume_size_matches_partition_length() {
    let vol = HarddiskVolume::open(1).unwrap();
    assert_eq!(vol.size(), vol.partition_info.length());
    assert_eq!(
        vol.partition_info.end_offset(),
        vol.partition_info.starting_offset() + vol.partition_info.length()
    );
}

#[test]
fn can_read_first_sector_of_volume() {
    let mut vol = HarddiskVolume::open(1)
        .expect("HarddiskVolume1 not accessible");

    let mut buf = vec![0u8; vol.bytes_per_sector() as usize];
    let n = vol.read_at(0, &mut buf).expect("read failed");
    assert_eq!(n, buf.len());

    // NTFS boot sectors have the OEM ID "NTFS    " at offset 3.
    // FAT32 has "FAT32   ". exFAT has "EXFAT   ".
    // If the volume is formatted, one of these should appear.
    let oem = &buf[3..11];
    let known: &[&[u8; 8]] = &[
        b"NTFS    ",
        b"FAT32   ",
        b"FAT16   ",
        b"EXFAT   ",
        b"MSDOS5.0",
        b"MSWIN4.1",
    ];

    println!("{:?}", core::str::from_utf8(oem));

    if !known.iter().any(|k| *k == oem) {
        // Not necessarily a failure — could be RAW, a non-Windows FS, etc.
        eprintln!("unrecognized OEM ID: {:?}", oem);
    }
}

#[test]
fn can_read_at_arbitrary_sector_offset() {
    let mut vol = HarddiskVolume::open(1).unwrap();
    let sector = vol.bytes_per_sector() as u64;

    let mut buf = vec![0u8; sector as usize];
    let n = vol.read_at(sector, &mut buf).expect("read at offset 1 failed");
    assert_eq!(n, sector as usize);
}

#[test]
fn rejects_unaligned_reads() {
    let mut vol = win_drives::HarddiskVolume::open(1).unwrap();
    let mut buf = vec![0u8; vol.bytes_per_sector() as usize];

    let err = vol.read_at(0, &mut buf[1..]).unwrap_err();
    assert!(matches!(err, win_drives::DriverError::InvalidParameter));

    let mut small = [0u8; 1];
    let err = vol.read_at(0, &mut small).unwrap_err();
    assert!(matches!(err, win_drives::DriverError::InvalidParameter));
}