1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
use core::mem; use uefi::Handle; use uefi::boot::LocateSearchType; use uefi::guid::Guid; use uefi::status::Result; use crate::system_table; pub trait Protocol<T: 'static> { fn guid() -> Guid; fn new(fs: &'static mut T) -> Self where Self: Sized; fn locate_protocol() -> Result<Self> where Self: Sized { let guid = Self::guid(); let mut interface = 0; (system_table().BootServices.LocateProtocol)(&guid, 0, &mut interface)?; Ok(Self::new(unsafe { &mut *(interface as *mut T) })) } fn handle_protocol(handle: Handle) -> Result<Self> where Self: Sized { let guid = Self::guid(); let mut interface = 0; (system_table().BootServices.HandleProtocol)(handle, &guid, &mut interface)?; Ok(Self::new(unsafe { &mut *(interface as *mut T) })) } fn locate_handle() -> Result<Vec<Self>> where Self: Sized { let guid = Self::guid(); let mut handles = Vec::with_capacity(256); let mut len = handles.capacity() * mem::size_of::<Handle>(); (system_table().BootServices.LocateHandle)(LocateSearchType::ByProtocol, &guid, 0, &mut len, handles.as_mut_ptr())?; unsafe { handles.set_len(len / mem::size_of::<Handle>()); } let mut instances = Vec::new(); for handle in handles { if let Ok(instance) = Self::handle_protocol(handle) { instances.push(instance); } } Ok(instances) } fn one() -> Result<Self> where Self: Sized { Self::locate_protocol() } fn all() -> Vec<Self> where Self: Sized { Self::locate_handle().unwrap_or(Vec::new()) } }