@@ -477,6 +477,28 @@ pub unsafe fn uninstall_protocol_interface(
477
477
( bt. uninstall_protocol_interface ) ( handle. as_ptr ( ) , protocol, interface) . to_result ( )
478
478
}
479
479
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
+
480
502
/// Returns an array of handles that support the requested protocol in a
481
503
/// pool-allocated buffer.
482
504
///
@@ -762,6 +784,38 @@ pub fn stall(microseconds: usize) {
762
784
}
763
785
}
764
786
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
+
765
819
/// A buffer returned by [`locate_handle_buffer`] that contains an array of
766
820
/// [`Handle`]s that support the requested protocol.
767
821
#[ derive( Debug , Eq , PartialEq ) ]
0 commit comments