From de8cea6f3c2d83966e131a2edc4b26daf970ccd4 Mon Sep 17 00:00:00 2001 From: Ruiyu Ni Date: Mon, 9 Jan 2017 10:51:58 +0800 Subject: [PATCH] ShellPkg/dh: Support dump from GUID and "decode" parameter To follow Shell spec 2.2, change "dh" to support dump from protocol GUID and support "decode" parameter to dump the GUID/name mapping. Contributed-under: TianoCore Contribution Agreement 1.0 Cc: Jaben Carsey Cc: Ruiyu Ni Signed-off-by: Chen A Chen Signed-off-by: Ruiyu Ni Reviewed-by: Jaben Carsey --- .../Library/UefiShellDriver1CommandsLib/Dh.c | 367 ++++++++++++++---- .../UefiShellDriver1CommandsLib.uni | 9 +- 2 files changed, 292 insertions(+), 84 deletions(-) diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c b/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c index 2773842722..d17a29d86f 100644 --- a/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c +++ b/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c @@ -41,6 +41,137 @@ STATIC CONST EFI_GUID *UefiDriverModelProtocolsGuidArray[] = { 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 - PrevWalker) == mGuidDataLen[Index]) { + Walker++; + PrevWalker = Walker; + Index++; + } else { + return FALSE; + } + } + } + + if ((UINTN)(Walker - PrevWalker) == 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. @@ -733,8 +864,7 @@ DoDhForHandleList( SHELL_STATUS ShellStatus; ShellStatus = SHELL_SUCCESS; - - for ( HandleWalker = HandleList; HandleWalker != NULL && *HandleWalker != NULL; HandleWalker++ ) { + for (HandleWalker = HandleList; HandleWalker != NULL && *HandleWalker != NULL; HandleWalker++) { DoDhByHandle (*HandleWalker, Verbose, Sfo, Language, DriverInfo, TRUE); if (ShellGetExecutionBreakFlag ()) { ShellStatus = SHELL_ABORTED; @@ -745,89 +875,166 @@ DoDhForHandleList( } /** - Display information for all handles. + Display information for a GUID of protocol. - @param[in] Sfo TRUE to output in standard format output (spec). + @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 -DoDhForAll( - IN CONST BOOLEAN Sfo, +DoDhByProtocolGuid( + IN CONST GUID *Guid, IN CONST BOOLEAN Verbose, + IN CONST BOOLEAN Sfo, IN CONST CHAR8 *Language, IN CONST BOOLEAN DriverInfo ) { - EFI_HANDLE *HandleList; + CHAR16 *Name; SHELL_STATUS ShellStatus; + EFI_HANDLE *HandleList; - HandleList = GetHandleListByProtocol(NULL); - - ShellStatus = DoDhForHandleList( - HandleList, - Verbose, - Sfo, - Language, - DriverInfo); - - FreePool(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); + return ShellStatus; } /** - Display information for all handles which have a specific protocol. + Function to determine use which method to print information. + If Protocol is NULL, The function will print all information. - @param[in] ProtocolName The pointer to the name of the protocol. + @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_INVALID_PARAMETER ProtocolName was NULL or invalid. + @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 *ProtocolName, +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 Guid; + EFI_GUID *GuidPtr; EFI_STATUS Status; - EFI_HANDLE *HandleList; - SHELL_STATUS ShellStatus; - if (ProtocolName == NULL) { - return (SHELL_INVALID_PARAMETER); - } + 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); + } + } - Status = GetGuidFromStringName(ProtocolName, Language, &Guid); - if (EFI_ERROR(Status)) { - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DH_NO_GUID_FOUND), gShellDriver1HiiHandle, ProtocolName); - return (SHELL_INVALID_PARAMETER); + return DoDhByProtocolGuid (GuidPtr, Verbose, Sfo, Language, DriverInfo); } +} - HandleList = GetHandleListByProtocol(Guid); +/** + 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. - ShellStatus = DoDhForHandleList( - HandleList, - Verbose, - Sfo, - Language, - DriverInfo); + @param[in] Protocol The pointer to the name or GUID of protocol. + @param[in] Language Language string per UEFI specification. - SHELL_FREE_NON_NULL(HandleList); + @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; + } - return (ShellStatus); + 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; } /** @@ -850,10 +1057,12 @@ ShellCommandRunDh ( 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; @@ -906,60 +1115,54 @@ ShellCommandRunDh ( 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 (ShellCommandLineGetFlag (Package, L"-p")) { - if (ShellCommandLineGetCount (Package) > 1) { - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"dh"); - ShellStatus = SHELL_INVALID_PARAMETER; - } else if (ShellCommandLineGetValue(Package, L"-p") == NULL) { - ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"dh", 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 by protocol + // Print information by protocol, The ProtocolVal maybe is name or GUID or NULL. // - ShellStatus = DoDhByProtocol( - ShellCommandLineGetValue(Package, L"-p"), - VerboseFlag, - SfoFlag, - Language, - DriverFlag - ); + ShellStatus = DoDhByProtocol (ProtocolVal, VerboseFlag, SfoFlag, Language, DriverFlag); } - } else { - RawValue = ShellCommandLineGetRawValue(Package, 1); - if (RawValue == NULL) { + } 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 everything + // Print decode informatino by protocol. // - ShellStatus = DoDhForAll( - SfoFlag, - VerboseFlag, - Language, - DriverFlag - ); + 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) || ConvertHandleIndexToHandle((UINTN)Intermediate) == NULL) { - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", RawValue); + 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 { - // - // print 1 handle - // - DoDhByHandle( - ConvertHandleIndexToHandle((UINTN)Intermediate), - VerboseFlag, - SfoFlag, - Language, - DriverFlag, - FALSE - ); + 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); } diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.uni b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.uni index ac520e2d92..52156d5b05 100644 --- a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.uni +++ b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.uni @@ -2,7 +2,7 @@ // // (C) Copyright 2016 Hewlett Packard Enterprise Development LP
// (C) Copyright 2012-2015 Hewlett-Packard Development Company, L.P.
-// Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.
+// Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.
// 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 @@ -98,9 +98,14 @@ #string STR_DRIVERS_ITEM_LINE #language en-US "%H%3x%N %08x %1c %1c %1c %3d %3d %-35s %s\r\n" #string STR_DRIVERS_ITEM_LINE_SFO #language en-US "DriversInfo,"%x","%x","%c","%c","%c","%d","%d","%s","%s"\r\n" -#string STR_DH_NO_GUID_FOUND #language en-US "Protocol ID '%s' could not be identified.\r\n" +#string STR_DH_OUTPUT_DECODE #language en-US "%s: %g\r\n" +#string STR_DH_NO_NAME_FOUND #language en-US "Protocol Name '%s' could not be identified.\r\n" +#string STR_DH_NO_GUID_FOUND #language en-US "Protocol GUID '%g' could not be identified.\r\n" #string STR_DH_SFO_OUTPUT #language en-US "%s, %s, %H%02x%N, %s, &s\r\n" #string STR_DH_OUTPUT #language en-US "%H%02x%N: %s\r\n" +#string STR_DH_OUTPUT_ALL_HEADER #language en-US "Handle dump\r\n" +#string STR_DH_OUTPUT_GUID_HEADER #language en-US "Handle dump by protocol '%g'\r\n" +#string STR_DH_OUTPUT_NAME_HEADER #language en-US "Handle dump by protocol '%s'\r\n" #string STR_DH_OUTPUT_SINGLE #language en-US "%H%02x%N: %x\r\n%s" #string STR_DH_OUTPUT_SFO #language en-US "%s, %s, %s, %H%02x%N, %s, %s\r\n" #string STR_DH_OUTPUT_DRIVER1 #language en-US " Controller Name : %B%s%N\r\n" -- 2.39.2