]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c
ShellPkg: Refine type cast for pointer subtraction
[mirror_edk2.git] / ShellPkg / Library / UefiShellDriver1CommandsLib / Dh.c
index 3d3f1b19f461ec48e71a7468ce8b88bee8a555f7..0bcee9245c63fdb6c616c5f843e394a1bbe9f179 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
   Main file for Dh shell Driver1 function.\r
 \r
-  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>\r
+  Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -40,8 +41,202 @@ STATIC CONST EFI_GUID *UefiDriverModelProtocolsGuidArray[] = {
   NULL\r
 };\r
 \r
+UINTN mGuidDataLen[] = {8, 4, 4, 4, 12};\r
+/**\r
+  Function to determine if the string can convert to a GUID.\r
+  The string must be restricted as "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" format.\r
+\r
+  @param[in]  String  The string to test.\r
+\r
+  @retval     TRUE    The string can convert to a GUID.\r
+  @retval     FALSE   The string can't convert to a GUID.\r
+**/\r
+BOOLEAN\r
+IsValidGuidString(\r
+  IN CONST CHAR16 *String\r
+  )\r
+{\r
+  CONST CHAR16  *Walker;\r
+  CONST CHAR16  *PrevWalker;\r
+  UINTN         Index;\r
+\r
+  if (String == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  Walker      = String;\r
+  PrevWalker  = String;\r
+  Index       = 0;\r
+\r
+  while (Walker != NULL && *Walker != CHAR_NULL) {\r
+    if ( (*Walker >= '0' && *Walker <= '9') ||\r
+         (*Walker >= 'a' && *Walker <= 'f') ||\r
+         (*Walker >= 'A' && *Walker <= 'F')\r
+       ) {\r
+      Walker++;\r
+    } else {\r
+      if (*Walker == L'-' && (((UINTN)Walker - (UINTN)PrevWalker) / sizeof (CHAR16)) == mGuidDataLen[Index]) {\r
+        Walker++;\r
+        PrevWalker = Walker;\r
+        Index++;\r
+      } else {\r
+        return FALSE;\r
+      }\r
+    }\r
+  }\r
+\r
+  if ((((UINTN)Walker - (UINTN)PrevWalker) / sizeof (CHAR16)) == mGuidDataLen[Index]) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/**\r
+  Convert a hex-character to decimal value.\r
+\r
+  This internal function only deal with Unicode character\r
+  which maps to a valid hexadecimal ASII character, i.e.\r
+  L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other\r
+  Unicode character, the value returned does not make sense.\r
+\r
+  @param[in]  Char      The character to convert.\r
+\r
+  @retval               The numerical value converted.\r
+**/\r
+UINTN\r
+HexCharToDecimal(\r
+  IN CHAR16 Char\r
+  )\r
+{\r
+  if (Char >= '0' && Char <= '9') {\r
+    return Char - L'0';\r
+  } else if (Char >= 'a' && Char <= 'f') {\r
+    return Char - L'a' + 10;\r
+  } else {\r
+    return Char - L'A' + 10;\r
+  }\r
+}\r
+\r
+/**\r
+  Function try to convert a string to GUID format.\r
+\r
+  @param[in]    String    The string will be converted.\r
+  @param[out]   Guid      Save the result convert from string.\r
+\r
+  @retval EFI_SUCCESS     The string was successfully converted to a GUID.\r
+  @retval EFI_UNSUPPORTED The input string is not in registry format.\r
+**/\r
+EFI_STATUS\r
+ConvertStrToGuid(\r
+  IN  CONST CHAR16 *String,\r
+  OUT GUID *Guid\r
+  )\r
+{\r
+  CONST CHAR16  *Walker;\r
+  UINT8         TempValue;\r
+  UINTN         Index;\r
+\r
+  if (String == NULL || !IsValidGuidString (String)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Index = 0;\r
+\r
+  Walker = String;\r
+  Guid->Data1 = (UINT32)StrHexToUint64 (Walker);\r
+\r
+  Walker += 9;\r
+  Guid->Data2 = (UINT16)StrHexToUint64 (Walker);\r
+\r
+  Walker += 5;\r
+  Guid->Data3 = (UINT16)StrHexToUint64 (Walker);\r
+\r
+  Walker += 5;\r
+  while (Walker != NULL && *Walker != CHAR_NULL) {\r
+    if (*Walker == L'-') {\r
+      Walker++;\r
+    } else {\r
+      TempValue = (UINT8)HexCharToDecimal (*Walker);\r
+      TempValue = (UINT8)LShiftU64 (TempValue, 4);\r
+      Walker++;\r
+\r
+      TempValue += (UINT8)HexCharToDecimal (*Walker);\r
+      Walker++;\r
+\r
+      Guid->Data4[Index] = TempValue;\r
+      Index++;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Get the name of a driver by it's handle.\r
+\r
+  If a name is found the memory must be callee freed.\r
+\r
+  @param[in] TheHandle    The driver's handle.\r
+  @param[in] Language     The language to use.\r
+  @param[in] NameFound    Upon a successful return the name found.\r
+\r
+  @retval EFI_SUCCESS     The name was found.\r
+**/\r
+EFI_STATUS\r
+GetDriverName (\r
+  IN EFI_HANDLE   TheHandle,\r
+  IN CONST CHAR8  *Language,\r
+  IN CHAR16       **NameFound\r
+  )\r
+{\r
+  CHAR8                             *Lang;\r
+  EFI_STATUS                        Status;\r
+  EFI_COMPONENT_NAME2_PROTOCOL      *CompName2;\r
+  CHAR16                            *NameToReturn;\r
+  //\r
+  // Go through those handles until we get one that passes for GetComponentName\r
+  //\r
+  Status = gBS->OpenProtocol(\r
+    TheHandle,\r
+    &gEfiComponentName2ProtocolGuid,\r
+    (VOID**)&CompName2,\r
+    gImageHandle,\r
+    NULL,\r
+    EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
+  if (EFI_ERROR(Status)) {\r
+    Status = gBS->OpenProtocol(\r
+      TheHandle,\r
+      &gEfiComponentNameProtocolGuid,\r
+      (VOID**)&CompName2,\r
+      gImageHandle,\r
+      NULL,\r
+      EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
+  }\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    return (EFI_NOT_FOUND);\r
+  }\r
+  Lang = GetBestLanguageForDriver (CompName2->SupportedLanguages, Language, FALSE);\r
+  Status = CompName2->GetDriverName(CompName2, Lang, &NameToReturn);\r
+  FreePool(Lang);\r
+\r
+  if (!EFI_ERROR(Status) && NameToReturn != NULL) {\r
+    *NameFound = NULL;\r
+    StrnCatGrow(NameFound, NULL, NameToReturn, 0);\r
+  }\r
+  return (Status);\r
+}\r
+\r
+/**\r
+  Discover if a protocol guid is one of the UEFI Driver Model Protocols.\r
+\r
+  @param[in] Guid   The guid to test.\r
+\r
+  @retval TRUE      The guid does represent a driver model protocol.\r
+  @retval FALSE     The guid does not represent a driver model protocol.\r
+**/\r
 BOOLEAN\r
-EFIAPI\r
 IsDriverProt (\r
   IN CONST EFI_GUID *Guid\r
   )\r
@@ -61,13 +256,23 @@ IsDriverProt (
   return (GuidFound);\r
 }\r
 \r
+/**\r
+  Get information for a handle.\r
+\r
+  @param[in] TheHandle        The handles to show info on.\r
+  @param[in] Language         Language string per UEFI specification.\r
+  @param[in] Separator        Separator string between information blocks.\r
+  @param[in] Verbose          TRUE for extra info, FALSE otherwise.\r
+  @param[in] ExtraInfo        TRUE for extra info, FALSE otherwise.\r
+\r
+  @retval SHELL_SUCCESS           The operation was successful.\r
+  @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.\r
+**/\r
 CHAR16*\r
-EFIAPI\r
 GetProtocolInfoString(\r
   IN CONST EFI_HANDLE TheHandle,\r
   IN CONST CHAR8      *Language,\r
-  IN CONST CHAR16     *Seperator,\r
-  IN CONST BOOLEAN    DriverInfo,\r
+  IN CONST CHAR16     *Separator,\r
   IN CONST BOOLEAN    Verbose,\r
   IN CONST BOOLEAN    ExtraInfo\r
   )\r
@@ -79,8 +284,11 @@ GetProtocolInfoString(
   CHAR16                    *RetVal;\r
   UINTN                     Size;\r
   CHAR16                    *Temp;\r
+  CHAR16                    GuidStr[40];\r
 \r
   ProtocolGuidArray = NULL;\r
+  RetVal            = NULL;\r
+  Size              = 0;\r
 \r
   Status = gBS->ProtocolsPerHandle (\r
                 TheHandle,\r
@@ -88,20 +296,21 @@ GetProtocolInfoString(
                 &ArrayCount\r
                );\r
   if (!EFI_ERROR (Status)) {\r
-    RetVal = NULL;\r
-    Size   = 0;\r
     for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
       Temp = GetStringNameFromGuid(ProtocolGuidArray[ProtocolIndex], Language);\r
-      if (Temp != NULL) {\r
-        ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));\r
-        if (Size != 0) {\r
-          StrnCatGrow(&RetVal, &Size, Seperator, 0);\r
-        }\r
-        StrnCatGrow(&RetVal, &Size, L"%H", 0);\r
+      ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));\r
+      if (Size != 0) {\r
+        StrnCatGrow(&RetVal, &Size, Separator, 0);\r
+      }\r
+      StrnCatGrow(&RetVal, &Size, L"%H", 0);\r
+      if (Temp == NULL) {\r
+        UnicodeSPrint (GuidStr, sizeof (GuidStr), L"%g", ProtocolGuidArray[ProtocolIndex]);\r
+        StrnCatGrow (&RetVal, &Size, GuidStr, 0);\r
+      } else {\r
         StrnCatGrow(&RetVal, &Size, Temp, 0);\r
-        StrnCatGrow(&RetVal, &Size, L"%N", 0);\r
         FreePool(Temp);\r
       }\r
+      StrnCatGrow(&RetVal, &Size, L"%N", 0);\r
       if (ExtraInfo) {\r
         Temp = GetProtocolInformationDump(TheHandle, ProtocolGuidArray[ProtocolIndex], Verbose);\r
         if (Temp != NULL) {\r
@@ -109,29 +318,463 @@ GetProtocolInfoString(
           if (!Verbose) {\r
             StrnCatGrow(&RetVal, &Size, L"(", 0);\r
             StrnCatGrow(&RetVal, &Size, Temp, 0);\r
-            StrnCatGrow(&RetVal, &Size, L")", 0);\r
+            StrnCatGrow(&RetVal, &Size, L")\r\n", 0);\r
           } else {\r
-            StrnCatGrow(&RetVal, &Size, Seperator, 0);\r
+            StrnCatGrow(&RetVal, &Size, Separator, 0);\r
             StrnCatGrow(&RetVal, &Size, Temp, 0);\r
           }\r
           FreePool(Temp);\r
         }\r
       }\r
     }\r
-  } else {\r
-    return (NULL);\r
   }\r
+  \r
+  SHELL_FREE_NON_NULL(ProtocolGuidArray);\r
 \r
-  if (ProtocolGuidArray != NULL) {\r
-    FreePool(ProtocolGuidArray);\r
+  if (RetVal == NULL) {\r
+    return (NULL);\r
   }\r
+\r
   ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));\r
-  StrnCatGrow(&RetVal, &Size, Seperator, 0);\r
+  StrnCatGrow(&RetVal, &Size, Separator, 0);\r
   return (RetVal);\r
 }\r
 \r
-SHELL_STATUS\r
-EFIAPI\r
+/**\r
+  Gets the name of the loaded image.\r
+\r
+  @param[in] TheHandle    The handle of the driver to get info on.\r
+  @param[out] Name        The pointer to the pointer.  Valid upon a successful return.\r
+\r
+  @retval EFI_SUCCESS     The operation was successful.\r
+**/\r
+EFI_STATUS\r
+GetDriverImageName (\r
+  IN EFI_HANDLE   TheHandle,\r
+  OUT CHAR16      **Name\r
+  )\r
+{\r
+  // get loaded image and devicepathtotext on image->Filepath\r
+  EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
+  EFI_STATUS                Status;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+\r
+  if (TheHandle == NULL || Name == NULL) {\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+\r
+  Status = gBS->OpenProtocol (\r
+                TheHandle,\r
+                &gEfiLoadedImageProtocolGuid,\r
+                (VOID **) &LoadedImage,\r
+                gImageHandle,\r
+                NULL,\r
+                EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+               );\r
+  if (EFI_ERROR(Status)) {\r
+    return (Status);\r
+  }\r
+  DevicePath = LoadedImage->FilePath;\r
+  *Name = ConvertDevicePathToText(DevicePath, TRUE, TRUE);\r
+  return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+  Display driver model information for a given handle.\r
+  \r
+  @param[in] Handle     The handle to display info on.\r
+  @param[in] BestName   Use the best name?\r
+  @param[in] Language   The language to output in.\r
+**/\r
+EFI_STATUS\r
+DisplayDriverModelHandle (\r
+  IN EFI_HANDLE  Handle,\r
+  IN BOOLEAN     BestName,\r
+  IN CONST CHAR8 *Language OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  BOOLEAN                     ConfigurationStatus;\r
+  BOOLEAN                     DiagnosticsStatus;\r
+  UINTN                       DriverBindingHandleCount;\r
+  EFI_HANDLE                  *DriverBindingHandleBuffer;\r
+  UINTN                       ParentControllerHandleCount;\r
+  EFI_HANDLE                  *ParentControllerHandleBuffer;\r
+  UINTN                       ChildControllerHandleCount;\r
+  EFI_HANDLE                  *ChildControllerHandleBuffer;\r
+  CHAR16                      *TempStringPointer;\r
+  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;\r
+  UINTN                       Index;\r
+  CHAR16                      *DriverName;\r
+  EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
+  UINTN                       NumberOfChildren;\r
+  UINTN                       HandleIndex;\r
+  UINTN                       ControllerHandleCount;\r
+  EFI_HANDLE                  *ControllerHandleBuffer;\r
+  UINTN                       ChildIndex;\r
+  BOOLEAN                     Image;\r
+\r
+  DriverName = NULL;\r
+\r
+  //\r
+  // See if Handle is a device handle and display its details.\r
+  //\r
+  DriverBindingHandleBuffer = NULL;\r
+  Status = PARSE_HANDLE_DATABASE_UEFI_DRIVERS (\r
+            Handle,\r
+            &DriverBindingHandleCount,\r
+            &DriverBindingHandleBuffer\r
+            );\r
+\r
+  ParentControllerHandleBuffer = NULL;\r
+  Status = PARSE_HANDLE_DATABASE_PARENTS (\r
+            Handle,\r
+            &ParentControllerHandleCount,\r
+            &ParentControllerHandleBuffer\r
+            );\r
+\r
+  ChildControllerHandleBuffer = NULL;\r
+  Status = ParseHandleDatabaseForChildControllers (\r
+            Handle,\r
+            &ChildControllerHandleCount,\r
+            &ChildControllerHandleBuffer\r
+            );\r
+\r
+  DiagnosticsStatus = FALSE;\r
+  ConfigurationStatus = FALSE;\r
+\r
+  if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfigurationProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {\r
+    ConfigurationStatus = TRUE;\r
+  }\r
+  if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverConfiguration2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {\r
+    ConfigurationStatus = TRUE;\r
+  }\r
+  if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnosticsProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {\r
+    DiagnosticsStatus = TRUE;\r
+  }\r
+  if (!EFI_ERROR(gBS->OpenProtocol(Handle, &gEfiDriverDiagnostics2ProtocolGuid, NULL, NULL, gImageHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {\r
+    DiagnosticsStatus = TRUE;\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (DriverBindingHandleCount > 0 || ParentControllerHandleCount > 0 || ChildControllerHandleCount > 0) {\r
+\r
+\r
+\r
+    DevicePath          = NULL;\r
+    TempStringPointer   = NULL;\r
+    Status              = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID**)&DevicePath);\r
+\r
+    Status = gEfiShellProtocol->GetDeviceName(Handle, EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);\r
+    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DRIVER1), gShellDriver1HiiHandle, TempStringPointer!=NULL?TempStringPointer:L"<Unknown>");\r
+    SHELL_FREE_NON_NULL(TempStringPointer);\r
+  \r
+    TempStringPointer = ConvertDevicePathToText(DevicePath, TRUE, FALSE);\r
+    ShellPrintHiiEx(\r
+      -1, \r
+      -1, \r
+      NULL, \r
+      STRING_TOKEN (STR_DH_OUTPUT_DRIVER2), \r
+      gShellDriver1HiiHandle, \r
+      TempStringPointer!=NULL?TempStringPointer:L"<None>",\r
+      ParentControllerHandleCount == 0?L"ROOT":(ChildControllerHandleCount > 0)?L"BUS":L"DEVICE",\r
+      ConfigurationStatus?L"YES":L"NO",\r
+      DiagnosticsStatus?L"YES":L"NO"\r
+      );\r
+\r
+    SHELL_FREE_NON_NULL(TempStringPointer);\r
+\r
+    if (DriverBindingHandleCount == 0) {\r
+      ShellPrintHiiEx(\r
+        -1, \r
+        -1, \r
+        NULL, \r
+        STRING_TOKEN (STR_DH_OUTPUT_DRIVER3), \r
+        gShellDriver1HiiHandle, \r
+        L"<None>"\r
+        );\r
+    } else {\r
+      ShellPrintHiiEx(\r
+        -1, \r
+        -1, \r
+        NULL, \r
+        STRING_TOKEN (STR_DH_OUTPUT_DRIVER3), \r
+        gShellDriver1HiiHandle, \r
+        L""\r
+        );\r
+      for (Index = 0; Index < DriverBindingHandleCount; Index++) {\r
+        Image = FALSE;\r
+        Status = GetDriverName (\r
+                  DriverBindingHandleBuffer[Index],\r
+                  Language,\r
+                  &DriverName\r
+                  );\r
+        if (EFI_ERROR (Status)) {\r
+          Status = GetDriverImageName (\r
+                    DriverBindingHandleBuffer[Index],\r
+                    &DriverName\r
+                    );\r
+          if (EFI_ERROR (Status)) {\r
+            DriverName = NULL;\r
+          }\r
+        }\r
+\r
+        if (Image) {\r
+          ShellPrintHiiEx(\r
+            -1, \r
+            -1, \r
+            NULL, \r
+            STRING_TOKEN (STR_DH_OUTPUT_DRIVER4A),\r
+            gShellDriver1HiiHandle,\r
+            ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),\r
+            DriverName!=NULL?DriverName:L"<Unknown>"\r
+            );\r
+        } else {\r
+          ShellPrintHiiEx(\r
+            -1, \r
+            -1, \r
+            NULL, \r
+            STRING_TOKEN (STR_DH_OUTPUT_DRIVER4B),\r
+            gShellDriver1HiiHandle,\r
+            ConvertHandleToHandleIndex (DriverBindingHandleBuffer[Index]),\r
+            DriverName!=NULL?DriverName:L"<Unknown>"\r
+            );\r
+        }\r
+        SHELL_FREE_NON_NULL(DriverName);\r
+      }\r
+    }\r
+\r
+    if (ParentControllerHandleCount == 0) {\r
+      ShellPrintHiiEx(\r
+        -1, \r
+        -1, \r
+        NULL, \r
+        STRING_TOKEN (STR_DH_OUTPUT_DRIVER5), \r
+        gShellDriver1HiiHandle, \r
+        L"<None>"\r
+        );\r
+    } else {\r
+      ShellPrintHiiEx(\r
+        -1, \r
+        -1, \r
+        NULL, \r
+        STRING_TOKEN (STR_DH_OUTPUT_DRIVER5), \r
+        gShellDriver1HiiHandle, \r
+        L""\r
+        );\r
+      for (Index = 0; Index < ParentControllerHandleCount; Index++) {\r
+        Status = gEfiShellProtocol->GetDeviceName(ParentControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);\r
+        ShellPrintHiiEx(\r
+          -1, \r
+          -1, \r
+          NULL, \r
+          STRING_TOKEN (STR_DH_OUTPUT_DRIVER5B),\r
+          gShellDriver1HiiHandle,\r
+          ConvertHandleToHandleIndex (ParentControllerHandleBuffer[Index]),\r
+          TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"\r
+          );\r
+        SHELL_FREE_NON_NULL(TempStringPointer);\r
+      }\r
+    }\r
+\r
+    if (ChildControllerHandleCount == 0) {\r
+      ShellPrintHiiEx(\r
+        -1, \r
+        -1, \r
+        NULL, \r
+        STRING_TOKEN (STR_DH_OUTPUT_DRIVER6), \r
+        gShellDriver1HiiHandle, \r
+        L"<None>"\r
+        );\r
+    } else {\r
+      ShellPrintHiiEx(\r
+        -1, \r
+        -1, \r
+        NULL, \r
+        STRING_TOKEN (STR_DH_OUTPUT_DRIVER6), \r
+        gShellDriver1HiiHandle, \r
+        L""\r
+        );\r
+      for (Index = 0; Index < ChildControllerHandleCount; Index++) {\r
+        Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[Index], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);\r
+        ShellPrintHiiEx(\r
+          -1, \r
+          -1, \r
+          NULL, \r
+          STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),\r
+          gShellDriver1HiiHandle,\r
+          ConvertHandleToHandleIndex (ChildControllerHandleBuffer[Index]),\r
+          TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"\r
+          );\r
+        SHELL_FREE_NON_NULL(TempStringPointer);\r
+      }\r
+    }\r
+  }\r
+\r
+  SHELL_FREE_NON_NULL(DriverBindingHandleBuffer);\r
+\r
+  SHELL_FREE_NON_NULL(ParentControllerHandleBuffer);\r
+\r
+  SHELL_FREE_NON_NULL(ChildControllerHandleBuffer);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // See if Handle is a driver binding handle and display its details.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                Handle,\r
+                &gEfiDriverBindingProtocolGuid,\r
+                (VOID **) &DriverBinding,\r
+                NULL,\r
+                NULL,\r
+                EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  NumberOfChildren        = 0;\r
+  ControllerHandleBuffer  = NULL;\r
+  Status = PARSE_HANDLE_DATABASE_DEVICES (\r
+            Handle,\r
+            &ControllerHandleCount,\r
+            &ControllerHandleBuffer\r
+            );\r
+  if (ControllerHandleCount > 0) {\r
+    for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {\r
+      Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (\r
+                Handle,\r
+                ControllerHandleBuffer[HandleIndex],\r
+                &ChildControllerHandleCount,\r
+                NULL\r
+                );\r
+      NumberOfChildren += ChildControllerHandleCount;\r
+    }\r
+  }\r
+\r
+  Status = GetDriverName (Handle, Language, &DriverName);\r
+  if (EFI_ERROR (Status)) {\r
+    DriverName = NULL;\r
+  }\r
+\r
+  ShellPrintHiiEx(\r
+    -1, \r
+    -1, \r
+    NULL, \r
+    STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),\r
+    gShellDriver1HiiHandle,\r
+    ConvertHandleToHandleIndex(Handle),\r
+    DriverName!=NULL?DriverName:L"<Unknown>"\r
+    );\r
+  SHELL_FREE_NON_NULL(DriverName);\r
+  Status = GetDriverImageName (\r
+            Handle,\r
+            &DriverName\r
+            );\r
+  if (EFI_ERROR (Status)) {\r
+    DriverName = NULL;\r
+  }\r
+  ShellPrintHiiEx(\r
+    -1, \r
+    -1, \r
+    NULL, \r
+    STRING_TOKEN (STR_DH_OUTPUT_DRIVER7B),\r
+    gShellDriver1HiiHandle,\r
+    DriverName!=NULL?DriverName:L"<Unknown>"\r
+    );\r
+  SHELL_FREE_NON_NULL(DriverName);\r
+\r
+  ShellPrintHiiEx(\r
+    -1, \r
+    -1, \r
+    NULL, \r
+    STRING_TOKEN (STR_DH_OUTPUT_DRIVER8), \r
+    gShellDriver1HiiHandle, \r
+    DriverBinding->Version,\r
+    NumberOfChildren > 0?L"Bus":ControllerHandleCount > 0?L"Device":L"<Unknown>",\r
+    ConfigurationStatus?L"YES":L"NO",\r
+    DiagnosticsStatus?L"YES":L"NO"\r
+    );\r
+\r
+  if (ControllerHandleCount == 0) {\r
+      ShellPrintHiiEx(\r
+        -1, \r
+        -1, \r
+        NULL, \r
+        STRING_TOKEN (STR_DH_OUTPUT_DRIVER6), \r
+        gShellDriver1HiiHandle, \r
+        L"None"\r
+        );\r
+  } else {\r
+    ShellPrintHiiEx(\r
+      -1, \r
+      -1, \r
+      NULL, \r
+      STRING_TOKEN (STR_DH_OUTPUT_DRIVER6), \r
+      gShellDriver1HiiHandle, \r
+      L""\r
+      );\r
+    for (HandleIndex = 0; HandleIndex < ControllerHandleCount; HandleIndex++) {\r
+      Status = gEfiShellProtocol->GetDeviceName(ControllerHandleBuffer[HandleIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);\r
+\r
+      ShellPrintHiiEx(\r
+        -1, \r
+        -1, \r
+        NULL, \r
+        STRING_TOKEN (STR_DH_OUTPUT_DRIVER9B),\r
+        gShellDriver1HiiHandle,\r
+        ConvertHandleToHandleIndex(ControllerHandleBuffer[HandleIndex]),\r
+        TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"\r
+        );\r
+      SHELL_FREE_NON_NULL(TempStringPointer);\r
+\r
+      Status = PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (\r
+                Handle,\r
+                ControllerHandleBuffer[HandleIndex],\r
+                &ChildControllerHandleCount,\r
+                &ChildControllerHandleBuffer\r
+                );\r
+      if (!EFI_ERROR (Status)) {\r
+        for (ChildIndex = 0; ChildIndex < ChildControllerHandleCount; ChildIndex++) {\r
+          Status = gEfiShellProtocol->GetDeviceName(ChildControllerHandleBuffer[ChildIndex], EFI_DEVICE_NAME_USE_COMPONENT_NAME|EFI_DEVICE_NAME_USE_DEVICE_PATH, (CHAR8*)Language, &TempStringPointer);\r
+\r
+          ShellPrintHiiEx(\r
+            -1, \r
+            -1, \r
+            NULL, \r
+            STRING_TOKEN (STR_DH_OUTPUT_DRIVER6B),\r
+            gShellDriver1HiiHandle,\r
+            ConvertHandleToHandleIndex(ChildControllerHandleBuffer[ChildIndex]),\r
+            TempStringPointer!=NULL?TempStringPointer:L"<Unknown>"\r
+            );\r
+          SHELL_FREE_NON_NULL(TempStringPointer);\r
+        }\r
+\r
+        SHELL_FREE_NON_NULL (ChildControllerHandleBuffer);\r
+      }\r
+    }\r
+\r
+    SHELL_FREE_NON_NULL (ControllerHandleBuffer);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Display information for a handle.\r
+\r
+  @param[in] TheHandle        The handles to show info on.\r
+  @param[in] Verbose          TRUE for extra info, FALSE otherwise.\r
+  @param[in] Sfo              TRUE to output in standard format output (spec).\r
+  @param[in] Language         Language string per UEFI specification.\r
+  @param[in] DriverInfo       TRUE to show all info about the handle.\r
+  @param[in] Multiple         TRUE indicates more than  will be output,\r
+                              FALSE for a single one.\r
+**/\r
+VOID\r
 DoDhByHandle(\r
   IN CONST EFI_HANDLE TheHandle,\r
   IN CONST BOOLEAN    Verbose,\r
@@ -141,17 +784,13 @@ DoDhByHandle(
   IN CONST BOOLEAN    Multiple\r
   )\r
 {\r
-  CHAR16              *ProtocolInfoString;\r
-  SHELL_STATUS        ShellStatus;\r
-  EFI_STATUS          Status;\r
+  CHAR16 *ProtocolInfoString;\r
 \r
-  Status              = EFI_SUCCESS;\r
-  ShellStatus         = SHELL_SUCCESS;\r
   ProtocolInfoString  = NULL;\r
 \r
   if (!Sfo) {\r
     if (Multiple) {\r
-      ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L" ", DriverInfo, Verbose, TRUE);\r
+      ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L" ", Verbose, TRUE);\r
       ShellPrintHiiEx(\r
         -1,\r
         -1,\r
@@ -159,9 +798,10 @@ DoDhByHandle(
         STRING_TOKEN (STR_DH_OUTPUT),\r
         gShellDriver1HiiHandle,\r
         ConvertHandleToHandleIndex(TheHandle),\r
-        ProtocolInfoString==NULL?L"":ProtocolInfoString);\r
+        ProtocolInfoString==NULL?L"":ProtocolInfoString\r
+      );\r
     } else {\r
-      ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L"\r\n", DriverInfo, Verbose, TRUE);\r
+      ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L"\r\n", Verbose, TRUE);\r
       ShellPrintHiiEx(\r
         -1,\r
         -1,\r
@@ -170,11 +810,15 @@ DoDhByHandle(
         gShellDriver1HiiHandle,\r
         ConvertHandleToHandleIndex(TheHandle),\r
         TheHandle,\r
-        ProtocolInfoString==NULL?L"":ProtocolInfoString);\r
+        ProtocolInfoString==NULL?L"":ProtocolInfoString\r
+      );\r
+    }\r
+\r
+    if (DriverInfo) {\r
+      DisplayDriverModelHandle ((EFI_HANDLE)TheHandle, TRUE, Language);\r
     }\r
   } else {\r
-//#string STR_DH_OUTPUT_SFO         #language en-US "%s, %s, %s, %H%02x%N, %s, %s\r\n"\r
-      ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L";", DriverInfo, FALSE, FALSE);\r
+      ProtocolInfoString = GetProtocolInfoString(TheHandle, Language, L";", FALSE, FALSE);\r
       ShellPrintHiiEx(\r
         -1,\r
         -1,\r
@@ -186,22 +830,31 @@ DoDhByHandle(
         L"ControllerName",\r
         ConvertHandleToHandleIndex(TheHandle),\r
         L"DevPath",\r
-        ProtocolInfoString==NULL?L"":ProtocolInfoString);\r
-\r
-\r
+        ProtocolInfoString==NULL?L"":ProtocolInfoString\r
+      );\r
   }\r
 \r
-\r
   if (ProtocolInfoString != NULL) {\r
     FreePool(ProtocolInfoString);\r
   }\r
-  return (ShellStatus);\r
 }\r
 \r
+/**\r
+  Display information for all handles on a list.\r
+\r
+  @param[in] HandleList       The NULL-terminated list of handles.\r
+  @param[in] Verbose          TRUE for extra info, FALSE otherwise.\r
+  @param[in] Sfo              TRUE to output in standard format output (spec).\r
+  @param[in] Language         Language string per UEFI specification.\r
+  @param[in] DriverInfo       TRUE to show all info about the handle.\r
+\r
+  @retval SHELL_SUCCESS       The operation was successful.\r
+  @retval SHELL_ABORTED       The operation was aborted.\r
+**/\r
 SHELL_STATUS\r
-EFIAPI\r
 DoDhForHandleList(\r
   IN CONST EFI_HANDLE *HandleList,\r
+  IN CONST BOOLEAN    Verbose,\r
   IN CONST BOOLEAN    Sfo,\r
   IN CONST CHAR8      *Language,\r
   IN CONST BOOLEAN    DriverInfo\r
@@ -211,79 +864,185 @@ DoDhForHandleList(
   SHELL_STATUS      ShellStatus;\r
 \r
   ShellStatus       = SHELL_SUCCESS;\r
-\r
-  for (HandleWalker = HandleList ; HandleWalker != NULL && *HandleWalker != NULL && ShellStatus == SHELL_SUCCESS; HandleWalker++) {\r
-    ShellStatus = DoDhByHandle(\r
-          *HandleWalker,\r
-          FALSE,\r
-          Sfo,\r
-          Language,\r
-          DriverInfo,\r
-          TRUE\r
-         );\r
+  for (HandleWalker = HandleList; HandleWalker != NULL && *HandleWalker != NULL; HandleWalker++) {\r
+    DoDhByHandle (*HandleWalker, Verbose, Sfo, Language, DriverInfo, TRUE);\r
+    if (ShellGetExecutionBreakFlag ()) {\r
+      ShellStatus = SHELL_ABORTED;\r
+      break;\r
+    }\r
   }\r
   return (ShellStatus);\r
 }\r
 \r
+/**\r
+  Display information for a GUID of protocol.\r
+\r
+  @param[in] Guid             The pointer to the name of the protocol.\r
+  @param[in] Verbose          TRUE for extra info, FALSE otherwise.\r
+  @param[in] Sfo              TRUE to output in standard format output (spec).\r
+  @param[in] Language         Language string per UEFI specification.\r
+  @param[in] DriverInfo       TRUE to show all info about the handle.\r
+\r
+  @retval SHELL_SUCCESS           The operation was successful.\r
+  @retval SHELL_NOT_FOUND         The GUID was not found.\r
+  @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.\r
+**/\r
 SHELL_STATUS\r
-EFIAPI\r
-DoDhForAll(\r
+DoDhByProtocolGuid(\r
+  IN CONST GUID     *Guid,\r
+  IN CONST BOOLEAN  Verbose,\r
   IN CONST BOOLEAN  Sfo,\r
   IN CONST CHAR8    *Language,\r
   IN CONST BOOLEAN  DriverInfo\r
   )\r
 {\r
-  EFI_HANDLE    *HandleList;\r
+  CHAR16        *Name;\r
   SHELL_STATUS  ShellStatus;\r
+  EFI_HANDLE    *HandleList;\r
 \r
-  HandleList = GetHandleListByProtocol(NULL);\r
+  if (!Sfo) {\r
+    if (Guid == NULL) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_ALL_HEADER), gShellDriver1HiiHandle);\r
+    } else {\r
+      Name = GetStringNameFromGuid (Guid, NULL);\r
+      if (Name == NULL) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_GUID_HEADER), gShellDriver1HiiHandle, Guid);\r
+      } else {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_NAME_HEADER), gShellDriver1HiiHandle, Name);\r
+      }\r
+    }\r
+  }\r
+  HandleList = GetHandleListByProtocol(Guid);\r
+  ShellStatus = DoDhForHandleList(HandleList, Verbose, Sfo, Language, DriverInfo);\r
+  SHELL_FREE_NON_NULL(HandleList);\r
 \r
