#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DetectedFs {
Ext,
Ntfs,
Fat,
Apfs,
LinuxSwap,
LinuxLvm,
Luks,
Xfs,
Btrfs,
ExFat,
AllZeros,
Unknown,
}
#[must_use]
pub fn detect(sector: &[u8]) -> DetectedFs {
if sector.is_empty() {
return DetectedFs::Unknown;
}
if sector.iter().all(|&b| b == 0) {
return DetectedFs::AllZeros;
}
if sector.len() >= 6 && §or[0..6] == b"LUKS\xba\xbe" {
return DetectedFs::Luks;
}
if sector.len() >= 4 && §or[0..4] == b"NXSB" {
return DetectedFs::Apfs;
}
if sector.len() >= 4 && §or[0..4] == b"XFSB" {
return DetectedFs::Xfs;
}
if sector.len() >= 11 && §or[3..11] == b"NTFS " {
return DetectedFs::Ntfs;
}
if sector.len() >= 11 && §or[3..11] == b"EXFAT " {
return DetectedFs::ExFat;
}
if sector.len() >= 11 {
let oem = §or[3..11];
if oem == b"MSDOS5.0"
|| oem == b"MSWIN4.0"
|| oem == b"MSWIN4.1"
|| oem == b"mkdosfs "
|| oem == b"FreeDOS "
{
return DetectedFs::Fat;
}
}
if sector.len() >= 1082 && sector[1080] == 0x53 && sector[1081] == 0xEF {
return DetectedFs::Ext;
}
if sector.len() >= 4096 {
if §or[4086..4096] == b"SWAPSPACE2" || §or[4086..4096] == b"PAGESPACE1" {
return DetectedFs::LinuxSwap;
}
}
if let Some(pos) = find_substr(sector, b"LABELONE") {
if pos < 512 {
return DetectedFs::LinuxLvm;
}
}
DetectedFs::Unknown
}
fn find_substr(haystack: &[u8], needle: &[u8]) -> Option<usize> {
haystack.windows(needle.len()).position(|w| w == needle)
}