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