Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6b25708

Browse files
committed
test: add load_image integration test
1 parent a4136a0 commit 6b25708

File tree

2 files changed

+80
-12
lines changed

2 files changed

+80
-12
lines changed

‎uefi-test-runner/src/boot/mod.rs

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
1+
use alloc::string::ToString;
12
use uefi::proto::console::text::Output;
2-
use uefi::table::boot::{BootServices, SearchType};
3+
use uefi::proto::device_path::media::FilePath;
4+
use uefi::proto::device_path::{DevicePath, LoadedImageDevicePath};
5+
use uefi::table::boot::{BootServices, LoadImageSource, SearchType};
36
use uefi::table::{Boot, SystemTable};
4-
use uefi::Identify;
7+
use uefi::{CString16, Identify};
8+
9+
mod memory;
10+
mod misc;
511

612
pub fn test(st: &SystemTable<Boot>) {
713
let bt = st.boot_services();
814
info!("Testing boot services");
915
memory::test(bt);
1016
misc::test(st);
1117
test_locate_handle_buffer(bt);
18+
test_load_image(bt);
1219
}
1320

14-
mod memory;
15-
mod misc;
16-
1721
fn test_locate_handle_buffer(bt: &BootServices) {
1822
info!("Testing the `locate_handle_buffer` function");
1923

@@ -36,3 +40,67 @@ fn test_locate_handle_buffer(bt: &BootServices) {
3640
);
3741
}
3842
}
43+
44+
/// This test loads the "self image" again into memory using the `load_image`
45+
/// boot service function. The image is not started but just loaded into memory.
46+
///
47+
/// It transitively tests the protocol [`LoadedImageDevicePath`] which is
48+
/// required as helper.
49+
fn test_load_image(bt: &BootServices) {
50+
/// The path of the loaded image executing this integration test.
51+
const LOADED_IMAGE_PATH: &str = r"\EFI\BOOT\TEST_RUNNER.EFI";
52+
53+
info!("Testing the `load_image` function");
54+
55+
let image_device_path_protocol = bt
56+
.open_protocol_exclusive::<LoadedImageDevicePath>(bt.image_handle())
57+
.expect("should open LoadedImage protocol");
58+
59+
// Note: This is the full device path. The LoadedImage protocol would only
60+
// provide us with the file-path portion of the device path.
61+
let image_device_path: &DevicePath = &image_device_path_protocol;
62+
63+
// Get the file-path portion of the device path which is typically behind
64+
// device path node (0x4, 0x4). The string is in upper case.
65+
66+
let image_device_path_file_path = image_device_path
67+
.node_iter()
68+
.find_map(|node| {
69+
let node: &FilePath = node.try_into().ok()?;
70+
let path = node.path_name().to_cstring16().ok()?;
71+
Some(path.to_string().to_uppercase())
72+
})
73+
.expect("should have file-path portion in device path");
74+
75+
assert_eq!(image_device_path_file_path.as_str(), LOADED_IMAGE_PATH);
76+
77+
// Variant A: FromBuffer
78+
{
79+
let mut fs = bt
80+
.get_image_file_system(bt.image_handle())
81+
.expect("should open file system");
82+
let path = CString16::try_from(image_device_path_file_path.as_str()).unwrap();
83+
let image_data = fs.read(&*path).expect("should read file content");
84+
let load_source = LoadImageSource::FromBuffer {
85+
buffer: image_data.as_slice(),
86+
file_path: None,
87+
};
88+
let _ = bt
89+
.load_image(bt.image_handle(), load_source)
90+
.expect("should load image");
91+
92+
log::debug!("load_image with FromBuffer strategy works");
93+
}
94+
// Variant B: FromFilePath
95+
{
96+
let load_source = LoadImageSource::FromFilePath {
97+
file_path: image_device_path,
98+
from_boot_manager: false,
99+
};
100+
let _ = bt
101+
.load_image(bt.image_handle(), load_source)
102+
.expect("should load image");
103+
104+
log::debug!("load_image with FromFilePath strategy works");
105+
}
106+
}

‎uefi/src/data_types/strs.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,8 @@ impl CStr16 {
211211
Self::from_u16_with_nul_unchecked(slice::from_raw_parts(ptr, len + 1))
212212
}
213213

214-
/// Creates a C string wrapper from a u16 slice
215-
///
216-
/// Since not every u16 value is a valid UCS-2 code point, this function
217-
/// must do a bit more validity checking than CStr::from_bytes_with_nul
214+
/// Creates a `&CStr16` from a u16 slice, if the slice contains exactly
215+
/// one terminating null-byte and all chars are valid UCS-2 chars.
218216
pub fn from_u16_with_nul(codes: &[u16]) -> Result<&Self, FromSliceWithNulError> {
219217
for (pos, &code) in codes.iter().enumerate() {
220218
match code.try_into() {
@@ -234,7 +232,7 @@ impl CStr16 {
234232
Err(FromSliceWithNulError::NotNulTerminated)
235233
}
236234

237-
/// Unsafely creates a C string wrapper from a u16 slice.
235+
/// Unsafely creates a `&CStr16` from a u16 slice.
238236
///
239237
/// # Safety
240238
///
@@ -287,11 +285,13 @@ impl CStr16 {
287285
Self::from_u16_with_nul(&buf[..index + 1]).map_err(|err| match err {
288286
FromSliceWithNulError::InvalidChar(p) => FromStrWithBufError::InvalidChar(p),
289287
FromSliceWithNulError::InteriorNul(p) => FromStrWithBufError::InteriorNul(p),
290-
FromSliceWithNulError::NotNulTerminated => unreachable!(),
288+
FromSliceWithNulError::NotNulTerminated => {
289+
unreachable!()
290+
}
291291
})
292292
}
293293

294-
/// Create a [`CStr16`] from an [`UnalignedSlice`] using an aligned
294+
/// Create a `&CStr16` from an [`UnalignedSlice`] using an aligned
295295
/// buffer for storage. The lifetime of the output is tied to `buf`,
296296
/// not `src`.
297297
pub fn from_unaligned_slice<'buf>(

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /