@@ -340,3 +340,90 @@ pub(crate) fn status_to_io_error(s: r_efi::efi::Status) -> io::Error {
340
340
_ => io:: Error :: new ( ErrorKind :: Uncategorized , format ! ( "Status: {}" , s. as_usize( ) ) ) ,
341
341
}
342
342
}
343
+
344
+ pub fn install_protocol < T > (
345
+ handle : & mut r_efi:: efi:: Handle ,
346
+ mut guid : r_efi:: efi:: Guid ,
347
+ interface : & mut T ,
348
+ ) -> io:: Result < ( ) > {
349
+ let boot_services = uefi:: env:: get_boot_services ( ) . ok_or ( BOOT_SERVICES_ERROR ) ?;
350
+ let r = unsafe {
351
+ ( ( * boot_services. as_ptr ( ) ) . install_protocol_interface ) (
352
+ handle,
353
+ & mut guid,
354
+ r_efi:: efi:: NATIVE_INTERFACE ,
355
+ interface as * mut T as * mut crate :: ffi:: c_void ,
356
+ )
357
+ } ;
358
+ if r. is_error ( ) { Err ( status_to_io_error ( r) ) } else { Ok ( ( ) ) }
359
+ }
360
+
361
+ pub fn uninstall_protocol < T > (
362
+ handle : r_efi:: efi:: Handle ,
363
+ mut guid : r_efi:: efi:: Guid ,
364
+ interface : & mut T ,
365
+ ) -> io:: Result < ( ) > {
366
+ let boot_services = uefi:: env:: get_boot_services ( ) . ok_or ( BOOT_SERVICES_ERROR ) ?;
367
+ let r = unsafe {
368
+ ( ( * boot_services. as_ptr ( ) ) . uninstall_protocol_interface ) (
369
+ handle,
370
+ & mut guid,
371
+ interface as * mut T as * mut crate :: ffi:: c_void ,
372
+ )
373
+ } ;
374
+ if r. is_error ( ) { Err ( status_to_io_error ( r) ) } else { Ok ( ( ) ) }
375
+ }
376
+
377
+ pub trait Protocol {
378
+ const PROTOCOL_GUID : Guid ;
379
+ }
380
+
381
+ pub struct ProtocolWrapper < P >
382
+ where
383
+ P : Protocol ,
384
+ {
385
+ handle : NonNull < crate :: ffi:: c_void > ,
386
+ protocol : Box < P > ,
387
+ }
388
+
389
+ impl < P > ProtocolWrapper < P >
390
+ where
391
+ P : Protocol ,
392
+ {
393
+ pub fn new ( handle : NonNull < crate :: ffi:: c_void > , protocol : Box < P > ) -> Self {
394
+ Self { handle, protocol }
395
+ }
396
+
397
+ pub fn install_protocol ( protocol : P ) -> io:: Result < ProtocolWrapper < P > > {
398
+ let mut handle: r_efi:: efi:: Handle = crate :: ptr:: null_mut ( ) ;
399
+ let mut protocol = Box :: new ( protocol) ;
400
+ install_protocol :: < P > ( & mut handle, P :: PROTOCOL_GUID , & mut protocol) ?;
401
+ let handle = NonNull :: new ( handle)
402
+ . ok_or ( io:: const_io_error!( io:: ErrorKind :: Uncategorized , "Found Null Handle" ) ) ?;
403
+ Ok ( Self :: new ( handle, protocol) )
404
+ }
405
+
406
+ pub fn install_protocol_in (
407
+ protocol : P ,
408
+ mut handle : r_efi:: efi:: Handle ,
409
+ ) -> io:: Result < ProtocolWrapper < P > > {
410
+ let mut protocol = Box :: new ( protocol) ;
411
+ install_protocol :: < P > ( & mut handle, P :: PROTOCOL_GUID , & mut protocol) ?;
412
+ let handle = NonNull :: new ( handle)
413
+ . ok_or ( io:: const_io_error!( io:: ErrorKind :: Uncategorized , "Found Null Handle" ) ) ?;
414
+ Ok ( Self :: new ( handle, protocol) )
415
+ }
416
+
417
+ pub fn handle_non_null ( & self ) -> NonNull < crate :: ffi:: c_void > {
418
+ self . handle
419
+ }
420
+ }
421
+
422
+ impl < P > Drop for ProtocolWrapper < P >
423
+ where
424
+ P : Protocol ,
425
+ {
426
+ fn drop ( & mut self ) {
427
+ let _ = uninstall_protocol :: < P > ( self . handle . as_ptr ( ) , P :: PROTOCOL_GUID , & mut self . protocol ) ;
428
+ }
429
+ }
0 commit comments