@@ -382,36 +382,43 @@ mod uefi_command_internal {
382382
383383 let loaded_image: NonNull < loaded_image:: Protocol > =
384384 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 > =
386386 Box :: new ( unsafe { crate :: ptr:: read ( ( * loaded_image. as_ptr ( ) ) . system_table ) } ) ;
387387
388- unsafe {
389- ( * loaded_image. as_ptr ( ) ) . system_table = st. as_mut ( ) ;
390- }
391-
392388 Ok ( Self :: new ( child_handle, st) )
393389 }
394390 }
395391
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+
397402 let boot_services: NonNull < r_efi:: efi:: BootServices > = boot_services ( )
398403 . ok_or_else ( || const_io_error ! ( io:: ErrorKind :: NotFound , "Boot Services not found" ) ) ?
399404 . cast ( ) ;
400- let mut exit_data_size: MaybeUninit < usize > = MaybeUninit :: uninit ( ) ;
405+ let mut exit_data_size: usize = 0 ;
401406 let mut exit_data: MaybeUninit < * mut u16 > = MaybeUninit :: uninit ( ) ;
402407
403408 let r = unsafe {
404409 ( ( * boot_services. as_ptr ( ) ) . start_image ) (
405410 self . handle . as_ptr ( ) ,
406- exit_data_size. as_mut_ptr ( ) ,
411+ & mut exit_data_size,
407412 exit_data. as_mut_ptr ( ) ,
408413 )
409414 } ;
410415
411416 // 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+ }
415422 }
416423
417424 Ok ( r)
@@ -476,6 +483,30 @@ mod uefi_command_internal {
476483
477484 self . args = Some ( args) ;
478485 }
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+ }
479510 }
480511
481512 impl Drop for Command {
@@ -501,13 +532,12 @@ mod uefi_command_internal {
501532 set_cursor_position : simple_text_output:: ProtocolSetCursorPosition ,
502533 enable_cursor : simple_text_output:: ProtocolEnableCursor ,
503534 mode : * mut simple_text_output:: Mode ,
504- _mode : Box < simple_text_output:: Mode > ,
505535 _buffer : Vec < u16 > ,
506536 }
507537
508538 impl PipeProtocol {
509539 pub fn new ( ) -> Self {
510- let mut mode = Box :: new ( simple_text_output:: Mode {
540+ let mode = Box :: new ( simple_text_output:: Mode {
511541 max_mode : 0 ,
512542 mode : 0 ,
513543 attribute : 0 ,
@@ -525,14 +555,13 @@ mod uefi_command_internal {
525555 clear_screen : Self :: clear_screen,
526556 set_cursor_position : Self :: set_cursor_position,
527557 enable_cursor : Self :: enable_cursor,
528- mode : mode. as_mut ( ) ,
529- _mode : mode,
558+ mode : Box :: into_raw ( mode) ,
530559 _buffer : Vec :: new ( ) ,
531560 }
532561 }
533562
534563 pub fn null ( ) -> Self {
535- let mut mode = Box :: new ( simple_text_output:: Mode {
564+ let mode = Box :: new ( simple_text_output:: Mode {
536565 max_mode : 0 ,
537566 mode : 0 ,
538567 attribute : 0 ,
@@ -550,8 +579,7 @@ mod uefi_command_internal {
550579 clear_screen : Self :: clear_screen,
551580 set_cursor_position : Self :: set_cursor_position,
552581 enable_cursor : Self :: enable_cursor,
553- mode : mode. as_mut ( ) ,
554- _mode : mode,
582+ mode : Box :: into_raw ( mode) ,
555583 _buffer : Vec :: new ( ) ,
556584 }
557585 }
@@ -660,4 +688,12 @@ mod uefi_command_internal {
660688 r_efi:: efi:: Status :: UNSUPPORTED
661689 }
662690 }
691+
692+ impl Drop for PipeProtocol {
693+ fn drop ( & mut self ) {
694+ unsafe {
695+ let _ = Box :: from_raw ( self . mode ) ;
696+ }
697+ }
698+ }
663699}
0 commit comments