@@ -18,6 +18,9 @@ use core::{mem, slice};
1818use uefi:: { table, Char16 , Error , Event , Guid , Handle , Result , Status , StatusExt } ;
1919use uefi_raw:: table:: boot:: InterfaceType ;
2020
21+ #[ cfg( feature = "alloc" ) ]
22+ use { alloc:: vec:: Vec , uefi:: ResultExt } ;
23+
2124#[ cfg( doc) ]
2225use {
2326 crate :: proto:: device_path:: LoadedImageDevicePath , crate :: proto:: loaded_image:: LoadedImage ,
@@ -741,6 +744,47 @@ pub fn locate_handle_buffer(search_ty: SearchType) -> Result<HandleBuffer> {
741744 } )
742745}
743746
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+
744788/// Find an arbitrary handle that supports a particular [`Protocol`]. Returns
745789/// [`NOT_FOUND`] if no handles support the protocol.
746790///
0 commit comments