Home | History | Annotate | Download | only in UefiShellDriver1CommandsLib
      1 /** @file
      2   Main file for Dh shell Driver1 function.
      3 
      4   (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
      5   Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
      6   This program and the accompanying materials
      7   are licensed and made available under the terms and conditions of the BSD License
      8   which accompanies this distribution.  The full text of the license may be found at
      9   http://opensource.org/licenses/bsd-license.php
     10 
     11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #include "UefiShellDriver1CommandsLib.h"
     17 
     18 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
     19   {L"-p", TypeValue},
     20   {L"-d", TypeFlag},
     21   {L"-v", TypeFlag},
     22   {L"-verbose", TypeFlag},
     23   {L"-sfo", TypeFlag},
     24   {L"-l", TypeValue},
     25   {NULL, TypeMax}
     26   };
     27 
     28 STATIC CONST EFI_GUID *UefiDriverModelProtocolsGuidArray[] = {
     29   &gEfiDriverBindingProtocolGuid,
     30   &gEfiPlatformDriverOverrideProtocolGuid,
     31   &gEfiBusSpecificDriverOverrideProtocolGuid,
     32   &gEfiDriverDiagnosticsProtocolGuid,
     33   &gEfiDriverDiagnostics2ProtocolGuid,
     34   &gEfiComponentNameProtocolGuid,
     35   &gEfiComponentName2ProtocolGuid,
     36   &gEfiPlatformToDriverConfigurationProtocolGuid,
     37   &gEfiDriverSupportedEfiVersionProtocolGuid,
     38   &gEfiDriverFamilyOverrideProtocolGuid,
     39   &gEfiDriverHealthProtocolGuid,
     40   &gEfiLoadedImageProtocolGuid,
     41   NULL
     42 };
     43 
     44 /**
     45   Get the name of a driver by it's handle.
     46 
     47   If a name is found the memory must be callee freed.
     48 
     49   @param[in] TheHandle    The driver's handle.
     50   @param[in] Language     The language to use.
     51   @param[in] NameFound    Upon a successful return the name found.
     52 
     53   @retval EFI_SUCCESS     The name was found.
     54 **/
     55 EFI_STATUS
     56 GetDriverName (
     57   IN EFI_HANDLE   TheHandle,
     58   IN CONST CHAR8  *Language,
     59   IN CHAR16       **NameFound
     60   )
     61 {
     62   CHAR8                             *Lang;
     63   EFI_STATUS                        Status;
     64   EFI_COMPONENT_NAME2_PROTOCOL      *CompName2;
     65   CHAR16                            *NameToReturn;
     66   //
     67   // Go through those handles until we get one that passes for GetComponentName
     68   //
     69   Status = gBS->OpenProtocol(
     70     TheHandle,
     71     &gEfiComponentName2ProtocolGuid,
     72     (VOID**)&CompName2,
     73     gImageHandle,
     74     NULL,
     75     EFI_OPEN_PROTOCOL_GET_PROTOCOL);
     76   if (EFI_ERROR(Status)) {
     77     Status = gBS->OpenProtocol(
     78       TheHandle,
     79       &gEfiComponentNameProtocolGuid,
     80       (VOID**)&CompName2,
     81       gImageHandle,
     82       NULL,
     83       EFI_OPEN_PROTOCOL_GET_PROTOCOL);
     84   }
     85 
     86   if (EFI_ERROR(Status)) {
     87     return (EFI_NOT_FOUND);
     88   }
     89   Lang = GetBestLanguageForDriver (CompName2->SupportedLanguages, Language, FALSE);
     90   Status = CompName2->GetDriverName(CompName2, Lang, &NameToReturn);
     91   FreePool(Lang);
     92 
     93   if (!EFI_ERROR(Status) && NameToReturn != NULL) {
     94     *NameFound = NULL;
     95     StrnCatGrow(NameFound, NULL, NameToReturn, 0);
     96   }
     97   return (Status);
     98 }
     99 
    100 /**
    101   Discover if a protocol guid is one of the UEFI Driver Model Protocols.
    102 
    103   @param[in] Guid   The guid to test.
    104 
    105   @retval TRUE      The guid does represent a driver model protocol.
    106   @retval FALSE     The guid does not represent a driver model protocol.
    107 **/
    108 BOOLEAN
    109 IsDriverProt (
    110   IN CONST EFI_GUID *Guid
    111   )
    112 {
    113   CONST EFI_GUID            **GuidWalker;
    114   BOOLEAN                   GuidFound;
    115   GuidFound = FALSE;
    116   for (GuidWalker = UefiDriverModelProtocolsGuidArray
    117     ;  GuidWalker != NULL && *GuidWalker != NULL
    118     ;  GuidWalker++
    119    ){
    120     if (CompareGuid(*GuidWalker, Guid)) {
    121       GuidFound = TRUE;
    122       break;
    123     }
    124   }
    125   return (GuidFound);
    126 }
    127 
    128 /**
    129   Get information for a handle.
    130 
    131   @param[in] TheHandle        The handles to show info on.
    132   @param[in] Language         Language string per UEFI specification.
    133   @param[in] Separator        Separator string between information blocks.
    134   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
    135   @param[in] ExtraInfo        TRUE for extra info, FALSE otherwise.
    136 
    137   @retval SHELL_SUCCESS           The operation was successful.
    138   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
    139 **/
    140 CHAR16*
    141 GetProtocolInfoString(
    142   IN CONST EFI_HANDLE TheHandle,
    143   IN CONST CHAR8      *Language,
    144   IN CONST CHAR16     *Separator,
    145   IN CONST BOOLEAN    Verbose,
    146   IN CONST BOOLEAN    ExtraInfo
    147   )
    148 {
    149   EFI_GUID                  **ProtocolGuidArray;
    150   UINTN                     ArrayCount;
    151   UINTN                     ProtocolIndex;
    152   EFI_STATUS                Status;
    153   CHAR16                    *RetVal;
    154   UINTN                     Size;
    155   CHAR16                    *Temp;
    156 
    157   ProtocolGuidArray = NULL;
    158   RetVal            = NULL;
    159   Size              = 0;
    160 
    161   Status = gBS->ProtocolsPerHandle (
    162                 TheHandle,
    163                 &ProtocolGuidArray,
    164                 &ArrayCount
    165                );
    166   if (!EFI_ERROR (Status)) {
    167     for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
    168       Temp = GetStringNameFromGuid(ProtocolGuidArray[ProtocolIndex], Language);
    169       if (Temp != NULL) {
    170         ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
    171         if (Size != 0) {
    172           StrnCatGrow(&RetVal, &Size, Separator, 0);
    173         }
    174         StrnCatGrow(&RetVal, &Size, L"%H", 0);
    175         StrnCatGrow(&RetVal, &Size, Temp, 0);
    176         StrnCatGrow(&RetVal, &Size, L"%N", 0);
    177         FreePool(Temp);
    178       }
    179       if (ExtraInfo) {
    180         Temp = GetProtocolInformationDump(TheHandle, ProtocolGuidArray[ProtocolIndex], Verbose);
    181         if (Temp != NULL) {
    182           ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
    183           if (!Verbose) {
    184             StrnCatGrow(&RetVal, &Size, L"(", 0);
    185             StrnCatGrow(&RetVal, &Size, Temp, 0);
    186             StrnCatGrow(&RetVal, &Size, L")\r\n", 0);
    187           } else {
    188             StrnCatGrow(&RetVal, &Size, Separator, 0);
    189             StrnCatGrow(&RetVal, &Size, Temp, 0);
    190           }
    191           FreePool(Temp);
    192         }
    193       }
    194     }
    195   }
    196 
    197   SHELL_FREE_NON_NULL(ProtocolGuidArray);
    198 
    199   if (RetVal == NULL) {
    200     return (NULL);
    201   }
    202 
    203   ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
    204   StrnCatGrow(&RetVal, &Size, Separator, 0);
    205   return (RetVal);
    206 }
    207 
    208 /**
    209   Gets the name of the loaded image.
    210 
    211   @param[in] TheHandle    The handle of the driver to get info on.
    212   @param[out] Name        The pointer to the pointer.  Valid upon a successful return.
    213 
    214   @retval EFI_SUCCESS     The operation was successful.
    215 **/
    216 EFI_STATUS
    217 GetDriverImageName (
    218   IN EFI_HANDLE   TheHandle,
    219   OUT CHAR16      **Name
    220   )
    221 {
    222   // get loaded image and devicepathtotext on image->Filepath
    223   EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
    224   EFI_STATUS                Status;
    225   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
    226 
    227   if (TheHandle == NULL || Name == NULL) {
    228     return (EFI_INVALID_PARAMETER);
    229   }
    230 
    231   Status = gBS->OpenProtocol (
    232                 TheHandle,
    233                 &gEfiLoadedImageProtocolGuid,
    234                 (VOID **) &LoadedImage,
    235                 gImageHandle,
    236                 NULL,
    237                 EFI_OPEN_PROTOCOL_GET_PROTOCOL
    238                );
    239   if (EFI_ERROR(Status)) {
    240     return (Status);
    241   }
    242   DevicePath = LoadedImage->FilePath;
    243   *Name = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
    244   return (EFI_SUCCESS);
    245 }
    246 
    247 /**
    248   Display driver model information for a given handle.
    249 
    250   @param[in] Handle     The handle to display info on.
    251   @param[in] BestName   Use the best name?
    252   @param[in] Language   The language to output in.
    253 **/
    254 EFI_STATUS
    255 DisplayDriverModelHandle (
    256   IN EFI_HANDLE  Handle,
    257   IN BOOLEAN     BestName,
    258   IN CONST CHAR8 *Language OPTIONAL
    259   )
    260 {
    261   EFI_STATUS                  Status;
    262   BOOLEAN                     ConfigurationStatus;
    263   BOOLEAN                     DiagnosticsStatus;
    264   UINTN                       DriverBindingHandleCount;
    265   EFI_HANDLE                  *DriverBindingHandleBuffer;
    266   UINTN                       ParentControllerHandleCount;
    267   EFI_HANDLE                  *ParentControllerHandleBuffer;
    268   UINTN                       ChildControllerHandleCount;
    269   EFI_HANDLE                  *ChildControllerHandleBuffer;
    270   CHAR16                      *TempStringPointer;
    271   EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
    272   UINTN                       Index;
    273   CHAR16                      *DriverName;
    274   EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
    275   UINTN                       NumberOfChildren;
    276   UINTN                       HandleIndex;
    277   UINTN                       ControllerHandleCount;
    278   EFI_HANDLE                  *ControllerHandleBuffer;
    279   UINTN                       ChildIndex;
    280   BOOLEAN                     Image;
    281 
    282   DriverName = NULL;
    283 
    284   //
    285   // See if Handle is a device handle and display its details.
    286   //
    287   DriverBindingHandleBuffer = NULL;
    288   Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
    289             Handle,
    290             &DriverBindingHandleCount,
    291             &DriverBindingHandleBuffer
    292             );
    293 
    294   ParentControllerHandleBuffer = NULL;
    295   Status = PARSE_HANDLE_DATABASE_PARENTS (
    296             Handle,
    297             &ParentControllerHandleCount,
    298             &ParentControllerHandleBuffer
    299             );
    300 
    301   ChildControllerHandleBuffer = NULL;
    302   Status = ParseHandleDatabaseForChildControllers (
    303             Handle,
    304             &ChildControllerHandleCount,
    305             &ChildControllerHandleBuffer
    306             );
    307 
    308   DiagnosticsStatus = FALSE;
    309   ConfigurationStatus = FALSE;
    310 
    311   if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfigurationProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
    312     ConfigurationStatus = TRUE;
    313   }
    314   if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfiguration2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
    315     ConfigurationStatus = TRUE;
    316   }
    317   if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnosticsProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
    318     DiagnosticsStatus = TRUE;
    319   }
    320   if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnostics2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
    321     DiagnosticsStatus = TRUE;
    322   }
    323 
    324   Status = EFI_SUCCESS;
    325 
    326   if (DriverBindingHandleCount > 0 || ParentControllerHandleCount > 0 || ChildControllerHandleCount > 0) {
    327 
    328 
    329 
    330     DevicePath          = NULL;
    331     TempStringPointer   = NULL;
    332     Status              = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID**)&DevicePath);
    333 
    334     Status = gEfiShellProtocol->GetDeviceName(Handle, EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
    335     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DRIVER1), gShellDriver1HiiHandle, TempStringPointer!=NULL?TempStringPointer:L"<Unknown>");
    336     SHELL_FREE_NON_NULL(TempStringPointer);
    337 
    338     TempStringPointer = ConvertDevicePathToText(DevicePath, TRUE, FALSE);
    339     ShellPrintHiiEx(
    340       -1,
    341       -1,
    342       NULL,
    343       STRING_TOKEN (STR_DH_OUTPUT_DRIVER2),
    344       gShellDriver1HiiHandle,
    345       TempStringPointer!=NULL?TempStringPointer:L"<None>",
    346       ParentControllerHandleCount == 0?L"ROOT":(ChildControllerHandleCount > 0)?L"BUS":L"DEVICE",
    347       ConfigurationStatus?L"YES":L"NO",
    348       DiagnosticsStatus?L"YES":L"NO"
    349       );
    350 
    351     SHELL_FREE_NON_NULL(TempStringPointer);
    352 
    353     if (DriverBindingHandleCount == 0) {
    354       ShellPrintHiiEx(
    355         -1,
    356         -1,
    357         NULL,
    358         STRING_TOKEN (STR_DH_OUTPUT_DRIVER3),
    359         gShellDriver1HiiHandle,
    360         L"<None>"
    361         );
    362     } else {
    363       ShellPrintHiiEx(
    364         -1,
    365         -1,
    366         NULL,
    367         STRING_TOKEN (STR_DH_OUTPUT_DRIVER3),
    368         gShellDriver1HiiHandle,
    369         L""
    370         );
    371       for (Index = 0; Index < DriverBindingHandleCount; Index++) {
    372         Image = FALSE;
    373         Status = GetDriverName (
    374                   DriverBindingHandleBuffer[Index],
    375                   Language,
    376                   &DriverName
    377                   );
    378         if (EFI_ERROR (Status)) {
    379           Status = GetDriverImageName (
    380                     DriverBindingHandleBuffer[Index],
    381                     &DriverName
    382                     );
    383           if (EFI_ERROR (Status)) {
    384             DriverName = NULL;
    385           }
    386         }
    387 
    388         if (Image) {
    389           ShellPrintHiiEx(
    390             -1,
    391             -1,
    392             NULL,
    393             STRING_TOKEN (STR_DH_OUTPUT_DRIVER4A),
    394             gShellDriver1HiiHandle,
    395             ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),
    396             DriverName!=NULL?DriverName:L"<Unknown>"
    397             );
    398         } else {
    399           ShellPrintHiiEx(
    400             -1,
    401             -1,
    402             NULL,
    403             STRING_TOKEN (STR_DH_OUTPUT_DRIVER4B),
    404             gShellDriver1HiiHandle,
    405             ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),
    406             DriverName!=NULL?DriverName:L"<Unknown>"
    407             );
    408         }
    409         SHELL_FREE_NON_NULL(DriverName);
    410       }
    411     }
    412 
    413     if (ParentControllerHandleCount == 0) {
    414       ShellPrintHiiEx(
    415         -1,
    416         -1,
    417         NULL,
    418         STRING_TOKEN (STR_DH_OUTPUT_DRIVER5),
    419         gShellDriver1HiiHandle,
    420         L"<None>"
    421         );
    422     } else {
    423       ShellPrintHiiEx(
    424         -1,
    425         -1,
    426         NULL,
    427         STRING_TOKEN (STR_DH_OUTPUT_DRIVER5),
    428         gShellDriver1HiiHandle,
    429         L""
    430         );
    431       for (Index = 0; Index < ParentControllerHandleCount; Index++) {
    432         Status = gEfiShellProtocol->GetDeviceName(ParentControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
    433         ShellPrintHiiEx(
    434           -1,
    435           -1,
    436           NULL,
    437           STRING_TOKEN (STR_DH_OUTPUT_DRIVER5B),
    438           gShellDriver1HiiHandle,
    439           ConvertHandleToHandleIndex (ParentControllerHandleBuffer[Index]),
    440           TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
    441           );
    442         SHELL_FREE_NON_NULL(TempStringPointer);
    443       }
    444     }
    445 
    446     if (ChildControllerHandleCount == 0) {
    447       ShellPrintHiiEx(
    448         -1,
    449         -1,
    450         NULL,
    451         STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
    452         gShellDriver1HiiHandle,
    453         L"<None>"
    454         );
    455     } else {
    456       ShellPrintHiiEx(
    457         -1,
    458         -1,
    459         NULL,
    460         STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
    461         gShellDriver1HiiHandle,
    462         L""
    463         );
    464       for (Index = 0; Index < ChildControllerHandleCount; Index++) {
    465         Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
    466         ShellPrintHiiEx(
    467           -1,
    468           -1,
    469           NULL,
    470           STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),
    471           gShellDriver1HiiHandle,
    472           ConvertHandleToHandleIndex (ChildControllerHandleBuffer[Index]),
    473           TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
    474           );
    475         SHELL_FREE_NON_NULL(TempStringPointer);
    476       }
    477     }
    478   }
    479 
    480   SHELL_FREE_NON_NULL(DriverBindingHandleBuffer);
    481 
    482   SHELL_FREE_NON_NULL(ParentControllerHandleBuffer);
    483 
    484   SHELL_FREE_NON_NULL(ChildControllerHandleBuffer);
    485 
    486   if (EFI_ERROR (Status)) {
    487     return Status;
    488   }
    489   //
    490   // See if Handle is a driver binding handle and display its details.
    491   //
    492   Status = gBS->OpenProtocol (
    493                 Handle,
    494                 &gEfiDriverBindingProtocolGuid,
    495                 (VOID **) &DriverBinding,
    496                 NULL,
    497                 NULL,
    498                 EFI_OPEN_PROTOCOL_GET_PROTOCOL
    499                 );
    500   if (EFI_ERROR (Status)) {
    501     return EFI_SUCCESS;
    502   }
    503 
    504   NumberOfChildren        = 0;
    505   ControllerHandleBuffer  = NULL;
    506   Status = PARSE_HANDLE_DATABASE_DEVICES (
    507             Handle,
    508             &ControllerHandleCount,
    509             &ControllerHandleBuffer
    510             );
    511   if (ControllerHandleCount > 0) {
    512     for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {
    513       Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
    514                 Handle,
    515                 ControllerHandleBuffer[HandleIndex],
    516                 &ChildControllerHandleCount,
    517                 NULL
    518                 );
    519       NumberOfChildren += ChildControllerHandleCount;
    520     }
    521   }
    522 
    523   Status = GetDriverName (Handle, Language, &DriverName);
    524   if (EFI_ERROR (Status)) {
    525     DriverName = NULL;
    526   }
    527 
    528   ShellPrintHiiEx(
    529     -1,
    530     -1,
    531     NULL,
    532     STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),
    533     gShellDriver1HiiHandle,
    534     ConvertHandleToHandleIndex(Handle),
    535     DriverName!=NULL?DriverName:L"<Unknown>"
    536     );
    537   SHELL_FREE_NON_NULL(DriverName);
    538   Status = GetDriverImageName (
    539             Handle,
    540             &DriverName
    541             );
    542   if (EFI_ERROR (Status)) {
    543     DriverName = NULL;
    544   }
    545   ShellPrintHiiEx(
    546     -1,
    547     -1,
    548     NULL,
    549     STRING_TOKEN (STR_DH_OUTPUT_DRIVER7B),
    550     gShellDriver1HiiHandle,
    551     DriverName!=NULL?DriverName:L"<Unknown>"
    552     );
    553   SHELL_FREE_NON_NULL(DriverName);
    554 
    555   ShellPrintHiiEx(
    556     -1,
    557     -1,
    558     NULL,
    559     STRING_TOKEN (STR_DH_OUTPUT_DRIVER8),
    560     gShellDriver1HiiHandle,
    561     DriverBinding->Version,
    562     NumberOfChildren > 0?L"Bus":ControllerHandleCount > 0?L"Device":L"<Unknown>",
    563     ConfigurationStatus?L"YES":L"NO",
    564     DiagnosticsStatus?L"YES":L"NO"
    565     );
    566 
    567   if (ControllerHandleCount == 0) {
    568       ShellPrintHiiEx(
    569         -1,
    570         -1,
    571         NULL,
    572         STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
    573         gShellDriver1HiiHandle,
    574         L"None"
    575         );
    576   } else {
    577     ShellPrintHiiEx(
    578       -1,
    579       -1,
    580       NULL,
    581       STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
    582       gShellDriver1HiiHandle,
    583       L""
    584       );
    585     for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {
    586       Status = gEfiShellProtocol->GetDeviceName(ControllerHandleBuffer[HandleIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
    587 
    588       ShellPrintHiiEx(
    589         -1,
    590         -1,
    591         NULL,
    592         STRING_TOKEN (STR_DH_OUTPUT_DRIVER9B),
    593         gShellDriver1HiiHandle,
    594         ConvertHandleToHandleIndex(ControllerHandleBuffer[HandleIndex]),
    595         TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
    596         );
    597       SHELL_FREE_NON_NULL(TempStringPointer);
    598 
    599       Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
    600                 Handle,
    601                 ControllerHandleBuffer[HandleIndex],
    602                 &ChildControllerHandleCount,
    603                 &ChildControllerHandleBuffer
    604                 );
    605       if (!EFI_ERROR (Status)) {
    606         for (ChildIndex = 0; ChildIndex < ChildControllerHandleCount; ChildIndex++) {
    607           Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[ChildIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
    608 
    609           ShellPrintHiiEx(
    610             -1,
    611             -1,
    612             NULL,
    613             STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),
    614             gShellDriver1HiiHandle,
    615             ConvertHandleToHandleIndex(ChildControllerHandleBuffer[ChildIndex]),
    616             TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
    617             );
    618           SHELL_FREE_NON_NULL(TempStringPointer);
    619         }
    620 
    621         SHELL_FREE_NON_NULL (ChildControllerHandleBuffer);
    622       }
    623     }
    624 
    625     SHELL_FREE_NON_NULL (ControllerHandleBuffer);
    626   }
    627 
    628   return EFI_SUCCESS;
    629 }
    630 
    631 /**
    632   Display information for a handle.
    633 
    634   @param[in] TheHandle        The handles to show info on.
    635   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
    636   @param[in] Sfo              TRUE to output in standard format output (spec).
    637   @param[in] Language         Language string per UEFI specification.
    638   @param[in] DriverInfo       TRUE to show all info about the handle.
    639   @param[in] Multiple         TRUE indicates more than  will be output,
    640                               FALSE for a single one.
    641 
    642   @retval SHELL_SUCCESS           The operation was successful.
    643   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
    644 **/
    645 SHELL_STATUS
    646 DoDhByHandle(
    647   IN CONST EFI_HANDLE TheHandle,
    648   IN CONST BOOLEAN    Verbose,
    649   IN CONST BOOLEAN    Sfo,
    650   IN CONST CHAR8      *Language,
    651   IN CONST BOOLEAN    DriverInfo,
    652   IN CONST BOOLEAN    Multiple
    653   )
    654 {
    655   CHAR16              *ProtocolInfoString;
    656   SHELL_STATUS        ShellStatus;
    657 
    658   ShellStatus         = SHELL_SUCCESS;
    659   ProtocolInfoString  = NULL;
    660 
    661   if (!Sfo) {
    662     if (Multiple) {
    663       ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L" ", Verbose, TRUE);
    664       ShellPrintHiiEx(
    665         -1,
    666         -1,
    667         NULL,
    668         STRING_TOKEN (STR_DH_OUTPUT),
    669         gShellDriver1HiiHandle,
    670         ConvertHandleToHandleIndex(TheHandle),
    671         ProtocolInfoString==NULL?L"":ProtocolInfoString);
    672     } else {
    673       ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L"\r\n", Verbose, TRUE);
    674       ShellPrintHiiEx(
    675         -1,
    676         -1,
    677         NULL,
    678         STRING_TOKEN (STR_DH_OUTPUT_SINGLE),
    679         gShellDriver1HiiHandle,
    680         ConvertHandleToHandleIndex(TheHandle),
    681         TheHandle,
    682         ProtocolInfoString==NULL?L"":ProtocolInfoString);
    683     }
    684 
    685     if (DriverInfo) {
    686       DisplayDriverModelHandle ((EFI_HANDLE)TheHandle, TRUE, Language);
    687     }
    688   } else {
    689       ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L";", FALSE, FALSE);
    690       ShellPrintHiiEx(
    691         -1,
    692         -1,
    693         NULL,
    694         STRING_TOKEN (STR_DH_OUTPUT_SFO),
    695         gShellDriver1HiiHandle,
    696         Multiple ?L"HandlesInfo":L"HandleInfo",
    697         L"DriverName",
    698         L"ControllerName",
    699         ConvertHandleToHandleIndex(TheHandle),
    700         L"DevPath",
    701         ProtocolInfoString==NULL?L"":ProtocolInfoString);
    702 
    703 
    704   }
    705 
    706 
    707   if (ProtocolInfoString != NULL) {
    708     FreePool(ProtocolInfoString);
    709   }
    710   return (ShellStatus);
    711 }
    712 
    713 /**
    714   Display information for all handles on a list.
    715 
    716   @param[in] HandleList       The NULL-terminated list of handles.
    717   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
    718   @param[in] Sfo              TRUE to output in standard format output (spec).
    719   @param[in] Language         Language string per UEFI specification.
    720   @param[in] DriverInfo       TRUE to show all info about the handle.
    721 
    722   @retval SHELL_SUCCESS           The operation was successful.
    723   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
    724 **/
    725 SHELL_STATUS
    726 DoDhForHandleList(
    727   IN CONST EFI_HANDLE *HandleList,
    728   IN CONST BOOLEAN    Verbose,
    729   IN CONST BOOLEAN    Sfo,
    730   IN CONST CHAR8      *Language,
    731   IN CONST BOOLEAN    DriverInfo
    732   )
    733 {
    734   CONST EFI_HANDLE  *HandleWalker;
    735   SHELL_STATUS      ShellStatus;
    736 
    737   ShellStatus       = SHELL_SUCCESS;
    738 
    739   for (HandleWalker = HandleList ; HandleWalker != NULL && *HandleWalker != NULL && ShellStatus == SHELL_SUCCESS; HandleWalker++) {
    740     ShellStatus = DoDhByHandle(
    741           *HandleWalker,
    742           Verbose,
    743           Sfo,
    744           Language,
    745           DriverInfo,
    746           TRUE
    747          );
    748     if (ShellGetExecutionBreakFlag ()) {
    749       ShellStatus = SHELL_ABORTED;
    750       break;
    751     }
    752   }
    753   return (ShellStatus);
    754 }
    755 
    756 /**
    757   Display information for all handles.
    758 
    759   @param[in] Sfo              TRUE to output in standard format output (spec).
    760   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
    761   @param[in] Language         Language string per UEFI specification.
    762   @param[in] DriverInfo       TRUE to show all info about the handle.
    763 
    764   @retval SHELL_SUCCESS           The operation was successful.
    765   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
    766 **/
    767 SHELL_STATUS
    768 DoDhForAll(
    769   IN CONST BOOLEAN  Sfo,
    770   IN CONST BOOLEAN  Verbose,
    771   IN CONST CHAR8    *Language,
    772   IN CONST BOOLEAN  DriverInfo
    773   )
    774 {
    775   EFI_HANDLE    *HandleList;
    776   SHELL_STATUS  ShellStatus;
    777 
    778   HandleList = GetHandleListByProtocol(NULL);
    779 
    780   ShellStatus = DoDhForHandleList(
    781     HandleList,
    782     Verbose,
    783     Sfo,
    784     Language,
    785     DriverInfo);
    786 
    787   FreePool(HandleList);
    788 
    789   return (ShellStatus);
    790 }
    791 
    792 /**
    793   Display information for all handles which have a specific protocol.
    794 
    795   @param[in] ProtocolName     The pointer to the name of the protocol.
    796   @param[in] Verbose          TRUE for extra info, FALSE otherwise.
    797   @param[in] Sfo              TRUE to output in standard format output (spec).
    798   @param[in] Language         Language string per UEFI specification.
    799   @param[in] DriverInfo       TRUE to show all info about the handle.
    800 
    801   @retval SHELL_SUCCESS           The operation was successful.
    802   @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
    803 **/
    804 SHELL_STATUS
    805 DoDhByProtocol(
    806   IN CONST CHAR16   *ProtocolName,
    807   IN CONST BOOLEAN  Verbose,
    808   IN CONST BOOLEAN  Sfo,
    809   IN CONST CHAR8    *Language,
    810   IN CONST BOOLEAN  DriverInfo
    811   )
    812 {
    813   EFI_GUID      *Guid;
    814   EFI_STATUS    Status;
    815   EFI_HANDLE    *HandleList;
    816   SHELL_STATUS  ShellStatus;
    817 
    818   if (ProtocolName == NULL) {
    819     return (SHELL_INVALID_PARAMETER);
    820   }
    821 
    822   Status = GetGuidFromStringName(ProtocolName, Language, &Guid);
    823   if (EFI_ERROR(Status)) {
    824     ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, ProtocolName);
    825     return (SHELL_INVALID_PARAMETER);
    826   }
    827 
    828   HandleList = GetHandleListByProtocol(Guid);
    829 
    830   ShellStatus = DoDhForHandleList(
    831     HandleList,
    832     Verbose,
    833     Sfo,
    834     Language,
    835     DriverInfo);
    836 
    837   SHELL_FREE_NON_NULL(HandleList);
    838 
    839   return (ShellStatus);
    840 }
    841 
    842 /**
    843   Function for 'dh' command.
    844 
    845   @param[in] ImageHandle  Handle to the Image (NULL if Internal).
    846   @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
    847 **/
    848 SHELL_STATUS
    849 EFIAPI
    850 ShellCommandRunDh (
    851   IN EFI_HANDLE        ImageHandle,
    852   IN EFI_SYSTEM_TABLE  *SystemTable
    853   )
    854 {
    855   EFI_STATUS          Status;
    856   LIST_ENTRY          *Package;
    857   CHAR16              *ProblemParam;
    858   SHELL_STATUS        ShellStatus;
    859   CHAR8               *Language;
    860   CONST CHAR16        *Lang;
    861   CONST CHAR16        *Temp2;
    862   BOOLEAN             SfoMode;
    863   BOOLEAN             FlagD;
    864   BOOLEAN             Verbose;
    865   UINT64              Intermediate;
    866 
    867   ShellStatus         = SHELL_SUCCESS;
    868   Status              = EFI_SUCCESS;
    869   Language            = NULL;
    870 
    871   //
    872   // initialize the shell lib (we must be in non-auto-init...)
    873   //
    874   Status = ShellInitialize();
    875   ASSERT_EFI_ERROR(Status);
    876 
    877   Status = CommandInit();
    878   ASSERT_EFI_ERROR(Status);
    879 
    880   //
    881   // parse the command line
    882   //
    883   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
    884   if (EFI_ERROR(Status)) {
    885     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
    886       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"dh", ProblemParam);
    887       FreePool(ProblemParam);
    888       ShellStatus = SHELL_INVALID_PARAMETER;
    889     } else {
    890       ASSERT(FALSE);
    891     }
    892   } else {
    893     if (ShellCommandLineGetCount(Package) > 2) {
    894       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");
    895       ShellCommandLineFreeVarList (Package);
    896       return (SHELL_INVALID_PARAMETER);
    897     }
    898 
    899     Lang = ShellCommandLineGetValue(Package, L"-l");
    900     if (Lang != NULL) {
    901       Language = AllocateZeroPool(StrSize(Lang));
    902       AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
    903     } else if (!ShellCommandLineGetFlag(Package, L"-l")){
    904       Language = AllocateZeroPool(10);
    905       AsciiSPrint(Language, 10, "en-us");
    906     } else {
    907       ASSERT(Language == NULL);
    908       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh",  L"-l");
    909       ShellCommandLineFreeVarList (Package);
    910       return (SHELL_INVALID_PARAMETER);
    911     }
    912 
    913     SfoMode = ShellCommandLineGetFlag(Package, L"-sfo");
    914     FlagD   = ShellCommandLineGetFlag(Package, L"-d");
    915     Verbose = (BOOLEAN)(ShellCommandLineGetFlag(Package, L"-v") || ShellCommandLineGetFlag(Package, L"-verbose"));
    916 
    917     if (ShellCommandLineGetFlag(Package, L"-p")) {
    918       if (ShellCommandLineGetCount(Package) > 1) {
    919         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");
    920         ShellStatus = SHELL_INVALID_PARAMETER;
    921       } else if (ShellCommandLineGetValue(Package, L"-p") == NULL) {
    922         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh",  L"-p");
    923         ShellStatus = SHELL_INVALID_PARAMETER;
    924       } else {
    925         //
    926         // print by protocol
    927         //
    928         ShellStatus = DoDhByProtocol(
    929           ShellCommandLineGetValue(Package, L"-p"),
    930           Verbose,
    931           SfoMode,
    932           Lang==NULL?NULL:Language,
    933           FlagD
    934          );
    935       }
    936     } else {
    937       Temp2 = ShellCommandLineGetRawValue(Package, 1);
    938       if (Temp2 == NULL) {
    939         //
    940         // Print everything
    941         //
    942         ShellStatus = DoDhForAll(
    943           SfoMode,
    944           Verbose,
    945           Lang==NULL?NULL:Language,
    946           FlagD
    947          );
    948       } else {
    949         Status = ShellConvertStringToUint64(Temp2, &Intermediate, TRUE, FALSE);
    950         if (EFI_ERROR(Status) || ConvertHandleIndexToHandle((UINTN)Intermediate) == NULL) {
    951           ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", Temp2);
    952           ShellStatus = SHELL_INVALID_PARAMETER;
    953         } else {
    954           //
    955           // print 1 handle
    956           //
    957           ShellStatus = DoDhByHandle(
    958             ConvertHandleIndexToHandle((UINTN)Intermediate),
    959             Verbose,
    960             SfoMode,
    961             Lang==NULL?NULL:Language,
    962             FlagD,
    963             FALSE
    964            );
    965         }
    966       }
    967     }
    968 
    969 
    970     ShellCommandLineFreeVarList (Package);
    971     SHELL_FREE_NON_NULL(Language);
    972   }
    973 
    974   return (ShellStatus);
    975 }
    976