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 8a54c28

Browse files
committed
fs: add high-level file system abstraction
1 parent 4db6d17 commit 8a54c28

File tree

14 files changed

+909
-18
lines changed

14 files changed

+909
-18
lines changed

‎CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,19 @@
22

33
## uefi - [Unreleased]
44

5+
### Added
6+
7+
- There is a new `fs` module that provides a high-level API for file-system
8+
access. The API is close to the `std::fs` module.
9+
510
### Changed
611

712
- The `global_allocator` module has been renamed to `allocator`, and is now
813
available regardless of whether the `global_allocator` feature is enabled. The
914
`global_allocator` feature now only controls whether `allocator::Allocator` is
1015
set as Rust's global allocator.
16+
- `Image::get_image_file_system` now returns a `fs::FileSystem` instead of the
17+
protocol.
1118

1219
## uefi-macros - [Unreleased]
1320

‎Cargo.lock

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//! Tests functionality from the `uefi::fs` module. See function [`test`].
2+
3+
use alloc::string::{String, ToString};
4+
use alloc::vec::Vec;
5+
use uefi::fs::{FileSystem, FileSystemError};
6+
use uefi::proto::media::fs::SimpleFileSystem;
7+
use uefi::table::boot::ScopedProtocol;
8+
9+
/// Tests functionality from the `uefi::fs` module. This test relies on a
10+
/// working File System Protocol, which is tested at a dedicated place.
11+
pub fn test(sfs: ScopedProtocol<SimpleFileSystem>) -> Result<(), FileSystemError> {
12+
let mut fs = FileSystem::new(sfs);
13+
14+
fs.create_dir("test_file_system_abs")?;
15+
16+
// slash is transparently transformed to backslash
17+
fs.write("test_file_system_abs/foo", "hello")?;
18+
// absolute or relative paths are supported; ./ is ignored
19+
fs.copy("\\test_file_system_abs/foo", "\\test_file_system_abs/./bar")?;
20+
let read = fs.read("\\test_file_system_abs\\bar")?;
21+
let read = String::from_utf8(read).expect("Should be valid utf8");
22+
assert_eq!(read, "hello");
23+
24+
assert_eq!(
25+
fs.try_exists("test_file_system_abs\\barfoo"),
26+
Err(FileSystemError::OpenError(
27+
"\\test_file_system_abs\\barfoo".to_string()
28+
))
29+
);
30+
fs.rename("test_file_system_abs\\bar", "test_file_system_abs\\barfoo")?;
31+
assert!(fs.try_exists("test_file_system_abs\\barfoo").is_ok());
32+
33+
let entries = fs
34+
.read_dir("test_file_system_abs")?
35+
.map(|e| {
36+
e.expect("Should return boxed file info")
37+
.file_name()
38+
.to_string()
39+
})
40+
.collect::<Vec<_>>();
41+
assert_eq!(&[".", "..", "foo", "barfoo"], entries.as_slice());
42+
43+
fs.create_dir("/deeply_nested_test")?;
44+
fs.create_dir("/deeply_nested_test/1")?;
45+
fs.create_dir("/deeply_nested_test/1/2")?;
46+
fs.create_dir("/deeply_nested_test/1/2/3")?;
47+
fs.create_dir("/deeply_nested_test/1/2/3/4")?;
48+
fs.create_dir_all("/deeply_nested_test/1/2/3/4/5/6/7")?;
49+
fs.try_exists("/deeply_nested_test/1/2/3/4/5/6/7")?;
50+
// TODO
51+
// fs.remove_dir_all("/deeply_nested_test/1/2/3/4/5/6/7")?;
52+
fs.remove_dir("/deeply_nested_test/1/2/3/4/5/6/7")?;
53+
let exists = matches!(fs.try_exists("/deeply_nested_test/1/2/3/4/5/6/7"), Ok(_));
54+
assert!(!exists);
55+
56+
Ok(())
57+
}

‎uefi-test-runner/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use uefi::Result;
1313
use uefi_services::{print, println};
1414

1515
mod boot;
16+
mod fs;
1617
mod proto;
1718
mod runtime;
1819

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,8 +433,12 @@ pub fn test(bt: &BootServices) {
433433
test_partition_info(bt, handle);
434434
}
435435

436-
// Close the `SimpleFileSystem` protocol so that the raw disk tests work.
437-
drop(sfs);
436+
// Invoke the fs test after the basic low-level file system protocol
437+
// tests succeeded.
438+
439+
// This will also drop the `SimpleFileSystem` protocol so that the raw disk
440+
// tests work.
441+
crate::fs::test(sfs).unwrap();
438442

439443
test_raw_disk_io(handle, bt);
440444
test_raw_disk_io2(handle, bt);

‎uefi/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ unstable = []
2525

2626
[dependencies]
2727
bitflags = "1.3.1"
28+
derive_more = { version = "0.99.17", features = ["display"] }
2829
log = { version = "0.4.5", default-features = false }
2930
ptr_meta = { version = "0.2.0", default-features = false }
3031
ucs2 = "0.3.2"

‎uefi/src/fs/dir_entry_iter.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//! Module for directory iteration. See [`UefiDirectoryIter`].
2+
3+
use super::*;
4+
use alloc::boxed::Box;
5+
use uefi::Result;
6+
7+
/// Iterates over the entries of an UEFI directory. It returns boxed values of
8+
/// type [`UefiFileInfo`].
9+
#[derive(Debug)]
10+
pub struct UefiDirectoryIter(UefiDirectoryHandle);
11+
12+
impl UefiDirectoryIter {
13+
/// Constructor.
14+
pub fn new(handle: UefiDirectoryHandle) -> Self {
15+
Self(handle)
16+
}
17+
}
18+
19+
impl Iterator for UefiDirectoryIter {
20+
type Item = Result<Box<UefiFileInfo>, ()>;
21+
22+
fn next(&mut self) -> Option<Self::Item> {
23+
let e = self.0.read_entry_boxed();
24+
match e {
25+
// no more entries
26+
Ok(None) => None,
27+
Ok(Some(e)) => Some(Ok(e)),
28+
Err(e) => Some(Err(e)),
29+
}
30+
}
31+
}

0 commit comments

Comments
(0)

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