-  ShellStatus = DoDhForHandleList(\r
-    HandleList,\r
-    Sfo,\r
-    Language,\r
-    DriverInfo);\r
+  return ShellStatus;\r
+}\r
 \r
-  FreePool(HandleList);\r
+/**\r
+  Function to determine use which method to print information.\r
+  If Protocol is NULL, The function will print all information.\r
 \r
-  return (ShellStatus);\r
-}\r
+  @param[in] Protocol         The pointer to the name or GUID of protocol or NULL.\r
+  @param[in] Verbose          TRUE for extra info, FALSE otherwise.\r
+  @param[in] Sfo              TRUE to output in standard format output (spec).\r
+  @param[in] Language         Language string per UEFI specification.\r
+  @param[in] DriverInfo       TRUE to show all info about the handle.\r
 \r
+  @retval SHELL_SUCCESS             The operation was successful.\r
+  @retval SHELL_NOT_FOUND           The protocol was not found.\r
+  @retval SHELL_INVALID_PARAMETER   Protocol is invalid parameter.\r
+**/\r
 SHELL_STATUS\r
-EFIAPI\r
-DoDhByProtocol(\r
-  IN CONST CHAR16   *ProtocolName,\r
+DoDhByProtocol (\r
+  IN CONST CHAR16   *Protocol,\r
+  IN CONST BOOLEAN  Verbose,\r
   IN CONST BOOLEAN  Sfo,\r
   IN CONST CHAR8    *Language,\r
   IN CONST BOOLEAN  DriverInfo\r
   )\r
 {\r
-  EFI_GUID      *Guid;\r
+  EFI_GUID      Guid;\r
+  EFI_GUID      *GuidPtr;\r
   EFI_STATUS    Status;\r
-  EFI_HANDLE    *HandleList;\r
-  SHELL_STATUS  ShellStatus;\r
 \r
-  ASSERT(ProtocolName != NULL);\r
+  if (Protocol == NULL) {\r
+    return DoDhByProtocolGuid (NULL, Verbose, Sfo, Language, DriverInfo);\r
+  } else {\r
+    Status = ConvertStrToGuid (Protocol, &Guid);\r
+    if (!EFI_ERROR (Status)) {\r
+      GuidPtr = &Guid;\r
+    } else {\r
+      //\r
+      // Protocol is a Name, convert it to GUID\r
+      //\r
+      Status = GetGuidFromStringName (Protocol, Language, &GuidPtr);\r
+      if (EFI_ERROR(Status)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_NAME_FOUND), gShellDriver1HiiHandle, Protocol);\r
+        return (SHELL_NOT_FOUND);\r
+      }\r
+    }\r
 \r
-  Status = GetGuidFromStringName(ProtocolName, Language, &Guid);\r
-  if (EFI_ERROR(Status)) {\r
-    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, ProtocolName);\r
-    return (SHELL_INVALID_PARAMETER);\r
+    return DoDhByProtocolGuid (GuidPtr, Verbose, Sfo, Language, DriverInfo);\r
   }\r
