]> 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 0ac49e1e7877323aaa3f53a561d2d36df50fb60c..0bcee9245c63fdb6c616c5f843e394a1bbe9f179 100644 (file)
@@ -41,6 +41,137 @@ 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
@@ -642,11 +773,8 @@ DisplayDriverModelHandle (
   @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
-  @retval SHELL_SUCCESS           The operation was successful.\r
-  @retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.\r
 **/\r
-SHELL_STATUS\r
+VOID\r
 DoDhByHandle(\r
   IN CONST EFI_HANDLE TheHandle,\r
   IN CONST BOOLEAN    Verbose,\r
@@ -656,10 +784,8 @@ DoDhByHandle(
   IN CONST BOOLEAN    Multiple\r
   )\r
 {\r
-  CHAR16              *ProtocolInfoString;\r
-  SHELL_STATUS        ShellStatus;\r
+  CHAR16 *ProtocolInfoString;\r
 \r
-  ShellStatus         = SHELL_SUCCESS;\r
   ProtocolInfoString  = NULL;\r
 \r
   if (!Sfo) {\r
@@ -672,7 +798,8 @@ 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", Verbose, TRUE);\r
       ShellPrintHiiEx(\r
@@ -683,7 +810,8 @@ DoDhByHandle(
         gShellDriver1HiiHandle,\r
         ConvertHandleToHandleIndex(TheHandle),\r
         TheHandle,\r
-        ProtocolInfoString==NULL?L"":ProtocolInfoString);\r
+        ProtocolInfoString==NULL?L"":ProtocolInfoString\r
+      );\r
     }\r
 \r
     if (DriverInfo) {\r
@@ -702,16 +830,13 @@ 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
@@ -723,8 +848,8 @@ DoDhByHandle(
   @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_INVALID_PARAMETER ProtocolName was NULL or invalid.\r
+  @retval SHELL_SUCCESS       The operation was successful.\r
+  @retval SHELL_ABORTED       The operation was aborted.\r
 **/\r
 SHELL_STATUS\r
 DoDhForHandleList(\r
@@ -739,16 +864,8 @@ 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
-          Verbose,\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
@@ -758,89 +875,166 @@ DoDhForHandleList(
 }\r
 \r
 /**\r
-  Display information for all handles.\r
+  Display information for a GUID of protocol.\r
 \r
-  @param[in] Sfo              TRUE to output in standard format output (spec).\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
-DoDhForAll(\r
-  IN CONST BOOLEAN  Sfo,\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
-\r
-  ShellStatus = DoDhForHandleList(\r
-    HandleList,\r
-    Verbose,\r
-    Sfo,\r
-    Language,\r
-    DriverInfo);\r
-\r
-  FreePool(HandleList);\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
-  return (ShellStatus);\r
+  return ShellStatus;\r
 }\r
 \r
 /**\r
-  Display information for all handles which have a specific protocol.\r
+  Function to determine use which method to print information.\r
+  If Protocol is NULL, The function will print all information.\r
 \r
-  @param[in] ProtocolName     The pointer to the name of the protocol.\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_INVALID_PARAMETER ProtocolName was NULL or invalid.\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
-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
-  if (ProtocolName == NULL) {\r
-    return (SHELL_INVALID_PARAMETER);\r
-  }\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
-    Verbose,\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
+  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
-  return (ShellStatus);\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
@@ -862,11 +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
@@ -900,77 +1096,73 @@ ShellCommandRunDh (
       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"dh",  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
-    Verbose = (BOOLEAN)(ShellCommandLineGetFlag(Package, L"-v") || ShellCommandLineGetFlag(Package, L"-verbose"));\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, L"dh");  \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"dh",  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
-          Verbose,\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
-          Verbose,\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
-        Status = ShellConvertStringToUint64(Temp2, &Intermediate, TRUE, FALSE);\r
-        if (EFI_ERROR(Status) || ConvertHandleIndexToHandle((UINTN)Intermediate) == NULL) {\r
-          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", 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((UINTN)Intermediate),\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