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