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 a288116

Browse files
Merge pull request #1740 from RenTrieu/enhancement/efi_shell_interface_cur_dir
EFI Shell Interface: CurDir Functions
2 parents 51fc706 + 18953be commit a288116

File tree

2 files changed

+149
-6
lines changed

2 files changed

+149
-6
lines changed

‎uefi-test-runner/src/proto/shell.rs

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,112 @@
11
// SPDX-License-Identifier: MIT OR Apache-2.0
22

3-
use uefi::boot;
3+
use uefi::boot::ScopedProtocol;
44
use uefi::proto::shell::Shell;
5+
use uefi::{Error, Status, boot, cstr16};
6+
7+
/// Test `current_dir()` and `set_current_dir()`
8+
pub fn test_current_dir(shell: &ScopedProtocol<Shell>) {
9+
/* Test setting and getting current file system and current directory */
10+
let fs_var = cstr16!("fs0:");
11+
let dir_var = cstr16!("/");
12+
let status = shell.set_current_dir(Some(fs_var), Some(dir_var));
13+
assert!(status.is_ok());
14+
15+
let cur_fs_str = shell
16+
.current_dir(Some(fs_var))
17+
.expect("Could not get the current file system mapping");
18+
let expected_fs_str = cstr16!("FS0:\\");
19+
assert_eq!(cur_fs_str, expected_fs_str);
20+
21+
// Changing current file system
22+
let fs_var = cstr16!("fs1:");
23+
let dir_var = cstr16!("/");
24+
let status = shell.set_current_dir(Some(fs_var), Some(dir_var));
25+
assert!(status.is_ok());
26+
27+
let cur_fs_str = shell
28+
.current_dir(Some(fs_var))
29+
.expect("Could not get the current file system mapping");
30+
assert_ne!(cur_fs_str, expected_fs_str);
31+
let expected_fs_str = cstr16!("FS1:\\");
32+
assert_eq!(cur_fs_str, expected_fs_str);
33+
34+
// Changing current file system and current directory
35+
let fs_var = cstr16!("fs0:");
36+
let dir_var = cstr16!("efi/");
37+
let status = shell.set_current_dir(Some(fs_var), Some(dir_var));
38+
assert!(status.is_ok());
39+
40+
let cur_fs_str = shell
41+
.current_dir(Some(fs_var))
42+
.expect("Could not get the current file system mapping");
43+
assert_ne!(cur_fs_str, expected_fs_str);
44+
let expected_fs_str = cstr16!("FS0:\\efi");
45+
assert_eq!(cur_fs_str, expected_fs_str);
46+
47+
/* Test current working directory cases */
48+
49+
// At this point, the current working file system has not been set
50+
// So we expect a NULL output
51+
assert!(shell.current_dir(None).is_err());
52+
assert_eq!(
53+
shell.current_dir(None).err().unwrap(),
54+
Error::new(Status::NOT_FOUND, ())
55+
);
56+
57+
// Setting the current working file system and current working directory
58+
let dir_var = cstr16!("fs0:/");
59+
let status = shell.set_current_dir(None, Some(dir_var));
60+
assert!(status.is_ok());
61+
let cur_fs_str = shell
62+
.current_dir(Some(fs_var))
63+
.expect("Could not get the current file system mapping");
64+
let expected_fs_str = cstr16!("FS0:");
65+
assert_eq!(cur_fs_str, expected_fs_str);
66+
67+
let cur_fs_str = shell
68+
.current_dir(None)
69+
.expect("Could not get the current file system mapping");
70+
assert_eq!(cur_fs_str, expected_fs_str);
71+
72+
// Changing current working directory
73+
let dir_var = cstr16!("/efi");
74+
let status = shell.set_current_dir(None, Some(dir_var));
75+
assert!(status.is_ok());
76+
let cur_fs_str = shell
77+
.current_dir(Some(fs_var))
78+
.expect("Could not get the current file system mapping");
79+
let expected_fs_str = cstr16!("FS0:\\efi");
80+
assert_eq!(cur_fs_str, expected_fs_str);
81+
let cur_fs_str = shell
82+
.current_dir(None)
83+
.expect("Could not get the current file system mapping");
84+
assert_eq!(cur_fs_str, expected_fs_str);
85+
86+
// Changing current directory in a non-current working file system
87+
let fs_var = cstr16!("fs0:");
88+
let dir_var = cstr16!("efi/tools");
89+
let status = shell.set_current_dir(Some(fs_var), Some(dir_var));
90+
assert!(status.is_ok());
91+
let cur_fs_str = shell
92+
.current_dir(None)
93+
.expect("Could not get the current file system mapping");
94+
assert_ne!(cur_fs_str, expected_fs_str);
95+
96+
let expected_fs_str = cstr16!("FS0:\\efi\\tools");
97+
let cur_fs_str = shell
98+
.current_dir(Some(fs_var))
99+
.expect("Could not get the current file system mapping");
100+
assert_eq!(cur_fs_str, expected_fs_str);
101+
}
5102

