/** @file
  Main file for Dh shell Driver1 function.

  (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2017 Hewlett Packard Enterprise Development LP<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "UefiShellDriver1CommandsLib.h"

STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
  {L"-p", TypeValue},
  {L"-d", TypeFlag},
  {L"-v", TypeFlag},
  {L"-verbose", TypeFlag},
  {L"-sfo", TypeFlag},
  {L"-l", TypeValue},
  {NULL, TypeMax}
  };

STATIC CONST EFI_GUID *UefiDriverModelProtocolsGuidArray[] = {
  &gEfiDriverBindingProtocolGuid,
  &gEfiPlatformDriverOverrideProtocolGuid,
  &gEfiBusSpecificDriverOverrideProtocolGuid,
  &gEfiDriverDiagnosticsProtocolGuid,
  &gEfiDriverDiagnostics2ProtocolGuid,
  &gEfiComponentNameProtocolGuid,
  &gEfiComponentName2ProtocolGuid,
  &gEfiPlatformToDriverConfigurationProtocolGuid,
  &gEfiDriverSupportedEfiVersionProtocolGuid,
  &gEfiDriverFamilyOverrideProtocolGuid,
  &gEfiDriverHealthProtocolGuid,
  &gEfiLoadedImageProtocolGuid,
  NULL
};

UINTN mGuidDataLen[] = {8, 4, 4, 4, 12};
/**
  Function to determine if the string can convert to a GUID.
  The string must be restricted as "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" format.

  @param[in]  String  The string to test.

  @retval     TRUE    The string can convert to a GUID.
  @retval     FALSE   The string can't convert to a GUID.
**/
BOOLEAN
IsValidGuidString(
  IN CONST CHAR16 *String
  )
{
  CONST CHAR16  *Walker;
  CONST CHAR16  *PrevWalker;
  UINTN         Index;

  if (String == NULL) {
    return FALSE;
  }

  Walker      = String;
  PrevWalker  = String;
  Index       = 0;

  while (Walker != NULL && *Walker != CHAR_NULL) {
    if ( (*Walker >= '0' && *Walker <= '9') ||
         (*Walker >= 'a' && *Walker <= 'f') ||
         (*Walker >= 'A' && *Walker <= 'F')
       ) {
      Walker++;
    } else {
      if (*Walker == L'-' && (((UINTN)Walker - (UINTN)PrevWalker) / sizeof (CHAR16)) == mGuidDataLen[Index]) {
        Walker++;
        PrevWalker = Walker;
        Index++;
      } else {
        return FALSE;
      }
    }
  }

  if ((((UINTN)Walker - (UINTN)PrevWalker) / sizeof (CHAR16)) == mGuidDataLen[Index]) {
    return TRUE;
  } else {
    return FALSE;
  }
}

/**
  Convert a hex-character to decimal value.

  This internal function only deal with Unicode character
  which maps to a valid hexadecimal ASII character, i.e.
  L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
  Unicode character, the value returned does not make sense.

  @param[in]  Char      The character to convert.

  @retval               The numerical value converted.
**/
UINTN
HexCharToDecimal(
  IN CHAR16 Char
  )
{
  if (Char >= '0' && Char <= '9') {
    return Char - L'0';
  } else if (Char >= 'a' && Char <= 'f') {
    return Char - L'a' + 10;
  } else {
    return Char - L'A' + 10;
  }
}

/**
  Function try to convert a string to GUID format.

  @param[in]    String    The string will be converted.
  @param[out]   Guid      Save the result convert from string.

  @retval EFI_SUCCESS     The string was successfully converted to a GUID.
  @retval EFI_UNSUPPORTED The input string is not in registry format.
**/
EFI_STATUS
ConvertStrToGuid(
  IN  CONST CHAR16 *String,
  OUT GUID *Guid
  )
{
  CONST CHAR16  *Walker;
  UINT8         TempValue;
  UINTN         Index;

  if (String == NULL || !IsValidGuidString (String)) {
    return EFI_UNSUPPORTED;
  }

  Index = 0;

  Walker = String;
  Guid->Data1 = (UINT32)StrHexToUint64 (Walker);

  Walker += 9;
  Guid->Data2 = (UINT16)StrHexToUint64 (Walker);

  Walker += 5;
  Guid->Data3 = (UINT16)StrHexToUint64 (Walker);

  Walker += 5;
  while (Walker != NULL && *Walker != CHAR_NULL) {
    if (*Walker == L'-') {
      Walker++;
    } else {
      TempValue = (UINT8)HexCharToDecimal (*Walker);
      TempValue = (UINT8)LShiftU64 (TempValue, 4);
      Walker++;

      TempValue += (UINT8)HexCharToDecimal (*Walker);
      Walker++;

      Guid->Data4[Index] = TempValue;
      Index++;
    }
  }

  return EFI_SUCCESS;
}

