feat(integrations): implement initial bootloader interface touchpoints

This commit is contained in:
2025-10-28 21:05:22 -04:00
parent fe714cc411
commit f82d24a206
6 changed files with 178 additions and 63 deletions

View File

@@ -4,7 +4,9 @@ use uefi::fs::{FileSystem, Path};
use uefi::proto::device_path::text::{AllowShortcuts, DevicePathFromText, DisplayOnly};
use uefi::proto::device_path::{DevicePath, PoolDevicePath};
use uefi::proto::media::fs::SimpleFileSystem;
use uefi::{CString16, Handle};
use uefi::proto::media::partition::PartitionInfo;
use uefi::{CString16, Guid, Handle};
use uefi_raw::Status;
/// Support code for the EFI framebuffer.
pub mod framebuffer;
@@ -181,3 +183,49 @@ pub fn combine_options<T: AsRef<str>>(options: impl Iterator<Item = T>) -> Strin
pub fn unique_hash(input: &str) -> String {
sha256::digest(input.as_bytes())
}
/// Represents the type of partition GUID that can be retrieved.
#[derive(PartialEq, Eq)]
pub enum PartitionGuidForm {
Partition,
PartitionType,
}
/// Retrieve the partition / partition type GUID of the device root `path`.
/// This only works on GPT partitions. If the root is not a GPT partition, None is returned.
pub fn partition_guid(path: &DevicePath, form: PartitionGuidForm) -> Result<Option<Guid>> {
// Clone the path so we can pass it to the UEFI stack.
let path = path.to_boxed();
let result = uefi::boot::locate_device_path::<PartitionInfo>(&mut &*path);
let handle = match result {
Ok(handle) => Ok(Some(handle)),
Err(error) => {
// If the error is NOT_FOUND or UNSUPPORTED, we can return None.
// These are non-fatal errors.
if error.status() == Status::NOT_FOUND || error.status() == Status::UNSUPPORTED {
Ok(None)
} else {
Err(error)
}
}
}
.context("unable to locate device path")?;
// If we have the handle, we can try to open the partition info protocol.
if let Some(handle) = handle {
// Open the partition info protocol.
let partition_info = uefi::boot::open_protocol_exclusive::<PartitionInfo>(handle)
.context("unable to open partition info protocol")?;
// Find the unique partition GUID.
// If this is not a GPT partition, this will produce None.
Ok(partition_info
.gpt_partition_entry()
.map(|entry| match form {
// Match the form of the partition GUID.
PartitionGuidForm::Partition => entry.unique_partition_guid,
PartitionGuidForm::PartitionType => entry.partition_type_guid.0,
}))
} else {
Ok(None)
}
}