@@ -18,6 +18,9 @@ use core::{mem, slice};
18
18
use uefi:: { table, Char16 , Error , Event , Guid , Handle , Result , Status , StatusExt } ;
19
19
use uefi_raw:: table:: boot:: InterfaceType ;
20
20
21
+ #[ cfg( feature = "alloc" ) ]
22
+ use { alloc:: vec:: Vec , uefi:: ResultExt } ;
23
+
21
24
#[ cfg( doc) ]
22
25
use {
23
26
crate :: proto:: device_path:: LoadedImageDevicePath , crate :: proto:: loaded_image:: LoadedImage ,
@@ -741,6 +744,47 @@ pub fn locate_handle_buffer(search_ty: SearchType) -> Result<HandleBuffer> {
741
744
} )
742
745
}
743
746
747
+ /// Returns all the handles implementing a certain protocol.
748
+ ///
749
+ /// # Errors
750
+ ///
751
+ /// * [`Status::NOT_FOUND`]: no matching handles.
752
+ #[ cfg( feature = "alloc" ) ]
753
+ pub fn find_handles < P : ProtocolPointer + ?Sized > ( ) -> Result < Vec < Handle > > {
754
+ // Search by protocol.
755
+ let search_type = SearchType :: from_proto :: < P > ( ) ;
756
+
757
+ // Determine how much we need to allocate.
758
+ let num_handles = match locate_handle ( search_type, & mut [ ] ) {
759
+ Err ( err) => {
760
+ if err. status ( ) == Status :: BUFFER_TOO_SMALL {
761
+ err. data ( ) . expect ( "error data is missing" )
762
+ } else {
763
+ return Err ( err. to_err_without_payload ( ) ) ;
764
+ }
765
+ }
766
+ // This should never happen: if no handles match the search then a
767
+ // `NOT_FOUND` error should be returned.
768
+ Ok ( _) => panic ! ( "locate_handle should not return success with empty buffer" ) ,
769
+ } ;
770
+
771
+ // Allocate a large enough buffer without pointless initialization.
772
+ let mut handles = Vec :: with_capacity ( num_handles) ;
773
+
774
+ // Perform the search.
775
+ let num_handles = locate_handle ( search_type, handles. spare_capacity_mut ( ) )
776
+ . discard_errdata ( ) ?
777
+ . len ( ) ;
778
+
779
+ // Mark the returned number of elements as initialized.
780
+ unsafe {
781
+ handles. set_len ( num_handles) ;
782
+ }
783
+
784
+ // Emit output, with warnings
785
+ Ok ( handles)
786
+ }
787
+
744
788
/// Find an arbitrary handle that supports a particular [`Protocol`]. Returns
745
789
/// [`NOT_FOUND`] if no handles support the protocol.
746
790
///
0 commit comments