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  * $FreeBSD: head/lib/libefivar/efivar-dp-format.c 343755 2019-02-04 21:28:25Z imp $
26  */
27 
28 /*
29  * Routines to format EFI_DEVICE_PATHs from the UEFI standard. Much of
30  * this file is taken from EDK2 and rototilled.
31  */
32 
33 #include <efivar.h>
34 #include <stdio.h>
35 #include <string.h>
36 
37 #include "libefivar_int.h"
38 
39 #include "efi-osdep.h"
40 #include "efivar-dp.h"
41 
42 #include "uefi-dplib.h"
43 
44 /*
45  * This is a lie, but since we have converted everything
46  * from wide to narrow, it's the right lie now.
47  */
48 #define UnicodeSPrint snprintf
49 
50 /*
51  * Taken from MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
52  * hash a11928f3310518ab1c6fd34e8d0fdbb72de9602c 2017-Mar-01
53  * heavily modified:
54  *	wide strings converted to narrow
55  *	Low level printing code redone for narrow strings
56  *	Routines made static
57  *	%s -> %S in spots (where it is still UCS-2)
58  *	%a (ascii) -> %s
59  *	%g -> %36s hack to print guid (see above for caveat)
60  *	some tidying up of const and deconsting. It's evil, but const
61  *	  poisoning the whole file was too much.
62  */
63 
64 /** @file
65   DevicePathToText protocol as defined in the UEFI 2.0 specification.
66 
67   (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
68 Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
69 This program and the accompanying materials
70 are licensed and made available under the terms and conditions of the BSD License
71 which accompanies this distribution.  The full text of the license may be found at
72 http://opensource.org/licenses/bsd-license.php
73 
74 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
75 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
76 
77 **/
78 
79 // #include "UefiDevicePathLib.h"
80 
81 /**
82   Concatenates a formatted unicode string to allocated pool. The caller must
83   free the resulting buffer.
84 
85   @param Str             Tracks the allocated pool, size in use, and
86                          amount of pool allocated.
87   @param Fmt             The format string
88   @param ...             Variable arguments based on the format string.
89 
90   @return Allocated buffer with the formatted string printed in it.
91           The caller must free the allocated buffer. The buffer
92           allocation is not packed.
93 
94 **/
95 static char *
96 EFIAPI
UefiDevicePathLibCatPrint(IN OUT POOL_PRINT * Str,IN const char * Fmt,...)97 UefiDevicePathLibCatPrint (
98   IN OUT POOL_PRINT   *Str,
99   IN const char       *Fmt,
100   ...
101   )
102 {
103   UINTN   Count;
104   VA_LIST Args;
105 
106   VA_START (Args, Fmt);
107   Count = vsnprintf(NULL, 0, Fmt, Args);
108   VA_END(Args);
109 
110   if ((Str->Count + (Count + 1)) > Str->Capacity) {
111     Str->Capacity = (Str->Count + (Count + 1) * 2);
112     Str->Str = reallocf(Str->Str, Str->Capacity);
113     ASSERT (Str->Str != NULL);
114   }
115   VA_START (Args, Fmt);
116   vsnprintf(Str->Str + Str->Count, Str->Capacity - Str->Count, Fmt, Args);
117   Str->Count += Count;
118 
119   VA_END (Args);
120   return Str->Str;
121 }
122 
123 /**
124   Converts a PCI device path structure to its string representative.
125 
126   @param Str             The string representative of input device.
127   @param DevPath         The input device path structure.
128   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
129                          of the display node is used, where applicable. If DisplayOnly
130                          is FALSE, then the longer text representation of the display node
131                          is used.
132   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
133                          representation for a device node can be used, where applicable.
134 
135 **/
136 static VOID
DevPathToTextPci(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)137 DevPathToTextPci (
138   IN OUT POOL_PRINT  *Str,
139   IN VOID            *DevPath,
140   IN BOOLEAN         DisplayOnly,
141   IN BOOLEAN         AllowShortcuts
142   )
143 {
144   PCI_DEVICE_PATH *Pci;
145 
146   Pci = DevPath;
147   UefiDevicePathLibCatPrint (Str, "Pci(0x%x,0x%x)", Pci->Device, Pci->Function);
148 }
149 
150 /**
151   Converts a PC Card device path structure to its string representative.
152 
153   @param Str             The string representative of input device.
154   @param DevPath         The input device path structure.
155   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
156                          of the display node is used, where applicable. If DisplayOnly
157                          is FALSE, then the longer text representation of the display node
158                          is used.
159   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
160                          representation for a device node can be used, where applicable.
161 
162 **/
163 static VOID
DevPathToTextPccard(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)164 DevPathToTextPccard (
165   IN OUT POOL_PRINT  *Str,
166   IN VOID            *DevPath,
167   IN BOOLEAN         DisplayOnly,
168   IN BOOLEAN         AllowShortcuts
169   )
170 {
171   PCCARD_DEVICE_PATH  *Pccard;
172 
173   Pccard = DevPath;
174   UefiDevicePathLibCatPrint (Str, "PcCard(0x%x)", Pccard->FunctionNumber);
175 }
176 
177 /**
178   Converts a Memory Map device path structure to its string representative.
179 
180   @param Str             The string representative of input device.
181   @param DevPath         The input device path structure.
182   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
183                          of the display node is used, where applicable. If DisplayOnly
184                          is FALSE, then the longer text representation of the display node
185                          is used.
186   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
187                          representation for a device node can be used, where applicable.
188 
189 **/
190 static VOID
DevPathToTextMemMap(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)191 DevPathToTextMemMap (
192   IN OUT POOL_PRINT  *Str,
193   IN VOID            *DevPath,
194   IN BOOLEAN         DisplayOnly,
195   IN BOOLEAN         AllowShortcuts
196   )
197 {
198   MEMMAP_DEVICE_PATH  *MemMap;
199 
200   MemMap = DevPath;
201   UefiDevicePathLibCatPrint (
202     Str,
203     "MemoryMapped(0x%x,0x%lx,0x%lx)",
204     MemMap->MemoryType,
205     MemMap->StartingAddress,
206     MemMap->EndingAddress
207     );
208 }
209 
210 /**
211   Converts a Vendor device path structure to its string representative.
212 
213   @param Str             The string representative of input device.
214   @param DevPath         The input device path structure.
215   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
216                          of the display node is used, where applicable. If DisplayOnly
217                          is FALSE, then the longer text representation of the display node
218                          is used.
219   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
220                          representation for a device node can be used, where applicable.
221 
222 **/
223 static VOID
DevPathToTextVendor(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)224 DevPathToTextVendor (
225   IN OUT POOL_PRINT  *Str,
226   IN VOID            *DevPath,
227   IN BOOLEAN         DisplayOnly,
228   IN BOOLEAN         AllowShortcuts
229   )
230 {
231   VENDOR_DEVICE_PATH  *Vendor;
232   const char          *Type;
233   UINTN               Index;
234   UINTN               DataLength;
235   UINT32              FlowControlMap;
236   UINT16              Info;
237 
238   Vendor = (VENDOR_DEVICE_PATH *) DevPath;
239   switch (DevicePathType (&Vendor->Header)) {
240   case HARDWARE_DEVICE_PATH:
241     Type = "Hw";
242     break;
243 
244   case MESSAGING_DEVICE_PATH:
245     Type = "Msg";
246     if (AllowShortcuts) {
247       if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {
248         UefiDevicePathLibCatPrint (Str, "VenPcAnsi()");
249         return ;
250       } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
251         UefiDevicePathLibCatPrint (Str, "VenVt100()");
252         return ;
253       } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
254         UefiDevicePathLibCatPrint (Str, "VenVt100Plus()");
255         return ;
256       } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
257         UefiDevicePathLibCatPrint (Str, "VenUft8()");
258         return ;
259       } else if (CompareGuid (&Vendor->Guid, &gEfiUartDevicePathGuid)) {
260         FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);
261         switch (FlowControlMap & 0x00000003) {
262         case 0:
263           UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "None");
264           break;
265 
266         case 1:
267           UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "Hardware");
268           break;
269 
270         case 2:
271           UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "XonXoff");
272           break;
273 
274         default:
275           break;
276         }
277 
278         return ;
279       } else if (CompareGuid (&Vendor->Guid, &gEfiSasDevicePathGuid)) {
280         UefiDevicePathLibCatPrint (
281           Str,
282           "SAS(0x%lx,0x%lx,0x%x,",
283           ((SAS_DEVICE_PATH *) Vendor)->SasAddress,
284           ((SAS_DEVICE_PATH *) Vendor)->Lun,
285           ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort
286           );
287         Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);
288         if (((Info & 0x0f) == 0) && ((Info & BIT7) == 0)) {
289           UefiDevicePathLibCatPrint (Str, "NoTopology,0,0,0,");
290         } else if (((Info & 0x0f) <= 2) && ((Info & BIT7) == 0)) {
291           UefiDevicePathLibCatPrint (
292             Str,
293             "%s,%s,%s,",
294             ((Info & BIT4) != 0) ? "SATA" : "SAS",
295             ((Info & BIT5) != 0) ? "External" : "Internal",
296             ((Info & BIT6) != 0) ? "Expanded" : "Direct"
297             );
298           if ((Info & 0x0f) == 1) {
299             UefiDevicePathLibCatPrint (Str, "0,");
300           } else {
301             //
302             // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256
303             //
304             UefiDevicePathLibCatPrint (Str, "0x%x,", ((Info >> 8) & 0xff) + 1);
305           }
306         } else {
307           UefiDevicePathLibCatPrint (Str, "0x%x,0,0,0,", Info);
308         }
309 
310         UefiDevicePathLibCatPrint (Str, "0x%x)", ((SAS_DEVICE_PATH *) Vendor)->Reserved);
311         return ;
312       } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
313         UefiDevicePathLibCatPrint (Str, "DebugPort()");
314         return ;
315       }
316     }
317     break;
318 
319   case MEDIA_DEVICE_PATH:
320     Type = "Media";
321     break;
322 
323   default:
324     Type = "?";
325     break;
326   }
327 
328   DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);
329   UefiDevicePathLibCatPrint (Str, "Ven%s(%36s", Type, G(&Vendor->Guid));
330   if (DataLength != 0) {
331     UefiDevicePathLibCatPrint (Str, ",");
332     for (Index = 0; Index < DataLength; Index++) {
333       UefiDevicePathLibCatPrint (Str, "%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
334     }
335   }
336 
337   UefiDevicePathLibCatPrint (Str, ")");
338 }
339 
340 /**
341   Converts a Controller device path structure to its string representative.
342 
343   @param Str             The string representative of input device.
344   @param DevPath         The input device path structure.
345   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
346                          of the display node is used, where applicable. If DisplayOnly
347                          is FALSE, then the longer text representation of the display node
348                          is used.
349   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
350                          representation for a device node can be used, where applicable.
351 
352 **/
353 static VOID
DevPathToTextController(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)354 DevPathToTextController (
355   IN OUT POOL_PRINT  *Str,
356   IN VOID            *DevPath,
357   IN BOOLEAN         DisplayOnly,
358   IN BOOLEAN         AllowShortcuts
359   )
360 {
361   CONTROLLER_DEVICE_PATH  *Controller;
362 
363   Controller = DevPath;
364   UefiDevicePathLibCatPrint (
365     Str,
366     "Ctrl(0x%x)",
367     Controller->ControllerNumber
368     );
369 }
370 
371 /**
372   Converts a BMC device path structure to its string representative.
373 
374   @param Str             The string representative of input device.
375   @param DevPath         The input device path structure.
376   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
377                          of the display node is used, where applicable. If DisplayOnly
378                          is FALSE, then the longer text representation of the display node
379                          is used.
380   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
381                          representation for a device node can be used, where applicable.
382 
383 **/
384 static VOID
DevPathToTextBmc(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)385 DevPathToTextBmc (
386   IN OUT POOL_PRINT  *Str,
387   IN VOID            *DevPath,
388   IN BOOLEAN         DisplayOnly,
389   IN BOOLEAN         AllowShortcuts
390   )
391 {
392   BMC_DEVICE_PATH    *Bmc;
393 
394   Bmc = DevPath;
395   UefiDevicePathLibCatPrint (
396     Str,
397     "BMC(0x%x,0x%lx)",
398     Bmc->InterfaceType,
399     ReadUnaligned64 ((&Bmc->BaseAddress))
400     );
401 }
402 
403 /**
404   Converts a ACPI device path structure to its string representative.
405 
406   @param Str             The string representative of input device.
407   @param DevPath         The input device path structure.
408   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
409                          of the display node is used, where applicable. If DisplayOnly
410                          is FALSE, then the longer text representation of the display node
411                          is used.
412   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
413                          representation for a device node can be used, where applicable.
414 
415 **/
416 static VOID
DevPathToTextAcpi(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)417 DevPathToTextAcpi (
418   IN OUT POOL_PRINT  *Str,
419   IN VOID            *DevPath,
420   IN BOOLEAN         DisplayOnly,
421   IN BOOLEAN         AllowShortcuts
422   )
423 {
424   ACPI_HID_DEVICE_PATH  *Acpi;
425 
426   Acpi = DevPath;
427   if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
428     switch (EISA_ID_TO_NUM (Acpi->HID)) {
429     case 0x0a03:
430       UefiDevicePathLibCatPrint (Str, "PciRoot(0x%x)", Acpi->UID);
431       break;
432 
433     case 0x0a08:
434       UefiDevicePathLibCatPrint (Str, "PcieRoot(0x%x)", Acpi->UID);
435       break;
436 
437     case 0x0604:
438       UefiDevicePathLibCatPrint (Str, "Floppy(0x%x)", Acpi->UID);
439       break;
440 
441     case 0x0301:
442       UefiDevicePathLibCatPrint (Str, "Keyboard(0x%x)", Acpi->UID);
443       break;
444 
445     case 0x0501:
446       UefiDevicePathLibCatPrint (Str, "Serial(0x%x)", Acpi->UID);
447       break;
448 
449     case 0x0401:
450       UefiDevicePathLibCatPrint (Str, "ParallelPort(0x%x)", Acpi->UID);
451       break;
452 
453     default:
454       UefiDevicePathLibCatPrint (Str, "Acpi(PNP%04x,0x%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
455       break;
456     }
457   } else {
458     UefiDevicePathLibCatPrint (Str, "Acpi(0x%08x,0x%x)", Acpi->HID, Acpi->UID);
459   }
460 }
461 
462 /**
463   Converts a ACPI extended HID device path structure to its string representative.
464 
465   @param Str             The string representative of input device.
466   @param DevPath         The input device path structure.
467   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
468                          of the display node is used, where applicable. If DisplayOnly
469                          is FALSE, then the longer text representation of the display node
470                          is used.
471   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
472                          representation for a device node can be used, where applicable.
473 
474 **/
475 static VOID
DevPathToTextAcpiEx(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)476 DevPathToTextAcpiEx (
477   IN OUT POOL_PRINT  *Str,
478   IN VOID            *DevPath,
479   IN BOOLEAN         DisplayOnly,
480   IN BOOLEAN         AllowShortcuts
481   )
482 {
483   ACPI_EXTENDED_HID_DEVICE_PATH  *AcpiEx;
484   CHAR8                          *HIDStr;
485   CHAR8                          *UIDStr;
486   CHAR8                          *CIDStr;
487   char                           HIDText[11];
488   char                           CIDText[11];
489 
490   AcpiEx = DevPath;
491   HIDStr = (CHAR8 *) (((UINT8 *) AcpiEx) + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
492   UIDStr = HIDStr + AsciiStrLen (HIDStr) + 1;
493   CIDStr = UIDStr + AsciiStrLen (UIDStr) + 1;
494 
495   //
496   // Converts EISA identification to string.
497   //
498   UnicodeSPrint (
499     HIDText,
500     sizeof (HIDText),
501     "%c%c%c%04X",
502     ((AcpiEx->HID >> 10) & 0x1f) + 'A' - 1,
503     ((AcpiEx->HID >>  5) & 0x1f) + 'A' - 1,
504     ((AcpiEx->HID >>  0) & 0x1f) + 'A' - 1,
505     (AcpiEx->HID >> 16) & 0xFFFF
506     );
507   UnicodeSPrint (
508     CIDText,
509     sizeof (CIDText),
510     "%c%c%c%04X",
511     ((AcpiEx->CID >> 10) & 0x1f) + 'A' - 1,
512     ((AcpiEx->CID >>  5) & 0x1f) + 'A' - 1,
513     ((AcpiEx->CID >>  0) & 0x1f) + 'A' - 1,
514     (AcpiEx->CID >> 16) & 0xFFFF
515     );
516 
517   if ((*HIDStr == '\0') && (*CIDStr == '\0') && (AcpiEx->UID == 0)) {
518     //
519     // use AcpiExp()
520     //
521     UefiDevicePathLibCatPrint (
522       Str,
523       "AcpiExp(%s,%s,%s)",
524       HIDText,
525       CIDText,
526       UIDStr
527       );
528   } else {
529     if (AllowShortcuts) {
530       //
531       // display only
532       //
533       if (AcpiEx->HID == 0) {
534         UefiDevicePathLibCatPrint (Str, "AcpiEx(%s,", HIDStr);
535       } else {
536         UefiDevicePathLibCatPrint (Str, "AcpiEx(%s,", HIDText);
537       }
538 
539       if (AcpiEx->UID == 0) {
540         UefiDevicePathLibCatPrint (Str, "%s,", UIDStr);
541       } else {
542         UefiDevicePathLibCatPrint (Str, "0x%x,", AcpiEx->UID);
543       }
544 
545       if (AcpiEx->CID == 0) {
546         UefiDevicePathLibCatPrint (Str, "%s)", CIDStr);
547       } else {
548         UefiDevicePathLibCatPrint (Str, "%s)", CIDText);
549       }
550     } else {
551       UefiDevicePathLibCatPrint (
552         Str,
553         "AcpiEx(%s,%s,0x%x,%s,%s,%s)",
554         HIDText,
555         CIDText,
556         AcpiEx->UID,
557         HIDStr,
558         CIDStr,
559         UIDStr
560         );
561     }
562   }
563 }
564 
565 /**
566   Converts a ACPI address device path structure to its string representative.
567 
568   @param Str             The string representative of input device.
569   @param DevPath         The input device path structure.
570   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
571                          of the display node is used, where applicable. If DisplayOnly
572                          is FALSE, then the longer text representation of the display node
573                          is used.
574   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
575                          representation for a device node can be used, where applicable.
576 
577 **/
578 static VOID
DevPathToTextAcpiAdr(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)579 DevPathToTextAcpiAdr (
580   IN OUT POOL_PRINT  *Str,
581   IN VOID            *DevPath,
582   IN BOOLEAN         DisplayOnly,
583   IN BOOLEAN         AllowShortcuts
584   )
585 {
586   ACPI_ADR_DEVICE_PATH    *AcpiAdr;
587   UINT32                  *Addr;
588   UINT16                  Index;
589   UINT16                  Length;
590   UINT16                  AdditionalAdrCount;
591 
592   AcpiAdr            = DevPath;
593   Length             = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);
594   AdditionalAdrCount = (UINT16) ((Length - 8) / 4);
595 
596   UefiDevicePathLibCatPrint (Str, "AcpiAdr(0x%x", AcpiAdr->ADR);
597   Addr = &AcpiAdr->ADR + 1;
598   for (Index = 0; Index < AdditionalAdrCount; Index++) {
599     UefiDevicePathLibCatPrint (Str, ",0x%x", Addr[Index]);
600   }
601   UefiDevicePathLibCatPrint (Str, ")");
602 }
603 
604 /**
605   Converts a ATAPI device path structure to its string representative.
606 
607   @param Str             The string representative of input device.
608   @param DevPath         The input device path structure.
609   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
610                          of the display node is used, where applicable. If DisplayOnly
611                          is FALSE, then the longer text representation of the display node
612                          is used.
613   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
614                          representation for a device node can be used, where applicable.
615 
616 **/
617 static VOID
DevPathToTextAtapi(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)618 DevPathToTextAtapi (
619   IN OUT POOL_PRINT  *Str,
620   IN VOID            *DevPath,
621   IN BOOLEAN         DisplayOnly,
622   IN BOOLEAN         AllowShortcuts
623   )
624 {
625   ATAPI_DEVICE_PATH *Atapi;
626 
627   Atapi = DevPath;
628 
629   if (DisplayOnly) {
630     UefiDevicePathLibCatPrint (Str, "Ata(0x%x)", Atapi->Lun);
631   } else {
632     UefiDevicePathLibCatPrint (
633       Str,
634       "Ata(%s,%s,0x%x)",
635       (Atapi->PrimarySecondary == 1) ? "Secondary" : "Primary",
636       (Atapi->SlaveMaster == 1) ? "Slave" : "Master",
637       Atapi->Lun
638       );
639   }
640 }
641 
642 /**
643   Converts a SCSI device path structure to its string representative.
644 
645   @param Str             The string representative of input device.
646   @param DevPath         The input device path structure.
647   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
648                          of the display node is used, where applicable. If DisplayOnly
649                          is FALSE, then the longer text representation of the display node
650                          is used.
651   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
652                          representation for a device node can be used, where applicable.
653 
654 **/
655 static VOID
DevPathToTextScsi(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)656 DevPathToTextScsi (
657   IN OUT POOL_PRINT  *Str,
658   IN VOID            *DevPath,
659   IN BOOLEAN         DisplayOnly,
660   IN BOOLEAN         AllowShortcuts
661   )
662 {
663   SCSI_DEVICE_PATH  *Scsi;
664 
665   Scsi = DevPath;
666   UefiDevicePathLibCatPrint (Str, "Scsi(0x%x,0x%x)", Scsi->Pun, Scsi->Lun);
667 }
668 
669 /**
670   Converts a Fibre device path structure to its string representative.
671 
672   @param Str             The string representative of input device.
673   @param DevPath         The input device path structure.
674   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
675                          of the display node is used, where applicable. If DisplayOnly
676                          is FALSE, then the longer text representation of the display node
677                          is used.
678   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
679                          representation for a device node can be used, where applicable.
680 
681 **/
682 static VOID
DevPathToTextFibre(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)683 DevPathToTextFibre (
684   IN OUT POOL_PRINT  *Str,
685   IN VOID            *DevPath,
686   IN BOOLEAN         DisplayOnly,
687   IN BOOLEAN         AllowShortcuts
688   )
689 {
690   FIBRECHANNEL_DEVICE_PATH  *Fibre;
691 
692   Fibre = DevPath;
693   UefiDevicePathLibCatPrint (Str, "Fibre(0x%lx,0x%lx)", Fibre->WWN, Fibre->Lun);
694 }
695 
696 /**
697   Converts a FibreEx device path structure to its string representative.
698 
699   @param Str             The string representative of input device.
700   @param DevPath         The input device path structure.
701   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
702                          of the display node is used, where applicable. If DisplayOnly
703                          is FALSE, then the longer text representation of the display node
704                          is used.
705   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
706                          representation for a device node can be used, where applicable.
707 
708 **/
709 static VOID
DevPathToTextFibreEx(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)710 DevPathToTextFibreEx (
711   IN OUT POOL_PRINT  *Str,
712   IN VOID            *DevPath,
713   IN BOOLEAN         DisplayOnly,
714   IN BOOLEAN         AllowShortcuts
715   )
716 {
717   FIBRECHANNELEX_DEVICE_PATH  *FibreEx;
718   UINTN                       Index;
719 
720   FibreEx = DevPath;
721   UefiDevicePathLibCatPrint (Str, "FibreEx(0x");
722   for (Index = 0; Index < sizeof (FibreEx->WWN) / sizeof (FibreEx->WWN[0]); Index++) {
723     UefiDevicePathLibCatPrint (Str, "%02x", FibreEx->WWN[Index]);
724   }
725   UefiDevicePathLibCatPrint (Str, ",0x");
726   for (Index = 0; Index < sizeof (FibreEx->Lun) / sizeof (FibreEx->Lun[0]); Index++) {
727     UefiDevicePathLibCatPrint (Str, "%02x", FibreEx->Lun[Index]);
728   }
729   UefiDevicePathLibCatPrint (Str, ")");
730 }
731 
732 /**
733   Converts a Sas Ex device path structure to its string representative.
734 
735   @param Str             The string representative of input device.
736   @param DevPath         The input device path structure.
737   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
738                          of the display node is used, where applicable. If DisplayOnly
739                          is FALSE, then the longer text representation of the display node
740                          is used.
741   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
742                          representation for a device node can be used, where applicable.
743 
744 **/
745 static VOID
DevPathToTextSasEx(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)746 DevPathToTextSasEx (
747   IN OUT POOL_PRINT  *Str,
748   IN VOID            *DevPath,
749   IN BOOLEAN         DisplayOnly,
750   IN BOOLEAN         AllowShortcuts
751   )
752 {
753   SASEX_DEVICE_PATH  *SasEx;
754   UINTN              Index;
755 
756   SasEx = DevPath;
757   UefiDevicePathLibCatPrint (Str, "SasEx(0x");
758 
759   for (Index = 0; Index < sizeof (SasEx->SasAddress) / sizeof (SasEx->SasAddress[0]); Index++) {
760     UefiDevicePathLibCatPrint (Str, "%02x", SasEx->SasAddress[Index]);
761   }
762   UefiDevicePathLibCatPrint (Str, ",0x");
763   for (Index = 0; Index < sizeof (SasEx->Lun) / sizeof (SasEx->Lun[0]); Index++) {
764     UefiDevicePathLibCatPrint (Str, "%02x", SasEx->Lun[Index]);
765   }
766   UefiDevicePathLibCatPrint (Str, ",0x%x,", SasEx->RelativeTargetPort);
767 
768   if (((SasEx->DeviceTopology & 0x0f) == 0) && ((SasEx->DeviceTopology & BIT7) == 0)) {
769     UefiDevicePathLibCatPrint (Str, "NoTopology,0,0,0");
770   } else if (((SasEx->DeviceTopology & 0x0f) <= 2) && ((SasEx->DeviceTopology & BIT7) == 0)) {
771     UefiDevicePathLibCatPrint (
772       Str,
773       "%s,%s,%s,",
774       ((SasEx->DeviceTopology & BIT4) != 0) ? "SATA" : "SAS",
775       ((SasEx->DeviceTopology & BIT5) != 0) ? "External" : "Internal",
776       ((SasEx->DeviceTopology & BIT6) != 0) ? "Expanded" : "Direct"
777       );
778     if ((SasEx->DeviceTopology & 0x0f) == 1) {
779       UefiDevicePathLibCatPrint (Str, "0");
780     } else {
781       //
782       // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256
783       //
784       UefiDevicePathLibCatPrint (Str, "0x%x", ((SasEx->DeviceTopology >> 8) & 0xff) + 1);
785     }
786   } else {
787     UefiDevicePathLibCatPrint (Str, "0x%x,0,0,0", SasEx->DeviceTopology);
788   }
789 
790   UefiDevicePathLibCatPrint (Str, ")");
791   return ;
792 
793 }
794 
795 /**
796   Converts a NVM Express Namespace device path structure to its string representative.
797 
798   @param Str             The string representative of input device.
799   @param DevPath         The input device path structure.
800   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
801                          of the display node is used, where applicable. If DisplayOnly
802                          is FALSE, then the longer text representation of the display node
803                          is used.
804   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
805                          representation for a device node can be used, where applicable.
806 
807 **/
808 static VOID
DevPathToTextNVMe(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)809 DevPathToTextNVMe (
810   IN OUT POOL_PRINT  *Str,
811   IN VOID            *DevPath,
812   IN BOOLEAN         DisplayOnly,
813   IN BOOLEAN         AllowShortcuts
814   )
815 {
816   NVME_NAMESPACE_DEVICE_PATH *Nvme;
817   UINT8                      *Uuid;
818 
819   Nvme = DevPath;
820   Uuid = (UINT8 *) &Nvme->NamespaceUuid;
821   UefiDevicePathLibCatPrint (
822     Str,
823     "NVMe(0x%x,%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)",
824     Nvme->NamespaceId,
825     Uuid[7], Uuid[6], Uuid[5], Uuid[4],
826     Uuid[3], Uuid[2], Uuid[1], Uuid[0]
827     );
828 }
829 
830 /**
831   Converts a UFS device path structure to its string representative.
832 
833   @param Str             The string representative of input device.
834   @param DevPath         The input device path structure.
835   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
836                          of the display node is used, where applicable. If DisplayOnly
837                          is FALSE, then the longer text representation of the display node
838                          is used.
839   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
840                          representation for a device node can be used, where applicable.
841 
842 **/
843 static VOID
DevPathToTextUfs(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)844 DevPathToTextUfs (
845   IN OUT POOL_PRINT  *Str,
846   IN VOID            *DevPath,
847   IN BOOLEAN         DisplayOnly,
848   IN BOOLEAN         AllowShortcuts
849   )
850 {
851   UFS_DEVICE_PATH  *Ufs;
852 
853   Ufs = DevPath;
854   UefiDevicePathLibCatPrint (Str, "UFS(0x%x,0x%x)", Ufs->Pun, Ufs->Lun);
855 }
856 
857 /**
858   Converts a SD (Secure Digital) device path structure to its string representative.
859 
860   @param Str             The string representative of input device.
861   @param DevPath         The input device path structure.
862   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
863                          of the display node is used, where applicable. If DisplayOnly
864                          is FALSE, then the longer text representation of the display node
865                          is used.
866   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
867                          representation for a device node can be used, where applicable.
868 
869 **/
870 static VOID
DevPathToTextSd(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)871 DevPathToTextSd (
872   IN OUT POOL_PRINT  *Str,
873   IN VOID            *DevPath,
874   IN BOOLEAN         DisplayOnly,
875   IN BOOLEAN         AllowShortcuts
876   )
877 {
878   SD_DEVICE_PATH             *Sd;
879 
880   Sd = DevPath;
881   UefiDevicePathLibCatPrint (
882     Str,
883     "SD(0x%x)",
884     Sd->SlotNumber
885     );
886 }
887 
888 /**
889   Converts a EMMC (Embedded MMC) device path structure to its string representative.
890 
891   @param Str             The string representative of input device.
892   @param DevPath         The input device path structure.
893   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
894                          of the display node is used, where applicable. If DisplayOnly
895                          is FALSE, then the longer text representation of the display node
896                          is used.
897   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
898                          representation for a device node can be used, where applicable.
899 
900 **/
901 static VOID
DevPathToTextEmmc(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)902 DevPathToTextEmmc (
903   IN OUT POOL_PRINT  *Str,
904   IN VOID            *DevPath,
905   IN BOOLEAN         DisplayOnly,
906   IN BOOLEAN         AllowShortcuts
907   )
908 {
909   EMMC_DEVICE_PATH             *Emmc;
910 
911   Emmc = DevPath;
912   UefiDevicePathLibCatPrint (
913     Str,
914     "eMMC(0x%x)",
915     Emmc->SlotNumber
916     );
917 }
918 
919 /**
920   Converts a 1394 device path structure to its string representative.
921 
922   @param Str             The string representative of input device.
923   @param DevPath         The input device path structure.
924   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
925                          of the display node is used, where applicable. If DisplayOnly
926                          is FALSE, then the longer text representation of the display node
927                          is used.
928   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
929                          representation for a device node can be used, where applicable.
930 
931 **/
932 static VOID
DevPathToText1394(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)933 DevPathToText1394 (
934   IN OUT POOL_PRINT  *Str,
935   IN VOID            *DevPath,
936   IN BOOLEAN         DisplayOnly,
937   IN BOOLEAN         AllowShortcuts
938   )
939 {
940   F1394_DEVICE_PATH *F1394DevPath;
941 
942   F1394DevPath = DevPath;
943   //
944   // Guid has format of IEEE-EUI64
945   //
946   UefiDevicePathLibCatPrint (Str, "I1394(%016lx)", F1394DevPath->Guid);
947 }
948 
949 /**
950   Converts a USB device path structure to its string representative.
951 
952   @param Str             The string representative of input device.
953   @param DevPath         The input device path structure.
954   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
955                          of the display node is used, where applicable. If DisplayOnly
956                          is FALSE, then the longer text representation of the display node
957                          is used.
958   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
959                          representation for a device node can be used, where applicable.
960 
961 **/
962 static VOID
DevPathToTextUsb(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)963 DevPathToTextUsb (
964   IN OUT POOL_PRINT  *Str,
965   IN VOID            *DevPath,
966   IN BOOLEAN         DisplayOnly,
967   IN BOOLEAN         AllowShortcuts
968   )
969 {
970   USB_DEVICE_PATH *Usb;
971 
972   Usb = DevPath;
973   UefiDevicePathLibCatPrint (Str, "USB(0x%x,0x%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);
974 }
975 
976 /**
977   Converts a USB WWID device path structure to its string representative.
978 
979   @param Str             The string representative of input device.
980   @param DevPath         The input device path structure.
981   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
982                          of the display node is used, where applicable. If DisplayOnly
983                          is FALSE, then the longer text representation of the display node
984                          is used.
985   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
986                          representation for a device node can be used, where applicable.
987 
988 **/
989 static VOID
DevPathToTextUsbWWID(IN OUT POOL_PRINT * Str,IN VOID * DevPath,IN BOOLEAN DisplayOnly,IN BOOLEAN AllowShortcuts)990 DevPathToTextUsbWWID (
991   IN OUT POOL_PRINT  *Str,
992   IN VOID            *DevPath,
993   IN BOOLEAN         DisplayOnly,
994   IN BOOLEAN         AllowShortcuts
995   )
996 {
997   USB_WWID_DEVICE_PATH  *UsbWWId;
998   CHAR16                *SerialNumberStr;
999   CHAR16                *NewStr;
1000   UINT16                Length;
1001 
1002   UsbWWId = DevPath;
1003 
1004   SerialNumberStr = (CHAR16 *) (&UsbWWId + 1);
1005   Length = (UINT16) ((DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) UsbWWId) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16));
1006   if (SerialNumberStr [Length - 1] != 0) {
1007     //
1008     // In case no NULL terminator in SerialNumber, create a new one with NULL terminator
1009     //
1010     NewStr = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), SerialNumberStr);
1011     ASSERT (NewStr != NULL);
1012     NewStr [Length] = 0;
1013     SerialNumberStr = NewStr;
1014   }
1015 
1016   UefiDevicePathLibCatPrint (
1017     Str,
1018     "UsbWwid(0x%x,0x%x,0x%x,\"%S\")",
1019     UsbWWId->VendorId,
1020     UsbWWId->ProductId,
1021     UsbWWId->InterfaceNumber,
1022     SerialNumberStr
1023     );
1024 }
1025 
1026 /**
1027   Converts a Logic Unit device path structure to its string representative.
1028 
1029   @param Str             The string representative of input device.
1030   @param DevPath         The input device path structure.
1031   @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
1032                          of the display node is used, where applicable. If DisplayOnly
1033                          is FALSE, then the longer text representation of the display node
1034                          is used.
1035   @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
1036                          representation for a device node can be used, where applicable.
1037 
1038 **/
1039 static VOID
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