@@ -382,36 +382,43 @@ mod uefi_command_internal {
382
382
383
383
let loaded_image: NonNull < loaded_image:: Protocol > =
384
384
helpers:: open_protocol ( child_handle, loaded_image:: PROTOCOL_GUID ) . unwrap ( ) ;
385
- let mut st: Box < r_efi:: efi:: SystemTable > =
385
+ let st: Box < r_efi:: efi:: SystemTable > =
386
386
Box :: new ( unsafe { crate :: ptr:: read ( ( * loaded_image. as_ptr ( ) ) . system_table ) } ) ;
387
387
388
- unsafe {
389
- ( * loaded_image. as_ptr ( ) ) . system_table = st. as_mut ( ) ;
390
- }
391
-
392
388
Ok ( Self :: new ( child_handle, st) )
393
389
}
394
390
}
395
391
396
- pub fn start_image ( & self ) -> io:: Result < r_efi:: efi:: Status > {
392
+ pub fn start_image ( & mut self ) -> io:: Result < r_efi:: efi:: Status > {
393
+ self . update_st_crc32 ( ) ?;
394
+
395
+ // Use our system table instead of the default one
396
+ let loaded_image: NonNull < loaded_image:: Protocol > =
397
+ helpers:: open_protocol ( self . handle , loaded_image:: PROTOCOL_GUID ) . unwrap ( ) ;
398
+ unsafe {
399
+ ( * loaded_image. as_ptr ( ) ) . system_table = self . st . as_mut ( ) ;
400
+ }
401
+
397
402
let boot_services: NonNull < r_efi:: efi:: BootServices > = boot_services ( )
398
403
. ok_or_else ( || const_io_error ! ( io:: ErrorKind :: NotFound , "Boot Services not found" ) ) ?
399
404
. cast ( ) ;
400
- let mut exit_data_size: MaybeUninit < usize > = MaybeUninit :: uninit ( ) ;
405
+ let mut exit_data_size: usize = 0 ;
401
406
let mut exit_data: MaybeUninit < * mut u16 > = MaybeUninit :: uninit ( ) ;
402
407
403
408
let r = unsafe {
404
409
( ( * boot_services. as_ptr ( ) ) . start_image ) (
405
410
self . handle . as_ptr ( ) ,
406
- exit_data_size. as_mut_ptr ( ) ,
411
+ & mut exit_data_size,
407
412
exit_data. as_mut_ptr ( ) ,
408
413
)
409
414
} ;
410
415
411
416
// Drop exitdata
412
- unsafe {
413
- exit_data_size. assume_init_drop ( ) ;
414
- exit_data. assume_init_drop ( ) ;
417
+ if exit_data_size != 0 {
418
+ unsafe {
419
+ let exit_data = exit_data. assume_init ( ) ;
420
+ ( ( * boot_services. as_ptr ( ) ) . free_pool ) ( exit_data as * mut crate :: ffi:: c_void ) ;
421
+ }
415
422
}
416
423
417
424
Ok ( r)
@@ -476,6 +483,30 @@ mod uefi_command_internal {
476
483
477
484
self . args = Some ( args) ;
478
485
}
486
+
487
+ fn update_st_crc32 ( & mut self ) -> io:: Result < ( ) > {
488
+ let bt: NonNull < r_efi:: efi:: BootServices > = boot_services ( ) . unwrap ( ) . cast ( ) ;
489
+ let st_size = self . st . hdr . header_size as usize ;
490
+ let mut crc32: u32 = 0 ;
491
+
492
+ // Set crc to 0 before calcuation
493
+ self . st . hdr . crc32 = 0 ;
494
+
495
+ let r = unsafe {
496
+ ( ( * bt. as_ptr ( ) ) . calculate_crc32 ) (
497
+ self . st . as_mut ( ) as * mut r_efi:: efi:: SystemTable as * mut crate :: ffi:: c_void ,
498
+ st_size,
499
+ & mut crc32,
500
+ )
501
+ } ;
502
+
503
+ if r. is_error ( ) {
504
+ Err ( io:: Error :: from_raw_os_error ( r. as_usize ( ) ) )
505
+ } else {
506
+ self . st . hdr . crc32 = crc32;
507
+ Ok ( ( ) )
508
+ }
509
+ }
479
510
}
480
511
481
512
impl Drop for Command {
@@ -501,13 +532,12 @@ mod uefi_command_internal {
501
532
set_cursor_position : simple_text_output:: ProtocolSetCursorPosition ,
502
533
enable_cursor : simple_text_output:: ProtocolEnableCursor ,
503
534
mode : * mut simple_text_output:: Mode ,
504
- _mode : Box < simple_text_output:: Mode > ,
505
535
_buffer : Vec < u16 > ,
506
536
}
507
537
508
538
impl PipeProtocol {
509
539
pub fn new ( ) -> Self {
510
- let mut mode = Box :: new ( simple_text_output:: Mode {
540
+ let mode = Box :: new ( simple_text_output:: Mode {
511
541
max_mode : 0 ,
512
542
mode : 0 ,
513
543
attribute : 0 ,
@@ -525,14 +555,13 @@ mod uefi_command_internal {
525
555
clear_screen : Self :: clear_screen,
526
556
set_cursor_position : Self :: set_cursor_position,
527
557
enable_cursor : Self :: enable_cursor,
528
- mode : mode. as_mut ( ) ,
529
- _mode : mode,
558
+ mode : Box :: into_raw ( mode) ,
530
559
_buffer : Vec :: new ( ) ,
531
560
}
532
561
}
533
562
534
563
pub fn null ( ) -> Self {
535
- let mut mode = Box :: new ( simple_text_output:: Mode {
564
+ let mode = Box :: new ( simple_text_output:: Mode {
536
565
max_mode : 0 ,
537
566
mode : 0 ,
538
567
attribute : 0 ,
@@ -550,8 +579,7 @@ mod uefi_command_internal {
550
579
clear_screen : Self :: clear_screen,
551
580
set_cursor_position : Self :: set_cursor_position,
552
581
enable_cursor : Self :: enable_cursor,
553
- mode : mode. as_mut ( ) ,
554
- _mode : mode,
582
+ mode : Box :: into_raw ( mode) ,
555
583
_buffer : Vec :: new ( ) ,
556
584
}
557
585
}
@@ -660,4 +688,12 @@ mod uefi_command_internal {
660
688
r_efi:: efi:: Status :: UNSUPPORTED
661
689
}
662
690
}
691
+
692
+ impl Drop for PipeProtocol {
693
+ fn drop ( & mut self ) {
694
+ unsafe {
695
+ let _ = Box :: from_raw ( self . mode ) ;
696
+ }
697
+ }
698
+ }
663
699
}
0 commit comments