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