This searches for handles that produce the dynamic command protocol after searching the commands compiled into the shell.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jaben Carsey <jaben.carsey@intel.com> Reviewed-by: Eugene Cohen <eugene@hp.com> Reviewed-by: Erik Bjorge <erik.c.bjorge@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15754 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@ -215,14 +215,80 @@ ShellCommandLibDestructor (
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks if a command is already on the list.
|
Find a dynamic command protocol instance given a command name string
|
||||||
|
|
||||||
|
@param CommandString the command name string
|
||||||
|
|
||||||
|
@return instance the command protocol instance, if dynamic command instance found
|
||||||
|
@retval NULL no dynamic command protocol instance found for name
|
||||||
|
**/
|
||||||
|
CONST EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *
|
||||||
|
EFIAPI
|
||||||
|
ShellCommandFindDynamicCommand (
|
||||||
|
IN CONST CHAR16 *CommandString
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_HANDLE *CommandHandleList;
|
||||||
|
EFI_HANDLE *NextCommand;
|
||||||
|
EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *DynamicCommand;
|
||||||
|
|
||||||
|
CommandHandleList = GetHandleListByProtocol(&gEfiShellDynamicCommandProtocolGuid);
|
||||||
|
if (CommandHandleList == NULL) {
|
||||||
|
//
|
||||||
|
// not found or out of resources
|
||||||
|
//
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NextCommand = CommandHandleList; *NextCommand != NULL; NextCommand++) {
|
||||||
|
Status = gBS->HandleProtocol(
|
||||||
|
*NextCommand,
|
||||||
|
&gEfiShellDynamicCommandProtocolGuid,
|
||||||
|
(VOID **)&DynamicCommand
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gUnicodeCollation->StriColl(
|
||||||
|
gUnicodeCollation,
|
||||||
|
(CHAR16*)CommandString,
|
||||||
|
(CHAR16*)DynamicCommand->CommandName) == 0
|
||||||
|
){
|
||||||
|
FreePool(CommandHandleList);
|
||||||
|
return (DynamicCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePool(CommandHandleList);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks if a command exists as a dynamic command protocol instance
|
||||||
|
|
||||||
@param[in] CommandString The command string to check for on the list.
|
@param[in] CommandString The command string to check for on the list.
|
||||||
**/
|
**/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ShellCommandIsCommandOnList (
|
ShellCommandDynamicCommandExists (
|
||||||
IN CONST CHAR16 *CommandString
|
IN CONST CHAR16 *CommandString
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return (ShellCommandFindDynamicCommand(CommandString) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks if a command is already on the internal command list.
|
||||||
|
|
||||||
|
@param[in] CommandString The command string to check for on the list.
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
ShellCommandIsCommandOnInternalList(
|
||||||
|
IN CONST CHAR16 *CommandString
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;
|
SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;
|
||||||
@ -252,7 +318,52 @@ ShellCommandIsCommandOnList (
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the help text for a command.
|
Checks if a command exists, either internally or through the dynamic command protocol.
|
||||||
|
|
||||||
|
@param[in] CommandString The command string to check for on the list.
|
||||||
|
**/
|
||||||
|
BOOLEAN
|
||||||
|
EFIAPI
|
||||||
|
ShellCommandIsCommandOnList(
|
||||||
|
IN CONST CHAR16 *CommandString
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (ShellCommandIsCommandOnInternalList(CommandString)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ShellCommandDynamicCommandExists(CommandString);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the help text for a dynamic command.
|
||||||
|
|
||||||
|
@param[in] CommandString The command name.
|
||||||
|
|
||||||
|
@retval NULL No help text was found.
|
||||||
|
@return String of help text. Caller required to free.
|
||||||
|
**/
|
||||||
|
CHAR16*
|
||||||
|
EFIAPI
|
||||||
|
ShellCommandGetDynamicCommandHelp(
|
||||||
|
IN CONST CHAR16 *CommandString
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *DynamicCommand;
|
||||||
|
|
||||||
|
DynamicCommand = (EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *)ShellCommandFindDynamicCommand(CommandString);
|
||||||
|
if (DynamicCommand == NULL) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: how to get proper language?
|
||||||
|
//
|
||||||
|
return DynamicCommand->GetHelp(DynamicCommand, "en");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the help text for an internal command.
|
||||||
|
|
||||||
@param[in] CommandString The command name.
|
@param[in] CommandString The command name.
|
||||||
|
|
||||||
@ -261,7 +372,7 @@ ShellCommandIsCommandOnList (
|
|||||||
**/
|
**/
|
||||||
CHAR16*
|
CHAR16*
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ShellCommandGetCommandHelp (
|
ShellCommandGetInternalCommandHelp(
|
||||||
IN CONST CHAR16 *CommandString
|
IN CONST CHAR16 *CommandString
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -291,6 +402,31 @@ ShellCommandGetCommandHelp (
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the help text for a command.
|
||||||
|
|
||||||
|
@param[in] CommandString The command name.
|
||||||
|
|
||||||
|
@retval NULL No help text was found.
|
||||||
|
@return String of help text.Caller reuiqred to free.
|
||||||
|
**/
|
||||||
|
CHAR16*
|
||||||
|
EFIAPI
|
||||||
|
ShellCommandGetCommandHelp (
|
||||||
|
IN CONST CHAR16 *CommandString
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CHAR16 *HelpStr;
|
||||||
|
HelpStr = ShellCommandGetInternalCommandHelp(CommandString);
|
||||||
|
|
||||||
|
if (HelpStr == NULL) {
|
||||||
|
HelpStr = ShellCommandGetDynamicCommandHelp(CommandString);
|
||||||
|
}
|
||||||
|
|
||||||
|
return HelpStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Registers handlers of type SHELL_RUN_COMMAND and
|
Registers handlers of type SHELL_RUN_COMMAND and
|
||||||
SHELL_GET_MAN_FILENAME for each shell command.
|
SHELL_GET_MAN_FILENAME for each shell command.
|
||||||
@ -505,7 +641,8 @@ ShellCommandRunCommandHandler (
|
|||||||
IN OUT BOOLEAN *CanAffectLE OPTIONAL
|
IN OUT BOOLEAN *CanAffectLE OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;
|
SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;
|
||||||
|
EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *DynamicCommand;
|
||||||
|
|
||||||
//
|
//
|
||||||
// assert for NULL parameters
|
// assert for NULL parameters
|
||||||
@ -524,7 +661,7 @@ ShellCommandRunCommandHandler (
|
|||||||
gUnicodeCollation,
|
gUnicodeCollation,
|
||||||
(CHAR16*)CommandString,
|
(CHAR16*)CommandString,
|
||||||
Node->CommandString) == 0
|
Node->CommandString) == 0
|
||||||
){
|
){
|
||||||
if (CanAffectLE != NULL) {
|
if (CanAffectLE != NULL) {
|
||||||
*CanAffectLE = Node->LastError;
|
*CanAffectLE = Node->LastError;
|
||||||
}
|
}
|
||||||
@ -536,6 +673,20 @@ ShellCommandRunCommandHandler (
|
|||||||
return (RETURN_SUCCESS);
|
return (RETURN_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// An internal command was not found, try to find a dynamic command
|
||||||
|
//
|
||||||
|
DynamicCommand = (EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *)ShellCommandFindDynamicCommand(CommandString);
|
||||||
|
if (DynamicCommand != NULL) {
|
||||||
|
if (RetVal != NULL) {
|
||||||
|
*RetVal = DynamicCommand->Handler(DynamicCommand, gST, gEfiShellParametersProtocol, gEfiShellProtocol);
|
||||||
|
} else {
|
||||||
|
DynamicCommand->Handler(DynamicCommand, gST, gEfiShellParametersProtocol, gEfiShellProtocol);
|
||||||
|
}
|
||||||
|
return (RETURN_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
return (RETURN_NOT_FOUND);
|
return (RETURN_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1199,114 +1350,114 @@ ShellCommandCreateInitialMappingsAndPaths(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (EFI_SUCCESS);
|
return (EFI_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Add mappings for any devices without one. Do not change any existing maps.
|
Add mappings for any devices without one. Do not change any existing maps.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The operation was successful.
|
@retval EFI_SUCCESS The operation was successful.
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ShellCommandUpdateMapping (
|
ShellCommandUpdateMapping (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_HANDLE *HandleList;
|
EFI_HANDLE *HandleList;
|
||||||
UINTN Count;
|
UINTN Count;
|
||||||
EFI_DEVICE_PATH_PROTOCOL **DevicePathList;
|
EFI_DEVICE_PATH_PROTOCOL **DevicePathList;
|
||||||
CHAR16 *NewDefaultName;
|
CHAR16 *NewDefaultName;
|
||||||
CHAR16 *NewConsistName;
|
CHAR16 *NewConsistName;
|
||||||
EFI_DEVICE_PATH_PROTOCOL **ConsistMappingTable;
|
EFI_DEVICE_PATH_PROTOCOL **ConsistMappingTable;
|
||||||
|
|
||||||
HandleList = NULL;
|
HandleList = NULL;
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
//
|
//
|
||||||
// remove mappings that represent removed devices.
|
// remove mappings that represent removed devices.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
// Find each handle with Simple File System
|
// Find each handle with Simple File System
|
||||||
//
|
//
|
||||||
HandleList = GetHandleListByProtocol(&gEfiSimpleFileSystemProtocolGuid);
|
HandleList = GetHandleListByProtocol(&gEfiSimpleFileSystemProtocolGuid);
|
||||||
if (HandleList != NULL) {
|
if (HandleList != NULL) {
|
||||||
//
|
//
|
||||||
// Do a count of the handles
|
// Do a count of the handles
|
||||||
//
|
//
|
||||||
for (Count = 0 ; HandleList[Count] != NULL ; Count++);
|
for (Count = 0 ; HandleList[Count] != NULL ; Count++);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get all Device Paths
|
// Get all Device Paths
|
||||||
//
|
//
|
||||||
DevicePathList = AllocateZeroPool(sizeof(EFI_DEVICE_PATH_PROTOCOL*) * Count);
|
DevicePathList = AllocateZeroPool(sizeof(EFI_DEVICE_PATH_PROTOCOL*) * Count);
|
||||||
ASSERT(DevicePathList != NULL);
|
ASSERT(DevicePathList != NULL);
|
||||||
|
|
||||||
for (Count = 0 ; HandleList[Count] != NULL ; Count++) {
|
for (Count = 0 ; HandleList[Count] != NULL ; Count++) {
|
||||||
DevicePathList[Count] = DevicePathFromHandle(HandleList[Count]);
|
DevicePathList[Count] = DevicePathFromHandle(HandleList[Count]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sort all DevicePaths
|
// Sort all DevicePaths
|
||||||
//
|
//
|
||||||
PerformQuickSort(DevicePathList, Count, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare);
|
PerformQuickSort(DevicePathList, Count, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare);
|
||||||
|
|
||||||
ShellCommandConsistMappingInitialize(&ConsistMappingTable);
|
ShellCommandConsistMappingInitialize(&ConsistMappingTable);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Assign new Mappings to remainders
|
// Assign new Mappings to remainders
|
||||||
//
|
//
|
||||||
for (Count = 0 ; HandleList[Count] != NULL && !EFI_ERROR(Status); Count++) {
|
for (Count = 0 ; HandleList[Count] != NULL && !EFI_ERROR(Status); Count++) {
|
||||||
//
|
//
|
||||||
// Skip ones that already have
|
// Skip ones that already have
|
||||||
//
|
//
|
||||||
if (gEfiShellProtocol->GetMapFromDevicePath(&DevicePathList[Count]) != NULL) {
|
if (gEfiShellProtocol->GetMapFromDevicePath(&DevicePathList[Count]) != NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Get default name
|
// Get default name
|
||||||
//
|
//
|
||||||
NewDefaultName = ShellCommandCreateNewMappingName(MappingTypeFileSystem);
|
NewDefaultName = ShellCommandCreateNewMappingName(MappingTypeFileSystem);
|
||||||
ASSERT(NewDefaultName != NULL);
|
ASSERT(NewDefaultName != NULL);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Call shell protocol SetMap function now...
|
// Call shell protocol SetMap function now...
|
||||||
//
|
//
|
||||||
Status = gEfiShellProtocol->SetMap(DevicePathList[Count], NewDefaultName);
|
Status = gEfiShellProtocol->SetMap(DevicePathList[Count], NewDefaultName);
|
||||||
|
|
||||||
if (!EFI_ERROR(Status)) {
|
if (!EFI_ERROR(Status)) {
|
||||||
//
|
//
|
||||||
// Now do consistent name
|
// Now do consistent name
|
||||||
//
|
//
|
||||||
NewConsistName = ShellCommandConsistMappingGenMappingName(DevicePathList[Count], ConsistMappingTable);
|
NewConsistName = ShellCommandConsistMappingGenMappingName(DevicePathList[Count], ConsistMappingTable);
|
||||||
if (NewConsistName != NULL) {
|
if (NewConsistName != NULL) {
|
||||||
Status = gEfiShellProtocol->SetMap(DevicePathList[Count], NewConsistName);
|
Status = gEfiShellProtocol->SetMap(DevicePathList[Count], NewConsistName);
|
||||||
FreePool(NewConsistName);
|
FreePool(NewConsistName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FreePool(NewDefaultName);
|
FreePool(NewDefaultName);
|
||||||
}
|
}
|
||||||
ShellCommandConsistMappingUnInitialize(ConsistMappingTable);
|
ShellCommandConsistMappingUnInitialize(ConsistMappingTable);
|
||||||
SHELL_FREE_NON_NULL(HandleList);
|
SHELL_FREE_NON_NULL(HandleList);
|
||||||
SHELL_FREE_NON_NULL(DevicePathList);
|
SHELL_FREE_NON_NULL(DevicePathList);
|
||||||
|
|
||||||
HandleList = NULL;
|
HandleList = NULL;
|
||||||
} else {
|
} else {
|
||||||
Count = (UINTN)-1;
|
Count = (UINTN)-1;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Do it all over again for gEfiBlockIoProtocolGuid
|
// Do it all over again for gEfiBlockIoProtocolGuid
|
||||||
//
|
//
|
||||||
|
|
||||||
return (Status);
|
return (Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Converts a SHELL_FILE_HANDLE to an EFI_FILE_PROTOCOL*.
|
Converts a SHELL_FILE_HANDLE to an EFI_FILE_PROTOCOL*.
|
||||||
|
|
||||||
@param[in] Handle The SHELL_FILE_HANDLE to convert.
|
@param[in] Handle The SHELL_FILE_HANDLE to convert.
|
||||||
|
|
||||||
@return a EFI_FILE_PROTOCOL* representing the same file.
|
@return a EFI_FILE_PROTOCOL* representing the same file.
|
||||||
**/
|
**/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Provides interface to shell internal functions for shell commands.
|
Provides interface to shell internal functions for shell commands.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved. <BR>
|
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved. <BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -28,6 +28,7 @@
|
|||||||
#include <Protocol/EfiShellParameters.h>
|
#include <Protocol/EfiShellParameters.h>
|
||||||
#include <Protocol/UnicodeCollation.h>
|
#include <Protocol/UnicodeCollation.h>
|
||||||
#include <Protocol/BlockIo.h>
|
#include <Protocol/BlockIo.h>
|
||||||
|
#include <Protocol/EfiShellDynamicCommand.h>
|
||||||
|
|
||||||
#include <Library/DevicePathLib.h>
|
#include <Library/DevicePathLib.h>
|
||||||
#include <Library/SortLib.h>
|
#include <Library/SortLib.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
## @file
|
## @file
|
||||||
# Provides interface to shell internal functions for shell commands.
|
# Provides interface to shell internal functions for shell commands.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved. <BR>
|
# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved. <BR>
|
||||||
#
|
#
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -52,6 +52,7 @@
|
|||||||
gEfiUnicodeCollation2ProtocolGuid # ALWAYS_CONSUMED
|
gEfiUnicodeCollation2ProtocolGuid # ALWAYS_CONSUMED
|
||||||
gEfiShellProtocolGuid # ALWAYS_CONSUMED
|
gEfiShellProtocolGuid # ALWAYS_CONSUMED
|
||||||
gEfiShellParametersProtocolGuid # ALWAYS_CONSUMED
|
gEfiShellParametersProtocolGuid # ALWAYS_CONSUMED
|
||||||
|
gEfiShellDynamicCommandProtocolGuid # SOMETIMES_CONSUMED
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gEfiSasDevicePathGuid # ALWAYS_CONSUMED
|
gEfiSasDevicePathGuid # ALWAYS_CONSUMED
|
||||||
|
Reference in New Issue
Block a user