/**
  Get the name of a driver by it's handle.

  If a name is found the memory must be callee freed.

  @param[in] TheHandle    The driver's handle.
  @param[in] Language     The language to use.
  @param[in] NameFound    Upon a successful return the name found.

  @retval EFI_SUCCESS     The name was found.
**/
EFI_STATUS
GetDriverName (
  IN EFI_HANDLE   TheHandle,
  IN CONST CHAR8  *Language,
  IN CHAR16       **NameFound
  )
{
  CHAR8                             *Lang;
  EFI_STATUS                        Status;
  EFI_COMPONENT_NAME2_PROTOCOL      *CompName2;
  CHAR16                            *NameToReturn;
  //
  // Go through those handles until we get one that passes for GetComponentName
  //
  Status = gBS->OpenProtocol(
    TheHandle,
    &gEfiComponentName2ProtocolGuid,
    (VOID**)&CompName2,
    gImageHandle,
    NULL,
    EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  if (EFI_ERROR(Status)) {
    Status = gBS->OpenProtocol(
      TheHandle,
      &gEfiComponentNameProtocolGuid,
      (VOID**)&CompName2,
      gImageHandle,
      NULL,
      EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  }

  if (EFI_ERROR(Status)) {
    return (EFI_NOT_FOUND);
  }
  Lang = GetBestLanguageForDriver (CompName2->SupportedLanguages, Language, FALSE);
  Status = CompName2->GetDriverName(CompName2, Lang, &NameToReturn);
  FreePool(Lang);

  if (!EFI_ERROR(Status) && NameToReturn != NULL) {
    *NameFound = NULL;
    StrnCatGrow(NameFound, NULL, NameToReturn, 0);
  }
  return (Status);
}

/**
  Discover if a protocol guid is one of the UEFI Driver Model Protocols.

  @param[in] Guid   The guid to test.

  @retval TRUE      The guid does represent a driver model protocol.
  @retval FALSE     The guid does not represent a driver model protocol.
**/
BOOLEAN
IsDriverProt (
  IN CONST EFI_GUID *Guid
  )
{
  CONST EFI_GUID            **GuidWalker;
  BOOLEAN                   GuidFound;
  GuidFound = FALSE;
  for (GuidWalker = UefiDriverModelProtocolsGuidArray
    ;  GuidWalker != NULL && *GuidWalker != NULL
    ;  GuidWalker++
   ){
    if (CompareGuid(*GuidWalker, Guid)) {
      GuidFound = TRUE;
      break;
    }
  }
  return (GuidFound);
}

/**
  Get information for a handle.

  @param[in] TheHandle        The handles to show info on.
  @param[in] Language         Language string per UEFI specification.
  @param[in] Separator        Separator string between information blocks.
  @param[in] Verbose          TRUE for extra info, FALSE otherwise.
  @param[in] ExtraInfo        TRUE for extra info, FALSE otherwise.

  @retval SHELL_SUCCESS           The operation was successful.
  @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
**/
CHAR16*
GetProtocolInfoString(
  IN CONST EFI_HANDLE TheHandle,
  IN CONST CHAR8      *Language,
  IN CONST CHAR16     *Separator,
  IN CONST BOOLEAN    Verbose,
  IN CONST BOOLEAN    ExtraInfo
  )
{
  EFI_GUID                  **ProtocolGuidArray;
  UINTN                     ArrayCount;
  UINTN                     ProtocolIndex;
  EFI_STATUS                Status;
  CHAR16                    *RetVal;
  UINTN                     Size;
  CHAR16                    *Temp;
  CHAR16                    GuidStr[40];
  VOID                      *Instance;
  CHAR16                    InstanceStr[17];

  ProtocolGuidArray = NULL;
  RetVal            = NULL;
  Size              = 0;

  Status = gBS->ProtocolsPerHandle (
                TheHandle,
                &ProtocolGuidArray,
                &ArrayCount
               );
  if (!EFI_ERROR (Status)) {
    for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
      Temp = GetStringNameFromGuid(ProtocolGuidArray[ProtocolIndex], Language);
      ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
      if (Size != 0) {
        StrnCatGrow(&RetVal, &Size, Separator, 0);
      }
      StrnCatGrow(&RetVal, &Size, L"%H", 0);
      if (Temp == NULL) {
        UnicodeSPrint (GuidStr, sizeof (GuidStr), L"%g", ProtocolGuidArray[ProtocolIndex]);
        StrnCatGrow (&RetVal, &Size, GuidStr, 0);
      } else {
        StrnCatGrow(&RetVal, &Size, Temp, 0);
        FreePool(Temp);
      }
      StrnCatGrow(&RetVal, &Size, L"%N", 0);

      if(Verbose) {
        Status = gBS->HandleProtocol (TheHandle, ProtocolGuidArray[ProtocolIndex], &Instance);
        if (!EFI_ERROR (Status)) {
          StrnCatGrow (&RetVal, &Size, L"(%H", 0);
          UnicodeSPrint (InstanceStr, sizeof (InstanceStr), L"%x", Instance);
          StrnCatGrow (&RetVal, &Size, InstanceStr, 0);
          StrnCatGrow (&RetVal, &Size, L"%N)", 0);
        }
      }

      if (ExtraInfo) {
        Temp = GetProtocolInformationDump(TheHandle, ProtocolGuidArray[ProtocolIndex], Verbose);
        if (Temp != NULL) {
          ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
          if (!Verbose) {
            StrnCatGrow(&RetVal, &Size, L"(", 0);
            StrnCatGrow(&RetVal, &Size, Temp, 0);
            StrnCatGrow(&RetVal, &Size, L")", 0);
          } else {
            StrnCatGrow(&RetVal, &Size, Separator, 0);
            StrnCatGrow(&RetVal, &Size, Temp, 0);
          }
          FreePool(Temp);
        }
      }
    }
  }

  SHELL_FREE_NON_NULL(ProtocolGuidArray);

  if (RetVal == NULL) {
    return (NULL);
  }

  ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
  StrnCatGrow(&RetVal, &Size, Separator, 0);
  return (RetVal);
}

/**
  Gets the name of the loaded image.

  @param[in] TheHandle    The handle of the driver to get info on.
  @param[out] Name        The pointer to the pointer.  Valid upon a successful return.

  @retval EFI_SUCCESS     The operation was successful.
**/
EFI_STATUS
GetDriverImageName (
  IN EFI_HANDLE   TheHandle,
  OUT CHAR16      **Name
  )
{
  // get loaded image and devicepathtotext on image->Filepath
  EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

  if (TheHandle == NULL || Name == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  Status = gBS->OpenProtocol (
                TheHandle,
                &gEfiLoadedImageProtocolGuid,
                (VOID **) &LoadedImage,
                gImageHandle,
                NULL,
                EFI_OPEN_PROTOCOL_GET_PROTOCOL
               );
  if (EFI_ERROR(Status)) {
    return (Status);
  }
  DevicePath = LoadedImage->FilePath;
  *Name = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
  return (EFI_SUCCESS);
}

/**
  Display driver model information for a given handle.

  @param[in] Handle     The handle to display info on.
  @param[in] BestName   Use the best name?
  @param[in] Language   The language to output in.
**/
EFI_STATUS
DisplayDriverModelHandle (
  IN EFI_HANDLE  Handle,
  IN BOOLEAN     BestName,
  IN CONST CHAR8 *Language OPTIONAL
  )
{
  EFI_STATUS                  Status;
  BOOLEAN                     ConfigurationStatus;
  BOOLEAN                     DiagnosticsStatus;
  UINTN                       DriverBindingHandleCount;
  EFI_HANDLE                  *DriverBindingHandleBuffer;
  UINTN                       ParentControllerHandleCount;
  EFI_HANDLE                  *ParentControllerHandleBuffer;
  UINTN                       ChildControllerHandleCount;
  EFI_HANDLE                  *ChildControllerHandleBuffer;
  CHAR16                      *TempStringPointer;
  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
  UINTN                       Index;
  CHAR16                      *DriverName;
  EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
  UINTN                       NumberOfChildren;
  UINTN                       HandleIndex;
  UINTN                       ControllerHandleCount;
  EFI_HANDLE                  *ControllerHandleBuffer;
  UINTN                       ChildIndex;
  BOOLEAN                     Image;

  DriverName = NULL;

  //
  // See if Handle is a device handle and display its details.
  //
  DriverBindingHandleBuffer = NULL;
  Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (
            Handle,
            &DriverBindingHandleCount,
            &DriverBindingHandleBuffer
            );

  ParentControllerHandleBuffer = NULL;
  Status = PARSE_HANDLE_DATABASE_PARENTS (
            Handle,
            &ParentControllerHandleCount,
            &ParentControllerHandleBuffer
            );

  ChildControllerHandleBuffer = NULL;
  Status = ParseHandleDatabaseForChildControllers (
            Handle,
            &ChildControllerHandleCount,
            &ChildControllerHandleBuffer
            );

  DiagnosticsStatus = FALSE;
  ConfigurationStatus = FALSE;

  if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfigurationProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
    ConfigurationStatus = TRUE;
  }
  if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfiguration2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
    ConfigurationStatus = TRUE;
  }
  if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnosticsProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
    DiagnosticsStatus = TRUE;
  }
  if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnostics2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
    DiagnosticsStatus = TRUE;
  }

  Status = EFI_SUCCESS;

  if (DriverBindingHandleCount > 0 || ParentControllerHandleCount > 0 || ChildControllerHandleCount > 0) {



    DevicePath          = NULL;
    TempStringPointer   = NULL;
    Status              = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID**)&DevicePath);

    Status = gEfiShellProtocol->GetDeviceName(Handle, EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DRIVER1), gShellDriver1HiiHandle, TempStringPointer!=NULL?TempStringPointer:L"<Unknown>");
    SHELL_FREE_NON_NULL(TempStringPointer);

    TempStringPointer = ConvertDevicePathToText(DevicePath, TRUE, FALSE);
    ShellPrintHiiEx(
      -1,
      -1,
      NULL,
      STRING_TOKEN (STR_DH_OUTPUT_DRIVER2),
      gShellDriver1HiiHandle,
      TempStringPointer!=NULL?TempStringPointer:L"<None>",
      ParentControllerHandleCount == 0?L"ROOT":(ChildControllerHandleCount > 0)?L"BUS":L"DEVICE",
      ConfigurationStatus?L"YES":L"NO",
      DiagnosticsStatus?L"YES":L"NO"
      );

    SHELL_FREE_NON_NULL(TempStringPointer);

    if (DriverBindingHandleCount == 0) {
      ShellPrintHiiEx(
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_DH_OUTPUT_DRIVER3),
        gShellDriver1HiiHandle,
        L"<None>"
        );
    } else {
      ShellPrintHiiEx(
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_DH_OUTPUT_DRIVER3),
        gShellDriver1HiiHandle,
        L""
        );
      for (Index = 0; Index < DriverBindingHandleCount; Index++) {
        Image = FALSE;
        Status = GetDriverName (
                  DriverBindingHandleBuffer[Index],
                  Language,
                  &DriverName
                  );
        if (EFI_ERROR (Status)) {
          Status = GetDriverImageName (
                    DriverBindingHandleBuffer[Index],
                    &DriverName
                    );
          if (EFI_ERROR (Status)) {
            DriverName = NULL;
          }
        }

        if (Image) {
          ShellPrintHiiEx(
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_DH_OUTPUT_DRIVER4A),
            gShellDriver1HiiHandle,
            ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),
            DriverName!=NULL?DriverName:L"<Unknown>"
            );
        } else {
          ShellPrintHiiEx(
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_DH_OUTPUT_DRIVER4B),
            gShellDriver1HiiHandle,
            ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),
            DriverName!=NULL?DriverName:L"<Unknown>"
            );
        }
        SHELL_FREE_NON_NULL(DriverName);
      }
    }

    if (ParentControllerHandleCount == 0) {
      ShellPrintHiiEx(
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_DH_OUTPUT_DRIVER5),
        gShellDriver1HiiHandle,
        L"<None>"
        );
    } else {
      ShellPrintHiiEx(
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_DH_OUTPUT_DRIVER5),
        gShellDriver1HiiHandle,
        L""
        );
      for (Index = 0; Index < ParentControllerHandleCount; Index++) {
        Status = gEfiShellProtocol->GetDeviceName(ParentControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
        ShellPrintHiiEx(
          -1,
          -1,
          NULL,
          STRING_TOKEN (STR_DH_OUTPUT_DRIVER5B),
          gShellDriver1HiiHandle,
          ConvertHandleToHandleIndex (ParentControllerHandleBuffer[Index]),
          TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
          );
        SHELL_FREE_NON_NULL(TempStringPointer);
      }
    }

    if (ChildControllerHandleCount == 0) {
      ShellPrintHiiEx(
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
        gShellDriver1HiiHandle,
        L"<None>"
        );
    } else {
      ShellPrintHiiEx(
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
        gShellDriver1HiiHandle,
        L""
        );
      for (Index = 0; Index < ChildControllerHandleCount; Index++) {
        Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);
        ShellPrintHiiEx(
          -1,
          -1,
          NULL,
          STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),
          gShellDriver1HiiHandle,
          ConvertHandleToHandleIndex (ChildControllerHandleBuffer[Index]),
          TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
          );
        SHELL_FREE_NON_NULL(TempStringPointer);
      }
    }
  }

  SHELL_FREE_NON_NULL(DriverBindingHandleBuffer);

  SHELL_FREE_NON_NULL(ParentControllerHandleBuffer);

  SHELL_FREE_NON_NULL(ChildControllerHandleBuffer);

  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // See if Handle is a driver binding handle and display its details.
  //
  Status = gBS->OpenProtocol (
                Handle,
                &gEfiDriverBindingProtocolGuid,
                (VOID **) &DriverBinding,
                NULL,
                NULL,
                EFI_OPEN_PROTOCOL_GET_PROTOCOL
                );
  if (EFI_ERROR (Status)) {
    return EFI_SUCCESS;
  }

  NumberOfChildren        = 0;
  ControllerHandleBuffer  = NULL;
  Status = PARSE_HANDLE_DATABASE_DEVICES (
            Handle,
            &ControllerHandleCount,
            &ControllerHandleBuffer
            );
  if (ControllerHandleCount > 0) {
    for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {
      Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
                Handle,
                ControllerHandleBuffer[HandleIndex],
                &ChildControllerHandleCount,
                NULL
                );
      NumberOfChildren += ChildControllerHandleCount;
    }
  }

  Status = GetDriverName (Handle, Language, &DriverName);
  if (EFI_ERROR (Status)) {
    DriverName = NULL;
  }

  ShellPrintHiiEx(
    -1,
    -1,
    NULL,
    STRING_TOKEN (STR_DH_OUTPUT_DRIVER7),
    gShellDriver1HiiHandle,
    ConvertHandleToHandleIndex(Handle),
    DriverName!=NULL?DriverName:L"<Unknown>"
    );
  SHELL_FREE_NON_NULL(DriverName);
  Status = GetDriverImageName (
            Handle,
            &DriverName
            );
  if (EFI_ERROR (Status)) {
    DriverName = NULL;
  }
  ShellPrintHiiEx(
    -1,
    -1,
    NULL,
    STRING_TOKEN (STR_DH_OUTPUT_DRIVER7B),
    gShellDriver1HiiHandle,
    DriverName!=NULL?DriverName:L"<Unknown>"
    );
  SHELL_FREE_NON_NULL(DriverName);

  ShellPrintHiiEx(
    -1,
    -1,
    NULL,
    STRING_TOKEN (STR_DH_OUTPUT_DRIVER8),
    gShellDriver1HiiHandle,
    DriverBinding->Version,
    NumberOfChildren > 0?L"Bus":ControllerHandleCount > 0?L"Device":L"<Unknown>",
    ConfigurationStatus?L"YES":L"NO",
    DiagnosticsStatus?L"YES":L"NO"
    );

  if (ControllerHandleCount == 0) {
      ShellPrintHiiEx(
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_DH_OUTPUT_DRIVER9),
        gShellDriver1HiiHandle,
        L"None"
        );
  } else {
    ShellPrintHiiEx(
      -1,
      -1,
      NULL,
      STRING_TOKEN (STR_DH_OUTPUT_DRIVER9),
      gShellDriver1HiiHandle,
      L""
      );
    for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {
      Status = gEfiShellProtocol->GetDeviceName(ControllerHandleBuffer[HandleIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);

      ShellPrintHiiEx(
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_DH_OUTPUT_DRIVER9B),
        gShellDriver1HiiHandle,
        ConvertHandleToHandleIndex(ControllerHandleBuffer[HandleIndex]),
        TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
        );
      SHELL_FREE_NON_NULL(TempStringPointer);

      Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
                Handle,
                ControllerHandleBuffer[HandleIndex],
                &ChildControllerHandleCount,
                &ChildControllerHandleBuffer
                );
      if (!EFI_ERROR (Status)) {
        for (ChildIndex = 0; ChildIndex < ChildControllerHandleCount; ChildIndex++) {
          Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[ChildIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);

          ShellPrintHiiEx(
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_DH_OUTPUT_DRIVER6C),
            gShellDriver1HiiHandle,
            ConvertHandleToHandleIndex(ChildControllerHandleBuffer[ChildIndex]),
            TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"
            );
          SHELL_FREE_NON_NULL(TempStringPointer);
        }

        SHELL_FREE_NON_NULL (ChildControllerHandleBuffer);
      }
    }

    SHELL_FREE_NON_NULL (ControllerHandleBuffer);
  }

  return EFI_SUCCESS;
}

