]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / UefiDevicePathLibDevicePathProtocol / UefiDevicePathLib.c
1 /** @file
2 Library instance that implement UEFI Device Path Library class based on protocol
3 gEfiDevicePathUtilitiesProtocolGuid.
4
5 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include <Uefi.h>
11
12 #include <Protocol/DevicePathUtilities.h>
13 #include <Protocol/DevicePathToText.h>
14 #include <Protocol/DevicePathFromText.h>
15
16 #include <Library/DevicePathLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/BaseLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/BaseMemoryLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/PcdLib.h>
23
24 GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mDevicePathLibDevicePathUtilities = NULL;
25 GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *mDevicePathLibDevicePathToText = NULL;
26 GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mDevicePathLibDevicePathFromText = NULL;
27
28 //
29 // Template for an end-of-device path node.
30 //
31 GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_DEVICE_PATH_PROTOCOL mUefiDevicePathLibEndDevicePath = {
32 END_DEVICE_PATH_TYPE,
33 END_ENTIRE_DEVICE_PATH_SUBTYPE,
34 {
35 END_DEVICE_PATH_LENGTH,
36 0
37 }
38 };
39
40 /**
41 The constructor function caches the pointer to DevicePathUtilites protocol.
42
43 The constructor function locates DevicePathUtilities protocol from protocol database.
44 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
45
46 @param ImageHandle The firmware allocated handle for the EFI image.
47 @param SystemTable A pointer to the EFI System Table.
48
49 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
50
51 **/
52 EFI_STATUS
53 EFIAPI
54 DevicePathLibConstructor (
55 IN EFI_HANDLE ImageHandle,
56 IN EFI_SYSTEM_TABLE *SystemTable
57 )
58 {
59 EFI_STATUS Status;
60
61 Status = gBS->LocateProtocol (
62 &gEfiDevicePathUtilitiesProtocolGuid,
63 NULL,
64 (VOID **)&mDevicePathLibDevicePathUtilities
65 );
66 ASSERT_EFI_ERROR (Status);
67 ASSERT (mDevicePathLibDevicePathUtilities != NULL);
68 return Status;
69 }
70
71 /**
72 Determine whether a given device path is valid.
73 If DevicePath is NULL, then ASSERT().
74
75 @param DevicePath A pointer to a device path data structure.
76 @param MaxSize The maximum size of the device path data structure.
77
78 @retval TRUE DevicePath is valid.
79 @retval FALSE The length of any node node in the DevicePath is less
80 than sizeof (EFI_DEVICE_PATH_PROTOCOL).
81 @retval FALSE If MaxSize is not zero, the size of the DevicePath
82 exceeds MaxSize.
83 @retval FALSE If PcdMaximumDevicePathNodeCount is not zero, the node
84 count of the DevicePath exceeds PcdMaximumDevicePathNodeCount.
85 **/
86 BOOLEAN
87 EFIAPI
88 IsDevicePathValid (
89 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
90 IN UINTN MaxSize
91 )
92 {
93 UINTN Count;
94 UINTN Size;
95 UINTN NodeLength;
96
97 ASSERT (DevicePath != NULL);
98
99 if (MaxSize == 0) {
100 MaxSize = MAX_UINTN;
101 }
102
103 //
104 // Validate the input size big enough to touch the first node.
105 //
106 if (MaxSize < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
107 return FALSE;
108 }
109
110 for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
111 NodeLength = DevicePathNodeLength (DevicePath);
112 if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
113 return FALSE;
114 }
115
116 if (NodeLength > MAX_UINTN - Size) {
117 return FALSE;
118 }
119
120 Size += NodeLength;
121
122 //
123 // Validate next node before touch it.
124 //
125 if (Size > MaxSize - END_DEVICE_PATH_LENGTH ) {
126 return FALSE;
127 }
128
129 if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) {
130 Count++;
131 if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) {
132 return FALSE;
133 }
134 }
135
136 //
137 // FilePath must be a NULL-terminated string.
138 //
139 if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
140 (DevicePathSubType (DevicePath) == MEDIA_FILEPATH_DP) &&
141 (*(CHAR16 *)((UINT8 *)DevicePath + NodeLength - 2) != 0))
142 {
143 return FALSE;
144 }
145 }
146
147 //
148 // Only return TRUE when the End Device Path node is valid.
149 //
150 return (BOOLEAN)(DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH);
151 }
152
153 /**
154 Returns the Type field of a device path node.
155
156 Returns the Type field of the device path node specified by Node.
157
158 If Node is NULL, then ASSERT().
159
160 @param Node A pointer to a device path node data structure.
161
162 @return The Type field of the device path node specified by Node.
163
164 **/
165 UINT8
166 EFIAPI
167 DevicePathType (
168 IN CONST VOID *Node
169 )
170 {
171 ASSERT (Node != NULL);
172 return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Type;
173 }
174
175 /**
176 Returns the SubType field of a device path node.
177
178 Returns the SubType field of the device path node specified by Node.
179
180 If Node is NULL, then ASSERT().
181
182 @param Node A pointer to a device path node data structure.
183
184 @return The SubType field of the device path node specified by Node.
185
186 **/
187 UINT8
188 EFIAPI
189 DevicePathSubType (
190 IN CONST VOID *Node
191 )
192 {
193 ASSERT (Node != NULL);
194 return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->SubType;
195 }
196
197 /**
198 Returns the 16-bit Length field of a device path node.
199
200 Returns the 16-bit Length field of the device path node specified by Node.
201 Node is not required to be aligned on a 16-bit boundary, so it is recommended
202 that a function such as ReadUnaligned16() be used to extract the contents of
203 the Length field.
204
205 If Node is NULL, then ASSERT().
206
207 @param Node A pointer to a device path node data structure.
208
209 @return The 16-bit Length field of the device path node specified by Node.
210
211 **/
212 UINTN
213 EFIAPI
214 DevicePathNodeLength (
215 IN CONST VOID *Node
216 )
217 {
218 ASSERT (Node != NULL);
219 return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);
220 }
221
222 /**
223 Returns a pointer to the next node in a device path.
224
225 Returns a pointer to the device path node that follows the device path node
226 specified by Node.
227
228 If Node is NULL, then ASSERT().
229
230 @param Node A pointer to a device path node data structure.
231
232 @return a pointer to the device path node that follows the device path node
233 specified by Node.
234
235 **/
236 EFI_DEVICE_PATH_PROTOCOL *
237 EFIAPI
238 NextDevicePathNode (
239 IN CONST VOID *Node
240 )
241 {
242 ASSERT (Node != NULL);
243 return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + DevicePathNodeLength (Node));
244 }
245
246 /**
247 Determines if a device path node is an end node of a device path.
248 This includes nodes that are the end of a device path instance and nodes that
249 are the end of an entire device path.
250
251 Determines if the device path node specified by Node is an end node of a device path.
252 This includes nodes that are the end of a device path instance and nodes that are the
253 end of an entire device path. If Node represents an end node of a device path,
254 then TRUE is returned. Otherwise, FALSE is returned.
255
256 If Node is NULL, then ASSERT().
257
258 @param Node A pointer to a device path node data structure.
259
260 @retval TRUE The device path node specified by Node is an end node of a device path.
261 @retval FALSE The device path node specified by Node is not an end node of
262 a device path.
263
264 **/
265 BOOLEAN
266 EFIAPI
267 IsDevicePathEndType (
268 IN CONST VOID *Node
269 )
270 {
271 ASSERT (Node != NULL);
272 return (BOOLEAN)(DevicePathType (Node) == END_DEVICE_PATH_TYPE);
273 }
274
275 /**
276 Determines if a device path node is an end node of an entire device path.
277
278 Determines if a device path node specified by Node is an end node of an entire
279 device path.
280 If Node represents the end of an entire device path, then TRUE is returned.
281 Otherwise, FALSE is returned.
282
283 If Node is NULL, then ASSERT().
284
285 @param Node A pointer to a device path node data structure.
286
287 @retval TRUE The device path node specified by Node is the end of an entire device path.
288 @retval FALSE The device path node specified by Node is not the end of an entire device path.
289
290 **/
291 BOOLEAN
292 EFIAPI
293 IsDevicePathEnd (
294 IN CONST VOID *Node
295 )
296 {
297 ASSERT (Node != NULL);
298 return (BOOLEAN)(IsDevicePathEndType (Node) && DevicePathSubType (Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE);
299 }
300
301 /**
302 Determines if a device path node is an end node of a device path instance.
303
304 Determines if a device path node specified by Node is an end node of a device
305 path instance.
306 If Node represents the end of a device path instance, then TRUE is returned.
307 Otherwise, FALSE is returned.
308
309 If Node is NULL, then ASSERT().
310
311 @param Node A pointer to a device path node data structure.
312
313 @retval TRUE The device path node specified by Node is the end of a device
314 path instance.
315 @retval FALSE The device path node specified by Node is not the end of a
316 device path instance.
317
318 **/
319 BOOLEAN
320 EFIAPI
321 IsDevicePathEndInstance (
322 IN CONST VOID *Node
323 )
324 {
325 ASSERT (Node != NULL);
326 return (BOOLEAN)(IsDevicePathEndType (Node) && DevicePathSubType (Node) == END_INSTANCE_DEVICE_PATH_SUBTYPE);
327 }
328
329 /**
330 Sets the length, in bytes, of a device path node.
331
332 Sets the length of the device path node specified by Node to the value specified
333 by NodeLength. NodeLength is returned. Node is not required to be aligned on
334 a 16-bit boundary, so it is recommended that a function such as WriteUnaligned16()
335 be used to set the contents of the Length field.
336
337 If Node is NULL, then ASSERT().
338 If NodeLength >= SIZE_64KB, then ASSERT().
339 If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT().
340
341 @param Node A pointer to a device path node data structure.
342 @param Length The length, in bytes, of the device path node.
343
344 @return Length
345
346 **/
347 UINT16
348 EFIAPI
349 SetDevicePathNodeLength (
350 IN OUT VOID *Node,
351 IN UINTN Length
352 )
353 {
354 ASSERT (Node != NULL);
355 ASSERT ((Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) && (Length < SIZE_64KB));
356 return WriteUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length));
357 }
358
359 /**
360 Fills in all the fields of a device path node that is the end of an entire device path.
361
362 Fills in all the fields of a device path node specified by Node so Node represents
363 the end of an entire device path. The Type field of Node is set to
364 END_DEVICE_PATH_TYPE, the SubType field of Node is set to
365 END_ENTIRE_DEVICE_PATH_SUBTYPE, and the Length field of Node is set to
366 END_DEVICE_PATH_LENGTH. Node is not required to be aligned on a 16-bit boundary,
367 so it is recommended that a function such as WriteUnaligned16() be used to set
368 the contents of the Length field.
369
370 If Node is NULL, then ASSERT().
371
372 @param Node A pointer to a device path node data structure.
373
374 **/
375 VOID
376 EFIAPI
377 SetDevicePathEndNode (
378 OUT VOID *Node
379 )
380 {
381 ASSERT (Node != NULL);
382 CopyMem (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath));
383 }
384
385 /**
386 Returns the size of a device path in bytes.
387
388 This function returns the size, in bytes, of the device path data structure
389 specified by DevicePath including the end of device path node.
390 If DevicePath is NULL or invalid, then 0 is returned.
391
392 @param DevicePath A pointer to a device path data structure.
393
394 @retval 0 If DevicePath is NULL or invalid.
395 @retval Others The size of a device path in bytes.
396
397 **/
398 UINTN
399 EFIAPI
400 GetDevicePathSize (
401 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
402 )
403 {
404 return mDevicePathLibDevicePathUtilities->GetDevicePathSize (DevicePath);
405 }
406
407 /**
408 Creates a new copy of an existing device path.
409
410 This function allocates space for a new copy of the device path specified by
411 DevicePath. If DevicePath is NULL, then NULL is returned.
412 If the memory is successfully allocated, then the
413 contents of DevicePath are copied to the newly allocated buffer, and a pointer to that buffer
414 is returned. Otherwise, NULL is returned.
415 The memory for the new device path is allocated from EFI boot services memory.
416 It is the responsibility of the caller to free the memory allocated.
417
418 @param DevicePath A pointer to a device path data structure.
419
420 @retval NULL If DevicePath is NULL or invalid.
421 @retval Others A pointer to the duplicated device path.
422
423 **/
424 EFI_DEVICE_PATH_PROTOCOL *
425 EFIAPI
426 DuplicateDevicePath (
427 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
428 )
429 {
430 return mDevicePathLibDevicePathUtilities->DuplicateDevicePath (DevicePath);
431 }
432
433 /**
434 Creates a new device path by appending a second device path to a first device path.
435
436 This function creates a new device path by appending a copy of SecondDevicePath to a copy of
437 FirstDevicePath in a newly allocated buffer. Only the end-of-device-path device node from
438 SecondDevicePath is retained. The newly created device path is returned.
439 If FirstDevicePath is NULL, then it is ignored, and a duplicate of SecondDevicePath is returned.
440 If SecondDevicePath is NULL, then it is ignored, and a duplicate of FirstDevicePath is returned.
441 If both FirstDevicePath and SecondDevicePath are NULL, then a copy of an end-of-device-path is
442 returned.
443 If there is not enough memory for the newly allocated buffer, then NULL is returned.
444 The memory for the new device path is allocated from EFI boot services memory. It is the
445 responsibility of the caller to free the memory allocated.
446
447 @param FirstDevicePath A pointer to a device path data structure.
448 @param SecondDevicePath A pointer to a device path data structure.
449
450 @retval NULL If there is not enough memory for the newly allocated buffer.
451 @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
452 @retval Others A pointer to the new device path if success.
453 Or a copy an end-of-device-path if both FirstDevicePath and
454 SecondDevicePath are NULL.
455
456 **/
457 EFI_DEVICE_PATH_PROTOCOL *
458 EFIAPI
459 AppendDevicePath (
460 IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath OPTIONAL,
461 IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
462 )
463 {
464 return mDevicePathLibDevicePathUtilities->AppendDevicePath (FirstDevicePath, SecondDevicePath);
465 }
466
467 /**
468 Creates a new path by appending the device node to the device path.
469
470 This function creates a new device path by appending a copy of the device node
471 specified by DevicePathNode to a copy of the device path specified by DevicePath
472 in an allocated buffer.
473 The end-of-device-path device node is moved after the end of the appended device node.
474 If DevicePathNode is NULL then a copy of DevicePath is returned.
475 If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
476 path device node is returned.
477 If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
478 device node is returned.
479 If there is not enough memory to allocate space for the new device path, then
480 NULL is returned.
481 The memory is allocated from EFI boot services memory. It is the responsibility
482 of the caller to free the memory allocated.
483
484 @param DevicePath A pointer to a device path data structure.
485 @param DevicePathNode A pointer to a single device path node.
486
487 @retval NULL If there is not enough memory for the new device path.
488 @retval Others A pointer to the new device path if success.
489 A copy of DevicePathNode followed by an end-of-device-path node
490 if both FirstDevicePath and SecondDevicePath are NULL.
491 A copy of an end-of-device-path node if both FirstDevicePath
492 and SecondDevicePath are NULL.
493
494 **/
495 EFI_DEVICE_PATH_PROTOCOL *
496 EFIAPI
497 AppendDevicePathNode (
498 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL,
499 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
500 )
501 {
502 return mDevicePathLibDevicePathUtilities->AppendDeviceNode (DevicePath, DevicePathNode);
503 }
504
505 /**
506 Creates a new device path by appending the specified device path instance to
507 the specified device path.
508
509 This function creates a new device path by appending a copy of the device path
510 instance specified by DevicePathInstance to a copy of the device path specified
511 by DevicePath in a allocated buffer.
512 The end-of-device-path device node is moved after the end of the appended device
513 path instance and a new end-of-device-path-instance node is inserted between.
514 If DevicePath is NULL, then a copy if DevicePathInstance is returned.
515 If DevicePathInstance is NULL, then NULL is returned.
516 If DevicePath or DevicePathInstance is invalid, then NULL is returned.
517 If there is not enough memory to allocate space for the new device path, then
518 NULL is returned.
519 The memory is allocated from EFI boot services memory. It is the responsibility
520 of the caller to free the memory allocated.
521
522 @param DevicePath A pointer to a device path data structure.
523 @param DevicePathInstance A pointer to a device path instance.
524
525 @return A pointer to the new device path.
526
527 **/
528 EFI_DEVICE_PATH_PROTOCOL *
529 EFIAPI
530 AppendDevicePathInstance (
531 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL,
532 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
533 )
534 {
535 return mDevicePathLibDevicePathUtilities->AppendDevicePathInstance (DevicePath, DevicePathInstance);
536 }
537
538 /**
539 Creates a copy of the current device path instance and returns a pointer to the
540 next device path instance.
541
542 This function creates a copy of the current device path instance. It also updates
543 DevicePath to point to the next device path instance in the device path (or NULL
544 if no more) and updates Size to hold the size of the device path instance copy.
545 If DevicePath is NULL, then NULL is returned.
546 If there is not enough memory to allocate space for the new device path, then
547 NULL is returned.
548 The memory is allocated from EFI boot services memory. It is the responsibility
549 of the caller to free the memory allocated.
550 If Size is NULL, then ASSERT().
551
552 @param DevicePath On input, this holds the pointer to the current
553 device path instance. On output, this holds
554 the pointer to the next device path instance
555 or NULL if there are no more device path
556 instances in the device path pointer to a
557 device path data structure.
558 @param Size On output, this holds the size of the device
559 path instance, in bytes or zero, if DevicePath
560 is NULL.
561
562 @return A pointer to the current device path instance.
563
564 **/
565 EFI_DEVICE_PATH_PROTOCOL *
566 EFIAPI
567 GetNextDevicePathInstance (
568 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
569 OUT UINTN *Size
570 )
571 {
572 ASSERT (Size != NULL);
573 return mDevicePathLibDevicePathUtilities->GetNextDevicePathInstance (DevicePath, Size);
574 }
575
576 /**
577 Creates a device node.
578
579 This function creates a new device node in a newly allocated buffer of size
580 NodeLength and initializes the device path node header with NodeType and NodeSubType.
581 The new device path node is returned.
582 If NodeLength is smaller than a device path header, then NULL is returned.
583 If there is not enough memory to allocate space for the new device path, then
584 NULL is returned.
585 The memory is allocated from EFI boot services memory. It is the responsibility
586 of the caller to free the memory allocated.
587
588 @param NodeType The device node type for the new device node.
589 @param NodeSubType The device node sub-type for the new device node.
590 @param NodeLength The length of the new device node.
591
592 @return The new device path.
593
594 **/
595 EFI_DEVICE_PATH_PROTOCOL *
596 EFIAPI
597 CreateDeviceNode (
598 IN UINT8 NodeType,
599 IN UINT8 NodeSubType,
600 IN UINT16 NodeLength
601 )
602 {
603 return mDevicePathLibDevicePathUtilities->CreateDeviceNode (NodeType, NodeSubType, NodeLength);
604 }
605
606 /**
607 Determines if a device path is single or multi-instance.
608
609 This function returns TRUE if the device path specified by DevicePath is
610 multi-instance.
611 Otherwise, FALSE is returned.
612 If DevicePath is NULL or invalid, then FALSE is returned.
613
614 @param DevicePath A pointer to a device path data structure.
615
616 @retval TRUE DevicePath is multi-instance.
617 @retval FALSE DevicePath is not multi-instance, or DevicePath
618 is NULL or invalid.
619
620 **/
621 BOOLEAN
622 EFIAPI
623 IsDevicePathMultiInstance (
624 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
625 )
626 {
627 return mDevicePathLibDevicePathUtilities->IsDevicePathMultiInstance (DevicePath);
628 }
629
630 /**
631 Retrieves the device path protocol from a handle.
632
633 This function returns the device path protocol from the handle specified by Handle.
634 If Handle is NULL or Handle does not contain a device path protocol, then NULL
635 is returned.
636
637 @param Handle The handle from which to retrieve the device
638 path protocol.
639
640 @return The device path protocol from the handle specified by Handle.
641
642 **/
643 EFI_DEVICE_PATH_PROTOCOL *
644 EFIAPI
645 DevicePathFromHandle (
646 IN EFI_HANDLE Handle
647 )
648 {
649 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
650 EFI_STATUS Status;
651
652 Status = gBS->HandleProtocol (
653 Handle,
654 &gEfiDevicePathProtocolGuid,
655 (VOID *)&DevicePath
656 );
657 if (EFI_ERROR (Status)) {
658 DevicePath = NULL;
659 }
660
661 return DevicePath;
662 }
663
664 /**
665 Allocates a device path for a file and appends it to an existing device path.
666
667 If Device is a valid device handle that contains a device path protocol, then
668 a device path for the file specified by FileName is allocated and appended to
669 the device path associated with the handle Device. The allocated device path
670 is returned. If Device is NULL or Device is a handle that does not support the
671 device path protocol, then a device path containing a single device path node
672 for the file specified by FileName is allocated and returned.
673 The memory for the new device path is allocated from EFI boot services memory.
674 It is the responsibility of the caller to free the memory allocated.
675
676 If FileName is NULL, then ASSERT().
677 If FileName is not aligned on a 16-bit boundary, then ASSERT().
678
679 @param Device A pointer to a device handle. This parameter
680 is optional and may be NULL.
681 @param FileName A pointer to a Null-terminated Unicode string.
682
683 @return The allocated device path.
684
685 **/
686 EFI_DEVICE_PATH_PROTOCOL *
687 EFIAPI
688 FileDevicePath (
689 IN EFI_HANDLE Device OPTIONAL,
690 IN CONST CHAR16 *FileName
691 )
692 {
693 UINTN Size;
694 FILEPATH_DEVICE_PATH *FilePath;
695 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
696 EFI_DEVICE_PATH_PROTOCOL *FileDevicePath;
697
698 DevicePath = NULL;
699
700 Size = StrSize (FileName);
701 FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);
702 if (FileDevicePath != NULL) {
703 FilePath = (FILEPATH_DEVICE_PATH *)FileDevicePath;
704 FilePath->Header.Type = MEDIA_DEVICE_PATH;
705 FilePath->Header.SubType = MEDIA_FILEPATH_DP;
706 CopyMem (&FilePath->PathName, FileName, Size);
707 SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
708 SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));
709
710 if (Device != NULL) {
711 DevicePath = DevicePathFromHandle (Device);
712 }
713
714 DevicePath = AppendDevicePath (DevicePath, FileDevicePath);
715 FreePool (FileDevicePath);
716 }
717
718 return DevicePath;
719 }
720
721 /**
722 Locate and return the protocol instance identified by the ProtocolGuid.
723
724 @param ProtocolGuid The GUID of the protocol.
725
726 @return A pointer to the protocol instance or NULL when absent.
727 **/
728 VOID *
729 UefiDevicePathLibLocateProtocol (
730 EFI_GUID *ProtocolGuid
731 )
732 {
733 EFI_STATUS Status;
734 VOID *Protocol;
735
736 Status = gBS->LocateProtocol (
737 ProtocolGuid,
738 NULL,
739 (VOID **)&Protocol
740 );
741 if (EFI_ERROR (Status)) {
742 return NULL;
743 } else {
744 return Protocol;
745 }
746 }
747
748 /**
749 Converts a device node to its string representation.
750
751 @param DeviceNode A Pointer to the device node to be converted.
752 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
753 of the display node is used, where applicable. If DisplayOnly
754 is FALSE, then the longer text representation of the display node
755 is used.
756 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
757 representation for a device node can be used, where applicable.
758
759 @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
760 is NULL or there was insufficient memory.
761
762 **/
763 CHAR16 *
764 EFIAPI
765 ConvertDeviceNodeToText (
766 IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
767 IN BOOLEAN DisplayOnly,
768 IN BOOLEAN AllowShortcuts
769 )
770 {
771 if (mDevicePathLibDevicePathToText == NULL) {
772 mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);
773 }
774
775 if (mDevicePathLibDevicePathToText != NULL) {
776 return mDevicePathLibDevicePathToText->ConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);
777 } else {
778 return NULL;
779 }
780 }
781
782 /**
783 Converts a device path to its text representation.
784
785 @param DevicePath A Pointer to the device to be converted.
786 @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
787 of the display node is used, where applicable. If DisplayOnly
788 is FALSE, then the longer text representation of the display node
789 is used.
790 @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
791 representation for a device node can be used, where applicable.
792
793 @return A pointer to the allocated text representation of the device path or
794 NULL if DeviceNode is NULL or there was insufficient memory.
795
796 **/
797 CHAR16 *
798 EFIAPI
799 ConvertDevicePathToText (
800 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
801 IN BOOLEAN DisplayOnly,
802 IN BOOLEAN AllowShortcuts
803 )
804 {
805 if (mDevicePathLibDevicePathToText == NULL) {
806 mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);
807 }
808
809 if (mDevicePathLibDevicePathToText != NULL) {
810 return mDevicePathLibDevicePathToText->ConvertDevicePathToText (DevicePath, DisplayOnly, AllowShortcuts);
811 } else {
812 return NULL;
813 }
814 }
815
816 /**
817 Convert text to the binary representation of a device node.
818
819 @param TextDeviceNode TextDeviceNode points to the text representation of a device
820 node. Conversion starts with the first character and continues
821 until the first non-device node character.
822
823 @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
824 insufficient memory or text unsupported.
825
826 **/
827 EFI_DEVICE_PATH_PROTOCOL *
828 EFIAPI
829 ConvertTextToDeviceNode (
830 IN CONST CHAR16 *TextDeviceNode
831 )
832 {
833 if (mDevicePathLibDevicePathFromText == NULL) {
834 mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);
835 }
836
837 if (mDevicePathLibDevicePathFromText != NULL) {
838 return mDevicePathLibDevicePathFromText->ConvertTextToDeviceNode (TextDeviceNode);
839 } else {
840 return NULL;
841 }
842 }
843
844 /**
845 Convert text to the binary representation of a device path.
846
847
848 @param TextDevicePath TextDevicePath points to the text representation of a device
849 path. Conversion starts with the first character and continues
850 until the first non-device node character.
851
852 @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
853 there was insufficient memory.
854
855 **/
856 EFI_DEVICE_PATH_PROTOCOL *
857 EFIAPI
858 ConvertTextToDevicePath (
859 IN CONST CHAR16 *TextDevicePath
860 )
861 {
862 if (mDevicePathLibDevicePathFromText == NULL) {
863 mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);
864 }
865
866 if (mDevicePathLibDevicePathFromText != NULL) {
867 return mDevicePathLibDevicePathFromText->ConvertTextToDevicePath (TextDevicePath);
868 } else {
869 return NULL;
870 }
871 }