Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions uefi-raw/src/protocol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub mod nvme;
pub mod pci;
pub mod rng;
pub mod scsi;
pub mod shell;
pub mod shell_params;
pub mod string;
pub mod tcg;
Expand Down
184 changes: 184 additions & 0 deletions uefi-raw/src/protocol/shell.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

//! EFI Shell Protocol v2.2

use core::ffi::c_void;

use crate::{Char8, Char16, Event, Guid, Handle, Status, guid};

use super::device_path::DevicePathProtocol;
use super::file_system::FileInfo;
use super::shell_params::ShellFileHandle;

use bitflags::bitflags;

/// List Entry for File Lists
#[derive(Debug)]
#[repr(C)]
pub struct ListEntry {
pub f_link: *mut ListEntry,
pub b_link: *mut ListEntry,
}

/// ShellFileInfo for File Lists
#[derive(Debug)]
#[repr(C)]
pub struct ShellFileInfo {
pub link: ListEntry,
pub status: Status,
pub full_name: *mut Char16,
pub file_name: *mut Char16,
pub handle: ShellFileHandle,
pub info: FileInfo,
}

/// Used to specify where component names should be taken from
pub type ShellDeviceNameFlags = u32;

bitflags! {
/// Specifies the source of the component name
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct DeviceName: u32 {
/// Use Component Name
const DEVICE_NAME_USE_COMPONENT_NAME = 0x0000001;
/// Use Device Path
const DEVICE_NAME_USE_DEVICE_PATH = 0x0000002;
}
}