/**
  Display information for a handle.

  @param[in] TheHandle        The handles to show info on.
  @param[in] Verbose          TRUE for extra info, FALSE otherwise.
  @param[in] Sfo              TRUE to output in standard format output (spec).
  @param[in] Language         Language string per UEFI specification.
  @param[in] DriverInfo       TRUE to show all info about the handle.
  @param[in] Multiple         TRUE indicates more than  will be output,
                              FALSE for a single one.
**/
VOID
DoDhByHandle(
  IN CONST EFI_HANDLE TheHandle,
  IN CONST BOOLEAN    Verbose,
  IN CONST BOOLEAN    Sfo,
  IN CONST CHAR8      *Language,
  IN CONST BOOLEAN    DriverInfo,
  IN CONST BOOLEAN    Multiple
  )
{
  CHAR16 *ProtocolInfoString;

  ProtocolInfoString  = NULL;

  if (!Sfo) {
    if (Multiple) {
      ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L" ", Verbose, TRUE);
      ShellPrintHiiEx(
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_DH_OUTPUT),
        gShellDriver1HiiHandle,
        ConvertHandleToHandleIndex(TheHandle),
        ProtocolInfoString==NULL?L"":ProtocolInfoString
      );
    } else {
      ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, Verbose ? L"\r\n" : L" ", Verbose, TRUE);
      if (Verbose) {
        ShellPrintHiiEx(
          -1,
          -1,
          NULL,
          STRING_TOKEN (STR_DH_OUTPUT_SINGLE),
          gShellDriver1HiiHandle,
          ConvertHandleToHandleIndex(TheHandle),
          TheHandle,
          ProtocolInfoString==NULL?L"":ProtocolInfoString
        );
      } else {
        ShellPrintHiiEx(
          -1,
          -1,
          NULL,
          STRING_TOKEN (STR_DH_OUTPUT_SINGLE_D),
          gShellDriver1HiiHandle,
          ConvertHandleToHandleIndex(TheHandle),
          ProtocolInfoString==NULL?L"":ProtocolInfoString
        );
      }
    }

    if (DriverInfo) {
      DisplayDriverModelHandle ((EFI_HANDLE)TheHandle, TRUE, Language);
    }
  } else {
      ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L";", FALSE, FALSE);
      ShellPrintHiiEx(
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_DH_OUTPUT_SFO),
        gShellDriver1HiiHandle,
        Multiple ?L"HandlesInfo":L"HandleInfo",
        L"DriverName",
        L"ControllerName",
        ConvertHandleToHandleIndex(TheHandle),
        L"DevPath",
        ProtocolInfoString==NULL?L"":ProtocolInfoString
      );
  }

  if (ProtocolInfoString != NULL) {
    FreePool(ProtocolInfoString);
  }
}

