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