Struct mbrman::MBR

source ·
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

source

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.

source

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.

source

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
source

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
source

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.

source

pub fn is_empty(&self) -> bool

Always false: primary partitions are always counted even if they are empty.

source

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");
source

pub fn read_from<R>(reader: &mut R, sector_size: u32) -> Result<MBR>where R: Read + Seek + ?Sized,

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");
source

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.

source

pub fn write_into<W>(&mut self, writer: &mut W) -> Result<()>where W: Write + Seek + ?Sized,

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")
source

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.

source

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.

source

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.

source

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)]
);
source

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));
source

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));
source

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));
source

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
);
source

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.

source

pub fn remove(&mut self, index: usize) -> LogicalPartition

Remove a logical partition. This will remove a logical partition in the array.

Remark

This operation will decrease by one the index of every logical partition after the one that has been removed.

Panics

Panics if index is out of bounds.

Trait Implementations§

source§

impl Clone for MBR

source§

fn clone(&self) -> MBR

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for MBR

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Index<usize> for MBR

§

type Output = MBRPartitionEntry

The returned type after indexing.
source§

fn index(&self, i: usize) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
source§

impl IndexMut<usize> for MBR

source§

fn index_mut(&mut self, i: usize) -> &mut Self::Output

Performs the mutable indexing (container[index]) operation. Read more
source§

impl PartialEq<MBR> for MBR

source§

fn eq(&self, other: &MBR) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Eq for MBR

source§

impl StructuralEq for MBR

source§

impl StructuralPartialEq for MBR

Auto Trait Implementations§

§

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> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Pipe for Twhere T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R ) -> Rwhere Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R ) -> Rwhere Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.