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