@@ -1338,10 +1338,13 @@ impl BootServices {
1338
1338
attributes as u32 ,
1339
1339
)
1340
1340
. to_result_with_val ( || {
1341
- let interface = P :: mut_ptr_from_ffi ( interface) as * const UnsafeCell < P > ;
1341
+ let interface = ( !interface. is_null ( ) ) . then ( || {
1342
+ let interface = P :: mut_ptr_from_ffi ( interface) as * const UnsafeCell < P > ;
1343
+ & * interface
1344
+ } ) ;
1342
1345
1343
1346
ScopedProtocol {
1344
- interface : & * interface ,
1347
+ interface,
1345
1348
open_params : params,
1346
1349
boot_services : self ,
1347
1350
}
@@ -1814,12 +1817,23 @@ pub struct OpenProtocolParams {
1814
1817
/// An open protocol interface. Automatically closes the protocol
1815
1818
/// interface on drop.
1816
1819
///
1820
+ /// Most protocols have interface data associated with them. `ScopedProtocol`
1821
+ /// implements [`Deref`] and [`DerefMut`] to access this data. A few protocols
1822
+ /// (such as [`DevicePath`] and [`LoadedImageDevicePath`]) may be installed with
1823
+ /// null interface data, in which case [`Deref`] and [`DerefMut`] will
1824
+ /// panic. The [`get`] and [`get_mut`] methods may be used to access the
1825
+ /// optional interface data without panicking.
1826
+ ///
1817
1827
/// See also the [`BootServices`] documentation for details of how to open a
1818
1828
/// protocol and why [`UnsafeCell`] is used.
1829
+ ///
1830
+ /// [`LoadedImageDevicePath`]: crate::proto::device_path::LoadedImageDevicePath
1831
+ /// [`get`]: ScopedProtocol::get
1832
+ /// [`get_mut`]: ScopedProtocol::get_mut
1819
1833
#[ derive( Debug ) ]
1820
1834
pub struct ScopedProtocol < ' a , P : Protocol + ?Sized > {
1821
1835
/// The protocol interface.
1822
- interface : & ' a UnsafeCell < P > ,
1836
+ interface : Option < & ' a UnsafeCell < P > > ,
1823
1837
1824
1838
open_params : OpenProtocolParams ,
1825
1839
boot_services : & ' a BootServices ,
@@ -1847,14 +1861,32 @@ impl<'a, P: Protocol + ?Sized> Drop for ScopedProtocol<'a, P> {
1847
1861
impl < ' a , P : Protocol + ?Sized > Deref for ScopedProtocol < ' a , P > {
1848
1862
type Target = P ;
1849
1863
1864
+ #[ track_caller]
1850
1865
fn deref ( & self ) -> & Self :: Target {
1851
- unsafe { & * self . interface . get ( ) }
1866
+ unsafe { & * self . interface . unwrap ( ) . get ( ) }
1852
1867
}
1853
1868
}
1854
1869
1855
1870
impl < ' a , P : Protocol + ?Sized > DerefMut for ScopedProtocol < ' a , P > {
1871
+ #[ track_caller]
1856
1872
fn deref_mut ( & mut self ) -> & mut Self :: Target {
1857
- unsafe { & mut * self . interface . get ( ) }
1873
+ unsafe { & mut * self . interface . unwrap ( ) . get ( ) }
1874
+ }
1875
+ }
1876
+
1877
+ impl < ' a , P : Protocol + ?Sized > ScopedProtocol < ' a , P > {
1878
+ /// Get the protocol interface data, or `None` if the open protocol's
1879
+ /// interface is null.
1880
+ #[ must_use]
1881
+ pub fn get ( & self ) -> Option < & P > {
1882
+ self . interface . map ( |p| unsafe { & * p. get ( ) } )
1883
+ }
1884
+
1885
+ /// Get the protocol interface data, or `None` if the open protocol's
1886
+ /// interface is null.
1887
+ #[ must_use]
1888
+ pub fn get_mut ( & self ) -> Option < & mut P > {
1889
+ self . interface . map ( |p| unsafe { & mut * p. get ( ) } )
1858
1890
}
1859
1891
}
1860
1892
0 commit comments