14
14
15
15
use core:: mem;
16
16
17
+ use base:: Status ;
17
18
use console:: SimpleTextOutput ;
18
19
use guid:: Guid ;
19
20
use protocol:: Protocol ;
20
21
use void:: CVoid ;
22
+ use util:: { utf16_ptr_to_str, str_to_utf16_ptr} ;
21
23
22
24
#[ repr( u8 ) ]
23
25
pub enum DevicePathTypes {
@@ -29,24 +31,141 @@ pub enum DevicePathTypes {
29
31
End = 0x7F
30
32
}
31
33
34
+ impl Into < u8 > for DevicePathTypes {
35
+ fn into ( self ) -> u8 {
36
+ self as u8
37
+ }
38
+ }
39
+
40
+ #[ repr( u8 ) ]
41
+ pub enum HardwareSubTypes {
42
+ PCI = 0x01 ,
43
+ PCCARD = 0x02 ,
44
+ MemoryMapped = 0x03 ,
45
+ Vendor = 0x04 ,
46
+ Controller = 0x05 ,
47
+ BMC = 0x06
48
+ }
49
+
50
+ impl Into < u8 > for HardwareSubTypes {
51
+ fn into ( self ) -> u8 {
52
+ self as u8
53
+ }
54
+ }
55
+
56
+ #[ repr( u8 ) ]
57
+ pub enum ACPISubTypes {
58
+ ACPIDevicePath = 0x01 ,
59
+ ExpandedACPIDevicePath = 0x02 ,
60
+ _ADR = 0x03
61
+ }
62
+
63
+ impl Into < u8 > for ACPISubTypes {
64
+ fn into ( self ) -> u8 {
65
+ self as u8
66
+ }
67
+ }
68
+
69
+ #[ allow( non_camel_case_types) ]
70
+ #[ repr( u8 ) ]
71
+ pub enum MessagingSubTypes {
72
+ ATAPI = 0x01 ,
73
+ SCSI = 0x02 ,
74
+ FibreChannel = 0x03 ,
75
+ // The EFI specification calls this type "1394", but that won't work as an enum variant for
76
+ // Rust.
77
+ FireWire = 0x4 ,
78
+ USB = 0x5 ,
79
+ I2O = 0x6 ,
80
+ Infiniband = 0x9 ,
81
+ Vendor = 0xA ,
82
+ MACAddress = 0xB ,
83
+ IPv4 = 0xC ,
84
+ IPv6 = 0xD ,
85
+ UART = 0xE ,
86
+ USBClass = 0xF ,
87
+ USBWWID = 0x10 ,
88
+ DeviceLogicalUnit = 0x11 ,
89
+ SATA = 0x12 ,
90
+ iSCSI = 0x13 ,
91
+ Vlan = 0x14 ,
92
+ FibreChannelEx = 0x15 ,
93
+ SASEx = 0x16 ,
94
+ NVMExpressNamespace = 0x17 ,
95
+ URI = 0x18 ,
96
+ UFS = 0x19 ,
97
+ SD = 0x1A ,
98
+ Bluetooth = 0x1B ,
99
+ WiFi = 0x1C ,
100
+ eMMC = 0x1D
101
+ }
102
+
103
+ impl Into < u8 > for MessagingSubTypes {
104
+ fn into ( self ) -> u8 {
105
+ self as u8
106
+ }
107
+ }
108
+
109
+ #[ repr( u8 ) ]
110
+ pub enum MediaSubTypes {
111
+ HardDrive = 0x1 ,
112
+ CDROM = 0x2 ,
113
+ Vendor = 0x3 ,
114
+ FilePath = 0x4 ,
115
+ MediaProtocol = 0x5 ,
116
+ PIWGFirmwareFile = 0x6 ,
117
+ PIWGFirmwareVolume = 0x7 ,
118
+ RelativeOffsetRange = 0x8 ,
119
+ RAMDisk = 0x9
120
+ }
121
+
122
+ impl Into < u8 > for MediaSubTypes {
123
+ fn into ( self ) -> u8 {
124
+ self as u8
125
+ }
126
+ }
127
+
128
+ #[ repr( u8 ) ]
129
+ pub enum BIOSSubTypes {
130
+ BIOSBootSpecification = 0x1
131
+ }
132
+
133
+ impl Into < u8 > for BIOSSubTypes {
134
+ fn into ( self ) -> u8 {
135
+ self as u8
136
+ }
137
+ }
138
+
32
139
#[ repr( u8 ) ]
33
140
pub enum EndPathSubTypes {
34
141
EndInstance = 0x01 ,
35
142
EndEntirePath = 0xFF
36
143
}
37
144
145
+ impl Into < u8 > for EndPathSubTypes {
146
+ fn into ( self ) -> u8 {
147
+ self as u8
148
+ }
149
+ }
150
+
38
151
/// GUID for UEFI protocol for device paths
39
152
pub static EFI_DEVICE_PATH_PROTOCOL_GUID : Guid = Guid ( 0x09576E91 , 0x6D3F , 0x11D2 , [ 0x8E , 0x39 , 0x00 , 0xA0 , 0xC9 , 0x69 , 0x72 , 0x3B ] ) ;
40
153
41
154
/// GUID for UEFI protocol for converting a DevicePath to text
42
155
pub static EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID : Guid = Guid ( 0x8B843E20 , 0x8132 , 0x4852 , [ 0x90 , 0xCC , 0x55 , 0x1A , 0x4E , 0x4A , 0x7F , 0x1C ] ) ;
43
156
157
+ /// GUID for UEFI protocol for converting text to a DevicePath
158
+ pub static EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID : Guid = Guid ( 0x5C99A21 , 0xC70F , 0x4AD2 , [ 0x8A , 0x5F , 0x35 , 0xDF , 0x33 , 0x43 , 0xF5 , 0x1E ] ) ;
159
+
160
+ /// GUID for UEFI protocol for device path utilities
161
+ pub static EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID : Guid = Guid ( 0x379BE4E , 0xD706 , 0x437D , [ 0xB0 , 0x37 , 0xED , 0xB8 , 0x2F , 0xB7 , 0x72 , 0xA4 ] ) ;
162
+
44
163
#[ derive( Debug ) ]
45
164
#[ repr( C ) ]
46
165
pub struct DevicePathProtocol {
47
- type_ : u8 ,
48
- sub_type : u8 ,
49
- length : [ u8 ; 2 ] ,
166
+ pub type_ : u8 ,
167
+ pub sub_type : u8 ,
168
+ pub length : [ u8 ; 2 ] ,
50
169
}
51
170
52
171
impl Protocol for DevicePathProtocol {
@@ -77,40 +196,119 @@ impl Protocol for DevicePathToTextProtocol {
77
196
}
78
197
79
198
impl DevicePathToTextProtocol {
80
- pub fn device_path_node_to_text ( & self , device_node : * const DevicePathProtocol , display_only : bool , allow_shortcuts : bool ) -> * const u16 {
81
- unsafe {
82
- ( self . device_path_node_to_text ) ( device_node, display_only as u8 , allow_shortcuts as u8 )
83
- }
199
+ pub fn device_path_node_to_text ( & self , device_node : * const DevicePathProtocol , display_only : bool , allow_shortcuts : bool ) -> Result < & str , Status > {
200
+ let chars: * const u16 = unsafe { ( self . device_path_node_to_text ) ( device_node, display_only as u8 , allow_shortcuts as u8 ) } ;
201
+ let out = utf16_ptr_to_str ( chars) ;
202
+ :: get_system_table ( ) . boot_services ( ) . free_pool ( chars) ;
203
+ out
84
204
}
85
205
86
- pub fn device_path_to_text ( & self , device_node : * const DevicePathProtocol , display_only : bool , allow_shortcuts : bool ) -> * const u16 {
87
- unsafe {
88
- ( self . device_path_to_text ) ( device_node, display_only as u8 , allow_shortcuts as u8 )
89
- }
206
+ pub fn device_path_to_text ( & self , device_node : * const DevicePathProtocol , display_only : bool , allow_shortcuts : bool ) -> Result < & str , Status > {
207
+ let chars: * const u16 = unsafe { ( self . device_path_to_text ) ( device_node, display_only as u8 , allow_shortcuts as u8 ) } ;
208
+ let out = utf16_ptr_to_str ( chars) ;
209
+ :: get_system_table ( ) . boot_services ( ) . free_pool ( chars) ;
210
+ out
90
211
}
91
212
92
- pub fn print_device_path_node ( device_node : * const DevicePathProtocol , display_only : bool , allow_shortcuts : bool ) {
213
+ pub fn print_device_path_node ( device_node : * const DevicePathProtocol , display_only : bool , allow_shortcuts : bool ) -> Result < ( ) , Status > {
93
214
let system_table = :: get_system_table ( ) ;
94
215
let boot_services = system_table. boot_services ( ) ;
95
216
96
- let this: & ' static DevicePathToTextProtocol = boot_services. locate_protocol ( 0 as * const CVoid ) . unwrap ( ) ;
97
-
98
- let ptr = this. device_path_node_to_text ( device_node, display_only, allow_shortcuts) ;
99
-
100
- system_table. console ( ) . write_raw ( ptr) ;
101
- system_table. boot_services ( ) . free_pool ( ptr) ;
217
+ boot_services
218
+ . locate_protocol :: < DevicePathToTextProtocol > ( 0 as * const CVoid )
219
+ . and_then ( |this| {
220
+ this. device_path_node_to_text ( device_node, display_only, allow_shortcuts)
221
+ . map ( |result| {
222
+ system_table. console ( ) . write ( result) ;
223
+ ( )
224
+ } )
225
+ } )
102
226
}
103
227
104
- pub fn print_device_path ( device_node : * const DevicePathProtocol , display_only : bool , allow_shortcuts : bool ) {
228
+ pub fn print_device_path ( device_node : * const DevicePathProtocol , display_only : bool , allow_shortcuts : bool ) -> Result < ( ) , Status > {
105
229
let system_table = :: get_system_table ( ) ;
106
230
let boot_services = system_table. boot_services ( ) ;
107
231
108
- let this: & ' static DevicePathToTextProtocol = boot_services. locate_protocol ( 0 as * const CVoid ) . unwrap ( ) ;
232
+ boot_services
233
+ . locate_protocol :: < DevicePathToTextProtocol > ( 0 as * const CVoid )
234
+ . and_then ( |this| {
235
+ this. device_path_to_text ( device_node, display_only, allow_shortcuts)
236
+ . map ( |result| {
237
+ system_table. console ( ) . write ( result) ;
238
+ ( )
239
+ } )
240
+ } )
241
+ }
242
+ }
243
+
244
+ #[ repr( C ) ]
245
+ pub struct DevicePathFromTextProtocol {
246
+ text_to_device_path_node : unsafe extern "win64" fn ( text : * const u16 ) -> * const DevicePathProtocol ,
247
+ text_to_device_path : unsafe extern "win64" fn ( text : * const u16 ) -> * const DevicePathProtocol ,
248
+ }
249
+
250
+ impl Protocol for DevicePathFromTextProtocol {
251
+ fn guid ( ) -> & ' static Guid {
252
+ & EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID
253
+ }
254
+ }
255
+
256
+ impl DevicePathFromTextProtocol {
257
+ pub fn text_to_device_path_node ( & self , path : & str ) -> Result < & DevicePathProtocol , Status > {
258
+ str_to_utf16_ptr ( path)
259
+ . map ( |utf16_str| {
260
+ let out = unsafe { & * ( ( self . text_to_device_path_node ) ( utf16_str) ) } ;
261
+ :: get_system_table ( ) . boot_services ( ) . free_pool ( utf16_str) ;
262
+ out
263
+ } )
264
+ }
109
265
110
- let ptr = this. device_path_to_text ( device_node, display_only, allow_shortcuts) ;
266
+ pub fn text_to_device_path ( & self , path : & str ) -> Result < & DevicePathProtocol , Status > {
267
+ str_to_utf16_ptr ( path)
268
+ . map ( |utf16_str| {
269
+ let out = unsafe { & * ( ( self . text_to_device_path ) ( utf16_str) ) } ;
270
+ :: get_system_table ( ) . boot_services ( ) . free_pool ( utf16_str) ;
271
+ out
272
+ } )
273
+ }
274
+ }
111
275
112
- system_table. console ( ) . write_raw ( ptr) ;
113
- system_table. boot_services ( ) . free_pool ( ptr) ;
276
+ #[ repr( C ) ]
277
+ pub struct DevicePathUtilitiesProtocol {
278
+ get_device_path_size : * const CVoid ,
279
+ duplicate_device_path : * const CVoid ,
280
+ append_device_path : unsafe extern "win64" fn ( src1 : * const DevicePathProtocol , src2 : * const DevicePathProtocol ) -> * const DevicePathProtocol ,
281
+ append_device_node : * const CVoid ,
282
+ append_device_path_instance : * const CVoid ,
283
+ get_next_device_path_instance : * const CVoid ,
284
+ is_device_path_multi_instance : * const CVoid ,
285
+ create_device_node : unsafe extern "win64" fn ( node_type : u8 , node_subtype : u8 , node_length : u16 ) -> * const DevicePathProtocol
286
+ }
287
+
288
+ impl Protocol for DevicePathUtilitiesProtocol {
289
+ fn guid ( ) -> & ' static Guid {
290
+ & EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID
114
291
}
115
292
}
116
293
294
+ impl DevicePathUtilitiesProtocol {
295
+ pub fn append_device_path ( & self , src1 : * const DevicePathProtocol , src2 : * const DevicePathProtocol ) -> Result < * const DevicePathProtocol , Status > {
296
+ unsafe {
297
+ let out = ( self . append_device_path ) ( src1, src2) ;
298
+ if out == 0 as * const DevicePathProtocol {
299
+ return Err ( Status :: InvalidParameter ) ;
300
+ }
301
+ Ok ( out)
302
+ }
303
+ }
304
+
305
+ pub fn create_device_node < T : Into < u8 > , U : Into < u8 > > ( & self , node_type : T , node_subtype : U , node_length : u16 ) -> Result < * const DevicePathProtocol , Status > {
306
+ unsafe {
307
+ let out = ( self . create_device_node ) ( node_type. into ( ) , node_subtype. into ( ) , node_length) ;
308
+ if out == 0 as * const DevicePathProtocol {
309
+ return Err ( Status :: InvalidParameter ) ;
310
+ }
311
+ Ok ( out)
312
+ }
313
+ }
314
+ }
0 commit comments