use std::io::{Read, Seek};
use crate::VssError;
#[derive(Debug, Clone)]
pub struct VssVolumeHeader {
pub vss_id: [u8; 16],
pub version: u32,
pub record_type: u32,
pub catalog_offset: u64,
pub max_size: u64,
pub volume_id: [u8; 16],
pub storage_volume_id: [u8; 16],
pub volume_size: u64,
}
const VSS_MAGIC_LE: [u8; 4] = [0x38, 0x08, 0x87, 0x6B]; const VSS_MAGIC_BE: [u8; 4] = [0x6B, 0x87, 0x08, 0x38];
impl VssVolumeHeader {
pub fn parse<R: Read + Seek>(reader: &mut R) -> Result<Self, VssError> {
let mut buf = [0u8; 128];
reader.read_exact(&mut buf).map_err(VssError::Io)?;
let first4: [u8; 4] = buf[0..4].try_into().unwrap();
let record_type = u32::from_le_bytes(buf[20..24].try_into().unwrap());
#[cfg(debug_assertions)]
{
eprintln!("[VSS DEBUG] First 4 bytes: {:02X?}, record_type: {:#x}", &first4, record_type);
}
let is_vss = (first4 == VSS_MAGIC_LE || first4 == VSS_MAGIC_BE) && record_type == 0x01;
if !is_vss {
return Err(VssError::InvalidSignature);
}
let vss_id: [u8; 16] = buf[0..16].try_into().unwrap();
let version = u32::from_le_bytes(buf[16..20].try_into().unwrap());
let record_type = u32::from_le_bytes(buf[20..24].try_into().unwrap());
let catalog_offset = u64::from_le_bytes(buf[48..56].try_into().unwrap());
let max_size = u64::from_le_bytes(buf[56..64].try_into().unwrap());
let volume_id: [u8; 16] = buf[64..80].try_into().unwrap();
let storage_volume_id: [u8; 16] = buf[80..96].try_into().unwrap();
Ok(Self {
vss_id,
version,
record_type,
catalog_offset,
max_size,
volume_id,
storage_volume_id,
volume_size: 0,
})
}
}