@@ -35,6 +35,7 @@ pub struct StdioPipes {
35
35
pub stderr : Option < AnonPipe > ,
36
36
}
37
37
38
+ #[ derive( Copy , Clone ) ]
38
39
pub enum Stdio {
39
40
Inherit ,
40
41
Null ,
@@ -96,14 +97,14 @@ impl Command {
96
97
97
98
fn create_pipe (
98
99
s : Stdio ,
99
- ) -> io:: Result < Option < helpers:: Protocol < uefi_command_internal:: PipeProtocol > > > {
100
+ ) -> io:: Result < Option < helpers:: OwnedProtocol < uefi_command_internal:: PipeProtocol > > > {
100
101
match s {
101
- Stdio :: MakePipe => helpers:: Protocol :: create (
102
+ Stdio :: MakePipe => helpers:: OwnedProtocol :: create (
102
103
uefi_command_internal:: PipeProtocol :: new ( ) ,
103
104
simple_text_output:: PROTOCOL_GUID ,
104
105
)
105
106
. map ( Some ) ,
106
- Stdio :: Null => helpers:: Protocol :: create (
107
+ Stdio :: Null => helpers:: OwnedProtocol :: create (
107
108
uefi_command_internal:: PipeProtocol :: null ( ) ,
108
109
simple_text_output:: PROTOCOL_GUID ,
109
110
)
@@ -116,36 +117,38 @@ impl Command {
116
117
let mut cmd = uefi_command_internal:: Command :: load_image ( & self . prog ) ?;
117
118
118
119
/* Setup Stdout */
119
- let stdout: Option < helpers:: Protocol < uefi_command_internal:: PipeProtocol > > =
120
- match self . stdout . take ( ) {
120
+ let stdout: Option < helpers:: OwnedProtocol < uefi_command_internal:: PipeProtocol > > =
121
+ match self . stdout {
121
122
Some ( s) => Self :: create_pipe ( s) ,
122
- None => helpers:: Protocol :: create (
123
+ None => helpers:: OwnedProtocol :: create (
123
124
uefi_command_internal:: PipeProtocol :: new ( ) ,
124
125
simple_text_output:: PROTOCOL_GUID ,
125
126
)
126
127
. map ( Some ) ,
127
128
} ?;
128
- match stdout {
129
- Some ( stdout) => cmd. stdout_init ( stdout) ,
130
- None => cmd. stdout_inherit ( ) ,
129
+ if let Some ( con) = stdout {
130
+ cmd. stdout_init ( con)
131
+ } else {
132
+ cmd. stdout_inherit ( )
131
133
} ;
132
134
133
135
/* Setup Stderr */
134
- let stderr: Option < helpers:: Protocol < uefi_command_internal:: PipeProtocol > > =
135
- match self . stderr . take ( ) {
136
+ let stderr: Option < helpers:: OwnedProtocol < uefi_command_internal:: PipeProtocol > > =
137
+ match self . stderr {
136
138
Some ( s) => Self :: create_pipe ( s) ,
137
- None => helpers:: Protocol :: create (
139
+ None => helpers:: OwnedProtocol :: create (
138
140
uefi_command_internal:: PipeProtocol :: new ( ) ,
139
141
simple_text_output:: PROTOCOL_GUID ,
140
142
)
141
143
. map ( Some ) ,
142
144
} ?;
143
- match stderr {
144
- Some ( stderr) => cmd. stderr_init ( stderr) ,
145
- None => cmd. stderr_inherit ( ) ,
145
+ if let Some ( con) = stderr {
146
+ cmd. stderr_init ( con)
147
+ } else {
148
+ cmd. stderr_inherit ( )
146
149
} ;
147
150
148
- /* No reason to set args if only program name is preset */
151
+ // No reason to set args if only program name is preset
149
152
if !self . args . is_empty ( ) {
150
153
let args = self . args . iter ( ) . fold ( OsString :: from ( & self . prog ) , |mut acc, arg| {
151
154
acc. push ( " " ) ;
@@ -341,8 +344,8 @@ mod uefi_command_internal {
341
344
342
345
pub struct Command {
343
346
handle : NonNull < crate :: ffi:: c_void > ,
344
- stdout : Option < helpers:: Protocol < PipeProtocol > > ,
345
- stderr : Option < helpers:: Protocol < PipeProtocol > > ,
347
+ stdout : Option < helpers:: OwnedProtocol < PipeProtocol > > ,
348
+ stderr : Option < helpers:: OwnedProtocol < PipeProtocol > > ,
346
349
st : Box < r_efi:: efi:: SystemTable > ,
347
350
args : Option < Vec < u16 > > ,
348
351
}
@@ -382,45 +385,52 @@ mod uefi_command_internal {
382
385
383
386
let loaded_image: NonNull < loaded_image:: Protocol > =
384
387
helpers:: open_protocol ( child_handle, loaded_image:: PROTOCOL_GUID ) . unwrap ( ) ;
385
- let mut st: Box < r_efi:: efi:: SystemTable > =
388
+ let st: Box < r_efi:: efi:: SystemTable > =
386
389
Box :: new ( unsafe { crate :: ptr:: read ( ( * loaded_image. as_ptr ( ) ) . system_table ) } ) ;
387
390
388
- unsafe {
389
- ( * loaded_image. as_ptr ( ) ) . system_table = st. as_mut ( ) ;
390
- }
391
-
392
391
Ok ( Self :: new ( child_handle, st) )
393
392
}
394
393
}
395
394
396
- pub fn start_image ( & self ) -> io:: Result < r_efi:: efi:: Status > {
395
+ pub fn start_image ( & mut self ) -> io:: Result < r_efi:: efi:: Status > {
396
+ self . update_st_crc32 ( ) ?;
397
+
398
+ // Use our system table instead of the default one
399
+ let loaded_image: NonNull < loaded_image:: Protocol > =
400
+ helpers:: open_protocol ( self . handle , loaded_image:: PROTOCOL_GUID ) . unwrap ( ) ;
401
+ unsafe {
402
+ ( * loaded_image. as_ptr ( ) ) . system_table = self . st . as_mut ( ) ;
403
+ }
404
+
397
405
let boot_services: NonNull < r_efi:: efi:: BootServices > = boot_services ( )
398
406
. ok_or_else ( || const_io_error ! ( io:: ErrorKind :: NotFound , "Boot Services not found" ) ) ?
399
407
. cast ( ) ;
400
- let mut exit_data_size: MaybeUninit < usize > = MaybeUninit :: uninit ( ) ;
408
+ let mut exit_data_size: usize = 0 ;
401
409
let mut exit_data: MaybeUninit < * mut u16 > = MaybeUninit :: uninit ( ) ;
402
410
403
411
let r = unsafe {
404
412
( ( * boot_services. as_ptr ( ) ) . start_image ) (
405
413
self . handle . as_ptr ( ) ,
406
- exit_data_size. as_mut_ptr ( ) ,
414
+ & mut exit_data_size,
407
415
exit_data. as_mut_ptr ( ) ,
408
416
)
409
417
} ;
410
418
411
419
// Drop exitdata
412
- unsafe {
413
- exit_data_size. assume_init_drop ( ) ;
414
- exit_data. assume_init_drop ( ) ;
420
+ if exit_data_size != 0 {
421
+ unsafe {
422
+ let exit_data = exit_data. assume_init ( ) ;
423
+ ( ( * boot_services. as_ptr ( ) ) . free_pool ) ( exit_data as * mut crate :: ffi:: c_void ) ;
424
+ }
415
425
}
416
426
417
427
Ok ( r)
418
428
}
419
429
420
- pub fn stdout_init ( & mut self , mut protocol : helpers:: Protocol < PipeProtocol > ) {
430
+ pub fn stdout_init ( & mut self , protocol : helpers:: OwnedProtocol < PipeProtocol > ) {
421
431
self . st . console_out_handle = protocol. handle ( ) . as_ptr ( ) ;
422
432
self . st . con_out =
423
- protocol. as_mut ( ) as * mut PipeProtocol as * mut simple_text_output:: Protocol ;
433
+ protocol. as_ref ( ) as * const PipeProtocol as * mut simple_text_output:: Protocol ;
424
434
425
435
self . stdout = Some ( protocol) ;
426
436
}
@@ -432,10 +442,10 @@ mod uefi_command_internal {
432
442
self . st . con_out = unsafe { ( * st. as_ptr ( ) ) . con_out } ;
433
443
}
434
444
435
- pub fn stderr_init ( & mut self , mut protocol : helpers:: Protocol < PipeProtocol > ) {
445
+ pub fn stderr_init ( & mut self , protocol : helpers:: OwnedProtocol < PipeProtocol > ) {
436
446
self . st . standard_error_handle = protocol. handle ( ) . as_ptr ( ) ;
437
447
self . st . std_err =
438
- protocol. as_mut ( ) as * mut PipeProtocol as * mut simple_text_output:: Protocol ;
448
+ protocol. as_ref ( ) as * const PipeProtocol as * mut simple_text_output:: Protocol ;
439
449
440
450
self . stderr = Some ( protocol) ;
441
451
}
@@ -476,6 +486,30 @@ mod uefi_command_internal {
476
486
477
487
self . args = Some ( args) ;
478
488
}
489
+
490
+ fn update_st_crc32 ( & mut self ) -> io:: Result < ( ) > {
491
+ let bt: NonNull < r_efi:: efi:: BootServices > = boot_services ( ) . unwrap ( ) . cast ( ) ;
492
+ let st_size = self . st . hdr . header_size as usize ;
493
+ let mut crc32: u32 = 0 ;
494
+
495
+ // Set crc to 0 before calcuation
496
+ self . st . hdr . crc32 = 0 ;
497
+
498
+ let r = unsafe {
499
+ ( ( * bt. as_ptr ( ) ) . calculate_crc32 ) (
500
+ self . st . as_mut ( ) as * mut r_efi:: efi:: SystemTable as * mut crate :: ffi:: c_void ,
501
+ st_size,
502
+ & mut crc32,
503
+ )
504
+ } ;
505
+
506
+ if r. is_error ( ) {
507
+ Err ( io:: Error :: from_raw_os_error ( r. as_usize ( ) ) )
508
+ } else {
509
+ self . st . hdr . crc32 = crc32;
510
+ Ok ( ( ) )
511
+ }
512
+ }
479
513
}
480
514
481
515
impl Drop for Command {
@@ -501,13 +535,12 @@ mod uefi_command_internal {
501
535
set_cursor_position : simple_text_output:: ProtocolSetCursorPosition ,
502
536
enable_cursor : simple_text_output:: ProtocolEnableCursor ,
503
537
mode : * mut simple_text_output:: Mode ,
504
- _mode : Box < simple_text_output:: Mode > ,
505
538
_buffer : Vec < u16 > ,
506
539
}
507
540
508
541
impl PipeProtocol {
509
542
pub fn new ( ) -> Self {
510
- let mut mode = Box :: new ( simple_text_output:: Mode {
543
+ let mode = Box :: new ( simple_text_output:: Mode {
511
544
max_mode : 0 ,
512
545
mode : 0 ,
513
546
attribute : 0 ,
@@ -525,14 +558,13 @@ mod uefi_command_internal {
525
558
clear_screen : Self :: clear_screen,
526
559
set_cursor_position : Self :: set_cursor_position,
527
560
enable_cursor : Self :: enable_cursor,
528
- mode : mode. as_mut ( ) ,
529
- _mode : mode,
561
+ mode : Box :: into_raw ( mode) ,
530
562
_buffer : Vec :: new ( ) ,
531
563
}
532
564
}
533
565
534
566
pub fn null ( ) -> Self {
535
- let mut mode = Box :: new ( simple_text_output:: Mode {
567
+ let mode = Box :: new ( simple_text_output:: Mode {
536
568
max_mode : 0 ,
537
569
mode : 0 ,
538
570
attribute : 0 ,
@@ -550,8 +582,7 @@ mod uefi_command_internal {
550
582
clear_screen : Self :: clear_screen,
551
583
set_cursor_position : Self :: set_cursor_position,
552
584
enable_cursor : Self :: enable_cursor,
553
- mode : mode. as_mut ( ) ,
554
- _mode : mode,
585
+ mode : Box :: into_raw ( mode) ,
555
586
_buffer : Vec :: new ( ) ,
556
587
}
557
588
}
@@ -660,4 +691,12 @@ mod uefi_command_internal {
660
691
r_efi:: efi:: Status :: UNSUPPORTED
661
692
}
662
693
}
694
+
695
+ impl Drop for PipeProtocol {
696
+ fn drop ( & mut self ) {
697
+ unsafe {
698
+ let _ = Box :: from_raw ( self . mode ) ;
699
+ }
700
+ }
701
+ }
663
702
}
0 commit comments