@@ -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
///
@@ -736,6 +758,38 @@ pub fn stall(microseconds: usize) {
736
758
}
737
759
}
738
760
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
+
739
793
/// A buffer returned by [`locate_handle_buffer`] that contains an array of
740
794
/// [`Handle`]s that support the requested protocol.
741
795
#[ derive( Debug , Eq , PartialEq ) ]
0 commit comments