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