1
1
use core:: ffi:: c_void;
2
2
use core:: ptr:: { self , NonNull } ;
3
3
4
+ use core:: mem;
4
5
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
+ } ;
6
10
use uefi:: table:: { Boot , SystemTable } ;
7
11
use uefi:: { guid, Event , Guid , Identify } ;
8
12
@@ -84,7 +88,9 @@ fn test_watchdog(bt: &BootServices) {
84
88
85
89
/// Dummy protocol for tests
86
90
#[ unsafe_protocol( "1a972918-3f69-4b5d-8cb4-cece2309c7f5" ) ]
87
- struct TestProtocol { }
91
+ struct TestProtocol {
92
+ data : u32 ,
93
+ }
88
94
89
95
unsafe extern "efiapi" fn _test_notify ( _event : Event , _context : Option < NonNull < c_void > > ) {
90
96
info ! ( "Protocol was (re)installed and this function notified." )
@@ -109,8 +115,17 @@ fn test_register_protocol_notify(bt: &BootServices) {
109
115
fn test_install_protocol_interface ( bt : & BootServices ) {
110
116
info ! ( "Installing TestProtocol" ) ;
111
117
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
+
112
127
let _ = unsafe {
113
- bt. install_protocol_interface ( None , & TestProtocol :: GUID , ptr :: null_mut ( ) )
128
+ bt. install_protocol_interface ( None , & TestProtocol :: GUID , alloc . cast ( ) )
114
129
. expect ( "Failed to install protocol interface" )
115
130
} ;
116
131
@@ -137,13 +152,34 @@ fn test_reinstall_protocol_interface(bt: &BootServices) {
137
152
138
153
fn test_uninstall_protocol_interface ( bt : & BootServices ) {
139
154
info ! ( "Uninstalling TestProtocol" ) ;
155
+
140
156
let handle = bt
141
157
. locate_handle_buffer ( SearchType :: from_proto :: < TestProtocol > ( ) )
142
158
. expect ( "Failed to find protocol to uninstall" ) [ 0 ] ;
143
159
144
160
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 ( ) )
146
180
. expect ( "Failed to uninstall protocol interface" ) ;
181
+
182
+ bt. free_pool ( interface_ptr. cast ( ) ) . unwrap ( ) ;
147
183
}
148
184
}
149
185
0 commit comments