mirror of
https://github.com/edera-dev/sprout.git
synced 2025-12-19 21:20:17 +00:00
improve filesystem device match to support uuids and add early splash
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
use crate::context::SproutContext;
|
||||
use crate::utils;
|
||||
use anyhow::{Context, Result};
|
||||
use anyhow::{Context, Result, anyhow, bail};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
use uefi::CString16;
|
||||
use std::str::FromStr;
|
||||
use uefi::fs::{FileSystem, Path};
|
||||
use uefi::proto::device_path::DevicePath;
|
||||
use uefi::proto::media::file::{File, FileSystemVolumeLabel};
|
||||
use uefi::proto::media::fs::SimpleFileSystem;
|
||||
use uefi::proto::media::partition::PartitionInfo;
|
||||
use uefi::{CString16, Guid};
|
||||
use uefi_raw::Status;
|
||||
|
||||
#[derive(Serialize, Deserialize, Default, Clone)]
|
||||
pub struct FilesystemDeviceMatchExtractor {
|
||||
@@ -16,6 +19,10 @@ pub struct FilesystemDeviceMatchExtractor {
|
||||
pub has_label: Option<String>,
|
||||
#[serde(default, rename = "has-item")]
|
||||
pub has_item: Option<String>,
|
||||
#[serde(default, rename = "has-partition-uuid")]
|
||||
pub has_partition_uuid: Option<String>,
|
||||
#[serde(default)]
|
||||
pub fallback: Option<String>,
|
||||
}
|
||||
|
||||
pub fn extract(
|
||||
@@ -25,6 +32,44 @@ pub fn extract(
|
||||
let handles = uefi::boot::find_handles::<SimpleFileSystem>()
|
||||
.context("failed to find filesystem handles")?;
|
||||
for handle in handles {
|
||||
let mut has_match = false;
|
||||
|
||||
let partition_uuid = {
|
||||
let partition_info = uefi::boot::open_protocol_exclusive::<PartitionInfo>(handle);
|
||||
|
||||
match partition_info {
|
||||
Ok(partition_info) => {
|
||||
if let Some(gpt) = partition_info.gpt_partition_entry() {
|
||||
let uuid = gpt.unique_partition_guid;
|
||||
Some(uuid)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
Err(error) => {
|
||||
if error.status() == Status::NOT_FOUND || error.status() == Status::UNSUPPORTED
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Err(error).context("failed to open filesystem partition info")?;
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(partition_uuid) = partition_uuid
|
||||
&& let Some(ref has_partition_uuid) = extractor.has_partition_uuid
|
||||
{
|
||||
let parsed_uuid = Guid::from_str(has_partition_uuid)
|
||||
.map_err(|e| anyhow!("failed to parse has-uuid: {}", e))?;
|
||||
if partition_uuid != parsed_uuid {
|
||||
continue;
|
||||
}
|
||||
has_match = true;
|
||||
}
|
||||
|
||||
let mut filesystem = uefi::boot::open_protocol_exclusive::<SimpleFileSystem>(handle)
|
||||
.context("failed to open filesystem protocol")?;
|
||||
|
||||
@@ -41,6 +86,7 @@ pub fn extract(
|
||||
if label.volume_label() != want_label {
|
||||
continue;
|
||||
}
|
||||
has_match = true;
|
||||
}
|
||||
|
||||
if let Some(ref item) = extractor.has_item {
|
||||
@@ -57,6 +103,11 @@ pub fn extract(
|
||||
if !(metadata.is_directory() || metadata.is_regular_file()) {
|
||||
continue;
|
||||
}
|
||||
has_match = true;
|
||||
}
|
||||
|
||||
if !has_match {
|
||||
continue;
|
||||
}
|
||||
|
||||
let path = uefi::boot::open_protocol_exclusive::<DevicePath>(handle)
|
||||
@@ -64,5 +115,9 @@ pub fn extract(
|
||||
let path = path.deref();
|
||||
return utils::device_path_root(path).context("failed to get device path root");
|
||||
}
|
||||
Ok(String::new())
|
||||
|
||||
if let Some(fallback) = &extractor.fallback {
|
||||
return Ok(fallback.clone());
|
||||
}
|
||||
bail!("unable to find matching filesystem")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user