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