@@ -77,16 +77,28 @@ pub mod build;
77
77
pub mod text;
78
78
79
79
mod device_path_gen;
80
+
80
81
pub use device_path_gen:: {
81
82
acpi, bios_boot_spec, end, hardware, media, messaging, DevicePathNodeEnum ,
82
83
} ;
84
+ #[ cfg( feature = "alloc" ) ]
85
+ use { alloc:: vec:: Vec , uefi:: CString16 } ;
83
86
84
87
use crate :: proto:: { unsafe_protocol, ProtocolPointer } ;
85
88
use core:: ffi:: c_void;
86
89
use core:: fmt:: { self , Debug , Formatter } ;
87
90
use core:: mem;
88
91
use core:: ops:: Deref ;
89
92
use ptr_meta:: Pointee ;
93
+ use uefi:: data_types:: FromSliceWithNulError ;
94
+ use uefi:: proto:: device_path:: text:: { AllowShortcuts , DisplayOnly } ;
95
+ use uefi:: CStr16 ;
96
+
97
+ use crate :: prelude:: BootServices ;
98
+ use crate :: proto:: device_path:: text:: DevicePathToText ;
99
+ use crate :: table:: boot:: { OpenProtocolParams , SearchType } ;
100
+ use crate :: table:: { Boot , Table } ;
101
+ use uefi:: table:: boot:: OpenProtocolAttributes ;
90
102
91
103
opaque_type ! {
92
104
/// Opaque type that should be used to represent a pointer to a
@@ -187,6 +199,18 @@ impl DevicePathNode {
187
199
pub fn as_enum ( & self ) -> Result < DevicePathNodeEnum , NodeConversionError > {
188
200
DevicePathNodeEnum :: try_from ( self )
189
201
}
202
+
203
+ /// If the device path node is of type (0x4, 0x4), it returns the underlying
204
+ /// data as [`CStr16`].
205
+ pub fn data_as_filename ( & self ) -> Option < Result < & CStr16 , FromSliceWithNulError > > {
206
+ if self . device_type ( ) == DeviceType :: MEDIA
207
+ && self . sub_type ( ) == DeviceSubType :: HARDWARE_VENDOR
208
+ {
209
+ Some ( CStr16 :: from_u8_with_nul ( self . data ( ) ) )
210
+ } else {
211
+ None
212
+ }
213
+ }
190
214
}
191
215
192
216
impl Debug for DevicePathNode {
@@ -332,6 +356,75 @@ impl DevicePath {
332
356
stop_condition : StopCondition :: EndEntireNode ,
333
357
}
334
358
}
359
+
360
+ #[ cfg( feature = "alloc" ) ]
361
+ pub fn to_text_by_node (
362
+ & self ,
363
+ bs : & BootServices ,
364
+ ) -> crate :: Result < Vec < ( & DevicePathNode , CString16 ) > > {
365
+ use uefi:: Identify ;
366
+ let & handle = bs
367
+ . locate_handle_buffer ( SearchType :: ByProtocol ( & DevicePathToText :: GUID ) )
368
+ . unwrap ( )
369
+ . first ( )
370
+ . unwrap ( ) ;
371
+
372
+ let to_text_protocol = unsafe {
373
+ bs. open_protocol :: < DevicePathToText > (
374
+ OpenProtocolParams {
375
+ handle,
376
+ agent : bs. image_handle ( ) ,
377
+ controller : None ,
378
+ } ,
379
+ OpenProtocolAttributes :: GetProtocol ,
380
+ )
381
+ }
382
+ . unwrap ( ) ;
383
+
384
+ Ok ( self
385
+ . node_iter ( )
386
+ . map ( |node| {
387
+ let cstr16 = to_text_protocol
388
+ . convert_device_node_to_text (
389
+ bs,
390
+ node,
391
+ DisplayOnly ( false ) ,
392
+ AllowShortcuts ( false ) ,
393
+ )
394
+ . unwrap ( ) ;
395
+ let cstr16 = & * cstr16;
396
+ ( node, CString16 :: from ( cstr16) )
397
+ } )
398
+ . collect ( ) )
399
+ }
400
+
401
+ #[ cfg( feature = "alloc" ) ]
402
+ pub fn to_text ( & self , bs : & BootServices ) -> crate :: Result < CString16 > {
403
+ use uefi:: Identify ;
404
+ let & handle = bs
405
+ . locate_handle_buffer ( SearchType :: ByProtocol ( & DevicePathToText :: GUID ) )
406
+ . unwrap ( )
407
+ . first ( )
408
+ . unwrap ( ) ;
409
+
410
+ let to_text_protocol = unsafe {
411
+ bs. open_protocol :: < DevicePathToText > (
412
+ OpenProtocolParams {
413
+ handle,
414
+ agent : bs. image_handle ( ) ,
415
+ controller : None ,
416
+ } ,
417
+ OpenProtocolAttributes :: GetProtocol ,
418
+ )
419
+ }
420
+ . unwrap ( ) ;
421
+
422
+ let cstr16 = to_text_protocol
423
+ . convert_device_path_to_text ( bs, self , DisplayOnly ( false ) , AllowShortcuts ( false ) )
424
+ . unwrap ( ) ;
425
+ let cstr16 = & * cstr16;
426
+ Ok ( CString16 :: from ( cstr16) )
427
+ }
335
428
}
336
429
337
430
impl Debug for DevicePath {
0 commit comments