/**
  Display information for all handles on a list.

  @param[in] HandleList       The NULL-terminated list of handles.
  @param[in] Verbose          TRUE for extra info, FALSE otherwise.
  @param[in] Sfo              TRUE to output in standard format output (spec).
  @param[in] Language         Language string per UEFI specification.
  @param[in] DriverInfo       TRUE to show all info about the handle.

  @retval SHELL_SUCCESS       The operation was successful.
  @retval SHELL_ABORTED       The operation was aborted.
**/
SHELL_STATUS
DoDhForHandleList(
  IN CONST EFI_HANDLE *HandleList,
  IN CONST BOOLEAN    Verbose,
  IN CONST BOOLEAN    Sfo,
  IN CONST CHAR8      *Language,
  IN CONST BOOLEAN    DriverInfo
  )
{
  CONST EFI_HANDLE  *HandleWalker;
  SHELL_STATUS      ShellStatus;

  ShellStatus       = SHELL_SUCCESS;
  for (HandleWalker = HandleList; HandleWalker != NULL && *HandleWalker != NULL; HandleWalker++) {
    DoDhByHandle (*HandleWalker, Verbose, Sfo, Language, DriverInfo, TRUE);
    if (ShellGetExecutionBreakFlag ()) {
      ShellStatus = SHELL_ABORTED;
      break;
    }
  }
  return (ShellStatus);
}