+}\r
 \r
-  HandleList = GetHandleListByProtocol(Guid);\r
+/**\r
+  Function to display decode information by Protocol.\r
+  The parameter Protocol is either a GUID or the name of protocol.\r
+  If the parameter Protocol is NULL, the function will print all\r
+  decode information.\r
 \r
-  ShellStatus = DoDhForHandleList(\r
-    HandleList,\r
-    Sfo,\r
-    Language,\r
-    DriverInfo);\r
+  @param[in] Protocol         The pointer to the name or GUID of protocol.\r
+  @param[in] Language         Language string per UEFI specification.\r
 \r
-  SHELL_FREE_NON_NULL(HandleList);\r
+  @retval SHELL_SUCCESS           The operation was successful.\r
+  @retval SHELL_OUT_OT_RESOURCES  A memory allocation failed.\r
+**/\r
+SHELL_STATUS\r
+DoDecodeByProtocol(\r
+  IN CONST CHAR16 *Protocol,\r
+  IN CONST CHAR8  *Language\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  EFI_GUID      *Guids;\r
+  EFI_GUID      Guid;\r
+  UINTN         Counts;\r
+  UINTN         Index;\r
+  CHAR16        *Name;\r
 \r
-  return (ShellStatus);\r
+  if (Protocol == NULL) {\r
+    Counts = 0;\r
+    Status = GetAllMappingGuids (NULL, &Counts);\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      Guids = AllocatePool (Counts * sizeof(EFI_GUID));\r
+      if (Guids == NULL) {\r
+        return SHELL_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      Status = GetAllMappingGuids (Guids, &Counts);\r
+      if (Status == EFI_SUCCESS) {\r
+        for (Index = 0; Index < Counts; Index++) {\r
+          Name = GetStringNameFromGuid (&Guids[Index], Language);\r
+          if (Name != NULL) {\r
+            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Name, &Guids[Index]);\r
+          } else {\r
+            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, &Guids[Index]);\r
+          }\r
+          SHELL_FREE_NON_NULL (Name);\r
+        }\r
+      }\r
+      FreePool (Guids);\r
+    }\r
+  } else {\r
+    if (ConvertStrToGuid (Protocol, &Guid) == EFI_SUCCESS) {\r
+      Name = GetStringNameFromGuid (&Guid, Language);\r
+      if (Name != NULL) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Name, &Guid);\r
+      } else {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, &Guid);\r
+      }\r
+      SHELL_FREE_NON_NULL(Name);\r
+    } else {\r
+      Status = GetGuidFromStringName (Protocol, Language, &Guids);\r
+      if (Status == EFI_SUCCESS) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_OUTPUT_DECODE), gShellDriver1HiiHandle, Protocol, Guids);\r
+      } else {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DH_NO_NAME_FOUND), gShellDriver1HiiHandle, Protocol);\r
+      }\r
+    }\r
+  }\r
+\r
+  return SHELL_SUCCESS;\r
 }\r
 \r
