@@ -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///
@@ -736,6 +758,38 @@ pub fn stall(microseconds: usize) {
736758 }
737759}
738760
761+ /// Protocol interface [`Guids`][Guid] that are installed on a [`Handle`] as
762+ /// returned by [`protocols_per_handle`].
763+ #[ derive( Debug ) ]
764+ pub struct ProtocolsPerHandle {
765+ protocols : NonNull < * const Guid > ,
766+ count : usize ,
767+ }
768+
769+ impl Drop for ProtocolsPerHandle {
770+ fn drop ( & mut self ) {
771+ let _ = unsafe { free_pool ( self . protocols . cast :: < u8 > ( ) ) } ;
772+ }
773+ }
774+
775+ impl Deref for ProtocolsPerHandle {
776+ type Target = [ & ' static Guid ] ;
777+
778+ fn deref ( & self ) -> & Self :: Target {
779+ let ptr: * const & ' static Guid = self . protocols . as_ptr ( ) . cast ( ) ;
780+
781+ // SAFETY:
782+ //
783+ // * The firmware is assumed to provide a correctly-aligned pointer and
784+ // array length.
785+ // * The firmware is assumed to provide valid GUID pointers.
786+ // * Protocol GUIDs should be constants or statics, so a 'static
787+ // lifetime (of the individual pointers, not the overall slice) can be
788+ // assumed.
789+ unsafe { slice:: from_raw_parts ( ptr, self . count ) }
790+ }
791+ }
792+
739793/// A buffer returned by [`locate_handle_buffer`] that contains an array of
740794/// [`Handle`]s that support the requested protocol.
741795#[ derive( Debug , Eq , PartialEq ) ]
0 commit comments