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:
Jaben Carsey 2014-08-05 20:09:25 +00:00 committed by jcarsey
parent 6306fd90b7
commit cf812a204c
3 changed files with 270 additions and 117 deletions

View File

@ -215,13 +215,79 @@ 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.
**/
BOOLEAN
EFIAPI
ShellCommandIsCommandOnList (
ShellCommandDynamicCommandExists (
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
)
{
@ -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.
@ -261,7 +372,7 @@ ShellCommandIsCommandOnList (
**/
CHAR16*
EFIAPI
ShellCommandGetCommandHelp (
ShellCommandGetInternalCommandHelp(
IN CONST CHAR16 *CommandString
)
{
@ -291,6 +402,31 @@ ShellCommandGetCommandHelp (
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
SHELL_GET_MAN_FILENAME for each shell command.
@ -506,6 +642,7 @@ ShellCommandRunCommandHandler (
)
{
SHELL_COMMAND_INTERNAL_LIST_ENTRY *Node;
EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *DynamicCommand;
//
// assert for NULL parameters
@ -536,6 +673,20 @@ ShellCommandRunCommandHandler (
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);
}

View File

@ -1,7 +1,7 @@
/** @file
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
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
@ -28,6 +28,7 @@
#include <Protocol/EfiShellParameters.h>
#include <Protocol/UnicodeCollation.h>
#include <Protocol/BlockIo.h>
#include <Protocol/EfiShellDynamicCommand.h>
#include <Library/DevicePathLib.h>
#include <Library/SortLib.h>

View File

@ -1,7 +1,7 @@
## @file
# 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
# are licensed and made available under the terms and conditions of the BSD License
@ -52,6 +52,7 @@
gEfiUnicodeCollation2ProtocolGuid # ALWAYS_CONSUMED
gEfiShellProtocolGuid # ALWAYS_CONSUMED
gEfiShellParametersProtocolGuid # ALWAYS_CONSUMED
gEfiShellDynamicCommandProtocolGuid # SOMETIMES_CONSUMED
[Guids]
gEfiSasDevicePathGuid # ALWAYS_CONSUMED