xref: /freebsd/lib/libefivar/efivar-dp-format.c (revision dd41de95a84d979615a2ef11df6850622bf6184e)
1 /*-
2  * Copyright (c) 2017 Netflix, Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25 
26 /*
27  * Routines to format EFI_DEVICE_PATHs from the UEFI standard. Much of
28  * this file is taken from EDK2 and rototilled.
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include <efivar.h>
35 #include <stdio.h>
36 #include <string.h>
37 
38 #include "efichar.h"
39 
40 #include "efi-osdep.h"
41 #include "efivar-dp.h"
42 
43 #include "uefi-dplib.h"
44 
45 /*
46  * This is a lie, but since we have converted everything
47  * from wide to narrow, it's the right lie now.
48  */
49 #define UnicodeSPrint snprintf
50 
51 /*
52  * Taken from MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
53  * hash a11928f3310518ab1c6fd34e8d0fdbb72de9602c 2017-Mar-01
54  * heavily modified:
55  *	wide strings converted to narrow
56  *	Low level printing code redone for narrow strings
57  *	Routines made static
58  *	%s -> %S in spots (where it is still UCS-2)
59  *	%a (ascii) -> %s
60  *	%g -> %36s hack to print guid (see above for caveat)
61  *	some tidying up of const and deconsting. It's evil, but const
62  *	  poisoning the whole file was too much.
63  */
64 
65 /** @file
66   DevicePathToText protocol as defined in the UEFI 2.0 specification.
67 
68   (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
69 Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
70 This program and the accompanying materials
71 are licensed and made available under the terms and conditions of the BSD License
72 which accompanies this distribution.  The full text of the license may be found at
73 http://opensource.org/licenses/bsd-license.php
74 
75 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
76 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
77 
78 **/
79 
80 // #include "UefiDevicePathLib.h"
81 
82 /**
83   Concatenates a formatted unicode string to allocated pool. The caller must
84   free the resulting buffer.
85 
86   @param Str             Tracks the allocated pool, size in use, and
87                          amount of pool allocated.
88   @param Fmt             The format string
89   @param ...             Variable arguments based on the format string.
90 
91   @return Allocated buffer with the formatted string printed in it.
92           The caller must free the allocated buffer. The buffer
93           allocation is not packed.
94 
95 **/
96 static char *
97 EFIAPI
98 UefiDevicePathLibCatPrint (
99   IN OUT POOL_PRINT   *Str,
100   IN const char       *Fmt,
101   ...
102   )
103 {
104   UINTN   Count;
105   VA_LIST Args;
106 
107   VA_START (Args, Fmt);
108   Count = vsnprintf(NULL, 0, Fmt, Args);
109   VA_END(Args);
110 
111   if ((Str->Count + (Count + 1)) > Str->Capacity) {
112     Str->Capacity = (Str->Count + (Count + 1) * 2);
113     Str->Str = reallocf(Str->Str, Str->Capacity);
114     ASSERT (Str->Str != NULL);
115   }
116   VA_START (Args, Fmt);
117   vsnprintf(Str->Str + Str->Count, Str->Capacity - Str->Count, Fmt, Args);
118   Str->Count += Count;
119 
120   VA_END (Args);
121   return Str->Str;
122 }
123 
124 /**
125   Converts a PCI device path structure to its string representative.
126 
127   @param Str             The string representative of input device.
128   @param DevPath         The input device path structure.
129   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
130                          of the display node is used, where applicable. If DisplayOnly
131                          is FALSE, then the longer text representation of the display node
132                          is used.
133   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
134                          representation for a device node can be used, where applicable.
135 
136 **/
137 static VOID
138 DevPathToTextPci (
139   IN OUT POOL_PRINT  *Str,
140   IN VOID            *DevPath,
141   IN BOOLEAN         DisplayOnly,
142   IN BOOLEAN         AllowShortcuts
143   )
144 {
145   PCI_DEVICE_PATH *Pci;
146 
147   Pci = DevPath;
148   UefiDevicePathLibCatPrint (Str, "Pci(0x%x,0x%x)", Pci->Device, Pci->Function);
149 }
150 
151 /**
152   Converts a PC Card device path structure to its string representative.
153 
154   @param Str             The string representative of input device.
155   @param DevPath         The input device path structure.
156   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
157                          of the display node is used, where applicable. If DisplayOnly
158                          is FALSE, then the longer text representation of the display node
159                          is used.
160   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
161                          representation for a device node can be used, where applicable.
162 
163 **/
164 static VOID
165 DevPathToTextPccard (
166   IN OUT POOL_PRINT  *Str,
167   IN VOID            *DevPath,
168   IN BOOLEAN         DisplayOnly,
169   IN BOOLEAN         AllowShortcuts
170   )
171 {
172   PCCARD_DEVICE_PATH  *Pccard;
173 
174   Pccard = DevPath;
175   UefiDevicePathLibCatPrint (Str, "PcCard(0x%x)", Pccard->FunctionNumber);
176 }
177 
178 /**
179   Converts a Memory Map device path structure to its string representative.
180 
181   @param Str             The string representative of input device.
182   @param DevPath         The input device path structure.
183   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
184                          of the display node is used, where applicable. If DisplayOnly
185                          is FALSE, then the longer text representation of the display node
186                          is used.
187   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
188                          representation for a device node can be used, where applicable.
189 
190 **/
191 static VOID
192 DevPathToTextMemMap (
193   IN OUT POOL_PRINT  *Str,
194   IN VOID            *DevPath,
195   IN BOOLEAN         DisplayOnly,
196   IN BOOLEAN         AllowShortcuts
197   )
198 {
199   MEMMAP_DEVICE_PATH  *MemMap;
200 
201   MemMap = DevPath;
202   UefiDevicePathLibCatPrint (
203     Str,
204     "MemoryMapped(0x%x,0x%lx,0x%lx)",
205     MemMap->MemoryType,
206     MemMap->StartingAddress,
207     MemMap->EndingAddress
208     );
209 }
210 
211 /**
212   Converts a Vendor device path structure to its string representative.
213 
214   @param Str             The string representative of input device.
215   @param DevPath         The input device path structure.
216   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
217                          of the display node is used, where applicable. If DisplayOnly
218                          is FALSE, then the longer text representation of the display node
219                          is used.
220   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
221                          representation for a device node can be used, where applicable.
222 
223 **/
224 static VOID
225 DevPathToTextVendor (
226   IN OUT POOL_PRINT  *Str,
227   IN VOID            *DevPath,
228   IN BOOLEAN         DisplayOnly,
229   IN BOOLEAN         AllowShortcuts
230   )
231 {
232   VENDOR_DEVICE_PATH  *Vendor;
233   const char          *Type;
234   UINTN               Index;
235   UINTN               DataLength;
236   UINT32              FlowControlMap;
237   UINT16              Info;
238 
239   Vendor = (VENDOR_DEVICE_PATH *) DevPath;
240   switch (DevicePathType (&Vendor->Header)) {
241   case HARDWARE_DEVICE_PATH:
242     Type = "Hw";
243     break;
244 
245   case MESSAGING_DEVICE_PATH:
246     Type = "Msg";
247     if (AllowShortcuts) {
248       if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {
249         UefiDevicePathLibCatPrint (Str, "VenPcAnsi()");
250         return ;
251       } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
252         UefiDevicePathLibCatPrint (Str, "VenVt100()");
253         return ;
254       } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
255         UefiDevicePathLibCatPrint (Str, "VenVt100Plus()");
256         return ;
257       } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
258         UefiDevicePathLibCatPrint (Str, "VenUft8()");
259         return ;
260       } else if (CompareGuid (&Vendor->Guid, &gEfiUartDevicePathGuid)) {
261         FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);
262         switch (FlowControlMap & 0x00000003) {
263         case 0:
264           UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "None");
265           break;
266 
267         case 1:
268           UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "Hardware");
269           break;
270 
271         case 2:
272           UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "XonXoff");
273           break;
274 
275         default:
276           break;
277         }
278 
279         return ;
280       } else if (CompareGuid (&Vendor->Guid, &gEfiSasDevicePathGuid)) {
281         UefiDevicePathLibCatPrint (
282           Str,
283           "SAS(0x%lx,0x%lx,0x%x,",
284           ((SAS_DEVICE_PATH *) Vendor)->SasAddress,
285           ((SAS_DEVICE_PATH *) Vendor)->Lun,
286           ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort
287           );
288         Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);
289         if (((Info & 0x0f) == 0) && ((Info & BIT7) == 0)) {
290           UefiDevicePathLibCatPrint (Str, "NoTopology,0,0,0,");
291         } else if (((Info & 0x0f) <= 2) && ((Info & BIT7) == 0)) {
292           UefiDevicePathLibCatPrint (
293             Str,
294             "%s,%s,%s,",
295             ((Info & BIT4) != 0) ? "SATA" : "SAS",
296             ((Info & BIT5) != 0) ? "External" : "Internal",
297             ((Info & BIT6) != 0) ? "Expanded" : "Direct"
298             );
299           if ((Info & 0x0f) == 1) {
300             UefiDevicePathLibCatPrint (Str, "0,");
301           } else {
302             //
303             // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256
304             //
305             UefiDevicePathLibCatPrint (Str, "0x%x,", ((Info >> 8) & 0xff) + 1);
306           }
307         } else {
308           UefiDevicePathLibCatPrint (Str, "0x%x,0,0,0,", Info);
309         }
310 
311         UefiDevicePathLibCatPrint (Str, "0x%x)", ((SAS_DEVICE_PATH *) Vendor)->Reserved);
312         return ;
313       } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
314         UefiDevicePathLibCatPrint (Str, "DebugPort()");
315         return ;
316       }
317     }
318     break;
319 
320   case MEDIA_DEVICE_PATH:
321     Type = "Media";
322     break;
323 
324   default:
325     Type = "?";
326     break;
327   }
328 
329   DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);
330   UefiDevicePathLibCatPrint (Str, "Ven%s(%36s", Type, G(&Vendor->Guid));
331   if (DataLength != 0) {
332     UefiDevicePathLibCatPrint (Str, ",");
333     for (Index = 0; Index < DataLength; Index++) {
334       UefiDevicePathLibCatPrint (Str, "%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
335     }
336   }
337 
338   UefiDevicePathLibCatPrint (Str, ")");
339 }
340 
341 /**
342   Converts a Controller device path structure to its string representative.
343 
344   @param Str             The string representative of input device.
345   @param DevPath         The input device path structure.
346   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
347                          of the display node is used, where applicable. If DisplayOnly
348                          is FALSE, then the longer text representation of the display node
349                          is used.
350   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
351                          representation for a device node can be used, where applicable.
352 
353 **/
354 static VOID
355 DevPathToTextController (
356   IN OUT POOL_PRINT  *Str,
357   IN VOID            *DevPath,
358   IN BOOLEAN         DisplayOnly,
359   IN BOOLEAN         AllowShortcuts
360   )
361 {
362   CONTROLLER_DEVICE_PATH  *Controller;
363 
364   Controller = DevPath;
365   UefiDevicePathLibCatPrint (
366     Str,
367     "Ctrl(0x%x)",
368     Controller->ControllerNumber
369     );
370 }
371 
372 /**
373   Converts a BMC device path structure to its string representative.
374 
375   @param Str             The string representative of input device.
376   @param DevPath         The input device path structure.
377   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
378                          of the display node is used, where applicable. If DisplayOnly
379                          is FALSE, then the longer text representation of the display node
380                          is used.
381   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
382                          representation for a device node can be used, where applicable.
383 
384 **/
385 static VOID
386 DevPathToTextBmc (
387   IN OUT POOL_PRINT  *Str,
388   IN VOID            *DevPath,
389   IN BOOLEAN         DisplayOnly,
390   IN BOOLEAN         AllowShortcuts
391   )
392 {
393   BMC_DEVICE_PATH    *Bmc;
394 
395   Bmc = DevPath;
396   UefiDevicePathLibCatPrint (
397     Str,
398     "BMC(0x%x,0x%lx)",
399     Bmc->InterfaceType,
400     ReadUnaligned64 ((&Bmc->BaseAddress))
401     );
402 }
403 
404 /**
405   Converts a ACPI device path structure to its string representative.
406 
407   @param Str             The string representative of input device.
408   @param DevPath         The input device path structure.
409   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
410                          of the display node is used, where applicable. If DisplayOnly
411                          is FALSE, then the longer text representation of the display node
412                          is used.
413   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
414                          representation for a device node can be used, where applicable.
415 
416 **/
417 static VOID
418 DevPathToTextAcpi (
419   IN OUT POOL_PRINT  *Str,
420   IN VOID            *DevPath,
421   IN BOOLEAN         DisplayOnly,
422   IN BOOLEAN         AllowShortcuts
423   )
424 {
425   ACPI_HID_DEVICE_PATH  *Acpi;
426 
427   Acpi = DevPath;
428   if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
429     switch (EISA_ID_TO_NUM (Acpi->HID)) {
430     case 0x0a03:
431       UefiDevicePathLibCatPrint (Str, "PciRoot(0x%x)", Acpi->UID);
432       break;
433 
434     case 0x0a08:
435       UefiDevicePathLibCatPrint (Str, "PcieRoot(0x%x)", Acpi->UID);
436       break;
437 
438     case 0x0604:
439       UefiDevicePathLibCatPrint (Str, "Floppy(0x%x)", Acpi->UID);
440       break;
441 
442     case 0x0301:
443       UefiDevicePathLibCatPrint (Str, "Keyboard(0x%x)", Acpi->UID);
444       break;
445 
446     case 0x0501:
447       UefiDevicePathLibCatPrint (Str, "Serial(0x%x)", Acpi->UID);
448       break;
449 
450     case 0x0401:
451       UefiDevicePathLibCatPrint (Str, "ParallelPort(0x%x)", Acpi->UID);
452       break;
453 
454     default:
455       UefiDevicePathLibCatPrint (Str, "Acpi(PNP%04x,0x%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
456       break;
457     }
458   } else {
459     UefiDevicePathLibCatPrint (Str, "Acpi(0x%08x,0x%x)", Acpi->HID, Acpi->UID);
460   }
461 }
462 
463 /**
464   Converts a ACPI extended HID device path structure to its string representative.
465 
466   @param Str             The string representative of input device.
467   @param DevPath         The input device path structure.
468   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
469                          of the display node is used, where applicable. If DisplayOnly
470                          is FALSE, then the longer text representation of the display node
471                          is used.
472   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
473                          representation for a device node can be used, where applicable.
474 
475 **/
476 static VOID
477 DevPathToTextAcpiEx (
478   IN OUT POOL_PRINT  *Str,
479   IN VOID            *DevPath,
480   IN BOOLEAN         DisplayOnly,
481   IN BOOLEAN         AllowShortcuts
482   )
483 {
484   ACPI_EXTENDED_HID_DEVICE_PATH  *AcpiEx;
485   CHAR8                          *HIDStr;
486   CHAR8                          *UIDStr;
487   CHAR8                          *CIDStr;
488   char                           HIDText[11];
489   char                           CIDText[11];
490 
491   AcpiEx = DevPath;
492   HIDStr = (CHAR8 *) (((UINT8 *) AcpiEx) + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
493   UIDStr = HIDStr + AsciiStrLen (HIDStr) + 1;
494   CIDStr = UIDStr + AsciiStrLen (UIDStr) + 1;
495 
496   //
497   // Converts EISA identification to string.
498   //
499   UnicodeSPrint (
500     HIDText,
501     sizeof (HIDText),
502     "%c%c%c%04X",
503     ((AcpiEx->HID >> 10) & 0x1f) + 'A' - 1,
504     ((AcpiEx->HID >>  5) & 0x1f) + 'A' - 1,
505     ((AcpiEx->HID >>  0) & 0x1f) + 'A' - 1,
506     (AcpiEx->HID >> 16) & 0xFFFF
507     );
508   UnicodeSPrint (
509     CIDText,
510     sizeof (CIDText),
511     "%c%c%c%04X",
512     ((AcpiEx->CID >> 10) & 0x1f) + 'A' - 1,
513     ((AcpiEx->CID >>  5) & 0x1f) + 'A' - 1,
514     ((AcpiEx->CID >>  0) & 0x1f) + 'A' - 1,
515     (AcpiEx->CID >> 16) & 0xFFFF
516     );
517 
518   if ((*HIDStr == '\0') && (*CIDStr == '\0') && (AcpiEx->UID == 0)) {
519     //
520     // use AcpiExp()
521     //
522     UefiDevicePathLibCatPrint (
523       Str,
524       "AcpiExp(%s,%s,%s)",
525       HIDText,
526       CIDText,
527       UIDStr
528       );
529   } else {
530     if (AllowShortcuts) {
531       //
532       // display only
533       //
534       if (AcpiEx->HID == 0) {
535         UefiDevicePathLibCatPrint (Str, "AcpiEx(%s,", HIDStr);
536       } else {
537         UefiDevicePathLibCatPrint (Str, "AcpiEx(%s,", HIDText);
538       }
539 
540       if (AcpiEx->UID == 0) {
541         UefiDevicePathLibCatPrint (Str, "%s,", UIDStr);
542       } else {
543         UefiDevicePathLibCatPrint (Str, "0x%x,", AcpiEx->UID);
544       }
545 
546       if (AcpiEx->CID == 0) {
547         UefiDevicePathLibCatPrint (Str, "%s)", CIDStr);
548       } else {
549         UefiDevicePathLibCatPrint (Str, "%s)", CIDText);
550       }
551     } else {
552       UefiDevicePathLibCatPrint (
553         Str,
554         "AcpiEx(%s,%s,0x%x,%s,%s,%s)",
555         HIDText,
556         CIDText,
557         AcpiEx->UID,
558         HIDStr,
559         CIDStr,
560         UIDStr
561         );
562     }
563   }
564 }
565 
566 /**
567   Converts a ACPI address device path structure to its string representative.
568 
569   @param Str             The string representative of input device.
570   @param DevPath         The input device path structure.
571   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
572                          of the display node is used, where applicable. If DisplayOnly
573                          is FALSE, then the longer text representation of the display node
574                          is used.
575   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
576                          representation for a device node can be used, where applicable.
577 
578 **/
579 static VOID
580 DevPathToTextAcpiAdr (
581   IN OUT POOL_PRINT  *Str,
582   IN VOID            *DevPath,
583   IN BOOLEAN         DisplayOnly,
584   IN BOOLEAN         AllowShortcuts
585   )
586 {
587   ACPI_ADR_DEVICE_PATH    *AcpiAdr;
588   UINT32                  *Addr;
589   UINT16                  Index;
590   UINT16                  Length;
591   UINT16                  AdditionalAdrCount;
592 
593   AcpiAdr            = DevPath;
594   Length             = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);
595   AdditionalAdrCount = (UINT16) ((Length - 8) / 4);
596 
597   UefiDevicePathLibCatPrint (Str, "AcpiAdr(0x%x", AcpiAdr->ADR);
598   Addr = &AcpiAdr->ADR + 1;
599   for (Index = 0; Index < AdditionalAdrCount; Index++) {
600     UefiDevicePathLibCatPrint (Str, ",0x%x", Addr[Index]);
601   }
602   UefiDevicePathLibCatPrint (Str, ")");
603 }
604 
605 /**
606   Converts a ATAPI device path structure to its string representative.
607 
608   @param Str             The string representative of input device.
609   @param DevPath         The input device path structure.
610   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
611                          of the display node is used, where applicable. If DisplayOnly
612                          is FALSE, then the longer text representation of the display node
613                          is used.
614   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
615                          representation for a device node can be used, where applicable.
616 
617 **/
618 static VOID
619 DevPathToTextAtapi (
620   IN OUT POOL_PRINT  *Str,
621   IN VOID            *DevPath,
622   IN BOOLEAN         DisplayOnly,
623   IN BOOLEAN         AllowShortcuts
624   )
625 {
626   ATAPI_DEVICE_PATH *Atapi;
627 
628   Atapi = DevPath;
629 
630   if (DisplayOnly) {
631     UefiDevicePathLibCatPrint (Str, "Ata(0x%x)", Atapi->Lun);
632   } else {
633     UefiDevicePathLibCatPrint (
634       Str,
635       "Ata(%s,%s,0x%x)",
636       (Atapi->PrimarySecondary == 1) ? "Secondary" : "Primary",
637       (Atapi->SlaveMaster == 1) ? "Slave" : "Master",
638       Atapi->Lun
639       );
640   }
641 }
642 
643 /**
644   Converts a SCSI device path structure to its string representative.
645 
646   @param Str             The string representative of input device.
647   @param DevPath         The input device path structure.
648   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
649                          of the display node is used, where applicable. If DisplayOnly
650                          is FALSE, then the longer text representation of the display node
651                          is used.
652   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
653                          representation for a device node can be used, where applicable.
654 
655 **/
656 static VOID
657 DevPathToTextScsi (
658   IN OUT POOL_PRINT  *Str,
659   IN VOID            *DevPath,
660   IN BOOLEAN         DisplayOnly,
661   IN BOOLEAN         AllowShortcuts
662   )
663 {
664   SCSI_DEVICE_PATH  *Scsi;
665 
666   Scsi = DevPath;
667   UefiDevicePathLibCatPrint (Str, "Scsi(0x%x,0x%x)", Scsi->Pun, Scsi->Lun);
668 }
669 
670 /**
671   Converts a Fibre device path structure to its string representative.
672 
673   @param Str             The string representative of input device.
674   @param DevPath         The input device path structure.
675   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
676                          of the display node is used, where applicable. If DisplayOnly
677                          is FALSE, then the longer text representation of the display node
678                          is used.
679   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
680                          representation for a device node can be used, where applicable.
681 
682 **/
683 static VOID
684 DevPathToTextFibre (
685   IN OUT POOL_PRINT  *Str,
686   IN VOID            *DevPath,
687   IN BOOLEAN         DisplayOnly,
688   IN BOOLEAN         AllowShortcuts
689   )
690 {
691   FIBRECHANNEL_DEVICE_PATH  *Fibre;
692 
693   Fibre = DevPath;
694   UefiDevicePathLibCatPrint (Str, "Fibre(0x%lx,0x%lx)", Fibre->WWN, Fibre->Lun);
695 }
696 
697 /**
698   Converts a FibreEx device path structure to its string representative.
699 
700   @param Str             The string representative of input device.
701   @param DevPath         The input device path structure.
702   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
703                          of the display node is used, where applicable. If DisplayOnly
704                          is FALSE, then the longer text representation of the display node
705                          is used.
706   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
707                          representation for a device node can be used, where applicable.
708 
709 **/
710 static VOID
711 DevPathToTextFibreEx (
712   IN OUT POOL_PRINT  *Str,
713   IN VOID            *DevPath,
714   IN BOOLEAN         DisplayOnly,
715   IN BOOLEAN         AllowShortcuts
716   )
717 {
718   FIBRECHANNELEX_DEVICE_PATH  *FibreEx;
719   UINTN                       Index;
720 
721   FibreEx = DevPath;
722   UefiDevicePathLibCatPrint (Str, "FibreEx(0x");
723   for (Index = 0; Index < sizeof (FibreEx->WWN) / sizeof (FibreEx->WWN[0]); Index++) {
724     UefiDevicePathLibCatPrint (Str, "%02x", FibreEx->WWN[Index]);
725   }
726   UefiDevicePathLibCatPrint (Str, ",0x");
727   for (Index = 0; Index < sizeof (FibreEx->Lun) / sizeof (FibreEx->Lun[0]); Index++) {
728     UefiDevicePathLibCatPrint (Str, "%02x", FibreEx->Lun[Index]);
729   }
730   UefiDevicePathLibCatPrint (Str, ")");
731 }
732 
733 /**
734   Converts a Sas Ex device path structure to its string representative.
735 
736   @param Str             The string representative of input device.
737   @param DevPath         The input device path structure.
738   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
739                          of the display node is used, where applicable. If DisplayOnly
740                          is FALSE, then the longer text representation of the display node
741                          is used.
742   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
743                          representation for a device node can be used, where applicable.
744 
745 **/
746 static VOID
747 DevPathToTextSasEx (
748   IN OUT POOL_PRINT  *Str,
749   IN VOID            *DevPath,
750   IN BOOLEAN         DisplayOnly,
751   IN BOOLEAN         AllowShortcuts
752   )
753 {
754   SASEX_DEVICE_PATH  *SasEx;
755   UINTN              Index;
756 
757   SasEx = DevPath;
758   UefiDevicePathLibCatPrint (Str, "SasEx(0x");
759 
760   for (Index = 0; Index < sizeof (SasEx->SasAddress) / sizeof (SasEx->SasAddress[0]); Index++) {
761     UefiDevicePathLibCatPrint (Str, "%02x", SasEx->SasAddress[Index]);
762   }
763   UefiDevicePathLibCatPrint (Str, ",0x");
764   for (Index = 0; Index < sizeof (SasEx->Lun) / sizeof (SasEx->Lun[0]); Index++) {
765     UefiDevicePathLibCatPrint (Str, "%02x", SasEx->Lun[Index]);
766   }
767   UefiDevicePathLibCatPrint (Str, ",0x%x,", SasEx->RelativeTargetPort);
768 
769   if (((SasEx->DeviceTopology & 0x0f) == 0) && ((SasEx->DeviceTopology & BIT7) == 0)) {
770     UefiDevicePathLibCatPrint (Str, "NoTopology,0,0,0");
771   } else if (((SasEx->DeviceTopology & 0x0f) <= 2) && ((SasEx->DeviceTopology & BIT7) == 0)) {
772     UefiDevicePathLibCatPrint (
773       Str,
774       "%s,%s,%s,",
775       ((SasEx->DeviceTopology & BIT4) != 0) ? "SATA" : "SAS",
776       ((SasEx->DeviceTopology & BIT5) != 0) ? "External" : "Internal",
777       ((SasEx->DeviceTopology & BIT6) != 0) ? "Expanded" : "Direct"
778       );
779     if ((SasEx->DeviceTopology & 0x0f) == 1) {
780       UefiDevicePathLibCatPrint (Str, "0");
781     } else {
782       //
783       // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256
784       //
785       UefiDevicePathLibCatPrint (Str, "0x%x", ((SasEx->DeviceTopology >> 8) & 0xff) + 1);
786     }
787   } else {
788     UefiDevicePathLibCatPrint (Str, "0x%x,0,0,0", SasEx->DeviceTopology);
789   }
790 
791   UefiDevicePathLibCatPrint (Str, ")");
792   return ;
793 
794 }
795 
796 /**
797   Converts a NVM Express Namespace device path structure to its string representative.
798 
799   @param Str             The string representative of input device.
800   @param DevPath         The input device path structure.
801   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
802                          of the display node is used, where applicable. If DisplayOnly
803                          is FALSE, then the longer text representation of the display node
804                          is used.
805   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
806                          representation for a device node can be used, where applicable.
807 
808 **/
809 static VOID
810 DevPathToTextNVMe (
811   IN OUT POOL_PRINT  *Str,
812   IN VOID            *DevPath,
813   IN BOOLEAN         DisplayOnly,
814   IN BOOLEAN         AllowShortcuts
815   )
816 {
817   NVME_NAMESPACE_DEVICE_PATH *Nvme;
818   UINT8                      *Uuid;
819 
820   Nvme = DevPath;
821   Uuid = (UINT8 *) &Nvme->NamespaceUuid;
822   UefiDevicePathLibCatPrint (
823     Str,
824     "NVMe(0x%x,%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)",
825     Nvme->NamespaceId,
826     Uuid[7], Uuid[6], Uuid[5], Uuid[4],
827     Uuid[3], Uuid[2], Uuid[1], Uuid[0]
828     );
829 }
830 
831 /**
832   Converts a UFS device path structure to its string representative.
833 
834   @param Str             The string representative of input device.
835   @param DevPath         The input device path structure.
836   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
837                          of the display node is used, where applicable. If DisplayOnly
838                          is FALSE, then the longer text representation of the display node
839                          is used.
840   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
841                          representation for a device node can be used, where applicable.
842 
843 **/
844 static VOID
845 DevPathToTextUfs (
846   IN OUT POOL_PRINT  *Str,
847   IN VOID            *DevPath,
848   IN BOOLEAN         DisplayOnly,
849   IN BOOLEAN         AllowShortcuts
850   )
851 {
852   UFS_DEVICE_PATH  *Ufs;
853 
854   Ufs = DevPath;
855   UefiDevicePathLibCatPrint (Str, "UFS(0x%x,0x%x)", Ufs->Pun, Ufs->Lun);
856 }
857 
858 /**
859   Converts a SD (Secure Digital) device path structure to its string representative.
860 
861   @param Str             The string representative of input device.
862   @param DevPath         The input device path structure.
863   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
864                          of the display node is used, where applicable. If DisplayOnly
865                          is FALSE, then the longer text representation of the display node
866                          is used.
867   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
868                          representation for a device node can be used, where applicable.
869 
870 **/
871 static VOID
872 DevPathToTextSd (
873   IN OUT POOL_PRINT  *Str,
874   IN VOID            *DevPath,
875   IN BOOLEAN         DisplayOnly,
876   IN BOOLEAN         AllowShortcuts
877   )
878 {
879   SD_DEVICE_PATH             *Sd;
880 
881   Sd = DevPath;
882   UefiDevicePathLibCatPrint (
883     Str,
884     "SD(0x%x)",
885     Sd->SlotNumber
886     );
887 }
888 
889 /**
890   Converts a EMMC (Embedded MMC) device path structure to its string representative.
891 
892   @param Str             The string representative of input device.
893   @param DevPath         The input device path structure.
894   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
895                          of the display node is used, where applicable. If DisplayOnly
896                          is FALSE, then the longer text representation of the display node
897                          is used.
898   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
899                          representation for a device node can be used, where applicable.
900 
901 **/
902 static VOID
903 DevPathToTextEmmc (
904   IN OUT POOL_PRINT  *Str,
905   IN VOID            *DevPath,
906   IN BOOLEAN         DisplayOnly,
907   IN BOOLEAN         AllowShortcuts
908   )
909 {
910   EMMC_DEVICE_PATH             *Emmc;
911 
912   Emmc = DevPath;
913   UefiDevicePathLibCatPrint (
914     Str,
915     "eMMC(0x%x)",
916     Emmc->SlotNumber
917     );
918 }
919 
920 /**
921   Converts a 1394 device path structure to its string representative.
922 
923   @param Str             The string representative of input device.
924   @param DevPath         The input device path structure.
925   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
926                          of the display node is used, where applicable. If DisplayOnly
927                          is FALSE, then the longer text representation of the display node
928                          is used.
929   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
930                          representation for a device node can be used, where applicable.
931 
932 **/
933 static VOID
934 DevPathToText1394 (
935   IN OUT POOL_PRINT  *Str,
936   IN VOID            *DevPath,
937   IN BOOLEAN         DisplayOnly,
938   IN BOOLEAN         AllowShortcuts
939   )
940 {
941   F1394_DEVICE_PATH *F1394DevPath;
942 
943   F1394DevPath = DevPath;
944   //
945   // Guid has format of IEEE-EUI64
946   //
947   UefiDevicePathLibCatPrint (Str, "I1394(%016lx)", F1394DevPath->Guid);
948 }
949 
950 /**
951   Converts a USB device path structure to its string representative.
952 
953   @param Str             The string representative of input device.
954   @param DevPath         The input device path structure.
955   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
956                          of the display node is used, where applicable. If DisplayOnly
957                          is FALSE, then the longer text representation of the display node
958                          is used.
959   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
960                          representation for a device node can be used, where applicable.
961 
962 **/
963 static VOID
964 DevPathToTextUsb (
965   IN OUT POOL_PRINT  *Str,
966   IN VOID            *DevPath,
967   IN BOOLEAN         DisplayOnly,
968   IN BOOLEAN         AllowShortcuts
969   )
970 {
971   USB_DEVICE_PATH *Usb;
972 
973   Usb = DevPath;
974   UefiDevicePathLibCatPrint (Str, "USB(0x%x,0x%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);
975 }
976 
977 /**
978   Converts a USB WWID device path structure to its string representative.
979 
980   @param Str             The string representative of input device.
981   @param DevPath         The input device path structure.
982   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
983                          of the display node is used, where applicable. If DisplayOnly
984                          is FALSE, then the longer text representation of the display node
985                          is used.
986   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
987                          representation for a device node can be used, where applicable.
988 
989 **/
990 static VOID
991 DevPathToTextUsbWWID (
992   IN OUT POOL_PRINT  *Str,
993   IN VOID            *DevPath,
994   IN BOOLEAN         DisplayOnly,
995   IN BOOLEAN         AllowShortcuts
996   )
997 {
998   USB_WWID_DEVICE_PATH  *UsbWWId;
999   CHAR16                *SerialNumberStr;
1000   CHAR16                *NewStr;
1001   UINT16                Length;
1002 
1003   UsbWWId = DevPath;
1004 
1005   SerialNumberStr = (CHAR16 *) (&UsbWWId + 1);
1006   Length = (UINT16) ((DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) UsbWWId) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16));
1007   if (SerialNumberStr [Length - 1] != 0) {
1008     //
1009     // In case no NULL terminator in SerialNumber, create a new one with NULL terminator
1010     //
1011     NewStr = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), SerialNumberStr);
1012     ASSERT (NewStr != NULL);
1013     NewStr [Length] = 0;
1014     SerialNumberStr = NewStr;
1015   }
1016 
1017   UefiDevicePathLibCatPrint (
1018     Str,
1019     "UsbWwid(0x%x,0x%x,0x%x,\"%S\")",
1020     UsbWWId->VendorId,
1021     UsbWWId->ProductId,
1022     UsbWWId->InterfaceNumber,
1023     SerialNumberStr
1024     );
1025 }
1026 
1027 /**
1028   Converts a Logic Unit device path structure to its string representative.
1029 
1030   @param Str             The string representative of input device.
1031   @param DevPath         The input device path structure.
1032   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1033                          of the display node is used, where applicable. If DisplayOnly
1034                          is FALSE, then the longer text representation of the display node
1035                          is used.
1036   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1037                          representation for a device node can be used, where applicable.
1038 
1039 **/
1040 static VOID
1041 DevPathToTextLogicalUnit (
1042   IN OUT POOL_PRINT  *Str,
1043   IN VOID            *DevPath,
1044   IN BOOLEAN         DisplayOnly,
1045   IN BOOLEAN         AllowShortcuts
1046   )
1047 {
1048   DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
1049 
1050   LogicalUnit = DevPath;
1051   UefiDevicePathLibCatPrint (Str, "Unit(0x%x)", LogicalUnit->Lun);
1052 }
1053 
1054 /**
1055   Converts a USB class device path structure to its string representative.
1056 
1057   @param Str             The string representative of input device.
1058   @param DevPath         The input device path structure.
1059   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1060                          of the display node is used, where applicable. If DisplayOnly
1061                          is FALSE, then the longer text representation of the display node
1062                          is used.
1063   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1064                          representation for a device node can be used, where applicable.
1065 
1066 **/
1067 static VOID
1068 DevPathToTextUsbClass (
1069   IN OUT POOL_PRINT  *Str,
1070   IN VOID            *DevPath,
1071   IN BOOLEAN         DisplayOnly,
1072   IN BOOLEAN         AllowShortcuts
1073   )
1074 {
1075   USB_CLASS_DEVICE_PATH *UsbClass;
1076   BOOLEAN               IsKnownSubClass;
1077 
1078 
1079   UsbClass = DevPath;
1080 
1081   IsKnownSubClass = TRUE;
1082   switch (UsbClass->DeviceClass) {
1083   case USB_CLASS_AUDIO:
1084     UefiDevicePathLibCatPrint (Str, "UsbAudio");
1085     break;
1086 
1087   case USB_CLASS_CDCCONTROL:
1088     UefiDevicePathLibCatPrint (Str, "UsbCDCControl");
1089     break;
1090 
1091   case USB_CLASS_HID:
1092     UefiDevicePathLibCatPrint (Str, "UsbHID");
1093     break;
1094 
1095   case USB_CLASS_IMAGE:
1096     UefiDevicePathLibCatPrint (Str, "UsbImage");
1097     break;
1098 
1099   case USB_CLASS_PRINTER:
1100     UefiDevicePathLibCatPrint (Str, "UsbPrinter");
1101     break;
1102 
1103   case USB_CLASS_MASS_STORAGE:
1104     UefiDevicePathLibCatPrint (Str, "UsbMassStorage");
1105     break;
1106 
1107   case USB_CLASS_HUB:
1108     UefiDevicePathLibCatPrint (Str, "UsbHub");
1109     break;
1110 
1111   case USB_CLASS_CDCDATA:
1112     UefiDevicePathLibCatPrint (Str, "UsbCDCData");
1113     break;
1114 
1115   case USB_CLASS_SMART_CARD:
1116     UefiDevicePathLibCatPrint (Str, "UsbSmartCard");
1117     break;
1118 
1119   case USB_CLASS_VIDEO:
1120     UefiDevicePathLibCatPrint (Str, "UsbVideo");
1121     break;
1122 
1123   case USB_CLASS_DIAGNOSTIC:
1124     UefiDevicePathLibCatPrint (Str, "UsbDiagnostic");
1125     break;
1126 
1127   case USB_CLASS_WIRELESS:
1128     UefiDevicePathLibCatPrint (Str, "UsbWireless");
1129     break;
1130 
1131   default:
1132     IsKnownSubClass = FALSE;
1133     break;
1134   }
1135 
1136   if (IsKnownSubClass) {
1137     UefiDevicePathLibCatPrint (
1138       Str,
1139       "(0x%x,0x%x,0x%x,0x%x)",
1140       UsbClass->VendorId,
1141       UsbClass->ProductId,
1142       UsbClass->DeviceSubClass,
1143       UsbClass->DeviceProtocol
1144       );
1145     return;
1146   }
1147 
1148   if (UsbClass->DeviceClass == USB_CLASS_RESERVE) {
1149     if (UsbClass->DeviceSubClass == USB_SUBCLASS_FW_UPDATE) {
1150       UefiDevicePathLibCatPrint (
1151         Str,
1152         "UsbDeviceFirmwareUpdate(0x%x,0x%x,0x%x)",
1153         UsbClass->VendorId,
1154         UsbClass->ProductId,
1155         UsbClass->DeviceProtocol
1156         );
1157       return;
1158     } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_IRDA_BRIDGE) {
1159       UefiDevicePathLibCatPrint (
1160         Str,
1161         "UsbIrdaBridge(0x%x,0x%x,0x%x)",
1162         UsbClass->VendorId,
1163         UsbClass->ProductId,
1164         UsbClass->DeviceProtocol
1165         );
1166       return;
1167     } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_TEST) {
1168       UefiDevicePathLibCatPrint (
1169         Str,
1170         "UsbTestAndMeasurement(0x%x,0x%x,0x%x)",
1171         UsbClass->VendorId,
1172         UsbClass->ProductId,
1173         UsbClass->DeviceProtocol
1174         );
1175       return;
1176     }
1177   }
1178 
1179   UefiDevicePathLibCatPrint (
1180     Str,
1181     "UsbClass(0x%x,0x%x,0x%x,0x%x,0x%x)",
1182     UsbClass->VendorId,
1183     UsbClass->ProductId,
1184     UsbClass->DeviceClass,
1185     UsbClass->DeviceSubClass,
1186     UsbClass->DeviceProtocol
1187     );
1188 }
1189 
1190 /**
1191   Converts a SATA device path structure to its string representative.
1192 
1193   @param Str             The string representative of input device.
1194   @param DevPath         The input device path structure.
1195   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1196                          of the display node is used, where applicable. If DisplayOnly
1197                          is FALSE, then the longer text representation of the display node
1198                          is used.
1199   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1200                          representation for a device node can be used, where applicable.
1201 
1202 **/
1203 static VOID
1204 DevPathToTextSata (
1205   IN OUT POOL_PRINT  *Str,
1206   IN VOID            *DevPath,
1207   IN BOOLEAN         DisplayOnly,
1208   IN BOOLEAN         AllowShortcuts
1209   )
1210 {
1211   SATA_DEVICE_PATH *Sata;
1212 
1213   Sata = DevPath;
1214   UefiDevicePathLibCatPrint (
1215     Str,
1216     "Sata(0x%x,0x%x,0x%x)",
1217     Sata->HBAPortNumber,
1218     Sata->PortMultiplierPortNumber,
1219     Sata->Lun
1220     );
1221 }
1222 
1223 /**
1224   Converts a I20 device path structure to its string representative.
1225 
1226   @param Str             The string representative of input device.
1227   @param DevPath         The input device path structure.
1228   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1229                          of the display node is used, where applicable. If DisplayOnly
1230                          is FALSE, then the longer text representation of the display node
1231                          is used.
1232   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1233                          representation for a device node can be used, where applicable.
1234 
1235 **/
1236 static VOID
1237 DevPathToTextI2O (
1238   IN OUT POOL_PRINT  *Str,
1239   IN VOID            *DevPath,
1240   IN BOOLEAN         DisplayOnly,
1241   IN BOOLEAN         AllowShortcuts
1242   )
1243 {
1244   I2O_DEVICE_PATH *I2ODevPath;
1245 
1246   I2ODevPath = DevPath;
1247   UefiDevicePathLibCatPrint (Str, "I2O(0x%x)", I2ODevPath->Tid);
1248 }
1249 
1250 /**
1251   Converts a MAC address device path structure to its string representative.
1252 
1253   @param Str             The string representative of input device.
1254   @param DevPath         The input device path structure.
1255   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1256                          of the display node is used, where applicable. If DisplayOnly
1257                          is FALSE, then the longer text representation of the display node
1258                          is used.
1259   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1260                          representation for a device node can be used, where applicable.
1261 
1262 **/
1263 static VOID
1264 DevPathToTextMacAddr (
1265   IN OUT POOL_PRINT  *Str,
1266   IN VOID            *DevPath,
1267   IN BOOLEAN         DisplayOnly,
1268   IN BOOLEAN         AllowShortcuts
1269   )
1270 {
1271   MAC_ADDR_DEVICE_PATH  *MacDevPath;
1272   UINTN                 HwAddressSize;
1273   UINTN                 Index;
1274 
1275   MacDevPath = DevPath;
1276 
1277   HwAddressSize = sizeof (EFI_MAC_ADDRESS);
1278   if (MacDevPath->IfType == 0x01 || MacDevPath->IfType == 0x00) {
1279     HwAddressSize = 6;
1280   }
1281 
1282   UefiDevicePathLibCatPrint (Str, "MAC(");
1283 
1284   for (Index = 0; Index < HwAddressSize; Index++) {
1285     UefiDevicePathLibCatPrint (Str, "%02x", MacDevPath->MacAddress.Addr[Index]);
1286   }
1287 
1288   UefiDevicePathLibCatPrint (Str, ",0x%x)", MacDevPath->IfType);
1289 }
1290 
1291 /**
1292   Converts network protocol string to its text representation.
1293 
1294   @param Str             The string representative of input device.
1295   @param Protocol        The network protocol ID.
1296 
1297 **/
1298 static VOID
1299 CatNetworkProtocol (
1300   IN OUT POOL_PRINT  *Str,
1301   IN UINT16          Protocol
1302   )
1303 {
1304   if (Protocol == RFC_1700_TCP_PROTOCOL) {
1305     UefiDevicePathLibCatPrint (Str, "TCP");
1306   } else if (Protocol == RFC_1700_UDP_PROTOCOL) {
1307     UefiDevicePathLibCatPrint (Str, "UDP");
1308   } else {
1309     UefiDevicePathLibCatPrint (Str, "0x%x", Protocol);
1310   }
1311 }
1312 
1313 /**
1314   Converts IP v4 address to its text representation.
1315 
1316   @param Str             The string representative of input device.
1317   @param Address         The IP v4 address.
1318 **/
1319 static VOID
1320 CatIPv4Address (
1321   IN OUT POOL_PRINT   *Str,
1322   IN EFI_IPv4_ADDRESS *Address
1323   )
1324 {
1325   UefiDevicePathLibCatPrint (Str, "%d.%d.%d.%d", Address->Addr[0], Address->Addr[1], Address->Addr[2], Address->Addr[3]);
1326 }
1327 
1328 /**
1329   Converts IP v6 address to its text representation.
1330 
1331   @param Str             The string representative of input device.
1332   @param Address         The IP v6 address.
1333 **/
1334 static VOID
1335 CatIPv6Address (
1336   IN OUT POOL_PRINT   *Str,
1337   IN EFI_IPv6_ADDRESS *Address
1338   )
1339 {
1340   UefiDevicePathLibCatPrint (
1341     Str, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
1342     Address->Addr[0],  Address->Addr[1],
1343     Address->Addr[2],  Address->Addr[3],
1344     Address->Addr[4],  Address->Addr[5],
1345     Address->Addr[6],  Address->Addr[7],
1346     Address->Addr[8],  Address->Addr[9],
1347     Address->Addr[10], Address->Addr[11],
1348     Address->Addr[12], Address->Addr[13],
1349     Address->Addr[14], Address->Addr[15]
1350   );
1351 }
1352 
1353 /**
1354   Converts a IPv4 device path structure to its string representative.
1355 
1356   @param Str             The string representative of input device.
1357   @param DevPath         The input device path structure.
1358   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1359                          of the display node is used, where applicable. If DisplayOnly
1360                          is FALSE, then the longer text representation of the display node
1361                          is used.
1362   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1363                          representation for a device node can be used, where applicable.
1364 
1365 **/
1366 static VOID
1367 DevPathToTextIPv4 (
1368   IN OUT POOL_PRINT  *Str,
1369   IN VOID            *DevPath,
1370   IN BOOLEAN         DisplayOnly,
1371   IN BOOLEAN         AllowShortcuts
1372   )
1373 {
1374   IPv4_DEVICE_PATH  *IPDevPath;
1375 
1376   IPDevPath = DevPath;
1377   UefiDevicePathLibCatPrint (Str, "IPv4(");
1378   CatIPv4Address (Str, &IPDevPath->RemoteIpAddress);
1379 
1380   if (DisplayOnly) {
1381     UefiDevicePathLibCatPrint (Str, ")");
1382     return ;
1383   }
1384 
1385   UefiDevicePathLibCatPrint (Str, ",");
1386   CatNetworkProtocol (Str, IPDevPath->Protocol);
1387 
1388   UefiDevicePathLibCatPrint (Str, ",%s,", IPDevPath->StaticIpAddress ? "Static" : "DHCP");
1389   CatIPv4Address (Str, &IPDevPath->LocalIpAddress);
1390   if (DevicePathNodeLength (IPDevPath) == sizeof (IPv4_DEVICE_PATH)) {
1391     UefiDevicePathLibCatPrint (Str, ",");
1392     CatIPv4Address (Str, &IPDevPath->GatewayIpAddress);
1393     UefiDevicePathLibCatPrint (Str, ",");
1394     CatIPv4Address (Str, &IPDevPath->SubnetMask);
1395   }
1396   UefiDevicePathLibCatPrint (Str, ")");
1397 }
1398 
1399 /**
1400   Converts a IPv6 device path structure to its string representative.
1401 
1402   @param Str             The string representative of input device.
1403   @param DevPath         The input device path structure.
1404   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1405                          of the display node is used, where applicable. If DisplayOnly
1406                          is FALSE, then the longer text representation of the display node
1407                          is used.
1408   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1409                          representation for a device node can be used, where applicable.
1410 
1411 **/
1412 static VOID
1413 DevPathToTextIPv6 (
1414   IN OUT POOL_PRINT  *Str,
1415   IN VOID            *DevPath,
1416   IN BOOLEAN         DisplayOnly,
1417   IN BOOLEAN         AllowShortcuts
1418   )
1419 {
1420   IPv6_DEVICE_PATH  *IPDevPath;
1421 
1422   IPDevPath = DevPath;
1423   UefiDevicePathLibCatPrint (Str, "IPv6(");
1424   CatIPv6Address (Str, &IPDevPath->RemoteIpAddress);
1425   if (DisplayOnly) {
1426     UefiDevicePathLibCatPrint (Str, ")");
1427     return ;
1428   }
1429 
1430   UefiDevicePathLibCatPrint (Str, ",");
1431   CatNetworkProtocol (Str, IPDevPath->Protocol);
1432 
1433   switch (IPDevPath->IpAddressOrigin) {
1434     case 0:
1435       UefiDevicePathLibCatPrint (Str, ",Static,");
1436       break;
1437     case 1:
1438       UefiDevicePathLibCatPrint (Str, ",StatelessAutoConfigure,");
1439       break;
1440     default:
1441       UefiDevicePathLibCatPrint (Str, ",StatefulAutoConfigure,");
1442       break;
1443   }
1444 
1445   CatIPv6Address (Str, &IPDevPath->LocalIpAddress);
1446 
1447   if (DevicePathNodeLength (IPDevPath) == sizeof (IPv6_DEVICE_PATH)) {
1448     UefiDevicePathLibCatPrint (Str, ",0x%x,", IPDevPath->PrefixLength);
1449     CatIPv6Address (Str, &IPDevPath->GatewayIpAddress);
1450   }
1451   UefiDevicePathLibCatPrint (Str, ")");
1452 }
1453 
1454 /**
1455   Converts an Infini Band device path structure to its string representative.
1456 
1457   @param Str             The string representative of input device.
1458   @param DevPath         The input device path structure.
1459   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1460                          of the display node is used, where applicable. If DisplayOnly
1461                          is FALSE, then the longer text representation of the display node
1462                          is used.
1463   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1464                          representation for a device node can be used, where applicable.
1465 
1466 **/
1467 static VOID
1468 DevPathToTextInfiniBand (
1469   IN OUT POOL_PRINT  *Str,
1470   IN VOID            *DevPath,
1471   IN BOOLEAN         DisplayOnly,
1472   IN BOOLEAN         AllowShortcuts
1473   )
1474 {
1475   INFINIBAND_DEVICE_PATH  *InfiniBand;
1476 
1477   InfiniBand = DevPath;
1478   UefiDevicePathLibCatPrint (
1479     Str,
1480     "Infiniband(0x%x,%36s,0x%lx,0x%lx,0x%lx)",
1481     InfiniBand->ResourceFlags,
1482     G(InfiniBand->PortGid),
1483     InfiniBand->ServiceId,
1484     InfiniBand->TargetPortId,
1485     InfiniBand->DeviceId
1486     );
1487 }
1488 
1489 /**
1490   Converts a UART device path structure to its string representative.
1491 
1492   @param Str             The string representative of input device.
1493   @param DevPath         The input device path structure.
1494   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1495                          of the display node is used, where applicable. If DisplayOnly
1496                          is FALSE, then the longer text representation of the display node
1497                          is used.
1498   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1499                          representation for a device node can be used, where applicable.
1500 
1501 **/
1502 static VOID
1503 DevPathToTextUart (
1504   IN OUT POOL_PRINT  *Str,
1505   IN VOID            *DevPath,
1506   IN BOOLEAN         DisplayOnly,
1507   IN BOOLEAN         AllowShortcuts
1508   )
1509 {
1510   UART_DEVICE_PATH  *Uart;
1511   CHAR8             Parity;
1512 
1513   Uart = DevPath;
1514   switch (Uart->Parity) {
1515   case 0:
1516     Parity = 'D';
1517     break;
1518 
1519   case 1:
1520     Parity = 'N';
1521     break;
1522 
1523   case 2:
1524     Parity = 'E';
1525     break;
1526 
1527   case 3:
1528     Parity = 'O';
1529     break;
1530 
1531   case 4:
1532     Parity = 'M';
1533     break;
1534 
1535   case 5:
1536     Parity = 'S';
1537     break;
1538 
1539   default:
1540     Parity = 'x';
1541     break;
1542   }
1543 
1544   if (Uart->BaudRate == 0) {
1545     UefiDevicePathLibCatPrint (Str, "Uart(DEFAULT,");
1546   } else {
1547     UefiDevicePathLibCatPrint (Str, "Uart(%ld,", Uart->BaudRate);
1548   }
1549 
1550   if (Uart->DataBits == 0) {
1551     UefiDevicePathLibCatPrint (Str, "DEFAULT,");
1552   } else {
1553     UefiDevicePathLibCatPrint (Str, "%d,", Uart->DataBits);
1554   }
1555 
1556   UefiDevicePathLibCatPrint (Str, "%c,", Parity);
1557 
1558   switch (Uart->StopBits) {
1559   case 0:
1560     UefiDevicePathLibCatPrint (Str, "D)");
1561     break;
1562 
1563   case 1:
1564     UefiDevicePathLibCatPrint (Str, "1)");
1565     break;
1566 
1567   case 2:
1568     UefiDevicePathLibCatPrint (Str, "1.5)");
1569     break;
1570 
1571   case 3:
1572     UefiDevicePathLibCatPrint (Str, "2)");
1573     break;
1574 
1575   default:
1576     UefiDevicePathLibCatPrint (Str, "x)");
1577     break;
1578   }
1579 }
1580 
1581 /**
1582   Converts an iSCSI device path structure to its string representative.
1583 
1584   @param Str             The string representative of input device.
1585   @param DevPath         The input device path structure.
1586   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1587                          of the display node is used, where applicable. If DisplayOnly
1588                          is FALSE, then the longer text representation of the display node
1589                          is used.
1590   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1591                          representation for a device node can be used, where applicable.
1592 
1593 **/
1594 static VOID
1595 DevPathToTextiSCSI (
1596   IN OUT POOL_PRINT  *Str,
1597   IN VOID            *DevPath,
1598   IN BOOLEAN         DisplayOnly,
1599   IN BOOLEAN         AllowShortcuts
1600   )
1601 {
1602   ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath;
1603   UINT16                      Options;
1604 
1605   ISCSIDevPath = DevPath;
1606   UefiDevicePathLibCatPrint (
1607     Str,
1608     "iSCSI(%s,0x%x,0x%lx,",
1609     ISCSIDevPath->TargetName,
1610     ISCSIDevPath->TargetPortalGroupTag,
1611     ISCSIDevPath->Lun
1612     );
1613 
1614   Options = ISCSIDevPath->LoginOption;
1615   UefiDevicePathLibCatPrint (Str, "%s,", (((Options >> 1) & 0x0001) != 0) ? "CRC32C" : "None");
1616   UefiDevicePathLibCatPrint (Str, "%s,", (((Options >> 3) & 0x0001) != 0) ? "CRC32C" : "None");
1617   if (((Options >> 11) & 0x0001) != 0) {
1618     UefiDevicePathLibCatPrint (Str, "%s,", "None");
1619   } else if (((Options >> 12) & 0x0001) != 0) {
1620     UefiDevicePathLibCatPrint (Str, "%s,", "CHAP_UNI");
1621   } else {
1622     UefiDevicePathLibCatPrint (Str, "%s,", "CHAP_BI");
1623 
1624   }
1625 
1626   UefiDevicePathLibCatPrint (Str, "%s)", (ISCSIDevPath->NetworkProtocol == 0) ? "TCP" : "reserved");
1627 }
1628 
1629 /**
1630   Converts a VLAN device path structure to its string representative.
1631 
1632   @param Str             The string representative of input device.
1633   @param DevPath         The input device path structure.
1634   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1635                          of the display node is used, where applicable. If DisplayOnly
1636                          is FALSE, then the longer text representation of the display node
1637                          is used.
1638   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1639                          representation for a device node can be used, where applicable.
1640 
1641 **/
1642 static VOID
1643 DevPathToTextVlan (
1644   IN OUT POOL_PRINT  *Str,
1645   IN VOID            *DevPath,
1646   IN BOOLEAN         DisplayOnly,
1647   IN BOOLEAN         AllowShortcuts
1648   )
1649 {
1650   VLAN_DEVICE_PATH  *Vlan;
1651 
1652   Vlan = DevPath;
1653   UefiDevicePathLibCatPrint (Str, "Vlan(%d)", Vlan->VlanId);
1654 }
1655 
1656 /**
1657   Converts a Bluetooth device path structure to its string representative.
1658 
1659   @param Str             The string representative of input device.
1660   @param DevPath         The input device path structure.
1661   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1662                          of the display node is used, where applicable. If DisplayOnly
1663                          is FALSE, then the longer text representation of the display node
1664                          is used.
1665   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1666                          representation for a device node can be used, where applicable.
1667 
1668 **/
1669 static VOID
1670 DevPathToTextBluetooth (
1671   IN OUT POOL_PRINT  *Str,
1672   IN VOID            *DevPath,
1673   IN BOOLEAN         DisplayOnly,
1674   IN BOOLEAN         AllowShortcuts
1675   )
1676 {
1677   BLUETOOTH_DEVICE_PATH  *Bluetooth;
1678 
1679   Bluetooth = DevPath;
1680   UefiDevicePathLibCatPrint (
1681     Str,
1682     "Bluetooth(%02x%02x%02x%02x%02x%02x)",
1683     Bluetooth->BD_ADDR.Address[5],
1684     Bluetooth->BD_ADDR.Address[4],
1685     Bluetooth->BD_ADDR.Address[3],
1686     Bluetooth->BD_ADDR.Address[2],
1687     Bluetooth->BD_ADDR.Address[1],
1688     Bluetooth->BD_ADDR.Address[0]
1689     );
1690 }
1691 
1692 /**
1693   Converts a Wi-Fi device path structure to its string representative.
1694 
1695   @param Str             The string representative of input device.
1696   @param DevPath         The input device path structure.
1697   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1698                          of the display node is used, where applicable. If DisplayOnly
1699                          is FALSE, then the longer text representation of the display node
1700                          is used.
1701   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1702                          representation for a device node can be used, where applicable.
1703 
1704 **/
1705 static VOID
1706 DevPathToTextWiFi (
1707   IN OUT POOL_PRINT  *Str,
1708   IN VOID            *DevPath,
1709   IN BOOLEAN         DisplayOnly,
1710   IN BOOLEAN         AllowShortcuts
1711   )
1712 {
1713   WIFI_DEVICE_PATH      *WiFi;
1714   UINT8                 SSId[33];
1715 
1716   WiFi = DevPath;
1717 
1718   SSId[32] = '\0';
1719   CopyMem (SSId, WiFi->SSId, 32);
1720 
1721   UefiDevicePathLibCatPrint (Str, "Wi-Fi(%s)", SSId);
1722 }
1723 
1724 /**
1725   Converts a URI device path structure to its string representative.
1726 
1727   @param Str             The string representative of input device.
1728   @param DevPath         The input device path structure.
1729   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1730                          of the display node is used, where applicable. If DisplayOnly
1731                          is FALSE, then the longer text representation of the display node
1732                          is used.
1733   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1734                          representation for a device node can be used, where applicable.
1735 
1736 **/
1737 static VOID
1738 DevPathToTextUri (
1739   IN OUT POOL_PRINT  *Str,
1740   IN VOID            *DevPath,
1741   IN BOOLEAN         DisplayOnly,
1742   IN BOOLEAN         AllowShortcuts
1743   )
1744 {
1745   URI_DEVICE_PATH    *Uri;
1746   UINTN              UriLength;
1747   CHAR8              *UriStr;
1748 
1749   //
1750   // Uri in the device path may not be null terminated.
1751   //
1752   Uri       = DevPath;
1753   UriLength = DevicePathNodeLength (Uri) - sizeof (URI_DEVICE_PATH);
1754   UriStr = AllocatePool (UriLength + 1);
1755   ASSERT (UriStr != NULL);
1756 
1757   CopyMem (UriStr, Uri->Uri, UriLength);
1758   UriStr[UriLength] = '\0';
1759   UefiDevicePathLibCatPrint (Str, "Uri(%s)", UriStr);
1760   FreePool (UriStr);
1761 }
1762 
1763 /**
1764   Converts a Hard drive device path structure to its string representative.
1765 
1766   @param Str             The string representative of input device.
1767   @param DevPath         The input device path structure.
1768   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1769                          of the display node is used, where applicable. If DisplayOnly
1770                          is FALSE, then the longer text representation of the display node
1771                          is used.
1772   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1773                          representation for a device node can be used, where applicable.
1774 
1775 **/
1776 static VOID
1777 DevPathToTextHardDrive (
1778   IN OUT POOL_PRINT  *Str,
1779   IN VOID            *DevPath,
1780   IN BOOLEAN         DisplayOnly,
1781   IN BOOLEAN         AllowShortcuts
1782   )
1783 {
1784   HARDDRIVE_DEVICE_PATH *Hd;
1785 
1786   Hd = DevPath;
1787   switch (Hd->SignatureType) {
1788   case SIGNATURE_TYPE_MBR:
1789     UefiDevicePathLibCatPrint (
1790       Str,
1791       "HD(%d,%s,0x%08x,",
1792       Hd->PartitionNumber,
1793       "MBR",
1794 //      *((UINT32 *) (&(Hd->Signature[0])))
1795       le32dec(&(Hd->Signature[0]))
1796       );
1797     break;
1798 
1799   case SIGNATURE_TYPE_GUID:
1800     UefiDevicePathLibCatPrint (
1801       Str,
1802       "HD(%d,%s,%36s,",
1803       Hd->PartitionNumber,
1804       "GPT",
1805       G(&(Hd->Signature[0]))
1806       );
1807     break;
1808 
1809   default:
1810     UefiDevicePathLibCatPrint (
1811       Str,
1812       "HD(%d,%d,0,",
1813       Hd->PartitionNumber,
1814       Hd->SignatureType
1815       );
1816     break;
1817   }
1818 
1819   UefiDevicePathLibCatPrint (Str, "0x%lx,0x%lx)", Hd->PartitionStart, Hd->PartitionSize);
1820 }
1821 
1822 /**
1823   Converts a CDROM device path structure to its string representative.
1824 
1825   @param Str             The string representative of input device.
1826   @param DevPath         The input device path structure.
1827   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1828                          of the display node is used, where applicable. If DisplayOnly
1829                          is FALSE, then the longer text representation of the display node
1830                          is used.
1831   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1832                          representation for a device node can be used, where applicable.
1833 
1834 **/
1835 static VOID
1836 DevPathToTextCDROM (
1837   IN OUT POOL_PRINT  *Str,
1838   IN VOID            *DevPath,
1839   IN BOOLEAN         DisplayOnly,
1840   IN BOOLEAN         AllowShortcuts
1841   )
1842 {
1843   CDROM_DEVICE_PATH *Cd;
1844 
1845   Cd = DevPath;
1846   if (DisplayOnly) {
1847     UefiDevicePathLibCatPrint (Str, "CDROM(0x%x)", Cd->BootEntry);
1848     return ;
1849   }
1850 
1851   UefiDevicePathLibCatPrint (Str, "CDROM(0x%x,0x%lx,0x%lx)", Cd->BootEntry, Cd->PartitionStart, Cd->PartitionSize);
1852 }
1853 
1854 /**
1855   Converts a File device path structure to its string representative.
1856 
1857   @param Str             The string representative of input device.
1858   @param DevPath         The input device path structure.
1859   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1860                          of the display node is used, where applicable. If DisplayOnly
1861                          is FALSE, then the longer text representation of the display node
1862                          is used.
1863   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1864                          representation for a device node can be used, where applicable.
1865 
1866 **/
1867 static VOID
1868 DevPathToTextFilePath (
1869   IN OUT POOL_PRINT  *Str,
1870   IN VOID            *DevPath,
1871   IN BOOLEAN         DisplayOnly,
1872   IN BOOLEAN         AllowShortcuts
1873   )
1874 {
1875   FILEPATH_DEVICE_PATH  *Fp;
1876   char *name = NULL;
1877 
1878   Fp = DevPath;
1879   ucs2_to_utf8(Fp->PathName, &name);
1880   UefiDevicePathLibCatPrint (Str, "File(%s)", name);
1881   free(name);
1882 }
1883 
1884 /**
1885   Converts a Media protocol device path structure to its string representative.
1886 
1887   @param Str             The string representative of input device.
1888   @param DevPath         The input device path structure.
1889   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1890                          of the display node is used, where applicable. If DisplayOnly
1891                          is FALSE, then the longer text representation of the display node
1892                          is used.
1893   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1894                          representation for a device node can be used, where applicable.
1895 
1896 **/
1897 static VOID
1898 DevPathToTextMediaProtocol (
1899   IN OUT POOL_PRINT  *Str,
1900   IN VOID            *DevPath,
1901   IN BOOLEAN         DisplayOnly,
1902   IN BOOLEAN         AllowShortcuts
1903   )
1904 {
1905   MEDIA_PROTOCOL_DEVICE_PATH  *MediaProt;
1906 
1907   MediaProt = DevPath;
1908   UefiDevicePathLibCatPrint (Str, "Media(%36s)", G(&MediaProt->Protocol));
1909 }
1910 
1911 /**
1912   Converts a Firmware Volume device path structure to its string representative.
1913 
1914   @param Str             The string representative of input device.
1915   @param DevPath         The input device path structure.
1916   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1917                          of the display node is used, where applicable. If DisplayOnly
1918                          is FALSE, then the longer text representation of the display node
1919                          is used.
1920   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1921                          representation for a device node can be used, where applicable.
1922 
1923 **/
1924 static VOID
1925 DevPathToTextFv (
1926   IN OUT POOL_PRINT  *Str,
1927   IN VOID            *DevPath,
1928   IN BOOLEAN         DisplayOnly,
1929   IN BOOLEAN         AllowShortcuts
1930   )
1931 {
1932   MEDIA_FW_VOL_DEVICE_PATH  *Fv;
1933 
1934   Fv = DevPath;
1935   UefiDevicePathLibCatPrint (Str, "Fv(%36s)", G(&Fv->FvName));
1936 }
1937 
1938 /**
1939   Converts a Firmware Volume File device path structure to its string representative.
1940 
1941   @param Str             The string representative of input device.
1942   @param DevPath         The input device path structure.
1943   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1944                          of the display node is used, where applicable. If DisplayOnly
1945                          is FALSE, then the longer text representation of the display node
1946                          is used.
1947   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1948                          representation for a device node can be used, where applicable.
1949 
1950 **/
1951 static VOID
1952 DevPathToTextFvFile (
1953   IN OUT POOL_PRINT  *Str,
1954   IN VOID            *DevPath,
1955   IN BOOLEAN         DisplayOnly,
1956   IN BOOLEAN         AllowShortcuts
1957   )
1958 {
1959   MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvFile;
1960 
1961   FvFile = DevPath;
1962   UefiDevicePathLibCatPrint (Str, "FvFile(%36s)", G(&FvFile->FvFileName));
1963 }
1964 
1965 /**
1966   Converts a Relative Offset device path structure to its string representative.
1967 
1968   @param Str             The string representative of input device.
1969   @param DevPath         The input device path structure.
1970   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1971                          of the display node is used, where applicable. If DisplayOnly
1972                          is FALSE, then the longer text representation of the display node
1973                          is used.
1974   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1975                          representation for a device node can be used, where applicable.
1976 
1977 **/
1978 static VOID
1979 DevPathRelativeOffsetRange (
1980   IN OUT POOL_PRINT       *Str,
1981   IN VOID                 *DevPath,
1982   IN BOOLEAN              DisplayOnly,
1983   IN BOOLEAN              AllowShortcuts
1984   )
1985 {
1986   MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
1987 
1988   Offset = DevPath;
1989   UefiDevicePathLibCatPrint (
1990     Str,
1991     "Offset(0x%lx,0x%lx)",
1992     Offset->StartingOffset,
1993     Offset->EndingOffset
1994     );
1995 }
1996 
1997 /**
1998   Converts a Ram Disk device path structure to its string representative.
1999 
2000   @param Str             The string representative of input device.
2001   @param DevPath         The input device path structure.
2002   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
2003                          of the display node is used, where applicable. If DisplayOnly
2004                          is FALSE, then the longer text representation of the display node
2005                          is used.
2006   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
2007                          representation for a device node can be used, where applicable.
2008 
2009 **/
2010 static VOID
2011 DevPathToTextRamDisk (
2012   IN OUT POOL_PRINT       *Str,
2013   IN VOID                 *DevPath,
2014   IN BOOLEAN              DisplayOnly,
2015   IN BOOLEAN              AllowShortcuts
2016   )
2017 {
2018   MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
2019 
2020   RamDisk = DevPath;
2021 
2022   if (CompareGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid)) {
2023     UefiDevicePathLibCatPrint (
2024       Str,
2025       "VirtualDisk(0x%lx,0x%lx,%d)",
2026       LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
2027       LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
2028       RamDisk->Instance
2029       );
2030   } else if (CompareGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid)) {
2031     UefiDevicePathLibCatPrint (
2032       Str,
2033       "VirtualCD(0x%lx,0x%lx,%d)",
2034       LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
2035       LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
2036       RamDisk->Instance
2037       );
2038   } else if (CompareGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid)) {
2039     UefiDevicePathLibCatPrint (
2040       Str,
2041       "PersistentVirtualDisk(0x%lx,0x%lx,%d)",
2042       LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
2043       LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
2044       RamDisk->Instance
2045       );
2046   } else if (CompareGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid)) {
2047     UefiDevicePathLibCatPrint (
2048       Str,
2049       "PersistentVirtualCD(0x%lx,0x%lx,%d)",
2050       LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
2051       LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
2052       RamDisk->Instance
2053       );
2054   } else {
2055     UefiDevicePathLibCatPrint (
2056       Str,
2057       "RamDisk(0x%lx,0x%lx,%d,%36s)",
2058       LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
2059       LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
2060       RamDisk->Instance,
2061       G(&RamDisk->TypeGuid)
2062       );
2063   }
2064 }
2065 
2066 /**
2067   Converts a BIOS Boot Specification device path structure to its string representative.
2068 
2069   @param Str             The string representative of input device.
2070   @param DevPath         The input device path structure.
2071   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
2072                          of the display node is used, where applicable. If DisplayOnly
2073                          is FALSE, then the longer text representation of the display node
2074                          is used.
2075   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
2076                          representation for a device node can be used, where applicable.
2077 
2078 **/
2079 static VOID
2080 DevPathToTextBBS (
2081   IN OUT POOL_PRINT  *Str,
2082   IN VOID            *DevPath,
2083   IN BOOLEAN         DisplayOnly,
2084   IN BOOLEAN         AllowShortcuts
2085   )
2086 {
2087   BBS_BBS_DEVICE_PATH *Bbs;
2088   const char          *Type;
2089 
2090   Bbs = DevPath;
2091   switch (Bbs->DeviceType) {
2092   case BBS_TYPE_FLOPPY:
2093     Type = "Floppy";
2094     break;
2095 
2096   case BBS_TYPE_HARDDRIVE:
2097     Type = "HD";
2098     break;
2099 
2100   case BBS_TYPE_CDROM:
2101     Type = "CDROM";
2102     break;
2103 
2104   case BBS_TYPE_PCMCIA:
2105     Type = "PCMCIA";
2106     break;
2107 
2108   case BBS_TYPE_USB:
2109     Type = "USB";
2110     break;
2111 
2112   case BBS_TYPE_EMBEDDED_NETWORK:
2113     Type = "Network";
2114     break;
2115 
2116   default:
2117     Type = NULL;
2118     break;
2119   }
2120 
2121   if (Type != NULL) {
2122     UefiDevicePathLibCatPrint (Str, "BBS(%s,%s", Type, Bbs->String);
2123   } else {
2124     UefiDevicePathLibCatPrint (Str, "BBS(0x%x,%s", Bbs->DeviceType, Bbs->String);
2125   }
2126 
2127   if (DisplayOnly) {
2128     UefiDevicePathLibCatPrint (Str, ")");
2129     return ;
2130   }
2131 
2132   UefiDevicePathLibCatPrint (Str, ",0x%x)", Bbs->StatusFlag);
2133 }
2134 
2135 /**
2136   Converts an End-of-Device-Path structure to its string representative.
2137 
2138   @param Str             The string representative of input device.
2139   @param DevPath         The input device path structure.
2140   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
2141                          of the display node is used, where applicable. If DisplayOnly
2142                          is FALSE, then the longer text representation of the display node
2143                          is used.
2144   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
2145                          representation for a device node can be used, where applicable.
2146 
2147 **/
2148 static VOID
2149 DevPathToTextEndInstance (
2150   IN OUT POOL_PRINT  *Str,
2151   IN VOID            *DevPath,
2152   IN BOOLEAN         DisplayOnly,
2153   IN BOOLEAN         AllowShortcuts
2154   )
2155 {
2156   UefiDevicePathLibCatPrint (Str, ",");
2157 }
2158 
2159 GLOBAL_REMOVE_IF_UNREFERENCED const DEVICE_PATH_TO_TEXT_GENERIC_TABLE mUefiDevicePathLibToTextTableGeneric[] = {
2160   {HARDWARE_DEVICE_PATH,  "HardwarePath"   },
2161   {ACPI_DEVICE_PATH,      "AcpiPath"       },
2162   {MESSAGING_DEVICE_PATH, "Msg"            },
2163   {MEDIA_DEVICE_PATH,     "MediaPath"      },
2164   {BBS_DEVICE_PATH,       "BbsPath"        },
2165   {0, NULL}
2166 };
2167 
2168 /**
2169   Converts an unknown device path structure to its string representative.
2170 
2171   @param Str             The string representative of input device.
2172   @param DevPath         The input device path structure.
2173   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
2174                          of the display node is used, where applicable. If DisplayOnly
2175                          is FALSE, then the longer text representation of the display node
2176                          is used.
2177   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
2178                          representation for a device node can be used, where applicable.
2179 
2180 **/
2181 static VOID
2182 DevPathToTextNodeGeneric (
2183   IN OUT POOL_PRINT  *Str,
2184   IN VOID            *DevPath,
2185   IN BOOLEAN         DisplayOnly,
2186   IN BOOLEAN         AllowShortcuts
2187   )
2188 {
2189   EFI_DEVICE_PATH_PROTOCOL *Node;
2190   UINTN                    Index;
2191 
2192   Node = DevPath;
2193 
2194   for (Index = 0; mUefiDevicePathLibToTextTableGeneric[Index].Text != NULL; Index++) {
2195     if (DevicePathType (Node) == mUefiDevicePathLibToTextTableGeneric[Index].Type) {
2196       break;
2197     }
2198   }
2199 
2200   if (mUefiDevicePathLibToTextTableGeneric[Index].Text == NULL) {
2201     //
2202     // It's a node whose type cannot be recognized
2203     //
2204     UefiDevicePathLibCatPrint (Str, "Path(%d,%d", DevicePathType (Node), DevicePathSubType (Node));
2205   } else {
2206     //
2207     // It's a node whose type can be recognized
2208     //
2209     UefiDevicePathLibCatPrint (Str, "%s(%d", mUefiDevicePathLibToTextTableGeneric[Index].Text, DevicePathSubType (Node));
2210   }
2211 
2212   Index = sizeof (EFI_DEVICE_PATH_PROTOCOL);
2213   if (Index < DevicePathNodeLength (Node)) {
2214     UefiDevicePathLibCatPrint (Str, ",");
2215     for (; Index < DevicePathNodeLength (Node); Index++) {
2216       UefiDevicePathLibCatPrint (Str, "%02x", ((UINT8 *) Node)[Index]);
2217     }
2218   }
2219 
2220   UefiDevicePathLibCatPrint (Str, ")");
2221 }
2222 
2223 static const DEVICE_PATH_TO_TEXT_TABLE mUefiDevicePathLibToTextTable[] = {
2224   {HARDWARE_DEVICE_PATH,  HW_PCI_DP,                        DevPathToTextPci            },
2225   {HARDWARE_DEVICE_PATH,  HW_PCCARD_DP,                     DevPathToTextPccard         },
2226   {HARDWARE_DEVICE_PATH,  HW_MEMMAP_DP,                     DevPathToTextMemMap         },
2227   {HARDWARE_DEVICE_PATH,  HW_VENDOR_DP,                     DevPathToTextVendor         },
2228   {HARDWARE_DEVICE_PATH,  HW_CONTROLLER_DP,                 DevPathToTextController     },
2229   {HARDWARE_DEVICE_PATH,  HW_BMC_DP,                        DevPathToTextBmc            },
2230   {ACPI_DEVICE_PATH,      ACPI_DP,                          DevPathToTextAcpi           },
2231   {ACPI_DEVICE_PATH,      ACPI_EXTENDED_DP,                 DevPathToTextAcpiEx         },
2232   {ACPI_DEVICE_PATH,      ACPI_ADR_DP,                      DevPathToTextAcpiAdr        },
2233   {MESSAGING_DEVICE_PATH, MSG_ATAPI_DP,                     DevPathToTextAtapi          },
2234   {MESSAGING_DEVICE_PATH, MSG_SCSI_DP,                      DevPathToTextScsi           },
2235   {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP,              DevPathToTextFibre          },
2236   {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNELEX_DP,            DevPathToTextFibreEx        },
2237   {MESSAGING_DEVICE_PATH, MSG_SASEX_DP,                     DevPathToTextSasEx          },
2238   {MESSAGING_DEVICE_PATH, MSG_NVME_NAMESPACE_DP,            DevPathToTextNVMe           },
2239   {MESSAGING_DEVICE_PATH, MSG_UFS_DP,                       DevPathToTextUfs            },
2240   {MESSAGING_DEVICE_PATH, MSG_SD_DP,                        DevPathToTextSd             },
2241   {MESSAGING_DEVICE_PATH, MSG_EMMC_DP,                      DevPathToTextEmmc           },
2242   {MESSAGING_DEVICE_PATH, MSG_1394_DP,                      DevPathToText1394           },
2243   {MESSAGING_DEVICE_PATH, MSG_USB_DP,                       DevPathToTextUsb            },
2244   {MESSAGING_DEVICE_PATH, MSG_USB_WWID_DP,                  DevPathToTextUsbWWID        },
2245   {MESSAGING_DEVICE_PATH, MSG_DEVICE_LOGICAL_UNIT_DP,       DevPathToTextLogicalUnit    },
2246   {MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP,                 DevPathToTextUsbClass       },
2247   {MESSAGING_DEVICE_PATH, MSG_SATA_DP,                      DevPathToTextSata           },
2248   {MESSAGING_DEVICE_PATH, MSG_I2O_DP,                       DevPathToTextI2O            },
2249   {MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP,                  DevPathToTextMacAddr        },
2250   {MESSAGING_DEVICE_PATH, MSG_IPv4_DP,                      DevPathToTextIPv4           },
2251   {MESSAGING_DEVICE_PATH, MSG_IPv6_DP,                      DevPathToTextIPv6           },
2252   {MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP,                DevPathToTextInfiniBand     },
2253   {MESSAGING_DEVICE_PATH, MSG_UART_DP,                      DevPathToTextUart           },
2254   {MESSAGING_DEVICE_PATH, MSG_VENDOR_DP,                    DevPathToTextVendor         },
2255   {MESSAGING_DEVICE_PATH, MSG_ISCSI_DP,                     DevPathToTextiSCSI          },
2256   {MESSAGING_DEVICE_PATH, MSG_VLAN_DP,                      DevPathToTextVlan           },
2257   {MESSAGING_DEVICE_PATH, MSG_URI_DP,                       DevPathToTextUri            },
2258   {MESSAGING_DEVICE_PATH, MSG_BLUETOOTH_DP,                 DevPathToTextBluetooth      },
2259   {MESSAGING_DEVICE_PATH, MSG_WIFI_DP,                      DevPathToTextWiFi           },
2260   {MEDIA_DEVICE_PATH,     MEDIA_HARDDRIVE_DP,               DevPathToTextHardDrive      },
2261   {MEDIA_DEVICE_PATH,     MEDIA_CDROM_DP,                   DevPathToTextCDROM          },
2262   {MEDIA_DEVICE_PATH,     MEDIA_VENDOR_DP,                  DevPathToTextVendor         },
2263   {MEDIA_DEVICE_PATH,     MEDIA_PROTOCOL_DP,                DevPathToTextMediaProtocol  },
2264   {MEDIA_DEVICE_PATH,     MEDIA_FILEPATH_DP,                DevPathToTextFilePath       },
2265   {MEDIA_DEVICE_PATH,     MEDIA_PIWG_FW_VOL_DP,             DevPathToTextFv             },
2266   {MEDIA_DEVICE_PATH,     MEDIA_PIWG_FW_FILE_DP,            DevPathToTextFvFile         },
2267   {MEDIA_DEVICE_PATH,     MEDIA_RELATIVE_OFFSET_RANGE_DP,   DevPathRelativeOffsetRange  },
2268   {MEDIA_DEVICE_PATH,     MEDIA_RAM_DISK_DP,                DevPathToTextRamDisk        },
2269   {BBS_DEVICE_PATH,       BBS_BBS_DP,                       DevPathToTextBBS            },
2270   {END_DEVICE_PATH_TYPE,  END_INSTANCE_DEVICE_PATH_SUBTYPE, DevPathToTextEndInstance    },
2271   {0, 0, NULL}
2272 };
2273 
2274 /**
2275   Converts a device node to its string representation.
2276 
2277   @param DeviceNode        A Pointer to the device node to be converted.
2278   @param DisplayOnly       If DisplayOnly is TRUE, then the shorter text representation
2279                            of the display node is used, where applicable. If DisplayOnly
2280                            is FALSE, then the longer text representation of the display node
2281                            is used.
2282   @param AllowShortcuts    If AllowShortcuts is TRUE, then the shortcut forms of text
2283                            representation for a device node can be used, where applicable.
2284 
2285   @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
2286           is NULL or there was insufficient memory.
2287 
2288 **/
2289 static char *
2290 EFIAPI
2291 UefiDevicePathLibConvertDeviceNodeToText (
2292   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,
2293   IN BOOLEAN                         DisplayOnly,
2294   IN BOOLEAN                         AllowShortcuts
2295   )
2296 {
2297   POOL_PRINT          Str;
2298   UINTN               Index;
2299   DEVICE_PATH_TO_TEXT ToText;
2300   EFI_DEVICE_PATH_PROTOCOL *Node;
2301 
2302   if (DeviceNode == NULL) {
2303     return NULL;
2304   }
2305 
2306   ZeroMem (&Str, sizeof (Str));
2307 
2308   //
2309   // Process the device path node
2310   // If not found, use a generic function
2311   //
2312   Node = __DECONST(EFI_DEVICE_PATH_PROTOCOL *, DeviceNode);
2313   ToText = DevPathToTextNodeGeneric;
2314   for (Index = 0; mUefiDevicePathLibToTextTable[Index].Function != NULL; Index++) {
2315     if (DevicePathType (DeviceNode) == mUefiDevicePathLibToTextTable[Index].Type &&
2316         DevicePathSubType (DeviceNode) == mUefiDevicePathLibToTextTable[Index].SubType
2317         ) {
2318       ToText = mUefiDevicePathLibToTextTable[Index].Function;
2319       break;
2320     }
2321   }
2322 
2323   //
2324   // Print this node
2325   //
2326   ToText (&Str, (VOID *) Node, DisplayOnly, AllowShortcuts);
2327 
2328   ASSERT (Str.Str != NULL);
2329   return Str.Str;
2330 }
2331 
2332 /**
2333   Converts a device path to its text representation.
2334 
2335   @param DevicePath      A Pointer to the device to be converted.
2336   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
2337                          of the display node is used, where applicable. If DisplayOnly
2338                          is FALSE, then the longer text representation of the display node
2339                          is used.
2340   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
2341                          representation for a device node can be used, where applicable.
2342 
2343   @return A pointer to the allocated text representation of the device path or
2344           NULL if DeviceNode is NULL or there was insufficient memory.
2345 
2346 **/
2347 static char *
2348 EFIAPI
2349 UefiDevicePathLibConvertDevicePathToText (
2350   IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,
2351   IN BOOLEAN                          DisplayOnly,
2352   IN BOOLEAN                          AllowShortcuts
2353   )
2354 {
2355   POOL_PRINT               Str;
2356   EFI_DEVICE_PATH_PROTOCOL *Node;
2357   EFI_DEVICE_PATH_PROTOCOL *AlignedNode;
2358   UINTN                    Index;
2359   DEVICE_PATH_TO_TEXT      ToText;
2360 
2361   if (DevicePath == NULL) {
2362     return NULL;
2363   }
2364 
2365   ZeroMem (&Str, sizeof (Str));
2366 
2367   //
2368   // Process each device path node
2369   //
2370   Node = __DECONST(EFI_DEVICE_PATH_PROTOCOL *, DevicePath);
2371   while (!IsDevicePathEnd (Node)) {
2372     //
2373     // Find the handler to dump this device path node
2374     // If not found, use a generic function
2375     //
2376     ToText = DevPathToTextNodeGeneric;
2377     for (Index = 0; mUefiDevicePathLibToTextTable[Index].Function != NULL; Index += 1) {
2378 
2379       if (DevicePathType (Node) == mUefiDevicePathLibToTextTable[Index].Type &&
2380           DevicePathSubType (Node) == mUefiDevicePathLibToTextTable[Index].SubType
2381           ) {
2382         ToText = mUefiDevicePathLibToTextTable[Index].Function;
2383         break;
2384       }
2385     }
2386     //
2387     //  Put a path separator in if needed
2388     //
2389     if ((Str.Count != 0) && (ToText != DevPathToTextEndInstance)) {
2390       if (Str.Str[Str.Count] != ',') {
2391         UefiDevicePathLibCatPrint (&Str, "/");
2392       }
2393     }
2394 
2395     AlignedNode = AllocateCopyPool (DevicePathNodeLength (Node), Node);
2396     //
2397     // Print this node of the device path
2398     //
2399     ToText (&Str, AlignedNode, DisplayOnly, AllowShortcuts);
2400     FreePool (AlignedNode);
2401 
2402     //
2403     // Next device path node
2404     //
2405     Node = NextDevicePathNode (Node);
2406   }
2407 
2408   if (Str.Str == NULL) {
2409     return AllocateZeroPool (sizeof (CHAR16));
2410   } else {
2411     return Str.Str;
2412   }
2413 }
2414 
2415 ssize_t
2416 efidp_format_device_path(char *buf, size_t len, const_efidp dp, ssize_t max)
2417 {
2418 	char *str;
2419 	ssize_t retval;
2420 
2421 	/*
2422 	 * Basic sanity check on the device path.
2423 	 */
2424 	if (!IsDevicePathValid((CONST EFI_DEVICE_PATH_PROTOCOL *) dp, max)) {
2425 		*buf = '\0';
2426 		return 0;
2427 	}
2428 
2429 	str = UefiDevicePathLibConvertDevicePathToText (
2430 		__DECONST(EFI_DEVICE_PATH_PROTOCOL *, dp), FALSE, TRUE);
2431 	if (str == NULL)
2432 		return -1;
2433 	strlcpy(buf, str, len);
2434 	retval = strlen(str);
2435 	free(str);
2436 
2437 	return retval;
2438 }
2439 
2440 ssize_t
2441 efidp_format_device_path_node(char *buf, size_t len, const_efidp dp)
2442 {
2443 	char *str;
2444 	ssize_t retval;
2445 
2446 	str = UefiDevicePathLibConvertDeviceNodeToText (
2447 		__DECONST(EFI_DEVICE_PATH_PROTOCOL *, dp), FALSE, TRUE);
2448 	if (str == NULL)
2449 		return -1;
2450 	strlcpy(buf, str, len);
2451 	retval = strlen(str);
2452 	free(str);
2453 
2454 	return retval;
2455 }
2456 
2457 size_t
2458 efidp_size(const_efidp dp)
2459 {
2460 
2461 	return GetDevicePathSize(__DECONST(EFI_DEVICE_PATH_PROTOCOL *, dp));
2462 }
2463 
2464 char *
2465 efidp_extract_file_path(const_efidp dp)
2466 {
2467 	const FILEPATH_DEVICE_PATH  *fp;
2468 	char *name = NULL;
2469 
2470 	fp = (const void *)dp;
2471 	ucs2_to_utf8(fp->PathName, &name);
2472 	return name;
2473 }
2474