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