Skip to content

Commit 1f47d4d

Browse files
committed
fs: add high-level file system abstraction
1 parent 314b8dd commit 1f47d4d

File tree

13 files changed

+891
-14
lines changed

13 files changed

+891
-14
lines changed

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: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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>) {
12+
let mut fs = FileSystem::new(sfs);
13+
14+
fs.create_dir("test_file_system_abs").unwrap();
15+
16+
// slash is transparently transformed to backslash
17+
fs.write("test_file_system_abs/foo", "hello").unwrap();
18+
// absolute or relative paths are supported; ./ is ignored
19+
fs.copy("\\test_file_system_abs/foo", "\\test_file_system_abs/./bar")
20+
.unwrap();
21+
let read = fs.read("\\test_file_system_abs\\bar").unwrap();
22+
let read = String::from_utf8(read).unwrap();
23+
assert_eq!(read, "hello");
24+
25+
assert_eq!(
26+
fs.try_exists("test_file_system_abs\\barfoo"),
27+
Err(FileSystemError::OpenError(
28+
"\\test_file_system_abs\\barfoo".to_string()
29+
))
30+
);
31+
fs.rename("test_file_system_abs\\bar", "test_file_system_abs\\barfoo")
32+
.unwrap();
33+
assert!(fs.try_exists("test_file_system_abs\\barfoo").is_ok());
34+
35+
let entries = fs
36+
.read_dir("test_file_system_abs")
37+
.unwrap()
38+
.map(|e| e.unwrap().file_name().to_string())
39+
.collect::<Vec<_>>();
40+
assert_eq!(&[".", "..", "foo", "barfoo"], entries.as_slice());
41+
42+
/*fs.create_dir("/deeply_nested_test").unwrap();
43+
fs.create_dir("/deeply_nested_test/1").unwrap();
44+
fs.create_dir("/deeply_nested_test/1/2").unwrap();
45+
fs.create_dir("/deeply_nested_test/1/2/3").unwrap();
46+
fs.create_dir("/deeply_nested_test/1/2/3/4").unwrap();*/
47+
fs.create_dir_all("/deeply_nested_test/1/2/3/4/5/6/7")
48+
.unwrap();
49+
fs.try_exists("/deeply_nested_test/1/2/3/4/5/6/7").unwrap();
50+
//fs.remove_dir_all("/deeply_nested_test/1/2/3/4/5/6/7").unwrap();
51+
fs.remove_dir("/deeply_nested_test/1/2/3/4/5/6/7").unwrap();
52+
let x = fs.try_exists("/deeply_nested_test/1/2/3/4/5/6/7");
53+
assert!(x.is_err());
54+
}

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);
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)