/// Shell Protocol
#[derive(Debug)]
#[repr(C)]
pub struct ShellProtocol {
pub execute: unsafe extern "efiapi" fn(
parent_image_handle: *const Handle,
command_line: *const Char16,
Copy link
Member

@phip1611 phip1611 May 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicholasbishop, I think we should use

Suggested change
command_line: *const Char16,
command_line: Option<*const Char16>,

here and other optional parameters, right? I know that this is not streamlined across the code base for all OPTIONAL parameters. What do you say?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uefi-raw should stick close to the C API, so it should not use Option. (Personally I think the UEFI spec should just remove the OPTIONAL annotation, as they use it quite inconsistently and it doesn't have a clear purpose.)

(Also, it wouldn't be compatible with the C ABI unless we also switched from a raw pointer to NonNull. Option<NonNull> is ABI compatible with a raw pointer, but Option<const*> is not, because it can't use the niche optimization.)

environment: *const *const Char16,
status_code: *mut Status,
) -> Status,
pub get_env: unsafe extern "efiapi" fn(name: *const Char16) -> *const Char16,
pub set_env: unsafe extern "efiapi" fn(
name: *const Char16,
value: *const Char16,
volatile: bool,
) -> Status,
pub get_alias: unsafe extern "efiapi" fn(alias: *const Char16, volatile: bool) -> *const Char16,
pub set_alias: unsafe extern "efiapi" fn(
command: *const Char16,
alias: *const Char16,
replace: bool,
volatile: bool,
) -> Status,
pub get_help_text: unsafe extern "efiapi" fn(
command: *const Char16,
sections: *const Char16,
help_text: *mut *mut Char16,
) -> Status,
pub get_device_path_from_map:
unsafe extern "efiapi" fn(mapping: *const Char16) -> *const DevicePathProtocol,
pub get_map_from_device_path:
unsafe extern "efiapi" fn(device_path: *mut *mut DevicePathProtocol) -> *const Char16,
pub get_device_path_from_file_path:
unsafe extern "efiapi" fn(path: *const Char16) -> *const DevicePathProtocol,
pub get_file_path_from_device_path:
unsafe extern "efiapi" fn(path: *const DevicePathProtocol) -> *const Char16,
pub set_map: unsafe extern "efiapi" fn(
device_path: *const DevicePathProtocol,
mapping: *const Char16,
) -> Status,

pub get_cur_dir: unsafe extern "efiapi" fn(file_system_mapping: *const Char16) -> *const Char16,
pub set_cur_dir:
unsafe extern "efiapi" fn(file_system: *const Char16, dir: *const Char16) -> Status,
pub open_file_list: unsafe extern "efiapi" fn(
path: *const Char16,
open_mode: u64,
file_list: *mut *mut ShellFileInfo,
) -> Status,
pub free_file_list: unsafe extern "efiapi" fn(file_list: *const *const ShellFileInfo) -> Status,
pub remove_dup_in_file_list:
unsafe extern "efiapi" fn(file_list: *const *const ShellFileInfo) -> Status,

pub batch_is_active: unsafe extern "efiapi" fn() -> bool,
pub is_root_shell: unsafe extern "efiapi" fn() -> bool,
pub enable_page_break: unsafe extern "efiapi" fn(),
pub disable_page_break: unsafe extern "efiapi" fn(),
pub get_page_break: unsafe extern "efiapi" fn() -> bool,
pub get_device_name: unsafe extern "efiapi" fn(
device_handle: Handle,
flags: ShellDeviceNameFlags,
language: *const Char8,
best_device_name: *mut *mut Char16,
) -> Status,

pub get_file_info: unsafe extern "efiapi" fn(file_handle: ShellFileHandle) -> *const FileInfo,
pub set_file_info: unsafe extern "efiapi" fn(
file_handle: ShellFileHandle,
file_info: *const FileInfo,
) -> Status,
pub open_file_by_name: unsafe extern "efiapi" fn(
file_name: *const Char16,
file_handle: *mut ShellFileHandle,
open_mode: u64,
) -> Status,
pub close_file: unsafe extern "efiapi" fn(file_handle: ShellFileHandle) -> Status,
pub create_file: unsafe extern "efiapi" fn(
file_name: *const Char16,
file_attribs: u64,
file_handle: *mut ShellFileHandle,
) -> Status,
pub read_file: unsafe extern "efiapi" fn(
file_handle: ShellFileHandle,
read_size: *mut usize,
buffer: *mut c_void,
) -> Status,
pub write_file: unsafe extern "efiapi" fn(
file_handle: ShellFileHandle,
buffer_size: *mut usize,
buffer: *mut c_void,
) -> Status,
pub delete_file: unsafe extern "efiapi" fn(file_handle: ShellFileHandle) -> Status,
pub delete_file_by_name: unsafe extern "efiapi" fn(file_name: *const Char16) -> Status,
pub get_file_position:
unsafe extern "efiapi" fn(file_handle: ShellFileHandle, position: *mut u64) -> Status,
pub set_file_position:
unsafe extern "efiapi" fn(file_handle: ShellFileHandle, position: u64) -> Status,
pub flush_file: unsafe extern "efiapi" fn(file_handle: ShellFileHandle) -> Status,
pub find_files: unsafe extern "efiapi" fn(
file_pattern: *const Char16,
file_list: *mut *mut ShellFileInfo,
) -> Status,
pub find_files_in_dir: unsafe extern "efiapi" fn(
file_dir_handle: ShellFileHandle,
file_list: *mut *mut ShellFileInfo,
) -> Status,
pub get_file_size:
unsafe extern "efiapi" fn(file_handle: ShellFileHandle, size: *mut u64) -> Status,

pub open_root: unsafe extern "efiapi" fn(
device_path: *const DevicePathProtocol,
file_handle: *mut ShellFileHandle,
) -> Status,
pub open_root_by_handle: unsafe extern "efiapi" fn(
device_handle: Handle,
file_handle: *mut ShellFileHandle,
) -> Status,

pub execution_break: Event,

pub major_version: u32,
pub minor_version: u32,
pub register_guid_name:
unsafe extern "efiapi" fn(guid: *const Guid, guid_name: *const Char16) -> Status,
pub get_guid_name:
unsafe extern "efiapi" fn(guid: *const Guid, guid_name: *mut *mut Char16) -> Status,
pub get_guid_from_name:
unsafe extern "efiapi" fn(guid_name: *const Char16, guid: *mut Guid) -> Status,
pub get_env_ex:
unsafe extern "efiapi" fn(name: *const Char16, attributes: *mut u32) -> *const Char16,
}

impl ShellProtocol {
pub const GUID: Guid = guid!("6302d008-7f9b-4f30-87ac-60c9fef5da4e");
}
4 changes: 3 additions & 1 deletion uefi-test-runner/src/proto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub fn test() {
target_arch = "aarch64"
))]
shim::test();
shell::test();
tcg::test();
}

Expand Down Expand Up @@ -89,13 +90,14 @@ mod pci;
mod pi;
mod rng;
mod scsi;
mod shell_params;
#[cfg(any(
target_arch = "x86",
target_arch = "x86_64",
target_arch = "arm",
target_arch = "aarch64"
))]
mod shell;
mod shell_params;
mod shim;
mod string;
mod tcg;
Expand Down
13 changes: 13 additions & 0 deletions uefi-test-runner/src/proto/shell.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

use uefi::boot;
use uefi::proto::shell::Shell;

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

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

let mut _shell =
boot::open_protocol_exclusive::<Shell>(handle).expect("Failed to open Shell protocol");
}
1 change: 1 addition & 0 deletions uefi/src/proto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub mod rng;
#[cfg(feature = "alloc")]
pub mod scsi;
pub mod security;
pub mod shell;
pub mod shell_params;
pub mod shim;
pub mod string;
Expand Down
13 changes: 13 additions & 0 deletions uefi/src/proto/shell/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

//! EFI Shell Protocol v2.2

use crate::proto::unsafe_protocol;

pub use uefi_raw::protocol::shell::ShellProtocol;

/// Shell Protocol
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(uefi_raw::protocol::shell::ShellProtocol::GUID)]
pub struct Shell(uefi_raw::protocol::shell::ShellProtocol);
Loading