Skip to content

Commit 4e43642

Browse files
nicholasbishopphip1611
authored andcommitted
test-runner: Improve uninstall_protocol_interface example
If a protocol is installed with a data pointer, you have to pass that same pointer in when uninstalling the interface. Update the test runner to demonstrate how to do this by opening the protocol and converting the ScopedProtocol to a raw pointer.
1 parent f8168f7 commit 4e43642

File tree

1 file changed

+40
-4
lines changed

1 file changed

+40
-4
lines changed

uefi-test-runner/src/boot/misc.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
use core::ffi::c_void;
22
use core::ptr::{self, NonNull};
33

4+
use core::mem;
45
use uefi::proto::unsafe_protocol;
5-
use uefi::table::boot::{BootServices, EventType, MemoryType, SearchType, TimerTrigger, Tpl};
6+
use uefi::table::boot::{
7+
BootServices, EventType, MemoryType, OpenProtocolAttributes, OpenProtocolParams, SearchType,
8+
TimerTrigger, Tpl,
9+
};
610
use uefi::table::{Boot, SystemTable};
711
use uefi::{guid, Event, Guid, Identify};
812

@@ -84,7 +88,9 @@ fn test_watchdog(bt: &BootServices) {
8488

8589
/// Dummy protocol for tests
8690
#[unsafe_protocol("1a972918-3f69-4b5d-8cb4-cece2309c7f5")]
87-
struct TestProtocol {}
91+
struct TestProtocol {
92+
data: u32,
93+
}
8894

8995
unsafe extern "efiapi" fn _test_notify(_event: Event, _context: Option<NonNull<c_void>>) {
9096
info!("Protocol was (re)installed and this function notified.")
@@ -109,8 +115,17 @@ fn test_register_protocol_notify(bt: &BootServices) {
109115
fn test_install_protocol_interface(bt: &BootServices) {
110116
info!("Installing TestProtocol");
111117

118+
let alloc: *mut TestProtocol = bt
119+
.allocate_pool(
120+
MemoryType::BOOT_SERVICES_DATA,
121+
mem::size_of::<TestProtocol>(),
122+
)
123+
.unwrap()
124+
.cast();
125+
unsafe { alloc.write(TestProtocol { data: 123 }) };
126+
112127
let _ = unsafe {
113-
bt.install_protocol_interface(None, &TestProtocol::GUID, ptr::null_mut())
128+
bt.install_protocol_interface(None, &TestProtocol::GUID, alloc.cast())
114129
.expect("Failed to install protocol interface")
115130
};
116131

@@ -137,13 +152,34 @@ fn test_reinstall_protocol_interface(bt: &BootServices) {
137152

138153
fn test_uninstall_protocol_interface(bt: &BootServices) {
139154
info!("Uninstalling TestProtocol");
155+
140156
let handle = bt
141157
.locate_handle_buffer(SearchType::from_proto::<TestProtocol>())
142158
.expect("Failed to find protocol to uninstall")[0];
143159

144160
unsafe {
145-
bt.uninstall_protocol_interface(handle, &TestProtocol::GUID, ptr::null_mut())
161+
// Uninstalling a protocol interface requires knowing the interface
162+
// pointer. Open the protocol to get that pointer, making sure to drop
163+
// the `ScopedProtocol` _before_ uninstalling the protocol interface.
164+
let interface_ptr: *mut TestProtocol = {
165+
let mut sp = bt
166+
.open_protocol::<TestProtocol>(
167+
OpenProtocolParams {
168+
handle,
169+
agent: bt.image_handle(),
170+
controller: None,
171+
},
172+
OpenProtocolAttributes::GetProtocol,
173+
)
174+
.unwrap();
175+
assert_eq!(sp.data, 123);
176+
&mut *sp
177+
};
178+
179+
bt.uninstall_protocol_interface(handle, &TestProtocol::GUID, interface_ptr.cast())
146180
.expect("Failed to uninstall protocol interface");
181+
182+
bt.free_pool(interface_ptr.cast()).unwrap();
147183
}
148184
}
149185

0 commit comments

Comments
 (0)