audk/ShellPkg/Library/UefiShellDriver1CommandsLib/Dh.c

976 lines
30 KiB
C

/** @file
Main file for Dh shell Driver1 function.
(C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "UefiShellDriver1CommandsLib.h"
STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
{L"-p", TypeValue},
{L"-d", TypeFlag},
{L"-v", TypeFlag},
{L"-verbose", TypeFlag},
{L"-sfo", TypeFlag},
{L"-l", TypeValue},
{NULL, TypeMax}
};
STATIC CONST EFI_GUID *UefiDriverModelProtocolsGuidArray[] = {
&gEfiDriverBindingProtocolGuid,
&gEfiPlatformDriverOverrideProtocolGuid,
&gEfiBusSpecificDriverOverrideProtocolGuid,
&gEfiDriverDiagnosticsProtocolGuid,
&gEfiDriverDiagnostics2ProtocolGuid,
&gEfiComponentNameProtocolGuid,
&gEfiComponentName2ProtocolGuid,
&gEfiPlatformToDriverConfigurationProtocolGuid,
&gEfiDriverSupportedEfiVersionProtocolGuid,
&gEfiDriverFamilyOverrideProtocolGuid,
&gEfiDriverHealthProtocolGuid,
&gEfiLoadedImageProtocolGuid,
NULL
};
/**
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] Seperator 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 *Seperator,
IN CONST BOOLEAN Verbose,
IN CONST BOOLEAN ExtraInfo
)
{
EFI_GUID **ProtocolGuidArray;
UINTN ArrayCount;
UINTN ProtocolIndex;
EFI_STATUS Status;
CHAR16 *RetVal;
UINTN Size;
CHAR16 *Temp;
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);
if (Temp != NULL) {
ASSERT((RetVal == NULL && Size == 0) || (RetVal != NULL));
if (Size != 0) {
StrnCatGrow(&RetVal, &Size, Seperator, 0);
}
StrnCatGrow(&RetVal, &Size, L"%H", 0);
StrnCatGrow(&RetVal, &Size, Temp, 0);
StrnCatGrow(&RetVal, &Size, L"%N", 0);
FreePool(Temp);
}
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")\r\n", 0);
} else {
StrnCatGrow(&RetVal, &Size, Seperator, 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, Seperator, 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_DRIVER6B),
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_DRIVER6),
gShellDriver1HiiHandle,
L"None"
);
} else {
ShellPrintHiiEx(
-1,
-1,
NULL,
STRING_TOKEN (STR_DH_OUTPUT_DRIVER6),
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_DRIVER6B),
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.
@retval SHELL_SUCCESS The operation was successful.
@retval SHELL_INVALID_PARAMETER ProtocolName was NULL or invalid.
**/
SHELL_STATUS
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;
SHELL_STATUS ShellStatus;
ShellStatus = SHELL_SUCCESS;
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, L"\r\n", Verbose, TRUE);
ShellPrintHiiEx(
-1,
-1,
NULL,
STRING_TOKEN (STR_DH_OUTPUT_SINGLE),
gShellDriver1HiiHandle,
ConvertHandleToHandleIndex(TheHandle),
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);
}
return (ShellStatus);
}
/**
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_INVALID_PARAMETER ProtocolName was NULL or invalid.
**/
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 && ShellStatus == SHELL_SUCCESS; HandleWalker++) {
ShellStatus = DoDhByHandle(
*HandleWalker,
Verbose,
Sfo,
Language,
DriverInfo,
TRUE
);
if (ShellGetExecutionBreakFlag ()) {
ShellStatus = SHELL_ABORTED;
break;
}
}
return (ShellStatus);
}
/**
Display information for all handles.
@param[in] Sfo TRUE to output in standard format output (spec).
@param[in] Verbose TRUE for extra info, FALSE otherwise.
@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.
**/
SHELL_STATUS
DoDhForAll(
IN CONST BOOLEAN Sfo,
IN CONST BOOLEAN Verbose,
IN CONST CHAR8 *Language,
IN CONST BOOLEAN DriverInfo
)
{
EFI_HANDLE *HandleList;
SHELL_STATUS ShellStatus;
HandleList = GetHandleListByProtocol(NULL);
ShellStatus = DoDhForHandleList(
HandleList,
Verbose,
Sfo,
Language,
DriverInfo);
FreePool(HandleList);
return (ShellStatus);
}
/**
Display information for all handles which have a specific protocol.
@param[in] ProtocolName 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_INVALID_PARAMETER ProtocolName was NULL or invalid.
**/
SHELL_STATUS
DoDhByProtocol(
IN CONST CHAR16 *ProtocolName,
IN CONST BOOLEAN Verbose,
IN CONST BOOLEAN Sfo,
IN CONST CHAR8 *Language,
IN CONST BOOLEAN DriverInfo
)
{
EFI_GUID *Guid;
EFI_STATUS Status;
EFI_HANDLE *HandleList;
SHELL_STATUS ShellStatus;
if (ProtocolName == NULL) {
return (SHELL_INVALID_PARAMETER);
}
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);
}
HandleList = GetHandleListByProtocol(Guid);
ShellStatus = DoDhForHandleList(
HandleList,
Verbose,
Sfo,
Language,
DriverInfo);
SHELL_FREE_NON_NULL(HandleList);
return (ShellStatus);
}
/**
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 *Temp2;
BOOLEAN SfoMode;
BOOLEAN FlagD;
BOOLEAN Verbose;
UINT64 Intermediate;
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);
}
Lang = ShellCommandLineGetValue(Package, L"-l");
if (Lang != NULL) {
Language = AllocateZeroPool(StrSize(Lang));
AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
} else if (!ShellCommandLineGetFlag(Package, L"-l")){
Language = AllocateZeroPool(10);
AsciiSPrint(Language, 10, "en-us");
} 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);
}
SfoMode = ShellCommandLineGetFlag(Package, L"-sfo");
FlagD = ShellCommandLineGetFlag(Package, L"-d");
Verbose = (BOOLEAN)(ShellCommandLineGetFlag(Package, L"-v") || ShellCommandLineGetFlag(Package, L"-verbose"));
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");
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
//
// print by protocol
//
ShellStatus = DoDhByProtocol(
ShellCommandLineGetValue(Package, L"-p"),
Verbose,
SfoMode,
Lang==NULL?NULL:Language,
FlagD
);
}
} else {
Temp2 = ShellCommandLineGetRawValue(Package, 1);
if (Temp2 == NULL) {
//
// Print everything
//
ShellStatus = DoDhForAll(
SfoMode,
Verbose,
Lang==NULL?NULL:Language,
FlagD
);
} else {
Status = ShellConvertStringToUint64(Temp2, &Intermediate, TRUE, FALSE);
if (EFI_ERROR(Status) || ConvertHandleIndexToHandle((UINTN)Intermediate) == NULL) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, L"dh", Temp2);
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
//
// print 1 handle
//
ShellStatus = DoDhByHandle(
ConvertHandleIndexToHandle((UINTN)Intermediate),
Verbose,
SfoMode,
Lang==NULL?NULL:Language,
FlagD,
FALSE
);
}
}
}
ShellCommandLineFreeVarList (Package);
SHELL_FREE_NON_NULL(Language);
}
return (ShellStatus);
}