+/**\r
+  Function for 'dh' command.\r
+\r
+  @param[in] ImageHandle  Handle to the Image (NULL if Internal).\r
+  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).\r
+**/\r
 SHELL_STATUS\r
 EFIAPI\r
 ShellCommandRunDh (\r
@@ -297,10 +1056,13 @@ ShellCommandRunDh (
   SHELL_STATUS        ShellStatus;\r
   CHAR8               *Language;\r
   CONST CHAR16        *Lang;\r
-  CONST CHAR16        *Temp2;\r
-  BOOLEAN             SfoMode;\r
-  BOOLEAN             FlagD;\r
-  BOOLEAN             Verbose;\r
+  CONST CHAR16        *RawValue;\r
+  CONST CHAR16        *ProtocolVal;\r
+  BOOLEAN             SfoFlag;\r
+  BOOLEAN             DriverFlag;\r
+  BOOLEAN             VerboseFlag;\r
+  UINT64              Intermediate;\r
+  EFI_HANDLE          Handle;\r
 \r
   ShellStatus         = SHELL_SUCCESS;\r
   Status              = EFI_SUCCESS;\r
@@ -321,7 +1083,7 @@ ShellCommandRunDh (
   Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
   if (EFI_ERROR(Status)) {\r
     if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, ProblemParam);\r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"dh", ProblemParam);  \r
       FreePool(ProblemParam);\r
       ShellStatus = SHELL_INVALID_PARAMETER;\r
     } else {\r
@@ -329,83 +1091,78 @@ ShellCommandRunDh (
     }\r
   } else {\r
     if (ShellCommandLineGetCount(Package) > 2) {\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle);\r
+      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");  \r
       ShellCommandLineFreeVarList (Package);\r
       return (SHELL_INVALID_PARAMETER);\r
     }\r
 \r
-    Lang = ShellCommandLineGetValue(Package, L"-l");\r
-    if (Lang != NULL) {\r
-      Language = AllocateZeroPool(StrSize(Lang));\r
-      AsciiSPrint(Language, StrSize(Lang), "%S", Lang);\r
-    } else if (!ShellCommandLineGetFlag(Package, L"-l")){\r
+    if (ShellCommandLineGetFlag(Package, L"-l")) {\r
+      Lang = ShellCommandLineGetValue(Package, L"-l");\r
+      if (Lang != NULL) {\r
+        Language = AllocateZeroPool(StrSize(Lang));\r
+        AsciiSPrint(Language, StrSize(Lang), "%S", Lang);\r
+      } else {\r
+        ASSERT(Language == NULL);\r
+        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-l");\r
+        ShellCommandLineFreeVarList(Package);\r
+        return (SHELL_INVALID_PARAMETER);\r
+      }\r
+    } else {\r
       Language = AllocateZeroPool(10);\r
       AsciiSPrint(Language, 10, "en-us");\r
-    } else {\r
-      ASSERT(Language == NULL);\r
-      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"-l");\r
-      ShellCommandLineFreeVarList (Package);\r
-      return (SHELL_INVALID_PARAMETER);\r
     }\r
 \r
-    SfoMode = ShellCommandLineGetFlag(Package, L"-sfo");\r
-    FlagD   = ShellCommandLineGetFlag(Package, L"-d");\r
-    if (ShellCommandLineGetFlag(Package, L"-v") || ShellCommandLineGetFlag(Package, L"-verbose")) {\r
-      Verbose = TRUE;\r
-    } else {\r
-      Verbose = FALSE;\r
-    }\r
+    SfoFlag     = ShellCommandLineGetFlag (Package, L"-sfo");\r
+    DriverFlag  = ShellCommandLineGetFlag (Package, L"-d");\r
+    VerboseFlag = (BOOLEAN)(ShellCommandLineGetFlag (Package, L"-v") || ShellCommandLineGetFlag (Package, L"-verbose"));\r
+    RawValue    = ShellCommandLineGetRawValue (Package, 1);\r
+    ProtocolVal = ShellCommandLineGetValue (Package, L"-p");\r
 \r
-    if (ShellCommandLineGetFlag(Package, L"-p")) {\r
-      if (ShellCommandLineGetCount(Package) > 1) {\r
-        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle);\r
-        ShellStatus = SHELL_INVALID_PARAMETER;\r
-      } else if (ShellCommandLineGetValue(Package, L"-p") == NULL) {\r
-        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"-p");\r
+    if (RawValue == NULL) {\r
+      if (ShellCommandLineGetFlag (Package, L"-p") && (ProtocolVal == NULL)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-p");\r
         ShellStatus = SHELL_INVALID_PARAMETER;\r
       } else {\r
         //\r
-        // print by protocol\r
+        // Print information by protocol, The ProtocolVal maybe is name or GUID or NULL.\r
         //\r
-        ShellStatus = DoDhByProtocol(\r
-          ShellCommandLineGetValue(Package, L"-p"),\r
-          SfoMode,\r
-          Lang==NULL?NULL:Language,\r
-          FlagD\r
-         );\r
+        ShellStatus = DoDhByProtocol (ProtocolVal, VerboseFlag, SfoFlag, Language, DriverFlag);\r
       }\r
-    } else {\r
-      Temp2 = ShellCommandLineGetRawValue(Package, 1);\r
-      if (Temp2 == NULL) {\r
+    } else if ((RawValue != NULL) &&\r
+               (gUnicodeCollation->StriColl(gUnicodeCollation, L"decode", (CHAR16 *) RawValue) == 0)) {\r
+      if (ShellCommandLineGetFlag (Package, L"-p") && (ProtocolVal == NULL)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", L"-p");\r
+        ShellStatus = SHELL_INVALID_PARAMETER;\r
+      } else {\r
         //\r
-        // Print everything\r
+        // Print decode informatino by protocol.\r
         //\r
-        ShellStatus = DoDhForAll(\r
-          SfoMode,\r
-          Lang==NULL?NULL:Language,\r
-          FlagD\r
-         );\r
+        ShellStatus = DoDecodeByProtocol (ProtocolVal, Language);\r
+      }\r
+    } else {\r
+      if (ShellCommandLineGetFlag (Package, L"-p")) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh");\r
+        ShellStatus = SHELL_INVALID_PARAMETER;\r
       } else {\r
-        if (!ShellIsHexOrDecimalNumber(Temp2, TRUE, FALSE) || ConvertHandleIndexToHandle(StrHexToUintn(Temp2)) == NULL) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, Temp2);\r
+        Status = ShellConvertStringToUint64 (RawValue, &Intermediate, TRUE, FALSE);\r
+        if (EFI_ERROR(Status)) {\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", RawValue);\r
           ShellStatus = SHELL_INVALID_PARAMETER;\r
         } else {\r
-          //\r
-          // print 1 handle\r
-          //\r
-          ShellStatus = DoDhByHandle(\r
-            ConvertHandleIndexToHandle(StrHexToUintn(Temp2)),\r
-            Verbose,\r
-            SfoMode,\r
-            Lang==NULL?NULL:Language,\r
-            FlagD,\r
-            FALSE\r
-           );\r
+          Handle = ConvertHandleIndexToHandle ((UINTN) Intermediate);\r
+          if (Handle == NULL) {\r
+            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", RawValue);\r
+            ShellStatus = SHELL_INVALID_PARAMETER;\r
+          } else {\r
+            //\r
+            // Print information by handle.\r
+            //\r
+            DoDhByHandle (Handle, VerboseFlag, SfoFlag, Language, DriverFlag, FALSE);\r
+          }\r
         }\r
       }\r
     }\r
 \r
-\r
     ShellCommandLineFreeVarList (Package);\r
     SHELL_FREE_NON_NULL(Language);\r
   }\r