@@ -477,6 +477,28 @@ pub unsafe fn uninstall_protocol_interface(
477477 ( bt. uninstall_protocol_interface ) ( handle. as_ptr ( ) , protocol, interface) . to_result ( )
478478}
479479
480+ /// Get the list of protocol interface [`Guids`][Guid] that are installed
481+ /// on a [`Handle`].
482+ ///
483+ /// # Errors
484+ ///
485+ /// * [`Status::INVALID_PARAMETER`]: `handle` is invalid.
486+ /// * [`Status::OUT_OF_RESOURCES`]: out of memory.
487+ pub fn protocols_per_handle ( handle : Handle ) -> Result < ProtocolsPerHandle > {
488+ let bt = boot_services_raw_panicking ( ) ;
489+ let bt = unsafe { bt. as_ref ( ) } ;
490+
491+ let mut protocols = ptr:: null_mut ( ) ;
492+ let mut count = 0 ;
493+
494+ unsafe { ( bt. protocols_per_handle ) ( handle. as_ptr ( ) , & mut protocols, & mut count) }
495+ . to_result_with_val ( || ProtocolsPerHandle {
496+ count,
497+ protocols : NonNull :: new ( protocols)
498+ . expect ( "protocols_per_handle must not return a null pointer" ) ,
499+ } )
500+ }
501+
480502/// Returns an array of handles that support the requested protocol in a
481503/// pool-allocated buffer.
482504///
@@ -762,6 +784,38 @@ pub fn stall(microseconds: usize) {
762784 }
763785}
764786
787+ /// Protocol interface [`Guids`][Guid] that are installed on a [`Handle`] as
788+ /// returned by [`protocols_per_handle`].
789+ #[ derive( Debug ) ]
790+ pub struct ProtocolsPerHandle {
791+ protocols : NonNull < * const Guid > ,
792+ count : usize ,
793+ }
794+
795+ impl Drop for ProtocolsPerHandle {
796+ fn drop ( & mut self ) {
797+ let _ = unsafe { free_pool ( self . protocols . cast :: < u8 > ( ) ) } ;
798+ }
799+ }
800+
801+ impl Deref for ProtocolsPerHandle {
802+ type Target = [ & ' static Guid ] ;
803+
804+ fn deref ( & self ) -> & Self :: Target {
805+ let ptr: * const & ' static Guid = self . protocols . as_ptr ( ) . cast ( ) ;
806+
807+ // SAFETY:
808+ //
809+ // * The firmware is assumed to provide a correctly-aligned pointer and
810+ // array length.
811+ // * The firmware is assumed to provide valid GUID pointers.
812+ // * Protocol GUIDs should be constants or statics, so a 'static
813+ // lifetime (of the individual pointers, not the overall slice) can be
814+ // assumed.
815+ unsafe { slice:: from_raw_parts ( ptr, self . count ) }
816+ }
817+ }
818+
765819/// A buffer returned by [`locate_handle_buffer`] that contains an array of
766820/// [`Handle`]s that support the requested protocol.
767821#[ derive( Debug , Eq , PartialEq ) ]
0 commit comments