#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BootCodeId {
WindowsVista,
Windows7Plus,
GrubLegacy,
Grub2,
Syslinux,
AllZeros,
AllOnes,
Unknown,
}
const WINDOWS_VISTA_SIG: &[(usize, &[u8])] = &[
(0, &[0x33, 0xC0, 0x8E, 0xD0, 0xBC, 0x00, 0x7C]), (424, b"BOOTMGR"), ];
const WINDOWS7_SIG: &[(usize, &[u8])] = &[
(0, &[0x33, 0xC0, 0x8E, 0xD0, 0xBC, 0x00, 0x7C]),
(418, b"BOOTMGR"),
];
const GRUB2_SIG: &[(usize, &[u8])] = &[
(0, &[0xEB, 0x63, 0x90]), ];
const GRUB_LEGACY_SIG: &[(usize, &[u8])] = &[
(0, &[0xEB, 0x48, 0x90]), ];
const SYSLINUX_SIG: &[(usize, &[u8])] = &[(3, b"SYSLINUX")];
#[must_use]
pub fn identify(code: &[u8; 446]) -> BootCodeId {
if code.iter().all(|&b| b == 0x00) {
return BootCodeId::AllZeros;
}
if code.iter().all(|&b| b == 0xFF) {
return BootCodeId::AllOnes;
}
if matches_all(code, WINDOWS7_SIG) {
return BootCodeId::Windows7Plus;
}
if matches_all(code, WINDOWS_VISTA_SIG) {
return BootCodeId::WindowsVista;
}
if matches_all(code, SYSLINUX_SIG) {
return BootCodeId::Syslinux;
}
if matches_all(code, GRUB_LEGACY_SIG) {
return BootCodeId::GrubLegacy;
}
if matches_all(code, GRUB2_SIG) {
return BootCodeId::Grub2;
}
BootCodeId::Unknown
}
fn matches_all(code: &[u8; 446], sigs: &[(usize, &[u8])]) -> bool {
sigs.iter().all(|(offset, pattern)| {
let end = offset + pattern.len();
end <= code.len() && &code[*offset..end] == *pattern
})
}