aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/edk2/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c')
-rw-r--r--roms/edk2/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c1191
1 files changed, 1191 insertions, 0 deletions
diff --git a/roms/edk2/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c b/roms/edk2/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c
new file mode 100644
index 000000000..ab6d39c88
--- /dev/null
+++ b/roms/edk2/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c
@@ -0,0 +1,1191 @@
+/** @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>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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);
+}