use std::{io, io::Read};
use zerocopy::{Immutable, IntoBytes, KnownLayout, LittleEndian, TryFromBytes, U16, U32};
use super::signature::DosSignature;
#[doc(alias("IMAGE_DOS_HEADER"))]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Immutable, IntoBytes, KnownLayout, TryFromBytes)]
#[repr(C)]
pub struct DosHeader {
#[doc(alias("e_magic"))]
signature: DosSignature,
#[doc(alias("e_cblp"))]
bytes_on_last_page: U16<LittleEndian>,
#[doc(alias("e_cp"))]
pages_in_file: U16<LittleEndian>,
#[doc(alias("e_crlc"))]
relocations: U16<LittleEndian>,
#[doc(alias("e_cparhdr"))]
size_of_header_in_paragraphs: U16<LittleEndian>,
#[doc(alias("e_minalloc"))]
minimum_extra_paragraphs_needed: U16<LittleEndian>,
#[doc(alias("e_maxalloc"))]
maximum_extra_paragraphs_needed: U16<LittleEndian>,
#[doc(alias("e_ss"))]
initial_relative_ss: U16<LittleEndian>,
#[doc(alias("e_sp"))]
initial_sp: U16<LittleEndian>,
#[doc(alias("e_csum"))]
checksum: U16<LittleEndian>,
#[doc(alias("e_ip"))]
initial_ip: U16<LittleEndian>,
#[doc(alias("e_cs"))]
initial_relative_cs: U16<LittleEndian>,
#[doc(alias("e_lfarlc"))]
file_address_of_relocation_table: U16<LittleEndian>,
#[doc(alias("e_ovno"))]
overlay_number: U16<LittleEndian>,
#[doc(alias("e_res"))]
reserved: [U16<LittleEndian>; 4],
#[doc(alias("e_oemid"))]
oem_id: U16<LittleEndian>,
#[doc(alias("e_oeminfo"))]
oem_info: U16<LittleEndian>,
#[doc(alias("e_res2"))]
reserved2: [U16<LittleEndian>; 10],
#[doc(alias("e_lfanew"))]
pe_pointer: U32<LittleEndian>,
}
impl DosHeader {
pub fn try_read_from_io<R>(mut src: R) -> io::Result<Self>
where
Self: Sized,
R: Read,
{
let mut buf = [0; size_of::<Self>()];
src.read_exact(&mut buf)?;
Self::try_read_from_bytes(&buf)
.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err.to_string()))
}
#[inline]
pub const fn bytes_on_last_page(&self) -> u16 {
self.bytes_on_last_page.get()
}
#[inline]
pub const fn pages_in_file(&self) -> u16 {
self.pages_in_file.get()
}
#[inline]
pub const fn relocations(&self) -> u16 {
self.relocations.get()
}
#[inline]
pub const fn size_of_header_in_paragraphs(&self) -> u16 {
self.size_of_header_in_paragraphs.get()
}
#[inline]
pub const fn minimum_extra_paragraphs_needed(&self) -> u16 {
self.minimum_extra_paragraphs_needed.get()
}
#[inline]
pub const fn maximum_extra_paragraphs_needed(&self) -> u16 {
self.maximum_extra_paragraphs_needed.get()
}
#[inline]
pub const fn initial_relative_ss(&self) -> u16 {
self.initial_relative_ss.get()
}
#[inline]
pub const fn initial_sp(&self) -> u16 {
self.initial_sp.get()
}
#[inline]
pub const fn checksum(&self) -> u16 {
self.checksum.get()
}
#[inline]
pub const fn initial_ip(&self) -> u16 {
self.initial_ip.get()
}
#[inline]
pub const fn initial_relative_cs(&self) -> u16 {
self.initial_relative_cs.get()
}
#[inline]
pub const fn file_address_of_relocation_table(&self) -> u16 {
self.file_address_of_relocation_table.get()
}
#[inline]
pub const fn overlay_number(&self) -> u16 {
self.overlay_number.get()
}
#[inline]
pub const fn oem_id(&self) -> u16 {
self.oem_id.get()
}
#[inline]
pub const fn oem_info(&self) -> u16 {
self.oem_info.get()
}
#[inline]
pub const fn pe_pointer(&self) -> u32 {
self.pe_pointer.get()
}
}