pub struct Disk<Io: BlockIo> { /* private fields */ }Expand description
Read and write GPT disk data.
The disk is accessed via an object implementing the BlockIo
trait, so all reads and writes are on block boundaries. Writes are
not guaranteed to be completed until flush is called. This
happens automatically when the Disk is dropped, but if an error
occurs at that point it will be silently ignored so it is
recommended to call flush directly before dropping the disk.
Many of the methods on Disk take a block_buf argument, which is
a mutable byte buffer with a length of at least one block. (The
read_gpt_partition_entry_array and
write_gpt_partition_entry_array methods take a larger storage
argument that is multiple blocks in size.) These buffer arguments
allow Disk to avoid doing any internal memory allocation.
§Partition entry arrays
Partition entry arrays can be read in two ways: one block at a time
with gpt_partition_entry_array_iter, or all at once with
read_gpt_partition_entry_array. The former allows a smaller
amount of memory usage bounded to the block size, while the latter
may be more efficient since all the blocks can be read at once.
Writing the array can currently only be done all at once via
write_gpt_partition_entry_array; a block-at-a-time method may be
added in the future.
Implementations§
Source§impl<Io: BlockIo> Disk<Io>
impl<Io: BlockIo> Disk<Io>
Sourcepub fn new(io: Io) -> Result<Self, DiskError<Io::Error>>
pub fn new(io: Io) -> Result<Self, DiskError<Io::Error>>
Create a Disk.
Examples found in repository?
23fn main() -> Result<(), Box<dyn error::Error>> {
24 let disk_path = env::args().nth(1).expect("one argument is required");
25 println!("opening {} for reading", disk_path);
26
27 let file = fs::File::open(disk_path)?;
28
29 let mut block_buf = vec![0u8; 512];
30
31 let block_io = BlockIoAdapter::new(file, BlockSize::BS_512);
32 let mut disk = Disk::new(block_io)?;
33
34 let primary_header = disk.read_primary_gpt_header(&mut block_buf)?;
35 println!("{}", primary_header);
36 assert!(primary_header.is_signature_valid());
37
38 let layout = primary_header.get_partition_entry_array_layout()?;
39 for entry in disk.gpt_partition_entry_array_iter(layout, &mut block_buf)? {
40 let entry = entry?;
41 if entry.is_used() {
42 println!("{}", entry);
43 }
44 }
45
46 Ok(())
47}Sourcepub fn read_primary_gpt_header(
&mut self,
block_buf: &mut [u8],
) -> Result<GptHeader, DiskError<Io::Error>>
pub fn read_primary_gpt_header( &mut self, block_buf: &mut [u8], ) -> Result<GptHeader, DiskError<Io::Error>>
Read the primary GPT header from the second block. No validation of the header is performed.
Examples found in repository?
23fn main() -> Result<(), Box<dyn error::Error>> {
24 let disk_path = env::args().nth(1).expect("one argument is required");
25 println!("opening {} for reading", disk_path);
26
27 let file = fs::File::open(disk_path)?;
28
29 let mut block_buf = vec![0u8; 512];
30
31 let block_io = BlockIoAdapter::new(file, BlockSize::BS_512);
32 let mut disk = Disk::new(block_io)?;
33
34 let primary_header = disk.read_primary_gpt_header(&mut block_buf)?;
35 println!("{}", primary_header);
36 assert!(primary_header.is_signature_valid());
37
38 let layout = primary_header.get_partition_entry_array_layout()?;
39 for entry in disk.gpt_partition_entry_array_iter(layout, &mut block_buf)? {
40 let entry = entry?;
41 if entry.is_used() {
42 println!("{}", entry);
43 }
44 }
45
46 Ok(())
47}Sourcepub fn read_secondary_gpt_header(
&mut self,
block_buf: &mut [u8],
) -> Result<GptHeader, DiskError<Io::Error>>
pub fn read_secondary_gpt_header( &mut self, block_buf: &mut [u8], ) -> Result<GptHeader, DiskError<Io::Error>>
Read the secondary GPT header from the last block. No validation of the header is performed.
block_buf is a mutable byte buffer with a length of at least one block.
Sourcepub fn read_gpt_header(
&mut self,
lba: Lba,
block_buf: &mut [u8],
) -> Result<GptHeader, DiskError<Io::Error>>
pub fn read_gpt_header( &mut self, lba: Lba, block_buf: &mut [u8], ) -> Result<GptHeader, DiskError<Io::Error>>
Read a GPT header at the given Lba. No validation of the
header is performed.
block_buf is a mutable byte buffer with a length of at least one block.
Sourcepub fn read_gpt_partition_entry_array<'buf>(
&mut self,
layout: GptPartitionEntryArrayLayout,
storage: &'buf mut [u8],
) -> Result<GptPartitionEntryArray<'buf>, DiskError<Io::Error>>
pub fn read_gpt_partition_entry_array<'buf>( &mut self, layout: GptPartitionEntryArrayLayout, storage: &'buf mut [u8], ) -> Result<GptPartitionEntryArray<'buf>, DiskError<Io::Error>>
Read the entire partition entry array. The storage buffer must
be at least layout.num_bytes_rounded_to_block in size.
Sourcepub fn write_gpt_partition_entry_array(
&mut self,
entry_array: &GptPartitionEntryArray<'_>,
) -> Result<(), DiskError<Io::Error>>
pub fn write_gpt_partition_entry_array( &mut self, entry_array: &GptPartitionEntryArray<'_>, ) -> Result<(), DiskError<Io::Error>>
Write an entire GptPartitionEntryArray to disk.
Sourcepub fn gpt_partition_entry_array_iter<'disk, 'buf>(
&'disk mut self,
layout: GptPartitionEntryArrayLayout,
block_buf: &'buf mut [u8],
) -> Result<impl Iterator<Item = Result<GptPartitionEntry, DiskError<Io::Error>>> + Captures<'disk, 'buf>, DiskError<Io::Error>>
pub fn gpt_partition_entry_array_iter<'disk, 'buf>( &'disk mut self, layout: GptPartitionEntryArrayLayout, block_buf: &'buf mut [u8], ) -> Result<impl Iterator<Item = Result<GptPartitionEntry, DiskError<Io::Error>>> + Captures<'disk, 'buf>, DiskError<Io::Error>>
Get an iterator over partition entries. The layout parameter
indicates where to read the entries from; see
GptPartitionEntryArrayLayout for more.
block_buf is a mutable byte buffer with a length of at least one block.
Examples found in repository?
23fn main() -> Result<(), Box<dyn error::Error>> {
24 let disk_path = env::args().nth(1).expect("one argument is required");
25 println!("opening {} for reading", disk_path);
26
27 let file = fs::File::open(disk_path)?;
28
29 let mut block_buf = vec![0u8; 512];
30
31 let block_io = BlockIoAdapter::new(file, BlockSize::BS_512);
32 let mut disk = Disk::new(block_io)?;
33
34 let primary_header = disk.read_primary_gpt_header(&mut block_buf)?;
35 println!("{}", primary_header);
36 assert!(primary_header.is_signature_valid());
37
38 let layout = primary_header.get_partition_entry_array_layout()?;
39 for entry in disk.gpt_partition_entry_array_iter(layout, &mut block_buf)? {
40 let entry = entry?;
41 if entry.is_used() {
42 println!("{}", entry);
43 }
44 }
45
46 Ok(())
47}Sourcepub fn write_protective_mbr(
&mut self,
block_buf: &mut [u8],
) -> Result<(), DiskError<Io::Error>>
pub fn write_protective_mbr( &mut self, block_buf: &mut [u8], ) -> Result<(), DiskError<Io::Error>>
Write a protective MBR to the first block. If the block size is bigger than the MBR, the rest of the block will be filled with zeroes.
block_buf is a mutable byte buffer with a length of at least one block.
Sourcepub fn write_mbr(
&mut self,
mbr: &MasterBootRecord,
block_buf: &mut [u8],
) -> Result<(), DiskError<Io::Error>>
pub fn write_mbr( &mut self, mbr: &MasterBootRecord, block_buf: &mut [u8], ) -> Result<(), DiskError<Io::Error>>
Write an MBR to the first block. If the block size is bigger than the MBR, the rest of the block will be filled with zeroes.
block_buf is a mutable byte buffer with a length of at least one block.
Sourcepub fn write_primary_gpt_header(
&mut self,
header: &GptHeader,
block_buf: &mut [u8],
) -> Result<(), DiskError<Io::Error>>
pub fn write_primary_gpt_header( &mut self, header: &GptHeader, block_buf: &mut [u8], ) -> Result<(), DiskError<Io::Error>>
Write the primary GPT header to the second block.
The header is written to the beginning of the block, and all remaining bytes in the block are set to zero (see Table 5-5 “GPT Header” in the UEFI Specification: “The rest of the block is reserved by UEFI and must be zero”).
block_buf is a mutable byte buffer with a length of at least one block.
Sourcepub fn write_secondary_gpt_header(
&mut self,
header: &GptHeader,
block_buf: &mut [u8],
) -> Result<(), DiskError<Io::Error>>
pub fn write_secondary_gpt_header( &mut self, header: &GptHeader, block_buf: &mut [u8], ) -> Result<(), DiskError<Io::Error>>
Write the secondary GPT header to the last block.
The header is written to the beginning of the block, and all remaining bytes in the block are set to zero (see Table 5-5 “GPT Header” in the UEFI Specification: “The rest of the block is reserved by UEFI and must be zero”).
block_buf is a mutable byte buffer with a length of at least one block.
Sourcepub fn write_gpt_header(
&mut self,
lba: Lba,
header: &GptHeader,
block_buf: &mut [u8],
) -> Result<(), DiskError<Io::Error>>
pub fn write_gpt_header( &mut self, lba: Lba, header: &GptHeader, block_buf: &mut [u8], ) -> Result<(), DiskError<Io::Error>>
Write a GptHeader to the specified Lba.
The header is written to the beginning of the block, and all remaining bytes in the block are set to zero (see Table 5-5 “GPT Header” in the UEFI Specification: “The rest of the block is reserved by UEFI and must be zero”).
block_buf is a mutable byte buffer with a length of at least one block.