@@ -18,13 +18,14 @@ use uefi::proto::device_path::build::{self, DevicePathBuilder};
18
18
use uefi:: proto:: device_path:: { DevicePath , DeviceSubType , DeviceType , LoadedImageDevicePath } ;
19
19
use uefi:: proto:: loaded_image:: LoadedImage ;
20
20
use uefi:: table:: boot:: LoadImageSource ;
21
- use uefi:: Status ;
21
+ use uefi:: { CStr16 , Status } ;
22
22
23
- /// Get the device path of the shell app. This is the same as the
23
+ /// Get the device path of another app. This is the same as the
24
24
/// currently-loaded image's device path, but with the file path part changed.
25
- fn get_shell_app_device_path < ' a > (
25
+ fn get_app_device_path < ' a > (
26
26
boot_services : & BootServices ,
27
27
storage : & ' a mut Vec < u8 > ,
28
+ file_path : & CStr16 ,
28
29
) -> & ' a DevicePath {
29
30
let loaded_image_device_path = boot_services
30
31
. open_protocol_exclusive :: < LoadedImageDevicePath > ( boot_services. image_handle ( ) )
@@ -39,19 +40,46 @@ fn get_shell_app_device_path<'a>(
39
40
}
40
41
builder = builder
41
42
. push ( & build:: media:: FilePath {
42
- path_name : cstr16 ! ( r"efi\boot\shell.efi" ) ,
43
+ path_name : file_path ,
43
44
} )
44
45
. unwrap ( ) ;
45
46
builder. finalize ( ) . unwrap ( )
46
47
}
47
48
49
+ fn run_quick_exit ( boot_services : & BootServices ) {
50
+ let mut storage = Vec :: new ( ) ;
51
+ let child_image_path = get_app_device_path (
52
+ boot_services,
53
+ & mut storage,
54
+ cstr16 ! ( r"efi\boot\quick_exit.efi" ) ,
55
+ ) ;
56
+
57
+ let child_image_handle = boot_services
58
+ . load_image (
59
+ boot_services. image_handle ( ) ,
60
+ LoadImageSource :: FromDevicePath {
61
+ device_path : child_image_path,
62
+ from_boot_manager : false ,
63
+ } ,
64
+ )
65
+ . expect ( "failed to load quick-exit app" ) ;
66
+
67
+ info ! ( "launching the quick-exit app" ) ;
68
+ boot_services
69
+ . start_image ( child_image_handle)
70
+ . expect ( "failed to launch the quick-exit app" ) ;
71
+ }
72
+
48
73
#[ entry]
49
74
fn efi_main ( image : Handle , mut st : SystemTable < Boot > ) -> Status {
50
75
uefi_services:: init ( & mut st) . unwrap ( ) ;
51
76
let boot_services = st. boot_services ( ) ;
52
77
53
78
let mut storage = Vec :: new ( ) ;
54
- let shell_image_path = get_shell_app_device_path ( boot_services, & mut storage) ;
79
+ let shell_image_path =
80
+ get_app_device_path ( boot_services, & mut storage, cstr16 ! ( r"efi\boot\shell.efi" ) ) ;
81
+
82
+ run_quick_exit ( boot_services) ;
55
83
56
84
// Load the shell app.
57
85
let shell_image_handle = boot_services
0 commit comments