24 releases (8 stable)

1.1.4 Feb 12, 2025
1.1.2 Feb 12, 2024
1.0.2 Aug 21, 2023
1.0.1 Jul 22, 2023
0.2.0 Jan 10, 2019

#50 in Filesystem

Download history 1501/week @ 2024-12-08 1813/week @ 2024-12-15 314/week @ 2024-12-22 1114/week @ 2024-12-29 2150/week @ 2025-01-05 1723/week @ 2025-01-12 990/week @ 2025-01-19 1781/week @ 2025-01-26 2494/week @ 2025-02-02 1476/week @ 2025-02-09 1843/week @ 2025-02-16 1973/week @ 2025-02-23 1997/week @ 2025-03-02 2371/week @ 2025-03-09 2203/week @ 2025-03-16 1279/week @ 2025-03-23

7,931 downloads per month
Used in 3 crates (2 directly)

MIT/Apache

78KB
1K SLoC

Rust Latest Version Rust 1.65+ License Docs.rs LOC Dependency Status

gptman

Pure Rust library to read and modify GUID partition tables.

Things you can do

  • Read/Write GPT from 512 and 4096 bytes sector size disks
  • Create a new GPT on a disk
  • Insert/delete a partition in the table
  • Align partitions automatically (to sector size)
  • Resize a partition
  • Copy/clone a partition from one disk and insert it into another
  • Change partition type
  • Fix partitions order
  • Change disk GUID
  • Change partition name
  • Change partition GUID
  • Toggle legacy BIOS bootable
  • Toggle no block IO protocol
  • Toggle required partition flag
  • Toggle attributes
  • Swap partition indexes
  • Copy/clone all partitions from one disk and insert it to another
  • Write protective MBR

Installation

Cargo.toml:

[dependencies]
gptman = "1"

Usage

Reading all the partitions of a disk:

let mut f = std::fs::File::open("tests/fixtures/disk1.img")
    .expect("could not open disk");
let gpt = gptman::GPT::find_from(&mut f)
    .expect("could not find GPT");

println!("Disk GUID: {:?}", gpt.header.disk_guid);

for (i, p) in gpt.iter() {
    if p.is_used() {
        println!("Partition #{}: type = {:?}, size = {} bytes, starting lba = {}",
            i,
            p.partition_type_guid,
            p.size().unwrap() * gpt.sector_size,
            p.starting_lba);
    }
}

Creating new partitions:

let mut f = std::fs::File::open("tests/fixtures/disk1.img")
    .expect("could not open disk");
let mut gpt = gptman::GPT::find_from(&mut f)
    .expect("could not find GPT");

let free_partition_number = gpt.iter().find(|(i, p)| p.is_unused()).map(|(i, _)| i)
    .expect("no more places available");
let size = gpt.get_maximum_partition_size()
    .expect("no more space available");
let starting_lba = gpt.find_optimal_place(size)
    .expect("could not find a place to put the partition");
let ending_lba = starting_lba + size - 1;

gpt[free_partition_number] = gptman::GPTPartitionEntry {
    partition_type_guid: [0xff; 16],
    unique_partition_guid: [0xff; 16],
    starting_lba,
    ending_lba,
    attribute_bits: 0,
    partition_name: "A Robot Named Fight!".into(),
};

Creating a new partition table with one entry that fills the entire disk:

let ss = 512;
let data = vec![0; 100 * ss as usize];
let mut cur = std::io::Cursor::new(data);
let mut gpt = gptman::GPT::new_from(&mut cur, ss as u64, [0xff; 16])
    .expect("could not create partition table");

gpt[1] = gptman::GPTPartitionEntry {
    partition_type_guid: [0xff; 16],
    unique_partition_guid: [0xff; 16],
    starting_lba: gpt.header.first_usable_lba,
    ending_lba: gpt.header.last_usable_lba,
    attribute_bits: 0,
    partition_name: "A Robot Named Fight!".into(),
};

Dependencies

~0.7–1.6MB
~37K SLoC