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