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