@@ -11,7 +11,8 @@ use core::ops::{Deref, DerefMut};
1111use core:: ptr:: { self , NonNull } ;
1212use core:: sync:: atomic:: { AtomicPtr , Ordering } ;
1313use core:: { mem, slice} ;
14- use uefi:: { table, Char16 , Event , Handle , Result , Status , StatusExt } ;
14+ use uefi:: { table, Char16 , Event , Guid , Handle , Result , Status , StatusExt } ;
15+ use uefi_raw:: table:: boot:: InterfaceType ;
1516
1617#[ cfg( doc) ]
1718use {
@@ -371,6 +372,94 @@ pub fn disconnect_controller(
371372 . to_result_with_err ( |_| ( ) )
372373}
373374
375+ /// Installs a protocol interface on a device handle.
376+ ///
377+ /// When a protocol interface is installed, firmware will call all functions
378+ /// that have registered to wait for that interface to be installed.
379+ ///
380+ /// If `handle` is `None`, a new handle will be created and returned.
381+ ///
382+ /// # Safety
383+ ///
384+ /// The caller is responsible for ensuring that they pass a valid `Guid` for `protocol`.
385+ ///
386+ /// # Errors
387+ ///
388+ /// * [`Status::OUT_OF_RESOURCES`]: failed to allocate a new handle.
389+ /// * [`Status::INVALID_PARAMETER`]: this protocol is already installed on the handle.
390+ pub unsafe fn install_protocol_interface (
391+ handle : Option < Handle > ,
392+ protocol : & Guid ,
393+ interface : * const c_void ,
394+ ) -> Result < Handle > {
395+ let bt = boot_services_raw_panicking ( ) ;
396+ let bt = unsafe { bt. as_ref ( ) } ;
397+
398+ let mut handle = Handle :: opt_to_ptr ( handle) ;
399+ ( ( bt. install_protocol_interface ) (
400+ & mut handle,
401+ protocol,
402+ InterfaceType :: NATIVE_INTERFACE ,
403+ interface,
404+ ) )
405+ . to_result_with_val ( || Handle :: from_ptr ( handle) . unwrap ( ) )
406+ }
407+
408+ /// Reinstalls a protocol interface on a device handle. `old_interface` is replaced with `new_interface`.
409+ /// These interfaces may be the same, in which case the registered protocol notifications occur for the handle
410+ /// without replacing the interface.
411+ ///
412+ /// As with `install_protocol_interface`, any process that has registered to wait for the installation of
413+ /// the interface is notified.
414+ ///
415+ /// # Safety
416+ ///
417+ /// The caller is responsible for ensuring that there are no references to the `old_interface` that is being
418+ /// removed.
419+ ///
420+ /// # Errors
421+ ///
422+ /// * [`Status::NOT_FOUND`]: the old interface was not found on the handle.
423+ /// * [`Status::ACCESS_DENIED`]: the old interface is still in use and cannot be uninstalled.
424+ pub unsafe fn reinstall_protocol_interface (
425+ handle : Handle ,
426+ protocol : & Guid ,
427+ old_interface : * const c_void ,
428+ new_interface : * const c_void ,
429+ ) -> Result < ( ) > {
430+ let bt = boot_services_raw_panicking ( ) ;
431+ let bt = unsafe { bt. as_ref ( ) } ;
432+
433+ ( bt. reinstall_protocol_interface ) ( handle. as_ptr ( ) , protocol, old_interface, new_interface)
434+ . to_result ( )
435+ }
436+
437+ /// Removes a protocol interface from a device handle.
438+ ///
439+ /// # Safety
440+ ///
441+ /// The caller is responsible for ensuring that there are no references to a protocol interface
442+ /// that has been removed. Some protocols may not be able to be removed as there is no information
443+ /// available regarding the references. This includes Console I/O, Block I/O, Disk I/o, and handles
444+ /// to device protocols.
445+ ///
446+ /// The caller is responsible for ensuring that they pass a valid `Guid` for `protocol`.
447+ ///
448+ /// # Errors
449+ ///
450+ /// * [`Status::NOT_FOUND`]: the interface was not found on the handle.
451+ /// * [`Status::ACCESS_DENIED`]: the interface is still in use and cannot be uninstalled.
452+ pub unsafe fn uninstall_protocol_interface (
453+ handle : Handle ,
454+ protocol : & Guid ,
455+ interface : * const c_void ,
456+ ) -> Result < ( ) > {
457+ let bt = boot_services_raw_panicking ( ) ;
458+ let bt = unsafe { bt. as_ref ( ) } ;
459+
460+ ( bt. uninstall_protocol_interface ) ( handle. as_ptr ( ) , protocol, interface) . to_result ( )
461+ }
462+
374463/// Returns an array of handles that support the requested protocol in a
375464/// pool-allocated buffer.
376465///
0 commit comments