/**
  Display information for a GUID of protocol.

  @param[in] Guid             The pointer to the name of the protocol.
  @param[in] Verbose          TRUE for extra info, FALSE otherwise.
  @param[in] Sfo              TRUE to output in standard format output (spec).
  @param[in] Language         Language string per UEFI specification.
  @param[in] DriverInfo       TRUE to show all info about the handle.

  @retval SHELL_SUCCESS           The operation was successful.
  @retval SHELL_NOT_FOUND         The GUID was not found.
  @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
**/
SHELL_STATUS
DoDhByProtocolGuid(
  IN CONST GUID     *Guid,
  IN CONST BOOLEAN  Verbose,
  IN CONST BOOLEAN  Sfo,
  IN CONST CHAR8    *Language,
  IN CONST BOOLEAN  DriverInfo
  )
{
  CHAR16        *Name;
  SHELL_STATUS  ShellStatus;
  EFI_HANDLE    *HandleList;

  if (!Sfo) {
    if (Guid == NULL) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_ALL_HEADER), gShellDriver1HiiHandle);
    } else {
      Name = GetStringNameFromGuid (Guid, NULL);
      if (Name == NULL) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_GUID_HEADER), gShellDriver1HiiHandle, Guid);
      } else {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_NAME_HEADER), gShellDriver1HiiHandle, Name);
      }
    }
  }
  HandleList = GetHandleListByProtocol(Guid);
  ShellStatus = DoDhForHandleList(HandleList, Verbose, Sfo, Language, DriverInfo);
  SHELL_FREE_NON_NULL(HandleList);

  return ShellStatus;
}

