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