6103
pub fn test() {
7104
info!("Running shell protocol tests");
8105

9106
let handle = boot::get_handle_for_protocol::<Shell>().expect("No Shell handles");
10107

11-
let mut _shell =
108+
let shell =
12109
boot::open_protocol_exclusive::<Shell>(handle).expect("Failed to open Shell protocol");
110+
111+
test_current_dir(&shell);
13112
}

‎uefi/src/proto/shell/mod.rs

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,55 @@
33
//! EFI Shell Protocol v2.2
44
55
use crate::proto::unsafe_protocol;
6-
7-
pub use uefi_raw::protocol::shell::ShellProtocol;
6+
use crate::{CStr16, Char16, Error, Result, Status, StatusExt};
7+
use core::ptr;
8+
use uefi_raw::protocol::shell::ShellProtocol;
89

910
/// Shell Protocol
1011
#[derive(Debug)]
1112
#[repr(transparent)]
12-
#[unsafe_protocol(uefi_raw::protocol::shell::ShellProtocol::GUID)]
13-
pub struct Shell(uefi_raw::protocol::shell::ShellProtocol);
13+
#[unsafe_protocol(ShellProtocol::GUID)]
14+
pub struct Shell(ShellProtocol);
15+
16+
impl Shell {
17+
/// Returns the current directory on the specified device.
18+
///
19+
/// # Arguments
20+
///
21+
/// * `file_system_mapping` - The file system mapping for which to get
22+
/// the current directory
23+
///
24+
/// # Errors
25+
///
26+
/// * [`Status::NOT_FOUND`] - Could not retrieve current directory
27+
pub fn current_dir(&self, file_system_mapping: Option<&CStr16>) -> Result<&CStr16> {
28+
let mapping_ptr: *const Char16 = file_system_mapping.map_or(ptr::null(), CStr16::as_ptr);
29+
let cur_dir = unsafe { (self.0.get_cur_dir)(mapping_ptr.cast()) };
30+
if cur_dir.is_null() {
31+
Err(Error::new(Status::NOT_FOUND, ()))
32+
} else {
33+
unsafe { Ok(CStr16::from_ptr(cur_dir.cast())) }
34+
}
35+
}
36+
37+
/// Changes the current directory on the specified device
38+
///
39+
/// # Arguments
40+
///
41+
/// * `file_system` - File system's mapped name.
42+
/// * `directory` - Directory on the device specified by
43+
/// `file_system`.
44+
///
45+
/// # Errors
46+
///
47+
/// * [`Status::NOT_FOUND`] - The directory does not exist
48+
pub fn set_current_dir(
49+
&self,
50+
file_system: Option<&CStr16>,
51+
directory: Option<&CStr16>,
52+
) -> Result {
53+
let fs_ptr: *const Char16 = file_system.map_or(ptr::null(), |x| x.as_ptr());
54+
let dir_ptr: *const Char16 = directory.map_or(ptr::null(), |x| x.as_ptr());
55+
unsafe { (self.0.set_cur_dir)(fs_ptr.cast(), dir_ptr.cast()) }.to_result()
56+
}
57+
}

0 commit comments

Comments
(0)

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