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