Home | History | Annotate | Download | only in UefiHandleParsingLib
      1 /** @file
      2   Provides interface to advanced shell functionality for parsing both handle and protocol database.
      3 
      4   Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
      5   (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>
      6   (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
      7   This program and the accompanying materials
      8   are licensed and made available under the terms and conditions of the BSD License
      9   which accompanies this distribution.  The full text of the license may be found at
     10   http://opensource.org/licenses/bsd-license.php
     11 
     12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 
     15 **/
     16 
     17 #include "UefiHandleParsingLib.h"
     18 #include "IndustryStandard/Acpi10.h"
     19 
     20 EFI_HANDLE        mHandleParsingHiiHandle = NULL;
     21 HANDLE_INDEX_LIST mHandleList = {{{NULL,NULL},0,0},0};
     22 GUID_INFO_BLOCK   *GuidList;
     23 UINTN             GuidListCount;
     24 /**
     25   Function to translate the EFI_MEMORY_TYPE into a string.
     26 
     27   @param[in] Memory     The memory type.
     28 
     29   @retval               A string representation of the type allocated from BS Pool.
     30 **/
     31 CHAR16*
     32 ConvertMemoryType (
     33   IN CONST EFI_MEMORY_TYPE Memory
     34   )
     35 {
     36   CHAR16 *RetVal;
     37   RetVal = NULL;
     38 
     39   switch (Memory) {
     40   case EfiReservedMemoryType:       StrnCatGrow(&RetVal, NULL, L"EfiReservedMemoryType", 0);        break;
     41   case EfiLoaderCode:               StrnCatGrow(&RetVal, NULL, L"EfiLoaderCode", 0);                break;
     42   case EfiLoaderData:               StrnCatGrow(&RetVal, NULL, L"EfiLoaderData", 0);                break;
     43   case EfiBootServicesCode:         StrnCatGrow(&RetVal, NULL, L"EfiBootServicesCode", 0);          break;
     44   case EfiBootServicesData:         StrnCatGrow(&RetVal, NULL, L"EfiBootServicesData", 0);          break;
     45   case EfiRuntimeServicesCode:      StrnCatGrow(&RetVal, NULL, L"EfiRuntimeServicesCode", 0);       break;
     46   case EfiRuntimeServicesData:      StrnCatGrow(&RetVal, NULL, L"EfiRuntimeServicesData", 0);       break;
     47   case EfiConventionalMemory:       StrnCatGrow(&RetVal, NULL, L"EfiConventionalMemory", 0);        break;
     48   case EfiUnusableMemory:           StrnCatGrow(&RetVal, NULL, L"EfiUnusableMemory", 0);            break;
     49   case EfiACPIReclaimMemory:        StrnCatGrow(&RetVal, NULL, L"EfiACPIReclaimMemory", 0);         break;
     50   case EfiACPIMemoryNVS:            StrnCatGrow(&RetVal, NULL, L"EfiACPIMemoryNVS", 0);             break;
     51   case EfiMemoryMappedIO:           StrnCatGrow(&RetVal, NULL, L"EfiMemoryMappedIO", 0);            break;
     52   case EfiMemoryMappedIOPortSpace:  StrnCatGrow(&RetVal, NULL, L"EfiMemoryMappedIOPortSpace", 0);   break;
     53   case EfiPalCode:                  StrnCatGrow(&RetVal, NULL, L"EfiPalCode", 0);                   break;
     54   case EfiMaxMemoryType:            StrnCatGrow(&RetVal, NULL, L"EfiMaxMemoryType", 0);             break;
     55   default: ASSERT(FALSE);
     56   }
     57   return (RetVal);
     58 }
     59 
     60 /**
     61   Function to translate the EFI_GRAPHICS_PIXEL_FORMAT into a string.
     62 
     63   @param[in] Fmt     The format type.
     64 
     65   @retval               A string representation of the type allocated from BS Pool.
     66 **/
     67 CHAR16*
     68 ConvertPixelFormat (
     69   IN CONST EFI_GRAPHICS_PIXEL_FORMAT Fmt
     70   )
     71 {
     72   CHAR16 *RetVal;
     73   RetVal = NULL;
     74 
     75   switch (Fmt) {
     76   case PixelRedGreenBlueReserved8BitPerColor: StrnCatGrow(&RetVal, NULL, L"PixelRedGreenBlueReserved8BitPerColor", 0);  break;
     77   case PixelBlueGreenRedReserved8BitPerColor: StrnCatGrow(&RetVal, NULL, L"PixelBlueGreenRedReserved8BitPerColor", 0);  break;
     78   case PixelBitMask:                          StrnCatGrow(&RetVal, NULL, L"PixelBitMask", 0);                           break;
     79   case PixelBltOnly:                          StrnCatGrow(&RetVal, NULL, L"PixelBltOnly", 0);                           break;
     80   case PixelFormatMax:                        StrnCatGrow(&RetVal, NULL, L"PixelFormatMax", 0);                         break;
     81   default: ASSERT(FALSE);
     82   }
     83   return (RetVal);
     84 }
     85 
     86 /**
     87   Constructor for the library.
     88 
     89   @param[in] ImageHandle    Ignored.
     90   @param[in] SystemTable    Ignored.
     91 
     92   @retval EFI_SUCCESS   The operation was successful.
     93 **/
     94 EFI_STATUS
     95 EFIAPI
     96 HandleParsingLibConstructor (
     97   IN EFI_HANDLE        ImageHandle,
     98   IN EFI_SYSTEM_TABLE  *SystemTable
     99   )
    100 {
    101   GuidListCount = 0;
    102   GuidList      = NULL;
    103 
    104   //
    105   // Do nothing with mHandleParsingHiiHandle.  Initialize HII as needed.
    106   //
    107   return (EFI_SUCCESS);
    108 }
    109 
    110 /**
    111   Initialization function for HII packages.
    112 
    113 **/
    114 VOID
    115 HandleParsingHiiInit (VOID)
    116 {
    117   if (mHandleParsingHiiHandle == NULL) {
    118     mHandleParsingHiiHandle = HiiAddPackages (&gHandleParsingHiiGuid, gImageHandle, UefiHandleParsingLibStrings, NULL);
    119     ASSERT (mHandleParsingHiiHandle != NULL);
    120   }
    121 }
    122 
    123 /**
    124   Destructor for the library.  free any resources.
    125 
    126   @param[in] ImageHandle    Ignored.
    127   @param[in] SystemTable    Ignored.
    128 
    129   @retval EFI_SUCCESS   The operation was successful.
    130 **/
    131 EFI_STATUS
    132 EFIAPI
    133 HandleParsingLibDestructor (
    134   IN EFI_HANDLE        ImageHandle,
    135   IN EFI_SYSTEM_TABLE  *SystemTable
    136   )
    137 {
    138   UINTN                 LoopCount;
    139 
    140   for (LoopCount = 0; GuidList != NULL && LoopCount < GuidListCount; LoopCount++) {
    141     SHELL_FREE_NON_NULL(GuidList[LoopCount].GuidId);
    142   }
    143 
    144   SHELL_FREE_NON_NULL(GuidList);
    145   if (mHandleParsingHiiHandle != NULL) {
    146     HiiRemovePackages(mHandleParsingHiiHandle);
    147   }
    148   return (EFI_SUCCESS);
    149 }
    150 
    151 /**
    152   Function to dump information about LoadedImage.
    153 
    154   This will allocate the return buffer from boot services pool.
    155 
    156   @param[in] TheHandle      The handle that has LoadedImage installed.
    157   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
    158 
    159   @retval A poitner to a string containing the information.
    160 **/
    161 CHAR16*
    162 EFIAPI
    163 LoadedImageProtocolDumpInformation(
    164   IN CONST EFI_HANDLE TheHandle,
    165   IN CONST BOOLEAN    Verbose
    166   )
    167 {
    168   EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
    169   EFI_STATUS                        Status;
    170   CHAR16                            *RetVal;
    171   CHAR16                            *Temp;
    172   CHAR16                            *CodeType;
    173   CHAR16                            *DataType;
    174 
    175   if (!Verbose) {
    176     return (CatSPrint(NULL, L"LoadedImage"));
    177   }
    178 
    179   HandleParsingHiiInit();
    180 
    181   Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_LI_DUMP_MAIN), NULL);
    182   if (Temp == NULL) {
    183     return NULL;
    184   }
    185 
    186   Status = gBS->OpenProtocol (
    187                 TheHandle,
    188                 &gEfiLoadedImageProtocolGuid,
    189                 (VOID**)&LoadedImage,
    190                 gImageHandle,
    191                 NULL,
    192                 EFI_OPEN_PROTOCOL_GET_PROTOCOL
    193                );
    194 
    195   if (EFI_ERROR (Status)) {
    196     SHELL_FREE_NON_NULL (Temp);
    197     return NULL;
    198   }
    199 
    200   DataType = ConvertMemoryType(LoadedImage->ImageDataType);
    201   CodeType = ConvertMemoryType(LoadedImage->ImageCodeType);
    202 
    203   RetVal = CatSPrint(
    204              NULL,
    205              Temp,
    206              LoadedImage->Revision,
    207              LoadedImage->ParentHandle,
    208              LoadedImage->SystemTable,
    209              LoadedImage->DeviceHandle,
    210              LoadedImage->FilePath,
    211              LoadedImage->LoadOptionsSize,
    212              LoadedImage->LoadOptions,
    213              LoadedImage->ImageBase,
    214              LoadedImage->ImageSize,
    215              CodeType,
    216              DataType,
    217              LoadedImage->Unload
    218              );
    219 
    220 
    221   SHELL_FREE_NON_NULL(Temp);
    222   SHELL_FREE_NON_NULL(CodeType);
    223   SHELL_FREE_NON_NULL(DataType);
    224 
    225   return RetVal;
    226 }
    227 
    228 /**
    229   Function to dump information about GOP.
    230 
    231   This will allocate the return buffer from boot services pool.
    232 
    233   @param[in] TheHandle      The handle that has LoadedImage installed.
    234   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
    235 
    236   @retval A poitner to a string containing the information.
    237 **/
    238 CHAR16*
    239 EFIAPI
    240 GraphicsOutputProtocolDumpInformation(
    241   IN CONST EFI_HANDLE TheHandle,
    242   IN CONST BOOLEAN    Verbose
    243   )
    244 {
    245   EFI_GRAPHICS_OUTPUT_PROTOCOL          *GraphicsOutput;
    246   EFI_STATUS                            Status;
    247   CHAR16                                *RetVal;
    248   CHAR16                                *Temp;
    249   CHAR16                                *Fmt;
    250   CHAR16                                *TempRetVal;
    251   UINTN                                 GopInfoSize;
    252   UINT32                                Mode;
    253   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *GopInfo;
    254 
    255   if (!Verbose) {
    256     return (CatSPrint(NULL, L"GraphicsOutput"));
    257   }
    258 
    259   HandleParsingHiiInit();
    260 
    261   Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_GOP_DUMP_MAIN), NULL);
    262   if (Temp == NULL) {
    263     return NULL;
    264   }
    265 
    266   Status = gBS->OpenProtocol (
    267                 TheHandle,
    268                 &gEfiGraphicsOutputProtocolGuid,
    269                 (VOID**)&GraphicsOutput,
    270                 gImageHandle,
    271                 NULL,
    272                 EFI_OPEN_PROTOCOL_GET_PROTOCOL
    273                );
    274 
    275   if (EFI_ERROR (Status)) {
    276     SHELL_FREE_NON_NULL (Temp);
    277     return NULL;
    278   }
    279 
    280   Fmt = ConvertPixelFormat(GraphicsOutput->Mode->Info->PixelFormat);
    281 
    282   RetVal = CatSPrint(
    283              NULL,
    284              Temp,
    285              GraphicsOutput->Mode->MaxMode,
    286              GraphicsOutput->Mode->Mode,
    287              GraphicsOutput->Mode->FrameBufferBase,
    288              (UINT64)GraphicsOutput->Mode->FrameBufferSize,
    289              (UINT64)GraphicsOutput->Mode->SizeOfInfo,
    290              GraphicsOutput->Mode->Info->Version,
    291              GraphicsOutput->Mode->Info->HorizontalResolution,
    292              GraphicsOutput->Mode->Info->VerticalResolution,
    293              Fmt,
    294              GraphicsOutput->Mode->Info->PixelsPerScanLine,
    295              GraphicsOutput->Mode->Info->PixelFormat!=PixelBitMask?0:GraphicsOutput->Mode->Info->PixelInformation.RedMask,
    296              GraphicsOutput->Mode->Info->PixelFormat!=PixelBitMask?0:GraphicsOutput->Mode->Info->PixelInformation.GreenMask,
    297              GraphicsOutput->Mode->Info->PixelFormat!=PixelBitMask?0:GraphicsOutput->Mode->Info->PixelInformation.BlueMask
    298              );
    299 
    300   SHELL_FREE_NON_NULL (Temp);
    301 
    302   Temp = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN (STR_GOP_RES_LIST_MAIN), NULL);
    303   if (Temp == NULL) {
    304     SHELL_FREE_NON_NULL (RetVal);
    305     goto EXIT;
    306   }
    307 
    308   TempRetVal = CatSPrint (RetVal, Temp);
    309   SHELL_FREE_NON_NULL (RetVal);
    310   if (TempRetVal == NULL) {
    311     goto EXIT;
    312   }
    313   RetVal = TempRetVal;
    314   SHELL_FREE_NON_NULL (Temp);
    315 
    316   Temp = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN (STR_GOP_RES_LIST_ENTRY), NULL);
    317   if (Temp == NULL) {
    318     SHELL_FREE_NON_NULL (RetVal);
    319     goto EXIT;
    320   }
    321 
    322 
    323   for (Mode = 0; Mode < GraphicsOutput->Mode->MaxMode; Mode++) {
    324     Status = GraphicsOutput->QueryMode (
    325                                GraphicsOutput,
    326                                Mode,
    327                                &GopInfoSize,
    328                                &GopInfo
    329                                );
    330     if (EFI_ERROR (Status)) {
    331       continue;
    332     }
    333 
    334     TempRetVal = CatSPrint (
    335                    RetVal,
    336                    Temp,
    337                    Mode,
    338                    GopInfo->HorizontalResolution,
    339                    GopInfo->VerticalResolution
    340                    );
    341 
    342     SHELL_FREE_NON_NULL (GopInfo);
    343     SHELL_FREE_NON_NULL (RetVal);
    344     RetVal = TempRetVal;
    345   }
    346 
    347 
    348 EXIT:
    349   SHELL_FREE_NON_NULL(Temp);
    350   SHELL_FREE_NON_NULL(Fmt);
    351 
    352   return RetVal;
    353 }
    354 
    355 /**
    356   Function to dump information about EDID Discovered Protocol.
    357 
    358   This will allocate the return buffer from boot services pool.
    359 
    360   @param[in] TheHandle      The handle that has LoadedImage installed.
    361   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
    362 
    363   @retval A pointer to a string containing the information.
    364 **/
    365 CHAR16*
    366 EFIAPI
    367 EdidDiscoveredProtocolDumpInformation (
    368   IN CONST EFI_HANDLE TheHandle,
    369   IN CONST BOOLEAN    Verbose
    370   )
    371 {
    372   EFI_EDID_DISCOVERED_PROTOCOL          *EdidDiscovered;
    373   EFI_STATUS                            Status;
    374   CHAR16                                *RetVal;
    375   CHAR16                                *Temp;
    376   CHAR16                                *TempRetVal;
    377 
    378   if (!Verbose) {
    379     return (CatSPrint (NULL, L"EDIDDiscovered"));
    380   }
    381 
    382   Status = gBS->OpenProtocol (
    383                   TheHandle,
    384                   &gEfiEdidDiscoveredProtocolGuid,
    385                   (VOID**)&EdidDiscovered,
    386                   NULL,
    387                   NULL,
    388                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    389                   );
    390 
    391   if (EFI_ERROR (Status)) {
    392     return NULL;
    393   }
    394 
    395   Temp = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN (STR_EDID_DISCOVERED_MAIN), NULL);
    396   if (Temp == NULL) {
    397     return NULL;
    398   }
    399 
    400   RetVal = CatSPrint (NULL, Temp, EdidDiscovered->SizeOfEdid);
    401   SHELL_FREE_NON_NULL (Temp);
    402 
    403   if (EdidDiscovered->SizeOfEdid != 0) {
    404     Temp = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN (STR_EDID_DISCOVERED_DATA), NULL);
    405     if (Temp == NULL) {
    406       SHELL_FREE_NON_NULL (RetVal);
    407       return NULL;
    408     }
    409     TempRetVal = CatSPrint (RetVal, Temp);
    410     SHELL_FREE_NON_NULL (RetVal);
    411     RetVal = TempRetVal;
    412 
    413     TempRetVal = CatSDumpHex (RetVal, 7, 0, EdidDiscovered->SizeOfEdid, EdidDiscovered->Edid);
    414     RetVal = TempRetVal;
    415   }
    416   return RetVal;
    417 }
    418 
    419 /**
    420   Function to dump information about EDID Active Protocol.
    421 
    422   This will allocate the return buffer from boot services pool.
    423 
    424   @param[in] TheHandle      The handle that has LoadedImage installed.
    425   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
    426 
    427   @retval A pointer to a string containing the information.
    428 **/
    429 CHAR16*
    430 EFIAPI
    431 EdidActiveProtocolDumpInformation (
    432   IN CONST EFI_HANDLE TheHandle,
    433   IN CONST BOOLEAN    Verbose
    434   )
    435 {
    436   EFI_EDID_ACTIVE_PROTOCOL  *EdidActive;
    437   EFI_STATUS                Status;
    438   CHAR16                    *RetVal;
    439   CHAR16                    *Temp;
    440   CHAR16                    *TempRetVal;
    441 
    442   if (!Verbose) {
    443     return (CatSPrint (NULL, L"EDIDActive"));
    444   }
    445 
    446   Status = gBS->OpenProtocol (
    447                   TheHandle,
    448                   &gEfiEdidActiveProtocolGuid,
    449                   (VOID**)&EdidActive,
    450                   NULL,
    451                   NULL,
    452                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    453                   );
    454 
    455   if (EFI_ERROR (Status)) {
    456     return NULL;
    457   }
    458 
    459   Temp = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN (STR_EDID_ACTIVE_MAIN), NULL);
    460   if (Temp == NULL) {
    461     return NULL;
    462   }
    463 
    464   RetVal = CatSPrint (NULL, Temp, EdidActive->SizeOfEdid);
    465   SHELL_FREE_NON_NULL (Temp);
    466 
    467   if (EdidActive->SizeOfEdid != 0) {
    468     Temp = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN (STR_EDID_ACTIVE_DATA), NULL);
    469     if (Temp == NULL) {
    470       SHELL_FREE_NON_NULL (RetVal);
    471       return NULL;
    472     }
    473     TempRetVal = CatSPrint (RetVal, Temp);
    474     SHELL_FREE_NON_NULL (RetVal);
    475     RetVal = TempRetVal;
    476 
    477     TempRetVal = CatSDumpHex (RetVal, 7, 0, EdidActive->SizeOfEdid, EdidActive->Edid);
    478     RetVal = TempRetVal;
    479   }
    480   return RetVal;
    481 }
    482 
    483 /**
    484   Function to dump information about PciRootBridgeIo.
    485 
    486   This will allocate the return buffer from boot services pool.
    487 
    488   @param[in] TheHandle      The handle that has PciRootBridgeIo installed.
    489   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
    490 
    491   @retval A poitner to a string containing the information.
    492 **/
    493 CHAR16*
    494 EFIAPI
    495 PciRootBridgeIoDumpInformation(
    496   IN CONST EFI_HANDLE TheHandle,
    497   IN CONST BOOLEAN    Verbose
    498   )
    499 {
    500   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   *PciRootBridgeIo;
    501   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration;
    502   UINT64                            Supports;
    503   UINT64                            Attributes;
    504   CHAR16                            *Temp;
    505   CHAR16                            *Temp2;
    506   CHAR16                            *RetVal;
    507   EFI_STATUS                        Status;
    508 
    509   RetVal  = NULL;
    510 
    511   if (!Verbose) {
    512     return (CatSPrint(NULL, L"PciRootBridgeIo"));
    513   }
    514 
    515   HandleParsingHiiInit();
    516 
    517   Status = gBS->HandleProtocol(
    518     TheHandle,
    519     &gEfiPciRootBridgeIoProtocolGuid,
    520     (VOID**)&PciRootBridgeIo);
    521 
    522   if (EFI_ERROR(Status)) {
    523     return NULL;
    524   }
    525 
    526   Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_PH), NULL);
    527   if (Temp == NULL) {
    528     return NULL;
    529   }
    530   Temp2 = CatSPrint(L"\r\n", Temp, PciRootBridgeIo->ParentHandle);
    531   FreePool(Temp);
    532   RetVal = Temp2;
    533   Temp2 = NULL;
    534 
    535   Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_SEG), NULL);
    536   if (Temp == NULL) {
    537     SHELL_FREE_NON_NULL(RetVal);
    538     return NULL;
    539   }
    540   Temp2 = CatSPrint(RetVal, Temp, PciRootBridgeIo->SegmentNumber);
    541   FreePool(Temp);
    542   FreePool(RetVal);
    543   RetVal = Temp2;
    544   Temp2 = NULL;
    545 
    546   Supports   = 0;
    547   Attributes = 0;
    548   Status = PciRootBridgeIo->GetAttributes (PciRootBridgeIo, &Supports, &Attributes);
    549   if (!EFI_ERROR(Status)) {
    550     Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_ATT), NULL);
    551     if (Temp == NULL) {
    552       SHELL_FREE_NON_NULL(RetVal);
    553       return NULL;
    554     }
    555     Temp2 = CatSPrint(RetVal, Temp, Attributes);
    556     FreePool(Temp);
    557     FreePool(RetVal);
    558     RetVal = Temp2;
    559     Temp2 = NULL;
    560 
    561     Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_SUPPORTS), NULL);
    562     if (Temp == NULL) {
    563       SHELL_FREE_NON_NULL(RetVal);
    564       return NULL;
    565     }
    566     Temp2 = CatSPrint(RetVal, Temp, Supports);
    567     FreePool(Temp);
    568     FreePool(RetVal);
    569     RetVal = Temp2;
    570     Temp2 = NULL;
    571   }
    572 
    573   Configuration   = NULL;
    574   Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Configuration);
    575   if (!EFI_ERROR(Status) && Configuration != NULL) {
    576     Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_TITLE), NULL);
    577     if (Temp == NULL) {
    578       SHELL_FREE_NON_NULL(RetVal);
    579       return NULL;
    580     }
    581     Temp2 = CatSPrint(RetVal, Temp, Supports);
    582     FreePool(Temp);
    583     FreePool(RetVal);
    584     RetVal = Temp2;
    585     Temp2 = NULL;
    586     while (Configuration->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
    587       Temp = NULL;
    588       switch (Configuration->ResType) {
    589       case ACPI_ADDRESS_SPACE_TYPE_MEM:
    590         Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_MEM), NULL);
    591         break;
    592       case ACPI_ADDRESS_SPACE_TYPE_IO:
    593         Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_IO), NULL);
    594         break;
    595       case ACPI_ADDRESS_SPACE_TYPE_BUS:
    596         Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_BUS), NULL);
    597         break;
    598       }
    599       if (Temp != NULL) {
    600         Temp2 = CatSPrint(RetVal, L"%s", Temp);
    601         FreePool(Temp);
    602         FreePool(RetVal);
    603         RetVal = Temp2;
    604         Temp2 = NULL;
    605       }
    606 
    607       Temp2 = CatSPrint(RetVal,
    608         L"%H%02x    %016lx  %016lx  %02x%N\r\n",
    609         Configuration->SpecificFlag,
    610         Configuration->AddrRangeMin,
    611         Configuration->AddrRangeMax,
    612         Configuration->AddrSpaceGranularity
    613         );
    614       FreePool(RetVal);
    615       RetVal = Temp2;
    616       Temp2 = NULL;
    617       Configuration++;
    618     }
    619   }
    620   return (RetVal);
    621 }
    622 
    623 /**
    624   Function to dump information about SimpleTextOut.
    625 
    626   This will allocate the return buffer from boot services pool.
    627 
    628   @param[in] TheHandle      The handle that has SimpleTextOut installed.
    629   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
    630 
    631   @retval A poitner to a string containing the information.
    632 **/
    633 CHAR16*
    634 EFIAPI
    635 TxtOutProtocolDumpInformation(
    636   IN CONST EFI_HANDLE TheHandle,
    637   IN CONST BOOLEAN    Verbose
    638   )
    639 {
    640   EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Dev;
    641   INTN                            Index;
    642   UINTN                           Col;
    643   UINTN                           Row;
    644   EFI_STATUS                      Status;
    645   CHAR16                          *RetVal;
    646   UINTN                           Size;
    647   CHAR16                          *Temp;
    648   UINTN                           NewSize;
    649 
    650   if (!Verbose) {
    651     return (NULL);
    652   }
    653 
    654   HandleParsingHiiInit();
    655 
    656   RetVal  = NULL;
    657   Size    = 0;
    658 
    659   Status = gBS->HandleProtocol(
    660     TheHandle,
    661     &gEfiSimpleTextOutProtocolGuid,
    662     (VOID**)&Dev);
    663 
    664   ASSERT_EFI_ERROR(Status);
    665   ASSERT (Dev != NULL && Dev->Mode != NULL);
    666 
    667   Size = (Dev->Mode->MaxMode + 1) * 80;
    668   RetVal = AllocateZeroPool(Size);
    669 
    670   Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_TXT_OUT_DUMP_HEADER), NULL);
    671   if (Temp != NULL) {
    672     UnicodeSPrint(RetVal, Size, Temp, Dev, Dev->Mode->Attribute);
    673     FreePool(Temp);
    674   }
    675 
    676   //
    677   // Dump TextOut Info
    678   //
    679   Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_TXT_OUT_DUMP_LINE), NULL);
    680   for (Index = 0; Index < Dev->Mode->MaxMode; Index++) {
    681     Status = Dev->QueryMode (Dev, Index, &Col, &Row);
    682     NewSize = Size - StrSize(RetVal);
    683     UnicodeSPrint(
    684       RetVal + StrLen(RetVal),
    685       NewSize,
    686       Temp == NULL?L"":Temp,
    687       Index == Dev->Mode->Mode ? L'*' : L' ',
    688       Index,
    689       !EFI_ERROR(Status)?(INTN)Col:-1,
    690       !EFI_ERROR(Status)?(INTN)Row:-1
    691      );
    692   }
    693   FreePool(Temp);
    694   return (RetVal);
    695 }
    696 
    697 STATIC CONST UINTN VersionStringSize = 60;
    698 
    699 /**
    700   Function to dump information about EfiDriverSupportedEfiVersion protocol.
    701 
    702   This will allocate the return buffer from boot services pool.
    703 
    704   @param[in] TheHandle      The handle that has the protocol installed.
    705   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
    706 
    707   @retval A poitner to a string containing the information.
    708 **/
    709 CHAR16*
    710 EFIAPI
    711 DriverEfiVersionProtocolDumpInformation(
    712   IN CONST EFI_HANDLE TheHandle,
    713   IN CONST BOOLEAN    Verbose
    714   )
    715 {
    716   EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL *DriverEfiVersion;
    717   EFI_STATUS                                Status;
    718   CHAR16                                    *RetVal;
    719 
    720   Status = gBS->HandleProtocol(
    721     TheHandle,
    722     &gEfiDriverSupportedEfiVersionProtocolGuid,
    723     (VOID**)&DriverEfiVersion);
    724 
    725   ASSERT_EFI_ERROR(Status);
    726 
    727   RetVal = AllocateZeroPool(VersionStringSize);
    728   if (RetVal != NULL) {
    729     UnicodeSPrint (RetVal, VersionStringSize, L"0x%08x", DriverEfiVersion->FirmwareVersion);
    730   }
    731   return (RetVal);
    732 }
    733 /**
    734   Function to convert device path to string.
    735 
    736   This will allocate the return buffer from boot services pool.
    737 
    738   @param[in] DevPath        Pointer to device path instance.
    739   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
    740   @param[in] Length         Maximum allowed text length of the device path.
    741 
    742   @retval A pointer to a string containing the information.
    743 **/
    744 CHAR16*
    745 ConvertDevicePathToShortText(
    746   IN CONST EFI_DEVICE_PATH_PROTOCOL *DevPath,
    747   IN CONST BOOLEAN                  Verbose,
    748   IN CONST UINTN                    Length
    749   )
    750 {
    751   CHAR16                            *Temp;
    752   CHAR16                            *Temp2;
    753   UINTN                             Size;
    754 
    755   //
    756   // I cannot decide whether to allow shortcuts here (the second BOOLEAN on the next line)
    757   //
    758   Temp = ConvertDevicePathToText(DevPath, TRUE, TRUE);
    759   if (!Verbose && Temp != NULL && StrLen(Temp) > Length) {
    760     Temp2 = NULL;
    761     Size  = 0;
    762     Temp2 = StrnCatGrow(&Temp2, &Size, L"..", 0);
    763     Temp2 = StrnCatGrow(&Temp2, &Size, Temp+(StrLen(Temp) - (Length - 2)), 0);
    764     FreePool(Temp);
    765     Temp = Temp2;
    766   }
    767   return (Temp);
    768 }
    769 
    770 /**
    771   Function to dump information about DevicePath protocol.
    772 
    773   This will allocate the return buffer from boot services pool.
    774 
    775   @param[in] TheHandle      The handle that has the protocol installed.
    776   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
    777 
    778   @retval A pointer to a string containing the information.
    779 **/
    780 CHAR16*
    781 EFIAPI
    782 DevicePathProtocolDumpInformation(
    783   IN CONST EFI_HANDLE TheHandle,
    784   IN CONST BOOLEAN    Verbose
    785   )
    786 {
    787   EFI_DEVICE_PATH_PROTOCOL          *DevPath;
    788   CHAR16                            *Temp;
    789   EFI_STATUS                        Status;
    790   Temp = NULL;
    791 
    792   Status = gBS->OpenProtocol(TheHandle, &gEfiDevicePathProtocolGuid, (VOID**)&DevPath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    793   if (!EFI_ERROR(Status)) {
    794     Temp = ConvertDevicePathToShortText (DevPath, Verbose, 30);
    795     gBS->CloseProtocol(TheHandle, &gEfiDevicePathProtocolGuid, gImageHandle, NULL);
    796   }
    797   return (Temp);
    798 }
    799 
    800 /**
    801   Function to dump information about LoadedImageDevicePath protocol.
    802 
    803   This will allocate the return buffer from boot services pool.
    804 
    805   @param[in] TheHandle      The handle that has the protocol installed.
    806   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
    807 
    808   @retval A pointer to a string containing the information.
    809 **/
    810 CHAR16*
    811 EFIAPI
    812 LoadedImageDevicePathProtocolDumpInformation(
    813   IN CONST EFI_HANDLE TheHandle,
    814   IN CONST BOOLEAN    Verbose
    815   )
    816 {
    817   EFI_DEVICE_PATH_PROTOCOL          *DevPath;
    818   CHAR16                            *Temp;
    819   EFI_STATUS                        Status;
    820   Temp = NULL;
    821 
    822   Status = gBS->OpenProtocol(TheHandle, &gEfiLoadedImageDevicePathProtocolGuid, (VOID**)&DevPath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    823   if (!EFI_ERROR(Status)) {
    824     Temp = ConvertDevicePathToShortText (DevPath, Verbose, 30);
    825     gBS->CloseProtocol(TheHandle, &gEfiDevicePathProtocolGuid, gImageHandle, NULL);
    826   }
    827   return (Temp);
    828 }
    829 
    830 /**
    831   Function to dump information about EfiAdapterInformation Protocol.
    832 
    833   @param[in] TheHandle      The handle that has the protocol installed.
    834   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
    835 
    836   @retval A pointer to a string containing the information.
    837 **/
    838 CHAR16*
    839 EFIAPI
    840 AdapterInformationDumpInformation (
    841   IN CONST EFI_HANDLE TheHandle,
    842   IN CONST BOOLEAN    Verbose
    843   )
    844 {
    845   EFI_STATUS                        Status;
    846   EFI_ADAPTER_INFORMATION_PROTOCOL  *EfiAdptrInfoProtocol;
    847   UINTN                             InfoTypesBufferCount;
    848   UINTN                             GuidIndex;
    849   EFI_GUID                          *InfoTypesBuffer;
    850   CHAR16                            *GuidStr;
    851   CHAR16                            *TempStr;
    852   CHAR16                            *RetVal;
    853   CHAR16                            *TempRetVal;
    854   VOID                              *InformationBlock;
    855   UINTN                             InformationBlockSize;
    856 
    857   if (!Verbose) {
    858     return (CatSPrint(NULL, L"AdapterInfo"));
    859   }
    860 
    861   InfoTypesBuffer   = NULL;
    862   InformationBlock  = NULL;
    863 
    864 
    865   Status = gBS->OpenProtocol (
    866                   (EFI_HANDLE) (TheHandle),
    867                   &gEfiAdapterInformationProtocolGuid,
    868                   (VOID **) &EfiAdptrInfoProtocol,
    869                   NULL,
    870                   NULL,
    871                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    872                   );
    873 
    874   if (EFI_ERROR (Status)) {
    875     return NULL;
    876   }
    877 
    878   //
    879   // Get a list of supported information types for this instance of the protocol.
    880   //
    881   Status = EfiAdptrInfoProtocol->GetSupportedTypes (
    882                                    EfiAdptrInfoProtocol,
    883                                    &InfoTypesBuffer,
    884                                    &InfoTypesBufferCount
    885                                    );
    886   RetVal = NULL;
    887   if (EFI_ERROR (Status)) {
    888     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_GET_SUPP_TYPES_FAILED), NULL);
    889     if (TempStr != NULL) {
    890       RetVal = CatSPrint (NULL, TempStr, Status);
    891     } else {
    892       goto ERROR_EXIT;
    893     }
    894   } else {
    895     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_SUPP_TYPE_HEADER), NULL);
    896     if (TempStr == NULL) {
    897       goto ERROR_EXIT;
    898     }
    899     RetVal = CatSPrint (NULL, TempStr);
    900     SHELL_FREE_NON_NULL (TempStr);
    901 
    902     for (GuidIndex = 0; GuidIndex < InfoTypesBufferCount; GuidIndex++) {
    903       TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_GUID_NUMBER), NULL);
    904       if (TempStr == NULL) {
    905         goto ERROR_EXIT;
    906       }
    907       TempRetVal = CatSPrint (RetVal, TempStr, (GuidIndex + 1), &InfoTypesBuffer[GuidIndex]);
    908       SHELL_FREE_NON_NULL (RetVal);
    909       RetVal = TempRetVal;
    910       SHELL_FREE_NON_NULL (TempStr);
    911 
    912       TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_GUID_STRING), NULL);
    913       if (TempStr == NULL) {
    914         goto ERROR_EXIT;
    915       }
    916 
    917       if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoMediaStateGuid)) {
    918         TempRetVal = CatSPrint (RetVal, TempStr, L"gEfiAdapterInfoMediaStateGuid");
    919         SHELL_FREE_NON_NULL (RetVal);
    920         RetVal = TempRetVal;
    921       } else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoNetworkBootGuid)) {
    922         TempRetVal = CatSPrint (RetVal, TempStr, L"gEfiAdapterInfoNetworkBootGuid");
    923         SHELL_FREE_NON_NULL (RetVal);
    924         RetVal = TempRetVal;
    925       } else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoSanMacAddressGuid)) {
    926         TempRetVal = CatSPrint (RetVal, TempStr, L"gEfiAdapterInfoSanMacAddressGuid");
    927         SHELL_FREE_NON_NULL (RetVal);
    928         RetVal = TempRetVal;
    929       } else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoUndiIpv6SupportGuid)) {
    930         TempRetVal = CatSPrint (RetVal, TempStr, L"gEfiAdapterInfoUndiIpv6SupportGuid");
    931         SHELL_FREE_NON_NULL (RetVal);
    932         RetVal = TempRetVal;
    933       } else {
    934 
    935         GuidStr = GetStringNameFromGuid (&InfoTypesBuffer[GuidIndex], NULL);
    936 
    937         if (GuidStr != NULL) {
    938           if (StrCmp(GuidStr, L"UnknownDevice") == 0) {
    939             TempRetVal = CatSPrint (RetVal, TempStr, L"UnknownInfoType");
    940             SHELL_FREE_NON_NULL (RetVal);
    941             RetVal = TempRetVal;
    942 
    943             SHELL_FREE_NON_NULL (TempStr);
    944             SHELL_FREE_NON_NULL(GuidStr);
    945             //
    946             // So that we never have to pass this UnknownInfoType to the parsing function "GetInformation" service of AIP
    947             //
    948             continue;
    949           } else {
    950             TempRetVal = CatSPrint (RetVal, TempStr, GuidStr);
    951             SHELL_FREE_NON_NULL (RetVal);
    952             RetVal = TempRetVal;
    953             SHELL_FREE_NON_NULL(GuidStr);
    954           }
    955         }
    956       }
    957 
    958       SHELL_FREE_NON_NULL (TempStr);
    959 
    960       Status = EfiAdptrInfoProtocol->GetInformation (
    961                                        EfiAdptrInfoProtocol,
    962                                        &InfoTypesBuffer[GuidIndex],
    963                                        &InformationBlock,
    964                                        &InformationBlockSize
    965                                        );
    966 
    967       if (EFI_ERROR (Status)) {
    968         TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_GETINFO_FAILED), NULL);
    969         if (TempStr == NULL) {
    970           goto ERROR_EXIT;
    971         }
    972         TempRetVal = CatSPrint (RetVal, TempStr, Status);
    973         SHELL_FREE_NON_NULL (RetVal);
    974         RetVal = TempRetVal;
    975       } else {
    976         if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoMediaStateGuid)) {
    977           TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_MEDIA_STATE), NULL);
    978           if (TempStr == NULL) {
    979             goto ERROR_EXIT;
    980           }
    981           TempRetVal = CatSPrint (
    982                          RetVal,
    983                          TempStr,
    984                          ((EFI_ADAPTER_INFO_MEDIA_STATE *)InformationBlock)->MediaState,
    985                          ((EFI_ADAPTER_INFO_MEDIA_STATE *)InformationBlock)->MediaState
    986                          );
    987           SHELL_FREE_NON_NULL (RetVal);
    988           RetVal = TempRetVal;
    989         } else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoNetworkBootGuid)) {
    990           TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_NETWORK_BOOT_INFO), NULL);
    991           if (TempStr == NULL) {
    992             goto ERROR_EXIT;
    993           }
    994           TempRetVal = CatSPrint (
    995                          RetVal,
    996                          TempStr,
    997                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->iScsiIpv4BootCapablity,
    998                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->iScsiIpv6BootCapablity,
    999                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->FCoeBootCapablity,
   1000                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->OffloadCapability,
   1001                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->iScsiMpioCapability,
   1002                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->iScsiIpv4Boot,
   1003                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->iScsiIpv6Boot,
   1004                          ((EFI_ADAPTER_INFO_NETWORK_BOOT *)InformationBlock)->FCoeBoot
   1005                          );
   1006           SHELL_FREE_NON_NULL (RetVal);
   1007           RetVal = TempRetVal;
   1008         } else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoSanMacAddressGuid) == TRUE) {
   1009           TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_SAN_MAC_ADDRESS_INFO), NULL);
   1010           if (TempStr == NULL) {
   1011             goto ERROR_EXIT;
   1012           }
   1013           TempRetVal = CatSPrint (
   1014                          RetVal,
   1015                          TempStr,
   1016                          ((EFI_ADAPTER_INFO_SAN_MAC_ADDRESS *)InformationBlock)->SanMacAddress.Addr[0],
   1017                          ((EFI_ADAPTER_INFO_SAN_MAC_ADDRESS *)InformationBlock)->SanMacAddress.Addr[1],
   1018                          ((EFI_ADAPTER_INFO_SAN_MAC_ADDRESS *)InformationBlock)->SanMacAddress.Addr[2],
   1019                          ((EFI_ADAPTER_INFO_SAN_MAC_ADDRESS *)InformationBlock)->SanMacAddress.Addr[3],
   1020                          ((EFI_ADAPTER_INFO_SAN_MAC_ADDRESS *)InformationBlock)->SanMacAddress.Addr[4],
   1021                          ((EFI_ADAPTER_INFO_SAN_MAC_ADDRESS *)InformationBlock)->SanMacAddress.Addr[5]
   1022                          );
   1023           SHELL_FREE_NON_NULL (RetVal);
   1024           RetVal = TempRetVal;
   1025         } else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoUndiIpv6SupportGuid) == TRUE) {
   1026           TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_UNDI_IPV6_INFO), NULL);
   1027           if (TempStr == NULL) {
   1028             goto ERROR_EXIT;
   1029           }
   1030 
   1031           TempRetVal = CatSPrint (
   1032                          RetVal,
   1033                          TempStr,
   1034                          ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *)InformationBlock)->Ipv6Support
   1035                          );
   1036           SHELL_FREE_NON_NULL (RetVal);
   1037           RetVal = TempRetVal;
   1038         } else {
   1039           TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_UNKNOWN_INFO_TYPE), NULL);
   1040           if (TempStr == NULL) {
   1041             goto ERROR_EXIT;
   1042           }
   1043           TempRetVal = CatSPrint (RetVal, TempStr, &InfoTypesBuffer[GuidIndex]);
   1044           SHELL_FREE_NON_NULL (RetVal);
   1045           RetVal = TempRetVal;
   1046         }
   1047       }
   1048       SHELL_FREE_NON_NULL (TempStr);
   1049       SHELL_FREE_NON_NULL (InformationBlock);
   1050     }
   1051   }
   1052 
   1053   SHELL_FREE_NON_NULL (InfoTypesBuffer);
   1054   return RetVal;
   1055 
   1056 ERROR_EXIT:
   1057   SHELL_FREE_NON_NULL (RetVal);
   1058   SHELL_FREE_NON_NULL (InfoTypesBuffer);
   1059   SHELL_FREE_NON_NULL (InformationBlock);
   1060   return NULL;
   1061 }
   1062 
   1063 /**
   1064   Function to dump information about EFI_FIRMWARE_MANAGEMENT_PROTOCOL Protocol.
   1065 
   1066   @param[in] TheHandle      The handle that has the protocol installed.
   1067   @param[in] Verbose        TRUE for additional information, FALSE otherwise.
   1068 
   1069   @retval A pointer to a string containing the information.
   1070 **/
   1071 CHAR16*
   1072 EFIAPI
   1073 FirmwareManagementDumpInformation (
   1074   IN CONST EFI_HANDLE TheHandle,
   1075   IN CONST BOOLEAN    Verbose
   1076   )
   1077 {
   1078   EFI_STATUS                          Status;
   1079   EFI_FIRMWARE_MANAGEMENT_PROTOCOL    *EfiFwMgmtProtocol;
   1080   EFI_FIRMWARE_IMAGE_DESCRIPTOR       *ImageInfo;
   1081   EFI_FIRMWARE_IMAGE_DESCRIPTOR_V1    *ImageInfoV1;
   1082   EFI_FIRMWARE_IMAGE_DESCRIPTOR_V2    *ImageInfoV2;
   1083   UINT64                              AttributeSetting;
   1084   UINTN                               ImageInfoSize;
   1085   UINTN                               DescriptorSize;
   1086   UINT32                              DescriptorVersion;
   1087   UINT32                              PackageVersion;
   1088   UINT8                               DescriptorCount;
   1089   UINT8                               Index;
   1090   UINT8                               Index1;
   1091   UINT8                               ImageCount;
   1092   CHAR16                              *PackageVersionName;
   1093   CHAR16                              *TempStr;
   1094   CHAR16                              *RetVal;
   1095   CHAR16                              *TempRetVal;
   1096   CHAR16                              *AttributeSettingStr;
   1097   BOOLEAN                             Found;
   1098   BOOLEAN                             AttributeSupported;
   1099 
   1100   //
   1101   // Initialize local variables
   1102   //
   1103   ImageCount             = 0;
   1104   ImageInfoSize          = 1;
   1105   AttributeSetting       = 0;
   1106   Found                  = FALSE;
   1107   AttributeSupported     = FALSE;
   1108   ImageInfo              = NULL;
   1109   ImageInfoV1            = NULL;
   1110   ImageInfoV2            = NULL;
   1111   PackageVersionName     = NULL;
   1112   RetVal                 = NULL;
   1113   TempRetVal             = NULL;
   1114   TempStr                = NULL;
   1115   AttributeSettingStr    = NULL;
   1116 
   1117   if (!Verbose) {
   1118     return (CatSPrint(NULL, L"FirmwareManagement"));
   1119   }
   1120 
   1121   Status = gBS->OpenProtocol (
   1122                   (EFI_HANDLE) (TheHandle),
   1123                   &gEfiFirmwareManagementProtocolGuid,
   1124                   (VOID **) &EfiFwMgmtProtocol,
   1125                   NULL,
   1126                   NULL,
   1127                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
   1128                   );
   1129 
   1130   if (EFI_ERROR (Status)) {
   1131     return NULL;
   1132   }
   1133 
   1134   Status = EfiFwMgmtProtocol->GetImageInfo (
   1135                                 EfiFwMgmtProtocol,
   1136                                 &ImageInfoSize,
   1137                                 ImageInfo,
   1138                                 &DescriptorVersion,
   1139                                 &DescriptorCount,
   1140                                 &DescriptorSize,
   1141                                 &PackageVersion,
   1142                                 &PackageVersionName
   1143                                 );
   1144 
   1145   if (Status == EFI_BUFFER_TOO_SMALL) {
   1146     ImageInfo = AllocateZeroPool (ImageInfoSize);
   1147 
   1148     if (ImageInfo == NULL) {
   1149       Status = EFI_OUT_OF_RESOURCES;
   1150     } else {
   1151       Status = EfiFwMgmtProtocol->GetImageInfo (
   1152                                     EfiFwMgmtProtocol,
   1153                                     &ImageInfoSize,
   1154                                     ImageInfo,
   1155                                     &DescriptorVersion,
   1156                                     &DescriptorCount,
   1157                                     &DescriptorSize,
   1158                                     &PackageVersion,
   1159                                     &PackageVersionName
   1160                                     );
   1161     }
   1162   }
   1163 
   1164   if (EFI_ERROR (Status)) {
   1165     goto ERROR_EXIT;
   1166   }
   1167 
   1168   //
   1169   // Decode Image Descriptor data only if its version is supported
   1170   //
   1171   if (DescriptorVersion <= EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION) {
   1172 
   1173     if (ImageInfo == NULL) {
   1174       goto ERROR_EXIT;
   1175     }
   1176 
   1177     ImageInfoV1 = (EFI_FIRMWARE_IMAGE_DESCRIPTOR_V1 *)ImageInfo;
   1178     ImageInfoV2 = (EFI_FIRMWARE_IMAGE_DESCRIPTOR_V2 *)ImageInfo;
   1179 
   1180     //
   1181     // Set ImageInfoSize in return buffer
   1182     //
   1183     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_IMAGE_INFO_SIZE), NULL);
   1184     if (TempStr == NULL) {
   1185       goto ERROR_EXIT;
   1186     }
   1187     RetVal = CatSPrint (NULL, TempStr, ImageInfoSize);
   1188     SHELL_FREE_NON_NULL (TempStr);
   1189 
   1190     //
   1191     // Set DescriptorVersion in return buffer
   1192     //
   1193     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_DESCRIPTOR_VERSION), NULL);
   1194     if (TempStr == NULL) {
   1195       goto ERROR_EXIT;
   1196     }
   1197     TempRetVal = CatSPrint (RetVal, TempStr, DescriptorVersion);
   1198     SHELL_FREE_NON_NULL (RetVal);
   1199     RetVal = TempRetVal;
   1200     SHELL_FREE_NON_NULL (TempStr);
   1201 
   1202     //
   1203     // Set DescriptorCount in return buffer
   1204     //
   1205     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_DESCRIPTOR_COUNT), NULL);
   1206     if (TempStr == NULL) {
   1207       goto ERROR_EXIT;
   1208     }
   1209     TempRetVal = CatSPrint (RetVal, TempStr, DescriptorCount);
   1210     SHELL_FREE_NON_NULL (RetVal);
   1211     RetVal = TempRetVal;
   1212     SHELL_FREE_NON_NULL (TempStr);
   1213 
   1214 
   1215     //
   1216     // Set DescriptorSize in return buffer
   1217     //
   1218     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_DESCRIPTOR_SIZE), NULL);
   1219     if (TempStr == NULL) {
   1220       goto ERROR_EXIT;
   1221     }
   1222     TempRetVal = CatSPrint (RetVal, TempStr, DescriptorSize);
   1223     SHELL_FREE_NON_NULL (RetVal);
   1224     RetVal = TempRetVal;
   1225     SHELL_FREE_NON_NULL (TempStr);
   1226 
   1227     //
   1228     // Set PackageVersion in return buffer
   1229     //
   1230     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_PACKAGE_VERSION), NULL);
   1231     if (TempStr == NULL) {
   1232       goto ERROR_EXIT;
   1233     }
   1234     TempRetVal = CatSPrint (RetVal, TempStr, PackageVersion);
   1235     SHELL_FREE_NON_NULL (RetVal);
   1236     RetVal = TempRetVal;
   1237     SHELL_FREE_NON_NULL (TempStr);
   1238 
   1239     //
   1240     // Set PackageVersionName in return buffer
   1241     //
   1242     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_PACKAGE_VERSION_NAME), NULL);
   1243     if (TempStr == NULL) {
   1244       goto ERROR_EXIT;
   1245     }
   1246     TempRetVal = CatSPrint (RetVal, TempStr, PackageVersionName);
   1247     SHELL_FREE_NON_NULL (RetVal);
   1248     RetVal = TempRetVal;
   1249     SHELL_FREE_NON_NULL (TempStr);
   1250 
   1251     for (Index = 0; Index < DescriptorCount; Index++) {
   1252       //
   1253       // First check if Attribute is supported
   1254       // and generate a string for AttributeSetting field
   1255       //
   1256       SHELL_FREE_NON_NULL (AttributeSettingStr);
   1257       AttributeSupported = FALSE;
   1258       AttributeSetting   = 0;
   1259       if (DescriptorVersion == EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V1) {
   1260         if (ImageInfoV1[Index].AttributesSupported != 0x0) {
   1261           AttributeSupported = TRUE;
   1262           AttributeSetting   = ImageInfoV1[Index].AttributesSetting;
   1263         }
   1264       } else if (DescriptorVersion == EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V2) {
   1265         if (ImageInfoV2[Index].AttributesSupported != 0x0) {
   1266           AttributeSupported = TRUE;
   1267           AttributeSetting   = ImageInfoV2[Index].AttributesSetting;
   1268         }
   1269       } else {
   1270         if (ImageInfo[Index].AttributesSupported != 0x0) {
   1271           AttributeSupported = TRUE;
   1272           AttributeSetting   = ImageInfo[Index].AttributesSetting;
   1273         }
   1274       }
   1275 
   1276       if (!AttributeSupported) {
   1277         AttributeSettingStr = CatSPrint (NULL, L"None");
   1278       } else {
   1279         AttributeSettingStr = CatSPrint (NULL, L"(");
   1280 
   1281         if ((AttributeSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE) != 0x0) {
   1282           TempRetVal = CatSPrint (AttributeSettingStr, L" IMAGE_ATTRIBUTE_IMAGE_UPDATABLE");
   1283           SHELL_FREE_NON_NULL (AttributeSettingStr);
   1284           AttributeSettingStr = TempRetVal;
   1285         }
   1286         if ((AttributeSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0x0) {
   1287           TempRetVal = CatSPrint (AttributeSettingStr, L" IMAGE_ATTRIBUTE_RESET_REQUIRED");
   1288           SHELL_FREE_NON_NULL (AttributeSettingStr);
   1289           AttributeSettingStr = TempRetVal;
   1290         }
   1291         if ((AttributeSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED) != 0x0) {
   1292           TempRetVal = CatSPrint (AttributeSettingStr, L" IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED");
   1293           SHELL_FREE_NON_NULL (AttributeSettingStr);
   1294           AttributeSettingStr = TempRetVal;
   1295         }
   1296         if ((AttributeSetting & IMAGE_ATTRIBUTE_IN_USE) != 0x0) {
   1297           TempRetVal = CatSPrint (AttributeSettingStr, L" IMAGE_ATTRIBUTE_IN_USE");
   1298           SHELL_FREE_NON_NULL (AttributeSettingStr);
   1299           AttributeSettingStr = TempRetVal;
   1300         }
   1301         if ((AttributeSetting & IMAGE_ATTRIBUTE_UEFI_IMAGE) != 0x0) {
   1302           TempRetVal = CatSPrint (AttributeSettingStr, L" IMAGE_ATTRIBUTE_UEFI_IMAGE");
   1303           SHELL_FREE_NON_NULL (AttributeSettingStr);
   1304           AttributeSettingStr = TempRetVal;
   1305         }
   1306         TempRetVal = CatSPrint (AttributeSettingStr, L" )");
   1307         SHELL_FREE_NON_NULL (AttributeSettingStr);
   1308         AttributeSettingStr = TempRetVal;
   1309       }
   1310 
   1311       if (DescriptorVersion == EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V1) {
   1312         if (ImageInfoV1[Index].ImageIndex != 0x0) {
   1313           ImageCount++;
   1314         }
   1315 
   1316         TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_IMAGE_DESCRIPTOR_INFO_V1), NULL);
   1317         if (TempStr == NULL) {
   1318           goto ERROR_EXIT;
   1319         }
   1320         TempRetVal = CatSPrint (
   1321                        RetVal,
   1322                        TempStr,
   1323                        Index,
   1324                        ImageInfoV1[Index].ImageIndex,
   1325                        &ImageInfoV1[Index].ImageTypeId,
   1326                        ImageInfoV1[Index].ImageId,
   1327                        ImageInfoV1[Index].ImageIdName,
   1328                        ImageInfoV1[Index].Version,
   1329                        ImageInfoV1[Index].VersionName,
   1330                        ImageInfoV1[Index].Size,
   1331                        ImageInfoV1[Index].AttributesSupported,
   1332                        AttributeSettingStr,
   1333                        ImageInfoV1[Index].Compatibilities
   1334                        );
   1335         SHELL_FREE_NON_NULL (RetVal);
   1336         RetVal = TempRetVal;
   1337         SHELL_FREE_NON_NULL (TempStr);
   1338       } else if (DescriptorVersion == EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V2) {
   1339         if (ImageInfoV2[Index].ImageIndex != 0x0) {
   1340           ImageCount++;
   1341         }
   1342 
   1343         TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_IMAGE_DESCRIPTOR_INFO_V2), NULL);
   1344         if (TempStr == NULL) {
   1345           goto ERROR_EXIT;
   1346         }
   1347         TempRetVal = CatSPrint (
   1348                        RetVal,
   1349                        TempStr,
   1350                        Index,
   1351                        ImageInfoV2[Index].ImageIndex,
   1352                        &ImageInfoV2[Index].ImageTypeId,
   1353                        ImageInfoV2[Index].ImageId,
   1354                        ImageInfoV2[Index].ImageIdName,
   1355                        ImageInfoV2[Index].Version,
   1356                        ImageInfoV2[Index].VersionName,
   1357                        ImageInfoV2[Index].Size,
   1358                        ImageInfoV2[Index].AttributesSupported,
   1359                        AttributeSettingStr,
   1360                        ImageInfoV2[Index].Compatibilities,
   1361                        ImageInfoV2[Index].LowestSupportedImageVersion
   1362                        );
   1363         SHELL_FREE_NON_NULL (RetVal);
   1364         RetVal = TempRetVal;
   1365         SHELL_FREE_NON_NULL (TempStr);
   1366       } else {
   1367         if (ImageInfo[Index].ImageIndex != 0x0) {
   1368           ImageCount++;
   1369         }
   1370 
   1371         TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_IMAGE_DESCRIPTOR_INFO), NULL);
   1372         if (TempStr == NULL) {
   1373           goto ERROR_EXIT;
   1374         }
   1375         TempRetVal = CatSPrint (
   1376                        RetVal,
   1377                        TempStr,
   1378                        Index,
   1379                        ImageInfo[Index].ImageIndex,
   1380                        &ImageInfo[Index].ImageTypeId,
   1381                        ImageInfo[Index].ImageId,
   1382                        ImageInfo[Index].ImageIdName,
   1383                        ImageInfo[Index].Version,
   1384                        ImageInfo[Index].VersionName,
   1385                        ImageInfo[Index].Size,
   1386                        ImageInfo[Index].AttributesSupported,
   1387                        AttributeSettingStr,
   1388                        ImageInfo[Index].Compatibilities,
   1389                        ImageInfo[Index].LowestSupportedImageVersion,
   1390                        ImageInfo[Index].LastAttemptVersion,
   1391                        ImageInfo[Index].LastAttemptStatus,
   1392                        ImageInfo[Index].HardwareInstance
   1393                        );
   1394         SHELL_FREE_NON_NULL (RetVal);
   1395         RetVal = TempRetVal;
   1396         SHELL_FREE_NON_NULL (TempStr);
   1397       }
   1398     }
   1399   }
   1400 
   1401   if (ImageCount > 0) {
   1402     for (Index=0; Index<DescriptorCount; Index++) {
   1403       for (Index1=Index+1; Index1<DescriptorCount; Index1++) {
   1404         if (DescriptorVersion == EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V1) {
   1405           if (ImageInfoV1[Index].ImageId == ImageInfoV1[Index1].ImageId) {
   1406             Found = TRUE;
   1407             //
   1408             // At least one match found indicating presense of non unique ImageId values so no more comparisons needed
   1409             //
   1410             goto ENDLOOP;
   1411           }
   1412         } else if (DescriptorVersion == EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V2) {
   1413           if (ImageInfoV2[Index].ImageId == ImageInfoV2[Index1].ImageId) {
   1414             Found = TRUE;
   1415             //
   1416             // At least one match found indicating presense of non unique ImageId values so no more comparisons needed
   1417             //
   1418             goto ENDLOOP;
   1419           }
   1420         } else {
   1421           if (ImageInfo[Index].ImageId == ImageInfo[Index1].ImageId) {
   1422             Found = TRUE;
   1423             //
   1424             // At least one match found indicating presense of non unique ImageId values so no more comparisons needed
   1425             //
   1426             goto ENDLOOP;
   1427           }
   1428         }
   1429       }
   1430     }
   1431   }
   1432 
   1433 ENDLOOP:
   1434   //
   1435   // Check if ImageId with duplicate value was found
   1436   //
   1437   if (Found) {
   1438     TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_FMP_IMAGEID_NON_UNIQUE), NULL);
   1439     if (TempStr == NULL) {
   1440       goto ERROR_EXIT;
   1441     }
   1442     TempRetVal = CatSPrint (RetVal, TempStr);
   1443     SHELL_FREE_NON_NULL (RetVal);
   1444     RetVal = TempRetVal;
   1445     SHELL_FREE_NON_NULL (TempStr);
   1446   }
   1447 
   1448   SHELL_FREE_NON_NULL (ImageInfo);
   1449   SHELL_FREE_NON_NULL (PackageVersionName);
   1450   SHELL_FREE_NON_NULL (AttributeSettingStr);
   1451 
   1452   return RetVal;
   1453 
   1454 ERROR_EXIT:
   1455   SHELL_FREE_NON_NULL (RetVal);
   1456   SHELL_FREE_NON_NULL (ImageInfo);
   1457   SHELL_FREE_NON_NULL (PackageVersionName);
   1458   SHELL_FREE_NON_NULL (AttributeSettingStr);
   1459 
   1460   return NULL;
   1461 }
   1462 
   1463 //
   1464 // Put the information on the NT32 protocol GUIDs here so we are not dependant on the Nt32Pkg
   1465 //
   1466 #define LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID \
   1467   { \
   1468     0x58c518b1, 0x76f3, 0x11d4, { 0xbc, 0xea, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
   1469   }
   1470 
   1471 #define LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID \
   1472   { \
   1473     0x96eb4ad6, 0xa32a, 0x11d4, { 0xbc, 0xfd, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
   1474   }
   1475 
   1476 #define LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID \
   1477   { \
   1478     0xc95a93d, 0xa006, 0x11d4, { 0xbc, 0xfa, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
   1479   }
   1480 STATIC CONST EFI_GUID WinNtThunkProtocolGuid = LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_GUID;
   1481 STATIC CONST EFI_GUID WinNtIoProtocolGuid    = LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID;
   1482 STATIC CONST EFI_GUID WinNtSerialPortGuid    = LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID;
   1483 
   1484 //
   1485 // Deprecated protocols we dont want to link from IntelFrameworkModulePkg
   1486 //
   1487 #define LOCAL_EFI_ISA_IO_PROTOCOL_GUID \
   1488   { \
   1489   0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
   1490   }
   1491 #define LOCAL_EFI_ISA_ACPI_PROTOCOL_GUID \
   1492   { \
   1493   0x64a892dc, 0x5561, 0x4536, { 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55 } \
   1494   }
   1495 STATIC CONST EFI_GUID EfiIsaIoProtocolGuid = LOCAL_EFI_ISA_IO_PROTOCOL_GUID;
   1496 STATIC CONST EFI_GUID EfiIsaAcpiProtocolGuid = LOCAL_EFI_ISA_ACPI_PROTOCOL_GUID;
   1497 
   1498 
   1499 STATIC CONST GUID_INFO_BLOCK mGuidStringListNT[] = {
   1500   {STRING_TOKEN(STR_WINNT_THUNK),           (EFI_GUID*)&WinNtThunkProtocolGuid,               NULL},
   1501   {STRING_TOKEN(STR_WINNT_DRIVER_IO),       (EFI_GUID*)&WinNtIoProtocolGuid,                  NULL},
   1502   {STRING_TOKEN(STR_WINNT_SERIAL_PORT),     (EFI_GUID*)&WinNtSerialPortGuid,                  NULL},
   1503   {STRING_TOKEN(STR_UNKNOWN_DEVICE),        NULL,                                             NULL},
   1504 };
   1505 
   1506 STATIC CONST GUID_INFO_BLOCK mGuidStringList[] = {
   1507   {STRING_TOKEN(STR_LOADED_IMAGE),          &gEfiLoadedImageProtocolGuid,                     LoadedImageProtocolDumpInformation},
   1508   {STRING_TOKEN(STR_DEVICE_PATH),           &gEfiDevicePathProtocolGuid,                      DevicePathProtocolDumpInformation},
   1509   {STRING_TOKEN(STR_IMAGE_PATH),            &gEfiLoadedImageDevicePathProtocolGuid,           LoadedImageDevicePathProtocolDumpInformation},
   1510   {STRING_TOKEN(STR_DEVICE_PATH_UTIL),      &gEfiDevicePathUtilitiesProtocolGuid,             NULL},
   1511   {STRING_TOKEN(STR_DEVICE_PATH_TXT),       &gEfiDevicePathToTextProtocolGuid,                NULL},
   1512   {STRING_TOKEN(STR_DEVICE_PATH_FTXT),      &gEfiDevicePathFromTextProtocolGuid,              NULL},
   1513   {STRING_TOKEN(STR_DEVICE_PATH_PC),        &gEfiPcAnsiGuid,                                  NULL},
   1514   {STRING_TOKEN(STR_DEVICE_PATH_VT100),     &gEfiVT100Guid,                                   NULL},
   1515   {STRING_TOKEN(STR_DEVICE_PATH_VT100P),    &gEfiVT100PlusGuid,                               NULL},
   1516   {STRING_TOKEN(STR_DEVICE_PATH_VTUTF8),    &gEfiVTUTF8Guid,                                  NULL},
   1517   {STRING_TOKEN(STR_DRIVER_BINDING),        &gEfiDriverBindingProtocolGuid,                   NULL},
   1518   {STRING_TOKEN(STR_PLATFORM_OVERRIDE),     &gEfiPlatformDriverOverrideProtocolGuid,          NULL},
   1519   {STRING_TOKEN(STR_BUS_OVERRIDE),          &gEfiBusSpecificDriverOverrideProtocolGuid,       NULL},
   1520   {STRING_TOKEN(STR_DRIVER_DIAG),           &gEfiDriverDiagnosticsProtocolGuid,               NULL},
   1521   {STRING_TOKEN(STR_DRIVER_DIAG2),          &gEfiDriverDiagnostics2ProtocolGuid,              NULL},
   1522   {STRING_TOKEN(STR_DRIVER_CN),             &gEfiComponentNameProtocolGuid,                   NULL},
   1523   {STRING_TOKEN(STR_DRIVER_CN2),            &gEfiComponentName2ProtocolGuid,                  NULL},
   1524   {STRING_TOKEN(STR_PLAT_DRV_CFG),          &gEfiPlatformToDriverConfigurationProtocolGuid,   NULL},
   1525   {STRING_TOKEN(STR_DRIVER_VERSION),        &gEfiDriverSupportedEfiVersionProtocolGuid,       DriverEfiVersionProtocolDumpInformation},
   1526   {STRING_TOKEN(STR_TXT_IN),                &gEfiSimpleTextInProtocolGuid,                    NULL},
   1527   {STRING_TOKEN(STR_TXT_IN_EX),             &gEfiSimpleTextInputExProtocolGuid,               NULL},
   1528   {STRING_TOKEN(STR_TXT_OUT),               &gEfiSimpleTextOutProtocolGuid,                   TxtOutProtocolDumpInformation},
   1529   {STRING_TOKEN(STR_SIM_POINTER),           &gEfiSimplePointerProtocolGuid,                   NULL},
   1530   {STRING_TOKEN(STR_ABS_POINTER),           &gEfiAbsolutePointerProtocolGuid,                 NULL},
   1531   {STRING_TOKEN(STR_SERIAL_IO),             &gEfiSerialIoProtocolGuid,                        NULL},
   1532   {STRING_TOKEN(STR_GRAPHICS_OUTPUT),       &gEfiGraphicsOutputProtocolGuid,                  GraphicsOutputProtocolDumpInformation},
   1533   {STRING_TOKEN(STR_EDID_DISCOVERED),       &gEfiEdidDiscoveredProtocolGuid,                  EdidDiscoveredProtocolDumpInformation},
   1534   {STRING_TOKEN(STR_EDID_ACTIVE),           &gEfiEdidActiveProtocolGuid,                      EdidActiveProtocolDumpInformation},
   1535   {STRING_TOKEN(STR_EDID_OVERRIDE),         &gEfiEdidOverrideProtocolGuid,                    NULL},
   1536   {STRING_TOKEN(STR_CON_IN),                &gEfiConsoleInDeviceGuid,                         NULL},
   1537   {STRING_TOKEN(STR_CON_OUT),               &gEfiConsoleOutDeviceGuid,                        NULL},
   1538   {STRING_TOKEN(STR_STD_ERR),               &gEfiStandardErrorDeviceGuid,                     NULL},
   1539   {STRING_TOKEN(STR_LOAD_FILE),             &gEfiLoadFileProtocolGuid,                        NULL},
   1540   {STRING_TOKEN(STR_LOAD_FILE2),            &gEfiLoadFile2ProtocolGuid,                       NULL},
   1541   {STRING_TOKEN(STR_SIMPLE_FILE_SYS),       &gEfiSimpleFileSystemProtocolGuid,                NULL},
   1542   {STRING_TOKEN(STR_TAPE_IO),               &gEfiTapeIoProtocolGuid,                          NULL},
   1543   {STRING_TOKEN(STR_DISK_IO),               &gEfiDiskIoProtocolGuid,                          NULL},
   1544   {STRING_TOKEN(STR_BLK_IO),                &gEfiBlockIoProtocolGuid,                         NULL},
   1545   {STRING_TOKEN(STR_UC),                    &gEfiUnicodeCollationProtocolGuid,                NULL},
   1546   {STRING_TOKEN(STR_UC2),                   &gEfiUnicodeCollation2ProtocolGuid,               NULL},
   1547   {STRING_TOKEN(STR_PCIRB_IO),              &gEfiPciRootBridgeIoProtocolGuid,                 PciRootBridgeIoDumpInformation},
   1548   {STRING_TOKEN(STR_PCI_IO),                &gEfiPciIoProtocolGuid,                           NULL},
   1549   {STRING_TOKEN(STR_SCSI_PT),               &gEfiScsiPassThruProtocolGuid,                    NULL},
   1550   {STRING_TOKEN(STR_SCSI_IO),               &gEfiScsiIoProtocolGuid,                          NULL},
   1551   {STRING_TOKEN(STR_SCSI_PT_EXT),           &gEfiExtScsiPassThruProtocolGuid,                 NULL},
   1552   {STRING_TOKEN(STR_ISCSI),                 &gEfiIScsiInitiatorNameProtocolGuid,              NULL},
   1553   {STRING_TOKEN(STR_USB_IO),                &gEfiUsbIoProtocolGuid,                           NULL},
   1554   {STRING_TOKEN(STR_USB_HC),                &gEfiUsbHcProtocolGuid,                           NULL},
   1555   {STRING_TOKEN(STR_USB_HC2),               &gEfiUsb2HcProtocolGuid,                          NULL},
   1556   {STRING_TOKEN(STR_DEBUG_SUPPORT),         &gEfiDebugSupportProtocolGuid,                    NULL},
   1557   {STRING_TOKEN(STR_DEBUG_PORT),            &gEfiDebugPortProtocolGuid,                       NULL},
   1558   {STRING_TOKEN(STR_DECOMPRESS),            &gEfiDecompressProtocolGuid,                      NULL},
   1559   {STRING_TOKEN(STR_ACPI_TABLE),            &gEfiAcpiTableProtocolGuid,                       NULL},
   1560   {STRING_TOKEN(STR_EBC_INTERPRETER),       &gEfiEbcProtocolGuid,                             NULL},
   1561   {STRING_TOKEN(STR_SNP),                   &gEfiSimpleNetworkProtocolGuid,                   NULL},
   1562   {STRING_TOKEN(STR_NII),                   &gEfiNetworkInterfaceIdentifierProtocolGuid,      NULL},
   1563   {STRING_TOKEN(STR_NII_31),                &gEfiNetworkInterfaceIdentifierProtocolGuid_31,   NULL},
   1564   {STRING_TOKEN(STR_PXE_BC),                &gEfiPxeBaseCodeProtocolGuid,                     NULL},
   1565   {STRING_TOKEN(STR_PXE_CB),                &gEfiPxeBaseCodeCallbackProtocolGuid,             NULL},
   1566   {STRING_TOKEN(STR_BIS),                   &gEfiBisProtocolGuid,                             NULL},
   1567   {STRING_TOKEN(STR_MNP_SB),                &gEfiManagedNetworkServiceBindingProtocolGuid,    NULL},
   1568   {STRING_TOKEN(STR_MNP),                   &gEfiManagedNetworkProtocolGuid,                  NULL},
   1569   {STRING_TOKEN(STR_ARP_SB),                &gEfiArpServiceBindingProtocolGuid,               NULL},
   1570   {STRING_TOKEN(STR_ARP),                   &gEfiArpProtocolGuid,                             NULL},
   1571   {STRING_TOKEN(STR_DHCPV4_SB),             &gEfiDhcp4ServiceBindingProtocolGuid,             NULL},
   1572   {STRING_TOKEN(STR_DHCPV4),                &gEfiDhcp4ProtocolGuid,                           NULL},
   1573   {STRING_TOKEN(STR_TCPV4_SB),              &gEfiTcp4ServiceBindingProtocolGuid,              NULL},
   1574   {STRING_TOKEN(STR_TCPV4),                 &gEfiTcp4ProtocolGuid,                            NULL},
   1575   {STRING_TOKEN(STR_IPV4_SB),               &gEfiIp4ServiceBindingProtocolGuid,               NULL},
   1576   {STRING_TOKEN(STR_IPV4),                  &gEfiIp4ProtocolGuid,                             NULL},
   1577   {STRING_TOKEN(STR_IPV4_CFG),              &gEfiIp4ConfigProtocolGuid,                       NULL},
   1578   {STRING_TOKEN(STR_IPV4_CFG2),             &gEfiIp4Config2ProtocolGuid,                      NULL},
   1579   {STRING_TOKEN(STR_UDPV4_SB),              &gEfiUdp4ServiceBindingProtocolGuid,              NULL},
   1580   {STRING_TOKEN(STR_UDPV4),                 &gEfiUdp4ProtocolGuid,                            NULL},
   1581   {STRING_TOKEN(STR_MTFTPV4_SB),            &gEfiMtftp4ServiceBindingProtocolGuid,            NULL},
   1582   {STRING_TOKEN(STR_MTFTPV4),               &gEfiMtftp4ProtocolGuid,                          NULL},
   1583   {STRING_TOKEN(STR_AUTH_INFO),             &gEfiAuthenticationInfoProtocolGuid,              NULL},
   1584   {STRING_TOKEN(STR_HASH_SB),               &gEfiHashServiceBindingProtocolGuid,              NULL},
   1585   {STRING_TOKEN(STR_HASH),                  &gEfiHashProtocolGuid,                            NULL},
   1586   {STRING_TOKEN(STR_HII_FONT),              &gEfiHiiFontProtocolGuid,                         NULL},
   1587   {STRING_TOKEN(STR_HII_STRING),            &gEfiHiiStringProtocolGuid,                       NULL},
   1588   {STRING_TOKEN(STR_HII_IMAGE),             &gEfiHiiImageProtocolGuid,                        NULL},
   1589   {STRING_TOKEN(STR_HII_DATABASE),          &gEfiHiiDatabaseProtocolGuid,                     NULL},
   1590   {STRING_TOKEN(STR_HII_CONFIG_ROUT),       &gEfiHiiConfigRoutingProtocolGuid,                NULL},
   1591   {STRING_TOKEN(STR_HII_CONFIG_ACC),        &gEfiHiiConfigAccessProtocolGuid,                 NULL},
   1592   {STRING_TOKEN(STR_HII_FORM_BROWSER2),     &gEfiFormBrowser2ProtocolGuid,                    NULL},
   1593   {STRING_TOKEN(STR_DRIVER_FAM_OVERRIDE),   &gEfiDriverFamilyOverrideProtocolGuid,            NULL},
   1594   {STRING_TOKEN(STR_PCD),                   &gPcdProtocolGuid,                                NULL},
   1595   {STRING_TOKEN(STR_TCG),                   &gEfiTcgProtocolGuid,                             NULL},
   1596   {STRING_TOKEN(STR_HII_PACKAGE_LIST),      &gEfiHiiPackageListProtocolGuid,                  NULL},
   1597 
   1598 //
   1599 // the ones under this are deprecated by the current UEFI Spec, but may be found anyways...
   1600 //
   1601   {STRING_TOKEN(STR_SHELL_INTERFACE),       &gEfiShellInterfaceGuid,                          NULL},
   1602   {STRING_TOKEN(STR_SHELL_ENV2),            &gEfiShellEnvironment2Guid,                       NULL},
   1603   {STRING_TOKEN(STR_SHELL_ENV),             &gEfiShellEnvironment2Guid,                       NULL},
   1604   {STRING_TOKEN(STR_DEVICE_IO),             &gEfiDeviceIoProtocolGuid,                        NULL},
   1605   {STRING_TOKEN(STR_UGA_DRAW),              &gEfiUgaDrawProtocolGuid,                         NULL},
   1606   {STRING_TOKEN(STR_UGA_IO),                &gEfiUgaIoProtocolGuid,                           NULL},
   1607   {STRING_TOKEN(STR_ESP),                   &gEfiPartTypeSystemPartGuid,                      NULL},
   1608   {STRING_TOKEN(STR_GPT_NBR),               &gEfiPartTypeLegacyMbrGuid,                       NULL},
   1609   {STRING_TOKEN(STR_DRIVER_CONFIG),         &gEfiDriverConfigurationProtocolGuid,             NULL},
   1610   {STRING_TOKEN(STR_DRIVER_CONFIG2),        &gEfiDriverConfiguration2ProtocolGuid,            NULL},
   1611 
   1612 //
   1613 // these are using local (non-global) definitions to reduce package dependancy.
   1614 //
   1615   {STRING_TOKEN(STR_ISA_IO),                (EFI_GUID*)&EfiIsaIoProtocolGuid,                 NULL},
   1616   {STRING_TOKEN(STR_ISA_ACPI),              (EFI_GUID*)&EfiIsaAcpiProtocolGuid,               NULL},
   1617 
   1618 //
   1619 // the ones under this are GUID identified structs, not protocols
   1620 //
   1621   {STRING_TOKEN(STR_FILE_INFO),             &gEfiFileInfoGuid,                                NULL},
   1622   {STRING_TOKEN(STR_FILE_SYS_INFO),         &gEfiFileSystemInfoGuid,                          NULL},
   1623 
   1624 //
   1625 // the ones under this are misc GUIDS.
   1626 //
   1627   {STRING_TOKEN(STR_EFI_GLOBAL_VARIABLE),   &gEfiGlobalVariableGuid,                          NULL},
   1628 
   1629 //
   1630 // UEFI 2.2
   1631 //
   1632   {STRING_TOKEN(STR_IP6_SB),                &gEfiIp6ServiceBindingProtocolGuid,               NULL},
   1633   {STRING_TOKEN(STR_IP6),                   &gEfiIp6ProtocolGuid,                             NULL},
   1634   {STRING_TOKEN(STR_IP6_CONFIG),            &gEfiIp6ConfigProtocolGuid,                       NULL},
   1635   {STRING_TOKEN(STR_MTFTP6_SB),             &gEfiMtftp6ServiceBindingProtocolGuid,            NULL},
   1636   {STRING_TOKEN(STR_MTFTP6),                &gEfiMtftp6ProtocolGuid,                          NULL},
   1637   {STRING_TOKEN(STR_DHCP6_SB),              &gEfiDhcp6ServiceBindingProtocolGuid,             NULL},
   1638   {STRING_TOKEN(STR_DHCP6),                 &gEfiDhcp6ProtocolGuid,                           NULL},
   1639   {STRING_TOKEN(STR_UDP6_SB),               &gEfiUdp6ServiceBindingProtocolGuid,              NULL},
   1640   {STRING_TOKEN(STR_UDP6),                  &gEfiUdp6ProtocolGuid,                            NULL},
   1641   {STRING_TOKEN(STR_TCP6_SB),               &gEfiTcp6ServiceBindingProtocolGuid,              NULL},
   1642   {STRING_TOKEN(STR_TCP6),                  &gEfiTcp6ProtocolGuid,                            NULL},
   1643   {STRING_TOKEN(STR_VLAN_CONFIG),           &gEfiVlanConfigProtocolGuid,                      NULL},
   1644   {STRING_TOKEN(STR_EAP),                   &gEfiEapProtocolGuid,                             NULL},
   1645   {STRING_TOKEN(STR_EAP_MGMT),              &gEfiEapManagementProtocolGuid,                   NULL},
   1646   {STRING_TOKEN(STR_FTP4_SB),               &gEfiFtp4ServiceBindingProtocolGuid,              NULL},
   1647   {STRING_TOKEN(STR_FTP4),                  &gEfiFtp4ProtocolGuid,                            NULL},
   1648   {STRING_TOKEN(STR_IP_SEC_CONFIG),         &gEfiIpSecConfigProtocolGuid,                     NULL},
   1649   {STRING_TOKEN(STR_DH),                    &gEfiDriverHealthProtocolGuid,                    NULL},
   1650   {STRING_TOKEN(STR_DEF_IMG_LOAD),          &gEfiDeferredImageLoadProtocolGuid,               NULL},
   1651   {STRING_TOKEN(STR_USER_CRED),             &gEfiUserCredentialProtocolGuid,                  NULL},
   1652   {STRING_TOKEN(STR_USER_MNGR),             &gEfiUserManagerProtocolGuid,                     NULL},
   1653   {STRING_TOKEN(STR_ATA_PASS_THRU),         &gEfiAtaPassThruProtocolGuid,                     NULL},
   1654 
   1655 //
   1656 // UEFI 2.3
   1657 //
   1658   {STRING_TOKEN(STR_FW_MGMT),               &gEfiFirmwareManagementProtocolGuid,              FirmwareManagementDumpInformation},
   1659   {STRING_TOKEN(STR_IP_SEC),                &gEfiIpSecProtocolGuid,                           NULL},
   1660   {STRING_TOKEN(STR_IP_SEC2),               &gEfiIpSec2ProtocolGuid,                          NULL},
   1661 
   1662 //
   1663 // UEFI 2.3.1
   1664 //
   1665   {STRING_TOKEN(STR_KMS),                   &gEfiKmsProtocolGuid,                             NULL},
   1666   {STRING_TOKEN(STR_BLK_IO2),               &gEfiBlockIo2ProtocolGuid,                        NULL},
   1667   {STRING_TOKEN(STR_SSC),                   &gEfiStorageSecurityCommandProtocolGuid,          NULL},
   1668   {STRING_TOKEN(STR_UCRED2),                &gEfiUserCredential2ProtocolGuid,                 NULL},
   1669 
   1670 //
   1671 // UEFI 2.4
   1672 //
   1673   {STRING_TOKEN(STR_DISK_IO2),              &gEfiDiskIo2ProtocolGuid,                         NULL},
   1674   {STRING_TOKEN(STR_ADAPTER_INFO),          &gEfiAdapterInformationProtocolGuid,              AdapterInformationDumpInformation},
   1675 
   1676 //
   1677 // PI Spec ones
   1678 //
   1679   {STRING_TOKEN(STR_IDE_CONT_INIT),         &gEfiIdeControllerInitProtocolGuid,               NULL},
   1680   {STRING_TOKEN(STR_DISK_INFO),             &gEfiDiskInfoProtocolGuid,                        NULL},
   1681 
   1682 //
   1683 // PI Spec 1.0
   1684 //
   1685   {STRING_TOKEN(STR_BDS_ARCH),              &gEfiBdsArchProtocolGuid,                         NULL},
   1686   {STRING_TOKEN(STR_CPU_ARCH),              &gEfiCpuArchProtocolGuid,                         NULL},
   1687   {STRING_TOKEN(STR_MET_ARCH),              &gEfiMetronomeArchProtocolGuid,                   NULL},
   1688   {STRING_TOKEN(STR_MON_ARCH),              &gEfiMonotonicCounterArchProtocolGuid,            NULL},
   1689   {STRING_TOKEN(STR_RTC_ARCH),              &gEfiRealTimeClockArchProtocolGuid,               NULL},
   1690   {STRING_TOKEN(STR_RESET_ARCH),            &gEfiResetArchProtocolGuid,                       NULL},
   1691   {STRING_TOKEN(STR_RT_ARCH),               &gEfiRuntimeArchProtocolGuid,                     NULL},
   1692   {STRING_TOKEN(STR_SEC_ARCH),              &gEfiSecurityArchProtocolGuid,                    NULL},
   1693   {STRING_TOKEN(STR_TIMER_ARCH),            &gEfiTimerArchProtocolGuid,                       NULL},
   1694   {STRING_TOKEN(STR_VAR_ARCH),              &gEfiVariableWriteArchProtocolGuid,               NULL},
   1695   {STRING_TOKEN(STR_V_ARCH),                &gEfiVariableArchProtocolGuid,                    NULL},
   1696   {STRING_TOKEN(STR_SECP),                  &gEfiSecurityPolicyProtocolGuid,                  NULL},
   1697   {STRING_TOKEN(STR_WDT_ARCH),              &gEfiWatchdogTimerArchProtocolGuid,               NULL},
   1698   {STRING_TOKEN(STR_SCR),                   &gEfiStatusCodeRuntimeProtocolGuid,               NULL},
   1699   {STRING_TOKEN(STR_SMB_HC),                &gEfiSmbusHcProtocolGuid,                         NULL},
   1700   {STRING_TOKEN(STR_FV_2),                  &gEfiFirmwareVolume2ProtocolGuid,                 NULL},
   1701   {STRING_TOKEN(STR_FV_BLOCK),              &gEfiFirmwareVolumeBlockProtocolGuid,             NULL},
   1702   {STRING_TOKEN(STR_CAP_ARCH),              &gEfiCapsuleArchProtocolGuid,                     NULL},
   1703   {STRING_TOKEN(STR_MP_SERVICE),            &gEfiMpServiceProtocolGuid,                       NULL},
   1704   {STRING_TOKEN(STR_HBRAP),                 &gEfiPciHostBridgeResourceAllocationProtocolGuid, NULL},
   1705   {STRING_TOKEN(STR_PCIP),                  &gEfiPciPlatformProtocolGuid,                     NULL},
   1706   {STRING_TOKEN(STR_PCIO),                  &gEfiPciOverrideProtocolGuid,                     NULL},
   1707   {STRING_TOKEN(STR_PCIE),                  &gEfiPciEnumerationCompleteProtocolGuid,          NULL},
   1708   {STRING_TOKEN(STR_IPCID),                 &gEfiIncompatiblePciDeviceSupportProtocolGuid,    NULL},
   1709   {STRING_TOKEN(STR_PCIHPI),                &gEfiPciHotPlugInitProtocolGuid,                  NULL},
   1710   {STRING_TOKEN(STR_PCIHPR),                &gEfiPciHotPlugRequestProtocolGuid,               NULL},
   1711   {STRING_TOKEN(STR_SMBIOS),                &gEfiSmbiosProtocolGuid,                          NULL},
   1712   {STRING_TOKEN(STR_S3_SAVE),               &gEfiS3SaveStateProtocolGuid,                     NULL},
   1713   {STRING_TOKEN(STR_S3_S_SMM),              &gEfiS3SmmSaveStateProtocolGuid,                  NULL},
   1714   {STRING_TOKEN(STR_RSC),                   &gEfiRscHandlerProtocolGuid,                      NULL},
   1715   {STRING_TOKEN(STR_S_RSC),                 &gEfiSmmRscHandlerProtocolGuid,                   NULL},
   1716   {STRING_TOKEN(STR_ACPI_SDT),              &gEfiAcpiSdtProtocolGuid,                         NULL},
   1717   {STRING_TOKEN(STR_SIO),                   &gEfiSioProtocolGuid,                             NULL},
   1718   {STRING_TOKEN(STR_S_CPU2),                &gEfiSmmCpuIo2ProtocolGuid,                       NULL},
   1719   {STRING_TOKEN(STR_S_BASE2),               &gEfiSmmBase2ProtocolGuid,                        NULL},
   1720   {STRING_TOKEN(STR_S_ACC_2),               &gEfiSmmAccess2ProtocolGuid,                      NULL},
   1721   {STRING_TOKEN(STR_S_CON_2),               &gEfiSmmControl2ProtocolGuid,                     NULL},
   1722   {STRING_TOKEN(STR_S_CONFIG),              &gEfiSmmConfigurationProtocolGuid,                NULL},
   1723   {STRING_TOKEN(STR_S_RTL),                 &gEfiSmmReadyToLockProtocolGuid,                  NULL},
   1724   {STRING_TOKEN(STR_DS_RTL),                &gEfiDxeSmmReadyToLockProtocolGuid,               NULL},
   1725   {STRING_TOKEN(STR_S_COMM),                &gEfiSmmCommunicationProtocolGuid,                NULL},
   1726   {STRING_TOKEN(STR_S_STAT),                &gEfiSmmStatusCodeProtocolGuid,                   NULL},
   1727   {STRING_TOKEN(STR_S_CPU),                 &gEfiSmmCpuProtocolGuid,                          NULL},
   1728   {STRING_TOKEN(STR_S_PCIRBIO),             &gEfiPciRootBridgeIoProtocolGuid,                 NULL},
   1729   {STRING_TOKEN(STR_S_SWD),                 &gEfiSmmSwDispatch2ProtocolGuid,                  NULL},
   1730   {STRING_TOKEN(STR_S_SXD),                 &gEfiSmmSxDispatch2ProtocolGuid,                  NULL},
   1731   {STRING_TOKEN(STR_S_PTD2),                &gEfiSmmPeriodicTimerDispatch2ProtocolGuid,       NULL},
   1732   {STRING_TOKEN(STR_S_UD2),                 &gEfiSmmUsbDispatch2ProtocolGuid,                 NULL},
   1733   {STRING_TOKEN(STR_S_GD2),                 &gEfiSmmGpiDispatch2ProtocolGuid,                 NULL},
   1734   {STRING_TOKEN(STR_S_SBD2),                &gEfiSmmStandbyButtonDispatch2ProtocolGuid,       NULL},
   1735   {STRING_TOKEN(STR_S_PBD2),                &gEfiSmmPowerButtonDispatch2ProtocolGuid,         NULL},
   1736   {STRING_TOKEN(STR_S_ITD2),                &gEfiSmmIoTrapDispatch2ProtocolGuid,              NULL},
   1737   {STRING_TOKEN(STR_PCD),                   &gEfiPcdProtocolGuid,                             NULL},
   1738   {STRING_TOKEN(STR_FVB2),                  &gEfiFirmwareVolumeBlock2ProtocolGuid,            NULL},
   1739   {STRING_TOKEN(STR_CPUIO2),                &gEfiCpuIo2ProtocolGuid,                          NULL},
   1740   {STRING_TOKEN(STR_LEGACY_R2),             &gEfiLegacyRegion2ProtocolGuid,                   NULL},
   1741   {STRING_TOKEN(STR_SAL_MIP),               &gEfiSalMcaInitPmiProtocolGuid,                   NULL},
   1742   {STRING_TOKEN(STR_ES_BS),                 &gEfiExtendedSalBootServiceProtocolGuid,          NULL},
   1743   {STRING_TOKEN(STR_ES_BIO),                &gEfiExtendedSalBaseIoServicesProtocolGuid,       NULL},
   1744   {STRING_TOKEN(STR_ES_STALL),              &gEfiExtendedSalStallServicesProtocolGuid,        NULL},
   1745   {STRING_TOKEN(STR_ES_RTC),                &gEfiExtendedSalRtcServicesProtocolGuid,          NULL},
   1746   {STRING_TOKEN(STR_ES_VS),                 &gEfiExtendedSalVariableServicesProtocolGuid,     NULL},
   1747   {STRING_TOKEN(STR_ES_MTC),                &gEfiExtendedSalMtcServicesProtocolGuid,          NULL},
   1748   {STRING_TOKEN(STR_ES_RESET),              &gEfiExtendedSalResetServicesProtocolGuid,        NULL},
   1749   {STRING_TOKEN(STR_ES_SC),                 &gEfiExtendedSalStatusCodeServicesProtocolGuid,   NULL},
   1750   {STRING_TOKEN(STR_ES_FBS),                &gEfiExtendedSalFvBlockServicesProtocolGuid,      NULL},
   1751   {STRING_TOKEN(STR_ES_MP),                 &gEfiExtendedSalMpServicesProtocolGuid,           NULL},
   1752   {STRING_TOKEN(STR_ES_PAL),                &gEfiExtendedSalPalServicesProtocolGuid,          NULL},
   1753   {STRING_TOKEN(STR_ES_BASE),               &gEfiExtendedSalBaseServicesProtocolGuid,         NULL},
   1754   {STRING_TOKEN(STR_ES_MCA),                &gEfiExtendedSalMcaServicesProtocolGuid,          NULL},
   1755   {STRING_TOKEN(STR_ES_PCI),                &gEfiExtendedSalPciServicesProtocolGuid,          NULL},
   1756   {STRING_TOKEN(STR_ES_CACHE),              &gEfiExtendedSalCacheServicesProtocolGuid,        NULL},
   1757   {STRING_TOKEN(STR_ES_MCA_LOG),            &gEfiExtendedSalMcaLogServicesProtocolGuid,       NULL},
   1758   {STRING_TOKEN(STR_S2ARCH),                &gEfiSecurity2ArchProtocolGuid,                   NULL},
   1759   {STRING_TOKEN(STR_EODXE),                 &gEfiSmmEndOfDxeProtocolGuid,                     NULL},
   1760   {STRING_TOKEN(STR_ISAHC),                 &gEfiIsaHcProtocolGuid,                           NULL},
   1761   {STRING_TOKEN(STR_ISAHC_B),               &gEfiIsaHcServiceBindingProtocolGuid,             NULL},
   1762   {STRING_TOKEN(STR_SIO_C),                 &gEfiSioControlProtocolGuid,                      NULL},
   1763   {STRING_TOKEN(STR_GET_PCD),               &gEfiGetPcdInfoProtocolGuid,                      NULL},
   1764   {STRING_TOKEN(STR_I2C_M),                 &gEfiI2cMasterProtocolGuid,                       NULL},
   1765   {STRING_TOKEN(STR_I2CIO),                 &gEfiI2cIoProtocolGuid,                           NULL},
   1766   {STRING_TOKEN(STR_I2CEN),                 &gEfiI2cEnumerateProtocolGuid,                    NULL},
   1767   {STRING_TOKEN(STR_I2C_H),                 &gEfiI2cHostProtocolGuid,                         NULL},
   1768   {STRING_TOKEN(STR_I2C_BCM),               &gEfiI2cBusConfigurationManagementProtocolGuid,   NULL},
   1769   {STRING_TOKEN(STR_TREE),                  &gEfiTrEEProtocolGuid,                            NULL},
   1770   {STRING_TOKEN(STR_TCG2),                  &gEfiTcg2ProtocolGuid,                            NULL},
   1771   {STRING_TOKEN(STR_TIMESTAMP),             &gEfiTimestampProtocolGuid,                       NULL},
   1772   {STRING_TOKEN(STR_RNG),                   &gEfiRngProtocolGuid,                             NULL},
   1773   {STRING_TOKEN(STR_NVMEPT),                &gEfiNvmExpressPassThruProtocolGuid,              NULL},
   1774   {STRING_TOKEN(STR_H2_SB),                 &gEfiHash2ServiceBindingProtocolGuid,             NULL},
   1775   {STRING_TOKEN(STR_HASH2),                 &gEfiHash2ProtocolGuid,                           NULL},
   1776   {STRING_TOKEN(STR_BIO_C),                 &gEfiBlockIoCryptoProtocolGuid,                   NULL},
   1777   {STRING_TOKEN(STR_SCR),                   &gEfiSmartCardReaderProtocolGuid,                 NULL},
   1778   {STRING_TOKEN(STR_SCE),                   &gEfiSmartCardEdgeProtocolGuid,                   NULL},
   1779   {STRING_TOKEN(STR_USB_FIO),               &gEfiUsbFunctionIoProtocolGuid,                   NULL},
   1780   {STRING_TOKEN(STR_BC_HC),                 &gEfiBluetoothHcProtocolGuid,                     NULL},
   1781   {STRING_TOKEN(STR_BC_IO_SB),              &gEfiBluetoothIoServiceBindingProtocolGuid,       NULL},
   1782   {STRING_TOKEN(STR_BC_IO),                 &gEfiBluetoothIoProtocolGuid,                     NULL},
   1783   {STRING_TOKEN(STR_BC_C),                  &gEfiBluetoothConfigProtocolGuid,                 NULL},
   1784   {STRING_TOKEN(STR_REG_EXP),               &gEfiRegularExpressionProtocolGuid,               NULL},
   1785   {STRING_TOKEN(STR_B_MGR_P),               &gEfiBootManagerPolicyProtocolGuid,               NULL},
   1786   {STRING_TOKEN(STR_CKH),                   &gEfiConfigKeywordHandlerProtocolGuid,            NULL},
   1787   {STRING_TOKEN(STR_WIFI),                  &gEfiWiFiProtocolGuid,                            NULL},
   1788   {STRING_TOKEN(STR_EAP_M),                 &gEfiEapManagement2ProtocolGuid,                  NULL},
   1789   {STRING_TOKEN(STR_EAP_C),                 &gEfiEapConfigurationProtocolGuid,                NULL},
   1790   {STRING_TOKEN(STR_PKCS7),                 &gEfiPkcs7VerifyProtocolGuid,                     NULL},
   1791   {STRING_TOKEN(STR_NET_DNS4_SB),           &gEfiDns4ServiceBindingProtocolGuid,              NULL},
   1792   {STRING_TOKEN(STR_NET_DNS4),              &gEfiDns4ProtocolGuid,                            NULL},
   1793   {STRING_TOKEN(STR_NET_DNS6_SB),           &gEfiDns6ServiceBindingProtocolGuid,              NULL},
   1794   {STRING_TOKEN(STR_NET_DNS6),              &gEfiDns6ProtocolGuid,                            NULL},
   1795   {STRING_TOKEN(STR_NET_HTTP_SB),           &gEfiHttpServiceBindingProtocolGuid,              NULL},
   1796   {STRING_TOKEN(STR_NET_HTTP),              &gEfiHttpProtocolGuid,                            NULL},
   1797   {STRING_TOKEN(STR_NET_HTTP_U),            &gEfiHttpUtilitiesProtocolGuid,                   NULL},
   1798   {STRING_TOKEN(STR_REST),                  &gEfiRestProtocolGuid,                            NULL},
   1799 
   1800 //
   1801 // UEFI Shell Spec 2.0
   1802 //
   1803   {STRING_TOKEN(STR_SHELL_PARAMETERS),      &gEfiShellParametersProtocolGuid,                 NULL},
   1804   {STRING_TOKEN(STR_SHELL),                 &gEfiShellProtocolGuid,                           NULL},
   1805 
   1806 //
   1807 // UEFI Shell Spec 2.1
   1808 //
   1809   {STRING_TOKEN(STR_SHELL_DYNAMIC),         &gEfiShellDynamicCommandProtocolGuid,             NULL},
   1810 
   1811 //
   1812 // Misc
   1813 //
   1814   {STRING_TOKEN(STR_PCDINFOPROT),           &gGetPcdInfoProtocolGuid,                         NULL},
   1815 
   1816 //
   1817 // terminator
   1818 //
   1819   {STRING_TOKEN(STR_UNKNOWN_DEVICE),        NULL,                                             NULL},
   1820 };
   1821 
   1822 /**
   1823   Function to get the node for a protocol or struct from it's GUID.
   1824 
   1825   if Guid is NULL, then ASSERT.
   1826 
   1827   @param[in] Guid               The GUID to look for the name of.
   1828 
   1829   @return                       The node.
   1830 **/
   1831 CONST GUID_INFO_BLOCK *
   1832 InternalShellGetNodeFromGuid(
   1833   IN CONST EFI_GUID* Guid
   1834   )
   1835 {
   1836   CONST GUID_INFO_BLOCK *ListWalker;
   1837   UINTN                 LoopCount;
   1838 
   1839   ASSERT(Guid != NULL);
   1840 
   1841   for (LoopCount = 0, ListWalker = GuidList; GuidList != NULL && LoopCount < GuidListCount; LoopCount++, ListWalker++) {
   1842     if (CompareGuid(ListWalker->GuidId, Guid)) {
   1843       return (ListWalker);
   1844     }
   1845   }
   1846 
   1847   if (PcdGetBool(PcdShellIncludeNtGuids)) {
   1848     for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
   1849       if (CompareGuid(ListWalker->GuidId, Guid)) {
   1850         return (ListWalker);
   1851       }
   1852     }
   1853   }
   1854   for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
   1855     if (CompareGuid(ListWalker->GuidId, Guid)) {
   1856       return (ListWalker);
   1857     }
   1858   }
   1859   return (NULL);
   1860 }
   1861 
   1862 /**
   1863 Function to add a new GUID/Name mapping.
   1864 
   1865 @param[in] Guid       The Guid
   1866 @param[in] NameID     The STRING id of the HII string to use
   1867 @param[in] DumpFunc   The pointer to the dump function
   1868 
   1869 
   1870 @retval EFI_SUCCESS           The operation was sucessful
   1871 @retval EFI_OUT_OF_RESOURCES  A memory allocation failed
   1872 @retval EFI_INVALID_PARAMETER Guid NameId was invalid
   1873 **/
   1874 EFI_STATUS
   1875 InsertNewGuidNameMapping(
   1876   IN CONST EFI_GUID           *Guid,
   1877   IN CONST EFI_STRING_ID      NameID,
   1878   IN CONST DUMP_PROTOCOL_INFO DumpFunc OPTIONAL
   1879   )
   1880 {
   1881   ASSERT(Guid   != NULL);
   1882   ASSERT(NameID != 0);
   1883 
   1884   GuidList = ReallocatePool(GuidListCount * sizeof(GUID_INFO_BLOCK), GuidListCount+1 * sizeof(GUID_INFO_BLOCK), GuidList);
   1885   if (GuidList == NULL) {
   1886     GuidListCount = 0;
   1887     return (EFI_OUT_OF_RESOURCES);
   1888   }
   1889   GuidListCount++;
   1890 
   1891   GuidList[GuidListCount - 1].GuidId   = AllocateCopyPool(sizeof(EFI_GUID), Guid);
   1892   GuidList[GuidListCount - 1].StringId = NameID;
   1893   GuidList[GuidListCount - 1].DumpInfo = DumpFunc;
   1894 
   1895   if (GuidList[GuidListCount - 1].GuidId == NULL) {
   1896     return (EFI_OUT_OF_RESOURCES);
   1897   }
   1898 
   1899   return (EFI_SUCCESS);
   1900 }
   1901 
   1902 /**
   1903   Function to add a new GUID/Name mapping.
   1904 
   1905   This cannot overwrite an existing mapping.
   1906 
   1907   @param[in] Guid       The Guid
   1908   @param[in] TheName    The Guid's name
   1909   @param[in] Lang       RFC4646 language code list or NULL
   1910 
   1911   @retval EFI_SUCCESS           The operation was sucessful
   1912   @retval EFI_ACCESS_DENIED     There was a duplicate
   1913   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed
   1914   @retval EFI_INVALID_PARAMETER Guid or TheName was NULL
   1915 **/
   1916 EFI_STATUS
   1917 EFIAPI
   1918 AddNewGuidNameMapping(
   1919   IN CONST EFI_GUID *Guid,
   1920   IN CONST CHAR16   *TheName,
   1921   IN CONST CHAR8    *Lang OPTIONAL
   1922   )
   1923 {
   1924   EFI_STRING_ID         NameID;
   1925 
   1926   HandleParsingHiiInit();
   1927 
   1928   if (Guid == NULL || TheName == NULL){
   1929     return (EFI_INVALID_PARAMETER);
   1930   }
   1931 
   1932   if ((InternalShellGetNodeFromGuid(Guid)) != NULL) {
   1933     return (EFI_ACCESS_DENIED);
   1934   }
   1935 
   1936   NameID = HiiSetString(mHandleParsingHiiHandle, 0, (CHAR16*)TheName, Lang);
   1937   if (NameID == 0) {
   1938     return (EFI_OUT_OF_RESOURCES);
   1939   }
   1940 
   1941   return (InsertNewGuidNameMapping(Guid, NameID, NULL));
   1942 }
   1943 
   1944 /**
   1945   Function to get the name of a protocol or struct from it's GUID.
   1946 
   1947   if Guid is NULL, then ASSERT.
   1948 
   1949   @param[in] Guid               The GUID to look for the name of.
   1950   @param[in] Lang               The language to use.
   1951 
   1952   @return                       pointer to string of the name.  The caller
   1953                                 is responsible to free this memory.
   1954 **/
   1955 CHAR16*
   1956 EFIAPI
   1957 GetStringNameFromGuid(
   1958   IN CONST EFI_GUID *Guid,
   1959   IN CONST CHAR8    *Lang OPTIONAL
   1960   )
   1961 {
   1962   CONST GUID_INFO_BLOCK *Id;
   1963 
   1964   HandleParsingHiiInit();
   1965 
   1966   Id = InternalShellGetNodeFromGuid(Guid);
   1967   return (HiiGetString(mHandleParsingHiiHandle, Id==NULL?STRING_TOKEN(STR_UNKNOWN_DEVICE):Id->StringId, Lang));
   1968 }
   1969 
   1970 /**
   1971   Function to dump protocol information from a handle.
   1972 
   1973   This function will return a allocated string buffer containing the
   1974   information.  The caller is responsible for freeing the memory.
   1975 
   1976   If Guid is NULL, ASSERT().
   1977   If TheHandle is NULL, ASSERT().
   1978 
   1979   @param[in] TheHandle      The handle to dump information from.
   1980   @param[in] Guid           The GUID of the protocol to dump.
   1981   @param[in] Verbose        TRUE for extra info.  FALSE otherwise.
   1982 
   1983   @return                   The pointer to string.
   1984   @retval NULL              An error was encountered.
   1985 **/
   1986 CHAR16*
   1987 EFIAPI
   1988 GetProtocolInformationDump(
   1989   IN CONST EFI_HANDLE TheHandle,
   1990   IN CONST EFI_GUID   *Guid,
   1991   IN CONST BOOLEAN    Verbose
   1992   )
   1993 {
   1994   CONST GUID_INFO_BLOCK *Id;
   1995 
   1996   ASSERT(TheHandle  != NULL);
   1997   ASSERT(Guid       != NULL);
   1998 
   1999   if (TheHandle == NULL || Guid == NULL) {
   2000     return (NULL);
   2001   }
   2002 
   2003   Id = InternalShellGetNodeFromGuid(Guid);
   2004   if (Id != NULL && Id->DumpInfo != NULL) {
   2005     return (Id->DumpInfo(TheHandle, Verbose));
   2006   }
   2007   return (NULL);
   2008 }
   2009 
   2010 /**
   2011   Function to get the Guid for a protocol or struct based on it's string name.
   2012 
   2013   do not modify the returned Guid.
   2014 
   2015   @param[in] Name           The pointer to the string name.
   2016   @param[in] Lang           The pointer to the language code.
   2017   @param[out] Guid          The pointer to the Guid.
   2018 
   2019   @retval EFI_SUCCESS       The operation was sucessful.
   2020 **/
   2021 EFI_STATUS
   2022 EFIAPI
   2023 GetGuidFromStringName(
   2024   IN CONST CHAR16 *Name,
   2025   IN CONST CHAR8  *Lang OPTIONAL,
   2026   OUT EFI_GUID    **Guid
   2027   )
   2028 {
   2029   CONST GUID_INFO_BLOCK  *ListWalker;
   2030   CHAR16                     *String;
   2031   UINTN                  LoopCount;
   2032 
   2033   HandleParsingHiiInit();
   2034 
   2035   ASSERT(Guid != NULL);
   2036   if (Guid == NULL) {
   2037     return (EFI_INVALID_PARAMETER);
   2038   }
   2039   *Guid = NULL;
   2040 
   2041   if (PcdGetBool(PcdShellIncludeNtGuids)) {
   2042     for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
   2043       String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
   2044       if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {
   2045         *Guid = ListWalker->GuidId;
   2046       }
   2047       SHELL_FREE_NON_NULL(String);
   2048       if (*Guid != NULL) {
   2049         return (EFI_SUCCESS);
   2050       }
   2051     }
   2052   }
   2053   for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
   2054     String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
   2055     if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {
   2056       *Guid = ListWalker->GuidId;
   2057     }
   2058     SHELL_FREE_NON_NULL(String);
   2059     if (*Guid != NULL) {
   2060       return (EFI_SUCCESS);
   2061     }
   2062   }
   2063 
   2064   for (LoopCount = 0, ListWalker = GuidList; GuidList != NULL && LoopCount < GuidListCount; LoopCount++, ListWalker++) {
   2065     String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
   2066     if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {
   2067       *Guid = ListWalker->GuidId;
   2068     }
   2069     SHELL_FREE_NON_NULL(String);
   2070     if (*Guid != NULL) {
   2071       return (EFI_SUCCESS);
   2072     }
   2073   }
   2074 
   2075   return (EFI_NOT_FOUND);
   2076 }
   2077 
   2078 /**
   2079   Get best support language for this driver.
   2080 
   2081   First base on the user input language  to search, second base on the current
   2082   platform used language to search, third get the first language from the
   2083   support language list. The caller need to free the buffer of the best language.
   2084 
   2085   @param[in] SupportedLanguages      The support languages for this driver.
   2086   @param[in] InputLanguage           The user input language.
   2087   @param[in] Iso639Language          Whether get language for ISO639.
   2088 
   2089   @return                            The best support language for this driver.
   2090 **/
   2091 CHAR8 *
   2092 EFIAPI
   2093 GetBestLanguageForDriver (
   2094   IN CONST CHAR8  *SupportedLanguages,
   2095   IN CONST CHAR8  *InputLanguage,
   2096   IN BOOLEAN      Iso639Language
   2097   )
   2098 {
   2099   CHAR8                         *LanguageVariable;
   2100   CHAR8                         *BestLanguage;
   2101 
   2102   GetVariable2 (Iso639Language ? L"Lang" : L"PlatformLang", &gEfiGlobalVariableGuid, (VOID**)&LanguageVariable, NULL);
   2103 
   2104   BestLanguage = GetBestLanguage(
   2105                    SupportedLanguages,
   2106                    Iso639Language,
   2107                    (InputLanguage != NULL) ? InputLanguage : "",
   2108                    (LanguageVariable != NULL) ? LanguageVariable : "",
   2109                    SupportedLanguages,
   2110                    NULL
   2111                    );
   2112 
   2113   if (LanguageVariable != NULL) {
   2114     FreePool (LanguageVariable);
   2115   }
   2116 
   2117   return BestLanguage;
   2118 }
   2119 
   2120 /**
   2121   Function to retrieve the driver name (if possible) from the ComponentName or
   2122   ComponentName2 protocol
   2123 
   2124   @param[in] TheHandle      The driver handle to get the name of.
   2125   @param[in] Language       The language to use.
   2126 
   2127   @retval NULL              The name could not be found.
   2128   @return                   A pointer to the string name.  Do not de-allocate the memory.
   2129 **/
   2130 CONST CHAR16*
   2131 EFIAPI
   2132 GetStringNameFromHandle(
   2133   IN CONST EFI_HANDLE TheHandle,
   2134   IN CONST CHAR8      *Language
   2135   )
   2136 {
   2137   EFI_COMPONENT_NAME2_PROTOCOL  *CompNameStruct;
   2138   EFI_STATUS                    Status;
   2139   CHAR16                        *RetVal;
   2140   CHAR8                         *BestLang;
   2141 
   2142   BestLang = NULL;
   2143 
   2144   Status = gBS->OpenProtocol(
   2145     TheHandle,
   2146     &gEfiComponentName2ProtocolGuid,
   2147     (VOID**)&CompNameStruct,
   2148     gImageHandle,
   2149     NULL,
   2150     EFI_OPEN_PROTOCOL_GET_PROTOCOL);
   2151   if (!EFI_ERROR(Status)) {
   2152     BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);
   2153     Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);
   2154     if (BestLang != NULL) {
   2155       FreePool (BestLang);
   2156       BestLang = NULL;
   2157     }
   2158     if (!EFI_ERROR(Status)) {
   2159       return (RetVal);
   2160     }
   2161   }
   2162   Status = gBS->OpenProtocol(
   2163     TheHandle,
   2164     &gEfiComponentNameProtocolGuid,
   2165     (VOID**)&CompNameStruct,
   2166     gImageHandle,
   2167     NULL,
   2168     EFI_OPEN_PROTOCOL_GET_PROTOCOL);
   2169   if (!EFI_ERROR(Status)) {
   2170     BestLang = GetBestLanguageForDriver (CompNameStruct->SupportedLanguages, Language, FALSE);
   2171     Status = CompNameStruct->GetDriverName(CompNameStruct, BestLang, &RetVal);
   2172     if (BestLang != NULL) {
   2173       FreePool (BestLang);
   2174     }
   2175     if (!EFI_ERROR(Status)) {
   2176       return (RetVal);
   2177     }
   2178   }
   2179   return (NULL);
   2180 }
   2181 
   2182 /**
   2183   Function to initialize the file global mHandleList object for use in
   2184   vonverting handles to index and index to handle.
   2185 
   2186   @retval EFI_SUCCESS     The operation was successful.
   2187 **/
   2188 EFI_STATUS
   2189 InternalShellInitHandleList(
   2190   VOID
   2191   )
   2192 {
   2193   EFI_STATUS   Status;
   2194   EFI_HANDLE   *HandleBuffer;
   2195   UINTN        HandleCount;
   2196   HANDLE_LIST  *ListWalker;
   2197 
   2198   if (mHandleList.NextIndex != 0) {
   2199     return EFI_SUCCESS;
   2200   }
   2201   InitializeListHead(&mHandleList.List.Link);
   2202   mHandleList.NextIndex = 1;
   2203   Status = gBS->LocateHandleBuffer (
   2204                 AllHandles,
   2205                 NULL,
   2206                 NULL,
   2207                 &HandleCount,
   2208                 &HandleBuffer
   2209                );
   2210   ASSERT_EFI_ERROR(Status);
   2211   if (EFI_ERROR(Status)) {
   2212     return (Status);
   2213   }
   2214   for (mHandleList.NextIndex = 1 ; mHandleList.NextIndex <= HandleCount ; mHandleList.NextIndex++){
   2215     ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));
   2216     if (ListWalker != NULL) {
   2217       ListWalker->TheHandle = HandleBuffer[mHandleList.NextIndex - 1];
   2218       ListWalker->TheIndex = mHandleList.NextIndex;
   2219       InsertTailList (&mHandleList.List.Link, &ListWalker->Link);
   2220     }
   2221   }
   2222   FreePool(HandleBuffer);
   2223   return (EFI_SUCCESS);
   2224 }
   2225 
   2226 /**
   2227   Function to retrieve the human-friendly index of a given handle.  If the handle
   2228   does not have a index one will be automatically assigned.  The index value is valid
   2229   until the termination of the shell application.
   2230 
   2231   @param[in] TheHandle    The handle to retrieve an index for.
   2232 
   2233   @retval 0               A memory allocation failed.
   2234   @return                 The index of the handle.
   2235 
   2236 **/
   2237 UINTN
   2238 EFIAPI
   2239 ConvertHandleToHandleIndex(
   2240   IN CONST EFI_HANDLE TheHandle
   2241   )
   2242 {
   2243   EFI_STATUS   Status;
   2244   EFI_GUID     **ProtocolBuffer;
   2245   UINTN        ProtocolCount;
   2246   HANDLE_LIST  *ListWalker;
   2247 
   2248   if (TheHandle == NULL) {
   2249     return 0;
   2250   }
   2251 
   2252   InternalShellInitHandleList();
   2253 
   2254   for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)
   2255     ;  !IsNull(&mHandleList.List.Link,&ListWalker->Link)
   2256     ;  ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)
   2257    ){
   2258     if (ListWalker->TheHandle == TheHandle) {
   2259       //
   2260       // Verify that TheHandle is still present in the Handle Database
   2261       //
   2262       Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);
   2263       if (EFI_ERROR (Status)) {
   2264         //
   2265         // TheHandle is not present in the Handle Database, so delete from the handle list
   2266         //
   2267         RemoveEntryList (&ListWalker->Link);
   2268         return 0;
   2269       }
   2270       FreePool (ProtocolBuffer);
   2271       return (ListWalker->TheIndex);
   2272     }
   2273   }
   2274 
   2275   //
   2276   // Verify that TheHandle is valid handle
   2277   //
   2278   Status = gBS->ProtocolsPerHandle(TheHandle, &ProtocolBuffer, &ProtocolCount);
   2279   if (EFI_ERROR (Status)) {
   2280     //
   2281     // TheHandle is not valid, so do not add to handle list
   2282     //
   2283     return 0;
   2284   }
   2285   FreePool (ProtocolBuffer);
   2286 
   2287   ListWalker = AllocateZeroPool(sizeof(HANDLE_LIST));
   2288   if (ListWalker == NULL) {
   2289     return 0;
   2290   }
   2291   ListWalker->TheHandle = TheHandle;
   2292   ListWalker->TheIndex  = mHandleList.NextIndex++;
   2293   InsertTailList(&mHandleList.List.Link,&ListWalker->Link);
   2294   return (ListWalker->TheIndex);
   2295 }
   2296 
   2297 
   2298 
   2299 /**
   2300   Function to retrieve the EFI_HANDLE from the human-friendly index.
   2301 
   2302   @param[in] TheIndex     The index to retrieve the EFI_HANDLE for.
   2303 
   2304   @retval NULL            The index was invalid.
   2305   @return                 The EFI_HANDLE that index represents.
   2306 
   2307 **/
   2308 EFI_HANDLE
   2309 EFIAPI
   2310 ConvertHandleIndexToHandle(
   2311   IN CONST UINTN TheIndex
   2312   )
   2313 {
   2314   EFI_STATUS   Status;
   2315   EFI_GUID     **ProtocolBuffer;
   2316   UINTN        ProtocolCount;
   2317   HANDLE_LIST *ListWalker;
   2318 
   2319   InternalShellInitHandleList();
   2320 
   2321   if (TheIndex >= mHandleList.NextIndex) {
   2322     return NULL;
   2323   }
   2324 
   2325   for (ListWalker = (HANDLE_LIST*)GetFirstNode(&mHandleList.List.Link)
   2326     ;  !IsNull(&mHandleList.List.Link,&ListWalker->Link)
   2327     ;  ListWalker = (HANDLE_LIST*)GetNextNode(&mHandleList.List.Link,&ListWalker->Link)
   2328    ){
   2329     if (ListWalker->TheIndex == TheIndex && ListWalker->TheHandle != NULL) {
   2330       //
   2331       // Verify that LinkWalker->TheHandle is valid handle
   2332       //
   2333       Status = gBS->ProtocolsPerHandle(ListWalker->TheHandle, &ProtocolBuffer, &ProtocolCount);
   2334       if (EFI_ERROR (Status)) {
   2335         //
   2336         // TheHandle is not valid, so do not add to handle list
   2337         //
   2338         ListWalker->TheHandle = NULL;
   2339       }
   2340       return (ListWalker->TheHandle);
   2341     }
   2342   }
   2343   return NULL;
   2344 }
   2345 
   2346 /**
   2347   Gets all the related EFI_HANDLEs based on the mask supplied.
   2348 
   2349   This function scans all EFI_HANDLES in the UEFI environment's handle database
   2350   and returns the ones with the specified relationship (Mask) to the specified
   2351   controller handle.
   2352 
   2353   If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
   2354   If MatchingHandleCount is NULL, then ASSERT.
   2355 
   2356   If MatchingHandleBuffer is not NULL upon a successful return the memory must be
   2357   caller freed.
   2358 
   2359   @param[in] DriverBindingHandle    The handle with Driver Binding protocol on it.
   2360   @param[in] ControllerHandle       The handle with Device Path protocol on it.
   2361   @param[in] MatchingHandleCount    The pointer to UINTN that specifies the number of HANDLES in
   2362                                     MatchingHandleBuffer.
   2363   @param[out] MatchingHandleBuffer  On a successful return, a buffer of MatchingHandleCount
   2364                                     EFI_HANDLEs with a terminating NULL EFI_HANDLE.
   2365   @param[out] HandleType            An array of type information.
   2366 
   2367   @retval EFI_SUCCESS               The operation was successful, and any related handles
   2368                                     are in MatchingHandleBuffer.
   2369   @retval EFI_NOT_FOUND             No matching handles were found.
   2370   @retval EFI_INVALID_PARAMETER     A parameter was invalid or out of range.
   2371 **/
   2372 EFI_STATUS
   2373 EFIAPI
   2374 ParseHandleDatabaseByRelationshipWithType (
   2375   IN CONST EFI_HANDLE DriverBindingHandle OPTIONAL,
   2376   IN CONST EFI_HANDLE ControllerHandle OPTIONAL,
   2377   IN UINTN            *HandleCount,
   2378   OUT EFI_HANDLE      **HandleBuffer,
   2379   OUT UINTN           **HandleType
   2380   )
   2381 {
   2382   EFI_STATUS                          Status;
   2383   UINTN                               HandleIndex;
   2384   EFI_GUID                            **ProtocolGuidArray;
   2385   UINTN                               ArrayCount;
   2386   UINTN                               ProtocolIndex;
   2387   EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
   2388   UINTN                               OpenInfoCount;
   2389   UINTN                               OpenInfoIndex;
   2390   UINTN                               ChildIndex;
   2391   INTN                                DriverBindingHandleIndex;
   2392 
   2393   ASSERT(HandleCount  != NULL);
   2394   ASSERT(HandleBuffer != NULL);
   2395   ASSERT(HandleType   != NULL);
   2396   ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);
   2397 
   2398   *HandleCount                  = 0;
   2399   *HandleBuffer                 = NULL;
   2400   *HandleType                   = NULL;
   2401 
   2402   //
   2403   // Retrieve the list of all handles from the handle database
   2404   //
   2405   Status = gBS->LocateHandleBuffer (
   2406                 AllHandles,
   2407                 NULL,
   2408                 NULL,
   2409                 HandleCount,
   2410                 HandleBuffer
   2411                );
   2412   if (EFI_ERROR (Status)) {
   2413     return (Status);
   2414   }
   2415 
   2416   *HandleType = AllocateZeroPool (*HandleCount * sizeof (UINTN));
   2417   if (*HandleType == NULL) {
   2418     SHELL_FREE_NON_NULL (*HandleBuffer);
   2419     *HandleCount = 0;
   2420     return EFI_OUT_OF_RESOURCES;
   2421   }
   2422 
   2423   DriverBindingHandleIndex = -1;
   2424   for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
   2425     if (DriverBindingHandle != NULL && (*HandleBuffer)[HandleIndex] == DriverBindingHandle) {
   2426       DriverBindingHandleIndex = (INTN)HandleIndex;
   2427     }
   2428   }
   2429 
   2430   for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {
   2431     //
   2432     // Retrieve the list of all the protocols on each handle
   2433     //
   2434     Status = gBS->ProtocolsPerHandle (
   2435                   (*HandleBuffer)[HandleIndex],
   2436                   &ProtocolGuidArray,
   2437                   &ArrayCount
   2438                  );
   2439     if (EFI_ERROR (Status)) {
   2440       continue;
   2441     }
   2442 
   2443     for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
   2444 
   2445       //
   2446       // Set the bit describing what this handle has
   2447       //
   2448       if        (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid)         ) {
   2449         (*HandleType)[HandleIndex] |= (UINTN)HR_IMAGE_HANDLE;
   2450       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid)       ) {
   2451         (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_BINDING_HANDLE;
   2452       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfiguration2ProtocolGuid)) {
   2453         (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_CONFIGURATION_HANDLE;
   2454       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid) ) {
   2455         (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_CONFIGURATION_HANDLE;
   2456       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnostics2ProtocolGuid)  ) {
   2457         (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_DIAGNOSTICS_HANDLE;
   2458       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid)   ) {
   2459         (*HandleType)[HandleIndex] |= (UINTN)HR_DRIVER_DIAGNOSTICS_HANDLE;
   2460       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentName2ProtocolGuid)      ) {
   2461         (*HandleType)[HandleIndex] |= (UINTN)HR_COMPONENT_NAME_HANDLE;
   2462       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid)       ) {
   2463         (*HandleType)[HandleIndex] |= (UINTN)HR_COMPONENT_NAME_HANDLE;
   2464       } else if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid)          ) {
   2465         (*HandleType)[HandleIndex] |= (UINTN)HR_DEVICE_HANDLE;
   2466       }
   2467       //
   2468       // Retrieve the list of agents that have opened each protocol
   2469       //
   2470       Status = gBS->OpenProtocolInformation (
   2471                       (*HandleBuffer)[HandleIndex],
   2472                       ProtocolGuidArray[ProtocolIndex],
   2473                       &OpenInfo,
   2474                       &OpenInfoCount
   2475                      );
   2476       if (EFI_ERROR (Status)) {
   2477         continue;
   2478       }
   2479 
   2480       if (ControllerHandle == NULL) {
   2481         //
   2482         // ControllerHandle == NULL and DriverBindingHandle != NULL.
   2483         // Return information on all the controller handles that the driver specified by DriverBindingHandle is managing
   2484         //
   2485         for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
   2486           if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
   2487             (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
   2488             if (DriverBindingHandleIndex != -1) {
   2489               (*HandleType)[DriverBindingHandleIndex] |= (UINTN)HR_DEVICE_DRIVER;
   2490             }
   2491           }
   2492           if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle && (OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
   2493             (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
   2494             if (DriverBindingHandleIndex != -1) {
   2495               (*HandleType)[DriverBindingHandleIndex] |= (UINTN)(HR_BUS_DRIVER | HR_DEVICE_DRIVER);
   2496             }
   2497             for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
   2498               if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
   2499                 (*HandleType)[ChildIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
   2500               }
   2501             }
   2502           }
   2503         }
   2504       }
   2505       if (DriverBindingHandle == NULL && ControllerHandle != NULL) {
   2506         if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {
   2507           (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
   2508           for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
   2509             if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
   2510               for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
   2511                 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
   2512                   (*HandleType)[ChildIndex] |= (UINTN)HR_DEVICE_DRIVER;
   2513                 }
   2514               }
   2515             }
   2516             if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
   2517               for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
   2518                 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
   2519                   (*HandleType)[ChildIndex] |= (UINTN)(HR_BUS_DRIVER | HR_DEVICE_DRIVER);
   2520                 }
   2521                 if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
   2522                   (*HandleType)[ChildIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
   2523                 }
   2524               }
   2525             }
   2526           }
   2527         } else {
   2528           for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
   2529             if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
   2530               if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
   2531                 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_PARENT_HANDLE);
   2532               }
   2533             }
   2534           }
   2535         }
   2536       }
   2537       if (DriverBindingHandle != NULL && ControllerHandle != NULL) {
   2538         if (ControllerHandle == (*HandleBuffer)[HandleIndex]) {
   2539           (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CONTROLLER_HANDLE);
   2540           for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
   2541             if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
   2542               if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
   2543                 if (DriverBindingHandleIndex != -1) {
   2544                   (*HandleType)[DriverBindingHandleIndex] |= (UINTN)HR_DEVICE_DRIVER;
   2545                 }
   2546               }
   2547             }
   2548             if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
   2549               if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
   2550                 for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
   2551                   if (OpenInfo[OpenInfoIndex].ControllerHandle == (*HandleBuffer)[ChildIndex]) {
   2552                     (*HandleType)[ChildIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_CHILD_HANDLE);
   2553                   }
   2554                 }
   2555               }
   2556 
   2557               for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) {
   2558                 if (OpenInfo[OpenInfoIndex].AgentHandle == (*HandleBuffer)[ChildIndex]) {
   2559                   (*HandleType)[ChildIndex] |= (UINTN)(HR_BUS_DRIVER | HR_DEVICE_DRIVER);
   2560                 }
   2561               }
   2562             }
   2563           }
   2564         } else {
   2565           for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
   2566             if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
   2567               if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
   2568                 (*HandleType)[HandleIndex] |= (UINTN)(HR_DEVICE_HANDLE | HR_PARENT_HANDLE);
   2569               }
   2570             }
   2571           }
   2572         }
   2573       }
   2574       FreePool (OpenInfo);
   2575     }
   2576     FreePool (ProtocolGuidArray);
   2577   }
   2578   return EFI_SUCCESS;
   2579 }
   2580 
   2581 /**
   2582   Gets all the related EFI_HANDLEs based on the single EFI_HANDLE and the mask
   2583   supplied.
   2584 
   2585   This function will scan all EFI_HANDLES in the UEFI environment's handle database
   2586   and return all the ones with the specified relationship (Mask) to the specified
   2587   controller handle.
   2588 
   2589   If both DriverBindingHandle and ControllerHandle are NULL, then ASSERT.
   2590   If MatchingHandleCount is NULL, then ASSERT.
   2591 
   2592   If MatchingHandleBuffer is not NULL upon a sucessful return the memory must be
   2593   caller freed.
   2594 
   2595   @param[in] DriverBindingHandle    Handle to a object with Driver Binding protocol
   2596                                     on it.
   2597   @param[in] ControllerHandle       Handle to a device with Device Path protocol on it.
   2598   @param[in] Mask                   Mask of what relationship(s) is desired.
   2599   @param[in] MatchingHandleCount    Poitner to UINTN specifying number of HANDLES in
   2600                                     MatchingHandleBuffer.
   2601   @param[out] MatchingHandleBuffer  On a sucessful return a buffer of MatchingHandleCount
   2602                                     EFI_HANDLEs and a terminating NULL EFI_HANDLE.
   2603 
   2604   @retval EFI_SUCCESS               The operation was sucessful and any related handles
   2605                                     are in MatchingHandleBuffer;
   2606   @retval EFI_NOT_FOUND             No matching handles were found.
   2607   @retval EFI_INVALID_PARAMETER     A parameter was invalid or out of range.
   2608 **/
   2609 EFI_STATUS
   2610 EFIAPI
   2611 ParseHandleDatabaseByRelationship (
   2612   IN CONST EFI_HANDLE       DriverBindingHandle OPTIONAL,
   2613   IN CONST EFI_HANDLE       ControllerHandle OPTIONAL,
   2614   IN CONST UINTN            Mask,
   2615   IN UINTN                  *MatchingHandleCount,
   2616   OUT EFI_HANDLE            **MatchingHandleBuffer OPTIONAL
   2617   )
   2618 {
   2619   EFI_STATUS            Status;
   2620   UINTN                 HandleCount;
   2621   EFI_HANDLE            *HandleBuffer;
   2622   UINTN                 *HandleType;
   2623   UINTN                 HandleIndex;
   2624 
   2625   ASSERT(MatchingHandleCount != NULL);
   2626   ASSERT(DriverBindingHandle != NULL || ControllerHandle != NULL);
   2627 
   2628   if ((Mask & HR_VALID_MASK) != Mask) {
   2629     return (EFI_INVALID_PARAMETER);
   2630   }
   2631 
   2632   if ((Mask & HR_CHILD_HANDLE) != 0 && DriverBindingHandle == NULL) {
   2633     return (EFI_INVALID_PARAMETER);
   2634   }
   2635 
   2636   *MatchingHandleCount = 0;
   2637   if (MatchingHandleBuffer != NULL) {
   2638     *MatchingHandleBuffer = NULL;
   2639   }
   2640 
   2641   HandleBuffer  = NULL;
   2642   HandleType    = NULL;
   2643 
   2644   Status = ParseHandleDatabaseByRelationshipWithType (
   2645             DriverBindingHandle,
   2646             ControllerHandle,
   2647             &HandleCount,
   2648             &HandleBuffer,
   2649             &HandleType
   2650            );
   2651   if (!EFI_ERROR (Status)) {
   2652     //
   2653     // Count the number of handles that match the attributes in Mask
   2654     //
   2655     for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
   2656       if ((HandleType[HandleIndex] & Mask) == Mask) {
   2657         (*MatchingHandleCount)++;
   2658       }
   2659     }
   2660     //
   2661     // If no handles match the attributes in Mask then return EFI_NOT_FOUND
   2662     //
   2663     if (*MatchingHandleCount == 0) {
   2664       Status = EFI_NOT_FOUND;
   2665     } else {
   2666 
   2667       if (MatchingHandleBuffer == NULL) {
   2668         //
   2669         // Someone just wanted the count...
   2670         //
   2671         Status = EFI_SUCCESS;
   2672       } else {
   2673         //
   2674         // Allocate a handle buffer for the number of handles that matched the attributes in Mask
   2675         //
   2676         *MatchingHandleBuffer = AllocateZeroPool ((*MatchingHandleCount +1)* sizeof (EFI_HANDLE));
   2677         if (*MatchingHandleBuffer == NULL) {
   2678           Status = EFI_OUT_OF_RESOURCES;
   2679         } else {
   2680           for (HandleIndex = 0, *MatchingHandleCount = 0
   2681                ;  HandleIndex < HandleCount
   2682                ;  HandleIndex++
   2683                ) {
   2684             //
   2685             // Fill the allocated buffer with the handles that matched the attributes in Mask
   2686             //
   2687             if ((HandleType[HandleIndex] & Mask) == Mask) {
   2688               (*MatchingHandleBuffer)[(*MatchingHandleCount)++] = HandleBuffer[HandleIndex];
   2689             }
   2690           }
   2691 
   2692           //
   2693           // Make the last one NULL
   2694           //
   2695           (*MatchingHandleBuffer)[*MatchingHandleCount] = NULL;
   2696 
   2697           Status = EFI_SUCCESS;
   2698         } // *MatchingHandleBuffer == NULL (ELSE)
   2699       } // MacthingHandleBuffer == NULL (ELSE)
   2700     } // *MatchingHandleCount  == 0 (ELSE)
   2701   } // no error on ParseHandleDatabaseByRelationshipWithType
   2702 
   2703   if (HandleBuffer != NULL) {
   2704     FreePool (HandleBuffer);
   2705   }
   2706 
   2707   if (HandleType != NULL) {
   2708     FreePool (HandleType);
   2709   }
   2710 
   2711   ASSERT ((MatchingHandleBuffer == NULL) ||
   2712           (*MatchingHandleCount == 0 && *MatchingHandleBuffer == NULL) ||
   2713           (*MatchingHandleCount != 0 && *MatchingHandleBuffer != NULL));
   2714   return Status;
   2715 }
   2716 
   2717 /**
   2718   Gets handles for any child controllers of the passed in controller.
   2719 
   2720   @param[in] ControllerHandle       The handle of the "parent controller"
   2721   @param[out] MatchingHandleCount   Pointer to the number of handles in
   2722                                     MatchingHandleBuffer on return.
   2723   @param[out] MatchingHandleBuffer  Buffer containing handles on a successful
   2724                                     return.
   2725 
   2726 
   2727   @retval EFI_SUCCESS               The operation was sucessful.
   2728 **/
   2729 EFI_STATUS
   2730 EFIAPI
   2731 ParseHandleDatabaseForChildControllers(
   2732   IN CONST EFI_HANDLE       ControllerHandle,
   2733   OUT UINTN                 *MatchingHandleCount,
   2734   OUT EFI_HANDLE            **MatchingHandleBuffer OPTIONAL
   2735   )
   2736 {
   2737   EFI_STATUS  Status;
   2738   UINTN       HandleIndex;
   2739   UINTN       DriverBindingHandleCount;
   2740   EFI_HANDLE  *DriverBindingHandleBuffer;
   2741   UINTN       DriverBindingHandleIndex;
   2742   UINTN       ChildControllerHandleCount;
   2743   EFI_HANDLE  *ChildControllerHandleBuffer;
   2744   UINTN       ChildControllerHandleIndex;
   2745   EFI_HANDLE  *HandleBufferForReturn;
   2746 
   2747   if (MatchingHandleCount == NULL) {
   2748     return (EFI_INVALID_PARAMETER);
   2749   }
   2750   *MatchingHandleCount = 0;
   2751 
   2752   Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
   2753             ControllerHandle,
   2754             &DriverBindingHandleCount,
   2755             &DriverBindingHandleBuffer
   2756            );
   2757   if (EFI_ERROR (Status)) {
   2758     return Status;
   2759   }
   2760 
   2761   //
   2762   // Get a buffer big enough for all the controllers.
   2763   //
   2764   HandleBufferForReturn = GetHandleListByProtocol(NULL);
   2765   if (HandleBufferForReturn == NULL) {
   2766     FreePool (DriverBindingHandleBuffer);
   2767     return (EFI_NOT_FOUND);
   2768   }
   2769 
   2770   for (DriverBindingHandleIndex = 0; DriverBindingHandleIndex < DriverBindingHandleCount; DriverBindingHandleIndex++) {
   2771     Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
   2772               DriverBindingHandleBuffer[DriverBindingHandleIndex],
   2773               ControllerHandle,
   2774               &ChildControllerHandleCount,
   2775               &ChildControllerHandleBuffer
   2776              );
   2777     if (EFI_ERROR (Status)) {
   2778       continue;
   2779     }
   2780 
   2781     for (ChildControllerHandleIndex = 0;
   2782          ChildControllerHandleIndex < ChildControllerHandleCount;
   2783          ChildControllerHandleIndex++
   2784        ) {
   2785       for (HandleIndex = 0; HandleIndex < *MatchingHandleCount; HandleIndex++) {
   2786         if (HandleBufferForReturn[HandleIndex] == ChildControllerHandleBuffer[ChildControllerHandleIndex]) {
   2787           break;
   2788         }
   2789       }
   2790       if (HandleIndex >= *MatchingHandleCount) {
   2791         HandleBufferForReturn[(*MatchingHandleCount)++] = ChildControllerHandleBuffer[ChildControllerHandleIndex];
   2792       }
   2793     }
   2794 
   2795     FreePool (ChildControllerHandleBuffer);
   2796   }
   2797 
   2798   FreePool (DriverBindingHandleBuffer);
   2799 
   2800   if (MatchingHandleBuffer == NULL || *MatchingHandleCount == 0) {
   2801     //
   2802     // The caller is not interested in the actual handles, or we've found none.
   2803     //
   2804     FreePool (HandleBufferForReturn);
   2805     HandleBufferForReturn = NULL;
   2806   }
   2807 
   2808   if (MatchingHandleBuffer != NULL) {
   2809     *MatchingHandleBuffer = HandleBufferForReturn;
   2810   }
   2811 
   2812   ASSERT ((MatchingHandleBuffer == NULL) ||
   2813           (*MatchingHandleCount == 0 && *MatchingHandleBuffer == NULL) ||
   2814           (*MatchingHandleCount != 0 && *MatchingHandleBuffer != NULL));
   2815 
   2816   return (EFI_SUCCESS);
   2817 }
   2818 
   2819 /**
   2820   Appends 1 buffer to another buffer.  This will re-allocate the destination buffer
   2821   if necessary to fit all of the data.
   2822 
   2823   If DestinationBuffer is NULL, then ASSERT().
   2824 
   2825   @param[in, out]  DestinationBuffer The pointer to the pointer to the buffer to append onto.
   2826   @param[in, out]  DestinationSize   The pointer to the size of DestinationBuffer.
   2827   @param[in]       SourceBuffer      The pointer to the buffer to append onto DestinationBuffer.
   2828   @param[in]       SourceSize        The number of bytes of SourceBuffer to append.
   2829 
   2830   @retval NULL                      A memory allocation failed.
   2831   @retval NULL                      A parameter was invalid.
   2832   @return                           A pointer to (*DestinationBuffer).
   2833 **/
   2834 VOID*
   2835 BuffernCatGrow (
   2836   IN OUT VOID   **DestinationBuffer,
   2837   IN OUT UINTN  *DestinationSize,
   2838   IN     VOID   *SourceBuffer,
   2839   IN     UINTN  SourceSize
   2840   )
   2841 {
   2842   UINTN LocalDestinationSize;
   2843   UINTN LocalDestinationFinalSize;
   2844 
   2845   ASSERT(DestinationBuffer != NULL);
   2846 
   2847   if (SourceSize == 0 || SourceBuffer == NULL) {
   2848     return (*DestinationBuffer);
   2849   }
   2850 
   2851   if (DestinationSize == NULL) {
   2852     LocalDestinationSize = 0;
   2853   } else {
   2854     LocalDestinationSize = *DestinationSize;
   2855   }
   2856 
   2857   LocalDestinationFinalSize = LocalDestinationSize + SourceSize;
   2858 
   2859   if (DestinationSize != NULL) {
   2860     *DestinationSize = LocalDestinationSize;
   2861   }
   2862 
   2863   if (LocalDestinationSize == 0) {
   2864     // allcoate
   2865     *DestinationBuffer = AllocateZeroPool(LocalDestinationFinalSize);
   2866   } else {
   2867     // reallocate
   2868     *DestinationBuffer = ReallocatePool(LocalDestinationSize, LocalDestinationFinalSize, *DestinationBuffer);
   2869   }
   2870 
   2871   ASSERT(*DestinationBuffer != NULL);
   2872 
   2873   // copy
   2874   return (CopyMem(((UINT8*)(*DestinationBuffer)) + LocalDestinationSize, SourceBuffer, SourceSize));
   2875 }
   2876 
   2877 /**
   2878   Gets handles for any child devices produced by the passed in driver.
   2879 
   2880   @param[in] DriverHandle           The handle of the driver.
   2881   @param[in] MatchingHandleCount    Pointer to the number of handles in
   2882                                     MatchingHandleBuffer on return.
   2883   @param[out] MatchingHandleBuffer  Buffer containing handles on a successful
   2884                                     return.
   2885   @retval EFI_SUCCESS               The operation was sucessful.
   2886   @sa ParseHandleDatabaseByRelationship
   2887 **/
   2888 EFI_STATUS
   2889 EFIAPI
   2890 ParseHandleDatabaseForChildDevices(
   2891   IN CONST EFI_HANDLE       DriverHandle,
   2892   IN UINTN                  *MatchingHandleCount,
   2893   OUT EFI_HANDLE            **MatchingHandleBuffer OPTIONAL
   2894   )
   2895 {
   2896   EFI_HANDLE      *Buffer;
   2897   EFI_HANDLE      *Buffer2;
   2898   UINTN           Count1;
   2899   UINTN           Count2;
   2900   UINTN           HandleIndex;
   2901   EFI_STATUS      Status;
   2902   UINTN           HandleBufferSize;
   2903 
   2904   ASSERT(MatchingHandleCount != NULL);
   2905 
   2906   HandleBufferSize      = 0;
   2907   Buffer                = NULL;
   2908   Buffer2               = NULL;
   2909   *MatchingHandleCount  = 0;
   2910 
   2911   Status = PARSE_HANDLE_DATABASE_DEVICES (
   2912             DriverHandle,
   2913             &Count1,
   2914             &Buffer
   2915            );
   2916   if (!EFI_ERROR (Status)) {
   2917     for (HandleIndex = 0; HandleIndex < Count1; HandleIndex++) {
   2918       //
   2919       // now find the children
   2920       //
   2921       Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
   2922                 DriverHandle,
   2923                 Buffer[HandleIndex],
   2924                 &Count2,
   2925                 &Buffer2
   2926                );
   2927       if (EFI_ERROR(Status)) {
   2928         break;
   2929       }
   2930       //
   2931       // save out required and optional data elements
   2932       //
   2933       *MatchingHandleCount += Count2;
   2934       if (MatchingHandleBuffer != NULL) {
   2935         *MatchingHandleBuffer = BuffernCatGrow((VOID**)MatchingHandleBuffer, &HandleBufferSize, Buffer2, Count2 * sizeof(Buffer2[0]));
   2936       }
   2937 
   2938       //
   2939       // free the memory
   2940       //
   2941       if (Buffer2 != NULL) {
   2942         FreePool(Buffer2);
   2943       }
   2944     }
   2945   }
   2946 
   2947   if (Buffer != NULL) {
   2948     FreePool(Buffer);
   2949   }
   2950   return (Status);
   2951 }
   2952 
   2953 /**
   2954   Function to get all handles that support a given protocol or all handles.
   2955 
   2956   @param[in] ProtocolGuid The guid of the protocol to get handles for.  If NULL
   2957                           then the function will return all handles.
   2958 
   2959   @retval NULL            A memory allocation failed.
   2960   @return                 A NULL terminated list of handles.
   2961 **/
   2962 EFI_HANDLE*
   2963 EFIAPI
   2964 GetHandleListByProtocol (
   2965   IN CONST EFI_GUID *ProtocolGuid OPTIONAL
   2966   )
   2967 {
   2968   EFI_HANDLE          *HandleList;
   2969   UINTN               Size;
   2970   EFI_STATUS          Status;
   2971 
   2972   Size = 0;
   2973   HandleList = NULL;
   2974 
   2975   //
   2976   // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list!
   2977   //
   2978   if (ProtocolGuid == NULL) {
   2979     Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);
   2980     if (Status == EFI_BUFFER_TOO_SMALL) {
   2981       HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));
   2982       if (HandleList == NULL) {
   2983         return (NULL);
   2984       }
   2985       Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList);
   2986       HandleList[Size/sizeof(EFI_HANDLE)] = NULL;
   2987     }
   2988   } else {
   2989     Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);
   2990     if (Status == EFI_BUFFER_TOO_SMALL) {
   2991       HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE));
   2992       if (HandleList == NULL) {
   2993         return (NULL);
   2994       }
   2995       Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList);
   2996       HandleList[Size/sizeof(EFI_HANDLE)] = NULL;
   2997     }
   2998   }
   2999   if (EFI_ERROR(Status)) {
   3000     if (HandleList != NULL) {
   3001       FreePool(HandleList);
   3002     }
   3003     return (NULL);
   3004   }
   3005   return (HandleList);
   3006 }
   3007 
   3008 /**
   3009   Function to get all handles that support some protocols.
   3010 
   3011   @param[in] ProtocolGuids  A NULL terminated list of protocol GUIDs.
   3012 
   3013   @retval NULL              A memory allocation failed.
   3014   @retval NULL              ProtocolGuids was NULL.
   3015   @return                   A NULL terminated list of EFI_HANDLEs.
   3016 **/
   3017 EFI_HANDLE*
   3018 EFIAPI
   3019 GetHandleListByProtocolList (
   3020   IN CONST EFI_GUID **ProtocolGuids
   3021   )
   3022 {
   3023   EFI_HANDLE          *HandleList;
   3024   UINTN               Size;
   3025   UINTN               TotalSize;
   3026   UINTN               TempSize;
   3027   EFI_STATUS          Status;
   3028   CONST EFI_GUID      **GuidWalker;
   3029   EFI_HANDLE          *HandleWalker1;
   3030   EFI_HANDLE          *HandleWalker2;
   3031 
   3032   Size        = 0;
   3033   HandleList  = NULL;
   3034   TotalSize   = sizeof(EFI_HANDLE);
   3035 
   3036   for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++,Size = 0){
   3037     Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &Size, NULL);
   3038     if (Status == EFI_BUFFER_TOO_SMALL) {
   3039       TotalSize += Size;
   3040     }
   3041   }
   3042 
   3043   //
   3044   // No handles were found...
   3045   //
   3046   if (TotalSize == sizeof(EFI_HANDLE)) {
   3047     return (NULL);
   3048   }
   3049 
   3050   HandleList = AllocateZeroPool(TotalSize);
   3051   if (HandleList == NULL) {
   3052     return (NULL);
   3053   }
   3054 
   3055   Size = 0;
   3056   for (GuidWalker = ProtocolGuids ; GuidWalker != NULL && *GuidWalker != NULL ; GuidWalker++){
   3057     TempSize = TotalSize - Size;
   3058     Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)(*GuidWalker), NULL, &TempSize, HandleList+(Size/sizeof(EFI_HANDLE)));
   3059 
   3060     //
   3061     // Allow for missing protocols... Only update the 'used' size upon success.
   3062     //
   3063     if (!EFI_ERROR(Status)) {
   3064       Size += TempSize;
   3065     }
   3066   }
   3067   ASSERT(HandleList[(TotalSize/sizeof(EFI_HANDLE))-1] == NULL);
   3068 
   3069   for (HandleWalker1 = HandleList ; HandleWalker1 != NULL && *HandleWalker1 != NULL ; HandleWalker1++) {
   3070     for (HandleWalker2 = HandleWalker1 + 1; HandleWalker2 != NULL && *HandleWalker2 != NULL ; HandleWalker2++) {
   3071       if (*HandleWalker1 == *HandleWalker2) {
   3072         //
   3073         // copy memory back 1 handle width.
   3074         //
   3075         CopyMem(HandleWalker2, HandleWalker2 + 1, TotalSize - ((HandleWalker2-HandleList+1)*sizeof(EFI_HANDLE)));
   3076       }
   3077     }
   3078   }
   3079 
   3080   return (HandleList);
   3081 }
   3082