use gaia_binary::{LittleEndian, ReadBytesExt};
use gaia_types::GaiaError;
use serde::{Deserialize, Serialize};
use std::io::Read;
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub struct DosHeader {
pub e_magic: u16,
pub e_cblp: u16,
pub e_cp: u16,
pub e_crlc: u16,
pub e_cparhdr: u16,
pub e_min_allocate: u16,
pub e_max_allocate: u16,
pub e_ss: u16,
pub e_sp: u16,
pub e_check_sum: u16,
pub e_ip: u16,
pub e_cs: u16,
pub e_lfarlc: u16,
pub e_ovno: u16,
pub e_res: [u16; 4],
pub e_oem_id: u16,
pub e_oem_info: u16,
pub e_res2: [u16; 10],
pub e_lfanew: u32,
}
impl Default for DosHeader {
fn default() -> Self {
Self {
e_magic: 0x5A4D, e_cblp: 0x90,
e_cp: 0x03,
e_crlc: 0x00,
e_cparhdr: 0x04,
e_min_allocate: 0x00,
e_max_allocate: 0xFFFF,
e_ss: 0x00,
e_sp: 0xB8,
e_check_sum: 0x00,
e_ip: 0x00,
e_cs: 0x00,
e_lfarlc: 0x40,
e_ovno: 0x00,
e_res: [0; 4],
e_oem_id: 0x00,
e_oem_info: 0x00,
e_res2: [0; 10],
e_lfanew: 0x80, }
}
}
impl DosHeader {
pub fn read<R: Read>(mut reader: R) -> Result<Self, GaiaError> {
let e_magic = reader.read_u16::<LittleEndian>()?;
let e_cblp = reader.read_u16::<LittleEndian>()?;
let e_cp = reader.read_u16::<LittleEndian>()?;
let e_crlc = reader.read_u16::<LittleEndian>()?;
let e_cparhdr = reader.read_u16::<LittleEndian>()?;
let e_min_allocate = reader.read_u16::<LittleEndian>()?;
let e_max_allocate = reader.read_u16::<LittleEndian>()?;
let e_ss = reader.read_u16::<LittleEndian>()?;
let e_sp = reader.read_u16::<LittleEndian>()?;
let e_check_sum = reader.read_u16::<LittleEndian>()?;
let e_ip = reader.read_u16::<LittleEndian>()?;
let e_cs = reader.read_u16::<LittleEndian>()?;
let e_lfarlc = reader.read_u16::<LittleEndian>()?;
let e_ovno = reader.read_u16::<LittleEndian>()?;
let mut e_res = [0u16; 4];
for i in 0..4 {
e_res[i] = reader.read_u16::<LittleEndian>()?;
}
let e_oem_id = reader.read_u16::<LittleEndian>()?;
let e_oem_info = reader.read_u16::<LittleEndian>()?;
let mut e_res2 = [0u16; 10];
for i in 0..10 {
e_res2[i] = reader.read_u16::<LittleEndian>()?;
}
let e_lfanew = reader.read_u32::<LittleEndian>()?;
Ok(DosHeader {
e_magic,
e_cblp,
e_cp,
e_crlc,
e_cparhdr,
e_min_allocate,
e_max_allocate,
e_ss,
e_sp,
e_check_sum,
e_ip,
e_cs,
e_lfarlc,
e_ovno,
e_res,
e_oem_id,
e_oem_info,
e_res2,
e_lfanew,
})
}
}
impl DosHeader {
pub fn new(header_offset: u32) -> Self {
Self { e_lfanew: header_offset, ..Default::default() }
}
}