/**
  Function to determine use which method to print information.
  If Protocol is NULL, The function will print all information.

  @param[in] Protocol         The pointer to the name or GUID of protocol or NULL.
  @param[in] Verbose          TRUE for extra info, FALSE otherwise.
  @param[in] Sfo              TRUE to output in standard format output (spec).
  @param[in] Language         Language string per UEFI specification.
  @param[in] DriverInfo       TRUE to show all info about the handle.

  @retval SHELL_SUCCESS             The operation was successful.
  @retval SHELL_NOT_FOUND           The protocol was not found.
  @retval SHELL_INVALID_PARAMETER   Protocol is invalid parameter.
**/
SHELL_STATUS
DoDhByProtocol (
  IN CONST CHAR16   *Protocol,
  IN CONST BOOLEAN  Verbose,
  IN CONST BOOLEAN  Sfo,
  IN CONST CHAR8    *Language,
  IN CONST BOOLEAN  DriverInfo
  )
{
  EFI_GUID      Guid;
  EFI_GUID      *GuidPtr;
  EFI_STATUS    Status;

  if (Protocol == NULL) {
    return DoDhByProtocolGuid (NULL, Verbose, Sfo, Language, DriverInfo);
  } else {
    Status = ConvertStrToGuid (Protocol, &Guid);
    if (!EFI_ERROR (Status)) {
      GuidPtr = &Guid;
    } else {
      //
      // Protocol is a Name, convert it to GUID
      //
      Status = GetGuidFromStringName (Protocol, Language, &GuidPtr);
      if (EFI_ERROR(Status)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_NAME_FOUND), gShellDriver1HiiHandle, Protocol);
        return (SHELL_NOT_FOUND);
      }
    }

    return DoDhByProtocolGuid (GuidPtr, Verbose, Sfo, Language, DriverInfo);
  }
}

