pub struct MBR {
pub sector_size: u32,
pub header: MBRHeader,
pub logical_partitions: Vec<LogicalPartition>,
pub align: u32,
pub cylinders: u16,
pub heads: u8,
pub sectors: u8,
pub disk_size: u32,
}
Expand description
A type representing a MBR partition table including its partition, the sector size of the disk and the alignment of the partitions to the sectors.
§Examples:
Read an existing MBR on a reader and list its partitions:
let mut f = std::fs::File::open("tests/fixtures/disk1.img")
.expect("could not open disk");
let mbr = mbrman::MBR::read_from(&mut f, 512)
.expect("could not find MBR");
println!("Disk signature: {:?}", mbr.header.disk_signature);
for (i, p) in mbr.iter() {
if p.is_used() {
println!("Partition #{}: type = {:?}, size = {} bytes, starting lba = {}",
i,
p.sys,
p.sectors * mbr.sector_size,
p.starting_lba);
}
}
Fields§
§sector_size: u32
Sector size of the disk.
You should not change this, otherwise the starting locations of your partitions will be different in bytes.
header: MBRHeader
MBR partition header (disk GUID, first/last usable LBA, etc…)
logical_partitions: Vec<LogicalPartition>
A vector with all the logical partitions. You can push new ones (even empty ones)
align: u32
Partitions alignment (in sectors)
This field change the behavior of the methods get_maximum_partition_size()
,
find_free_sectors()
, find_first_place()
, find_last_place()
and find_optimal_place()
so they return only values aligned to the alignment.
§Panics
The value must be greater than 0, otherwise you will encounter divisions by zero.
cylinders: u16
Disk geometry: number of cylinders
heads: u8
Disk geometry: number of heads
sectors: u8
Disk geometry: number of sectors
disk_size: u32
Disk size in sectors
Implementations§
source§impl MBR
impl MBR
sourcepub fn iter(&self) -> impl Iterator<Item = (usize, &MBRPartitionEntry)>
pub fn iter(&self) -> impl Iterator<Item = (usize, &MBRPartitionEntry)>
Get an iterator over the partition entries and their index. The index always starts at 1.
sourcepub fn iter_mut(
&mut self,
) -> impl Iterator<Item = (usize, &mut MBRPartitionEntry)>
pub fn iter_mut( &mut self, ) -> impl Iterator<Item = (usize, &mut MBRPartitionEntry)>
Get a mutable iterator over the partition entries and their index. The index always starts at 1.
sourcepub fn get(&self, i: usize) -> Option<&MBRPartitionEntry>
pub fn get(&self, i: usize) -> Option<&MBRPartitionEntry>
Get Some(&MBRPartitionEntry)
if it exists, None otherwise.
§Remarks
- The partitions start at index 1
- The first 4 partitions always exist
sourcepub fn get_mut(&mut self, i: usize) -> Option<&mut MBRPartitionEntry>
pub fn get_mut(&mut self, i: usize) -> Option<&mut MBRPartitionEntry>
Get Some(&mut MBRPartitionEntry)
if it exists, None otherwise.
§Remarks
- The partitions start at index 1
- The first 4 partitions always exist
sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
The total number of partitions on the disk: primary partitions and logical partitions.
§Remark
The primary partitions are always counted even if they are empty.
sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Always false: primary partitions are always counted even if they are empty.
sourcepub fn new_from<S>(
seeker: &mut S,
sector_size: u32,
disk_signature: [u8; 4],
) -> Result<MBR>where
S: Seek,
pub fn new_from<S>(
seeker: &mut S,
sector_size: u32,
disk_signature: [u8; 4],
) -> Result<MBR>where
S: Seek,
Make a new MBR
§Examples
Basic usage:
let mut f = std::fs::File::open("tests/fixtures/disk1.img")
.expect("could not open disk");
let mbr = mbrman::MBR::new_from(&mut f, 512, [0x01, 0x02, 0x03, 0x04])
.expect("could not make a partition table");
sourcepub fn read_from<R>(reader: &mut R, sector_size: u32) -> Result<MBR>
pub fn read_from<R>(reader: &mut R, sector_size: u32) -> Result<MBR>
Read the MBR on a reader.
§Examples
Basic usage:
let mut f = std::fs::File::open("tests/fixtures/disk1.img")
.expect("could not open disk");
let mbr = mbrman::MBR::read_from(&mut f, 512)
.expect("could not read the partition table");
sourcepub fn check_geometry(&self) -> bool
pub fn check_geometry(&self) -> bool
Return true
if the MBR has a valid geometry. The geometry can be set by setting
the fiels cylinders
, heads
and sectors
.
Remarks
The cylinders, heads and sectors must have a value greater than zero.
The cylinders cannot exceed 1023.
The sectors cannot exceed 63.
sourcepub fn write_into<W>(&mut self, writer: &mut W) -> Result<()>
pub fn write_into<W>(&mut self, writer: &mut W) -> Result<()>
Write the MBR to a writer. This function will seek automatically in the writer.
This function will update the CHS address of the partitions automatically if a valid
geometry has been set. See check_geometry
.
§Examples
Basic usage:
let ss = 512;
let data = vec![0; 100 * ss as usize];
let mut cur = std::io::Cursor::new(data);
let mut mbr = mbrman::MBR::new_from(&mut cur, ss as u32, [0xff; 4])
.expect("could not make a partition table");
// actually write:
mbr.write_into(&mut cur)
.expect("could not write MBR to disk")
sourcepub fn get_cylinder_size(&self) -> u32
pub fn get_cylinder_size(&self) -> u32
Get a cylinder size in sectors. This function is useful if you want to align your partitions to the cylinder.
sourcepub fn find_at_sector(&self, sector: u32) -> Option<usize>
pub fn find_at_sector(&self, sector: u32) -> Option<usize>
Finds the primary partition (ignoring extended partitions) or logical partition where the given sector resides.
sourcepub fn remove_at_sector(&mut self, sector: u32) -> Result<()>
pub fn remove_at_sector(&mut self, sector: u32) -> Result<()>
Remove a partition entry that resides at a given sector. If the partition is the extended partition, it will delete also all the logical partitions.
§Errors
It is an error to provide a sector which does not belong to a partition.
sourcepub fn find_free_sectors(&self) -> Vec<(u32, u32)>
pub fn find_free_sectors(&self) -> Vec<(u32, u32)>
Find free spots in the partition table.
This function will return a vector of tuple with on the left: the starting LBA of the free
spot; and on the right: the size (in sectors) of the free spot.
This function will automatically align with the alignment defined in the MBR
.
§Examples
Basic usage:
let ss = 512;
let data = vec![0; 100 * ss as usize];
let mut cur = std::io::Cursor::new(data);
let mut mbr = mbrman::MBR::new_from(&mut cur, ss as u32, [0xff; 4])
.expect("could not create partition table");
mbr[1] = mbrman::MBRPartitionEntry {
boot: mbrman::BOOT_INACTIVE,
first_chs: mbrman::CHS::empty(),
sys: 0x83,
last_chs: mbrman::CHS::empty(),
starting_lba: 6,
sectors: mbr.disk_size - 11,
};
// NOTE: align to the sectors, so we can use every last one of them
// NOTE: this is only for the demonstration purpose, this is not recommended
mbr.align = 1;
assert_eq!(
mbr.find_free_sectors(),
vec![(1, 5), (mbr.disk_size - 5, 5)]
);
sourcepub fn find_first_place(&self, size: u32) -> Option<u32>
pub fn find_first_place(&self, size: u32) -> Option<u32>
Find the first place (most on the left) where you could start a new partition of the size
given in parameter.
This function will automatically align with the alignment defined in the MBR
.
§Examples:
Basic usage:
let ss = 512;
let data = vec![0; 100 * ss as usize];
let mut cur = std::io::Cursor::new(data);
let mut mbr = mbrman::MBR::new_from(&mut cur, ss as u32, [0xff; 4])
.expect("could not create partition table");
mbr[1] = mbrman::MBRPartitionEntry {
boot: mbrman::BOOT_INACTIVE,
first_chs: mbrman::CHS::empty(),
sys: 0x83,
last_chs: mbrman::CHS::empty(),
starting_lba: 6,
sectors: mbr.disk_size - 6,
};
// NOTE: align to the sectors, so we can use every last one of them
// NOTE: this is only for the demonstration purpose, this is not recommended
mbr.align = 1;
assert_eq!(mbr.find_first_place(5), Some(1));
sourcepub fn find_last_place(&self, size: u32) -> Option<u32>
pub fn find_last_place(&self, size: u32) -> Option<u32>
Find the last place (most on the right) where you could start a new partition of the size
given in parameter.
This function will automatically align with the alignment defined in the MBR
.
§Examples:
Basic usage:
let ss = 512;
let data = vec![0; 100 * ss as usize];
let mut cur = std::io::Cursor::new(data);
let mut mbr = mbrman::MBR::new_from(&mut cur, ss as u32, [0xff; 4])
.expect("could not create partition table");
mbr[1] = mbrman::MBRPartitionEntry {
boot: mbrman::BOOT_INACTIVE,
first_chs: mbrman::CHS::empty(),
sys: 0x83,
last_chs: mbrman::CHS::empty(),
starting_lba: 6,
sectors: 5,
};
// NOTE: align to the sectors, so we can use every last one of them
// NOTE: this is only for the demonstration purpose, this is not recommended
mbr.align = 1;
assert_eq!(mbr.find_last_place(5), Some(mbr.disk_size - 5));
sourcepub fn find_optimal_place(&self, size: u32) -> Option<u32>
pub fn find_optimal_place(&self, size: u32) -> Option<u32>
Find the most optimal place (in the smallest free space) where you could start a new
partition of the size given in parameter.
This function will automatically align with the alignment defined in the MBR
.
§Examples:
Basic usage:
let ss = 512;
let data = vec![0; 100 * ss as usize];
let mut cur = std::io::Cursor::new(data);
let mut mbr = mbrman::MBR::new_from(&mut cur, ss as u32, [0xff; 4])
.expect("could not create partition table");
mbr[1] = mbrman::MBRPartitionEntry {
boot: mbrman::BOOT_INACTIVE,
first_chs: mbrman::CHS::empty(),
sys: 0x83,
last_chs: mbrman::CHS::empty(),
starting_lba: 11,
sectors: mbr.disk_size - 11 - 5,
};
// NOTE: align to the sectors, so we can use every last one of them
// NOTE: this is only for the demonstration purpose, this is not recommended
mbr.align = 1;
// NOTE: the space as the end is more optimal because it will allow you to still be able to
// insert a bigger partition later
assert_eq!(mbr.find_optimal_place(5), Some(mbr.disk_size - 5));
sourcepub fn get_maximum_partition_size(&self) -> Result<u32>
pub fn get_maximum_partition_size(&self) -> Result<u32>
Get the maximum size (in sectors) of a partition you could create in the MBR.
This function will automatically align with the alignment defined in the MBR
.
§Examples:
Basic usage:
let ss = 512;
let data = vec![0; 100 * ss as usize];
let mut cur = std::io::Cursor::new(data);
let mut mbr = mbrman::MBR::new_from(&mut cur, ss as u32, [0xff; 4])
.expect("could not create partition table");
// NOTE: align to the sectors, so we can use every last one of them
// NOTE: this is only for the demonstration purpose, this is not recommended
mbr.align = 1;
assert_eq!(
mbr.get_maximum_partition_size().unwrap_or(0),
mbr.disk_size - 1
);
sourcepub fn push(
&mut self,
sys: u8,
starting_lba: u32,
sectors: u32,
) -> Result<&mut LogicalPartition>
pub fn push( &mut self, sys: u8, starting_lba: u32, sectors: u32, ) -> Result<&mut LogicalPartition>
Push a new logical partition to the end of the extended partition list. This function will
take care of creating the EBR for you. The EBR will be located at starting_lba
(provided
in input) and the logical partition itself will be located a block further to stay
aligned. The size of the logical partition will be one block smaller than the sectors
provided in input.
sourcepub fn remove(&mut self, index: usize) -> LogicalPartition
pub fn remove(&mut self, index: usize) -> LogicalPartition
Trait Implementations§
impl Eq for MBR
impl StructuralPartialEq for MBR
Auto Trait Implementations§
impl Freeze for MBR
impl RefUnwindSafe for MBR
impl Send for MBR
impl Sync for MBR
impl Unpin for MBR
impl UnwindSafe for MBR
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§default unsafe fn clone_to_uninit(&self, dst: *mut T)
default unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)source§impl<T> FmtForward for T
impl<T> FmtForward for T
source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moresource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moresource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.source§impl<T> Tap for T
impl<T> Tap for T
source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read moresource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read moresource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read moresource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read moresource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read moresource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read moresource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.