/**
  Function to display decode information by Protocol.
  The parameter Protocol is either a GUID or the name of protocol.
  If the parameter Protocol is NULL, the function will print all
  decode information.

  @param[in] Protocol         The pointer to the name or GUID of protocol.
  @param[in] Language         Language string per UEFI specification.

  @retval SHELL_SUCCESS           The operation was successful.
  @retval SHELL_OUT_OT_RESOURCES  A memory allocation failed.
**/
SHELL_STATUS
DoDecodeByProtocol(
  IN CONST CHAR16 *Protocol,
  IN CONST CHAR8  *Language
  )
{
  EFI_STATUS    Status;
  EFI_GUID      *Guids;
  EFI_GUID      Guid;
  UINTN         Counts;
  UINTN         Index;
  CHAR16        *Name;

  if (Protocol == NULL) {
    Counts = 0;
    Status = GetAllMappingGuids (NULL, &Counts);
    if (Status == EFI_BUFFER_TOO_SMALL) {
      Guids = AllocatePool (Counts * sizeof(EFI_GUID));
      if (Guids == NULL) {
        return SHELL_OUT_OF_RESOURCES;
      }

      Status = GetAllMappingGuids (Guids, &Counts);
      if (Status == EFI_SUCCESS) {
        for (Index = 0; Index < Counts; Index++) {
          Name = GetStringNameFromGuid (&Guids[Index], Language);
          if (Name != NULL) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Name, &Guids[Index]);
          } else {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, &Guids[Index]);
          }
          SHELL_FREE_NON_NULL (Name);
        }
      }
      FreePool (Guids);
    }
  } else {
    if (ConvertStrToGuid (Protocol, &Guid) == EFI_SUCCESS) {
      Name = GetStringNameFromGuid (&Guid, Language);
      if (Name != NULL) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Name, &Guid);
      } else {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, &Guid);
      }
      SHELL_FREE_NON_NULL(Name);
    } else {
      Status = GetGuidFromStringName (Protocol, Language, &Guids);
      if (Status == EFI_SUCCESS) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Protocol, Guids);
      } else {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_NAME_FOUND), gShellDriver1HiiHandle, Protocol);
      }
    }
  }

  return SHELL_SUCCESS;
}

/**
  Function for 'dh' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunDh (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS          Status;
  LIST_ENTRY          *Package;
  CHAR16              *ProblemParam;
  SHELL_STATUS        ShellStatus;
  CHAR8               *Language;
  CONST CHAR16        *Lang;
  CONST CHAR16        *RawValue;
  CONST CHAR16        *ProtocolVal;
  BOOLEAN             SfoFlag;
  BOOLEAN             DriverFlag;
  BOOLEAN             VerboseFlag;
  UINT64              Intermediate;
  EFI_HANDLE          Handle;

  ShellStatus         = SHELL_SUCCESS;
  Status              = EFI_SUCCESS;
  Language            = NULL;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize();
  ASSERT_EFI_ERROR(Status);

  Status = CommandInit();
  ASSERT_EFI_ERROR(Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR(Status)) {
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"dh", ProblemParam);
      FreePool(ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT(FALSE);
    }
  } else {
    if (ShellCommandLineGetCount(Package) > 2) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");
      ShellCommandLineFreeVarList (Package);
      return (SHELL_INVALID_PARAMETER);
    }

    if (ShellCommandLineGetFlag(Package, L"-l")) {
      Lang = ShellCommandLineGetValue(Package, L"-l");
      if (Lang != NULL) {
        Language = AllocateZeroPool(StrSize(Lang));
        AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
      } else {
        ASSERT(Language == NULL);
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-l");
        ShellCommandLineFreeVarList(Package);
        return (SHELL_INVALID_PARAMETER);
      }
    } else {
      Language = AllocateZeroPool(10);
      AsciiSPrint(Language, 10, "en-us");
    }

    SfoFlag     = ShellCommandLineGetFlag (Package, L"-sfo");
    DriverFlag  = ShellCommandLineGetFlag (Package, L"-d");
    VerboseFlag = (BOOLEAN)(ShellCommandLineGetFlag (Package, L"-v") || ShellCommandLineGetFlag (Package, L"-verbose"));
    RawValue    = ShellCommandLineGetRawValue (Package, 1);
    ProtocolVal = ShellCommandLineGetValue (Package, L"-p");

    if (RawValue == NULL) {
      if (ShellCommandLineGetFlag (Package, L"-p") && (ProtocolVal == NULL)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-p");
        ShellStatus = SHELL_INVALID_PARAMETER;
      } else {
        //
        // Print information by protocol, The ProtocolVal maybe is name or GUID or NULL.
        //
        ShellStatus = DoDhByProtocol (ProtocolVal, VerboseFlag, SfoFlag, Language, DriverFlag);
      }
    } else if ((RawValue != NULL) &&
               (gUnicodeCollation->StriColl(gUnicodeCollation, L"decode", (CHAR16 *) RawValue) == 0)) {
      if (ShellCommandLineGetFlag (Package, L"-p") && (ProtocolVal == NULL)) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-p");
        ShellStatus = SHELL_INVALID_PARAMETER;
      } else {
        //
        // Print decode informatino by protocol.
        //
        ShellStatus = DoDecodeByProtocol (ProtocolVal, Language);
      }
    } else {
      if (ShellCommandLineGetFlag (Package, L"-p")) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");
        ShellStatus = SHELL_INVALID_PARAMETER;
      } else {
        Status = ShellConvertStringToUint64 (RawValue, &Intermediate, TRUE, FALSE);
        if (EFI_ERROR(Status)) {
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", RawValue);
          ShellStatus = SHELL_INVALID_PARAMETER;
        } else {
          Handle = ConvertHandleIndexToHandle ((UINTN) Intermediate);
          if (Handle == NULL) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", RawValue);
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            //
            // Print information by handle.
            //
            DoDhByHandle (Handle, VerboseFlag, SfoFlag, Language, DriverFlag, FALSE);
          }
        }
      }
    }

    ShellCommandLineFreeVarList (Package);
    SHELL_FREE_NON_NULL(Language);
  }

  return (ShellStatus);
}
