summaryrefslogtreecommitdiff
path: root/ShellPkg
diff options
context:
space:
mode:
authorLeif Lindholm <leif.lindholm@linaro.org>2014-01-24 17:18:26 +0000
committerLeif Lindholm <leif.lindholm@linaro.org>2014-01-24 17:18:26 +0000
commite1e57aa891deef00276b26a4569802a5cd13ce92 (patch)
tree9061825c6c9f5c8bed33d5b2087101ce38f23fdf /ShellPkg
parent18110e987bb049e24ade0fb63b5577def8f99114 (diff)
parent04d965c0713468e055ef328f9f49903bc5944e54 (diff)
Merging uefi-next/linaro-release into masterHEADlinaro-uefi-2014.01master
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Diffstat (limited to 'ShellPkg')
-rw-r--r--ShellPkg/Application/Shell/ConsoleLogger.c41
-rw-r--r--ShellPkg/Application/Shell/ConsoleWrappers.c4
-rw-r--r--ShellPkg/Application/Shell/FileHandleWrappers.c4
-rw-r--r--ShellPkg/Application/Shell/Shell.c1123
-rw-r--r--ShellPkg/Application/Shell/Shell.h44
-rw-r--r--ShellPkg/Application/Shell/ShellManParser.c13
-rw-r--r--ShellPkg/Application/Shell/ShellParametersProtocol.c43
-rw-r--r--ShellPkg/Application/Shell/ShellProtocol.c46
-rw-r--r--ShellPkg/Application/Shell/ShellProtocol.h4
-rw-r--r--ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c35
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/Bcfg.c18
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c722
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c849
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.unibin152966 -> 171002 bytes
-rw-r--r--ShellPkg/Library/UefiShellInstall1CommandsLib/Bcfg.c18
-rw-r--r--ShellPkg/Library/UefiShellLevel1CommandsLib/For.c8
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c1
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c7
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Rm.c1
-rw-r--r--ShellPkg/Library/UefiShellLib/UefiShellLib.c24
20 files changed, 2462 insertions, 543 deletions
diff --git a/ShellPkg/Application/Shell/ConsoleLogger.c b/ShellPkg/Application/Shell/ConsoleLogger.c
index c3729f16c..6f7ed95a6 100644
--- a/ShellPkg/Application/Shell/ConsoleLogger.c
+++ b/ShellPkg/Application/Shell/ConsoleLogger.c
@@ -2,7 +2,7 @@
Provides interface to shell console logger.
Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2013, 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
@@ -819,22 +819,41 @@ ConsoleLoggerOutputString (
IN CHAR16 *WString
)
{
- EFI_INPUT_KEY Key;
- UINTN EventIndex;
- CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
+ EFI_STATUS Status;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TxtInEx;
+ EFI_KEY_DATA KeyData;
+ UINTN EventIndex;
+ CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;
+
ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);
if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {
return (EFI_UNSUPPORTED);
}
ASSERT(ShellInfoObject.ConsoleInfo == ConsoleInfo);
- if (ShellInfoObject.HaltOutput) {
- //
- // just get some key
- //
- gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
- gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
- ShellInfoObject.HaltOutput = FALSE;
+
+ Status = gBS->HandleProtocol (gST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **) &TxtInEx);
+ if (!EFI_ERROR (Status)) {
+ while (ShellInfoObject.HaltOutput) {
+
+ ShellInfoObject.HaltOutput = FALSE;
+ //
+ // just get some key
+ //
+ Status = gBS->WaitForEvent (1, &TxtInEx->WaitForKeyEx, &EventIndex);
+ ASSERT_EFI_ERROR (Status);
+ Status = TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData);
+ ASSERT_EFI_ERROR (Status);
+
+ if ((KeyData.Key.UnicodeChar == L's') && (KeyData.Key.ScanCode == SCAN_NULL) &&
+ ((KeyData.KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED)) ||
+ (KeyData.KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID | EFI_RIGHT_CONTROL_PRESSED))
+ )
+ ) {
+ ShellInfoObject.HaltOutput = TRUE;
+ }
+ }
}
+
if (!ShellInfoObject.ConsoleInfo->Enabled) {
return (EFI_DEVICE_ERROR);
} else if (ShellInfoObject.PageBreakEnabled) {
diff --git a/ShellPkg/Application/Shell/ConsoleWrappers.c b/ShellPkg/Application/Shell/ConsoleWrappers.c
index 38491216f..49ba6e90e 100644
--- a/ShellPkg/Application/Shell/ConsoleWrappers.c
+++ b/ShellPkg/Application/Shell/ConsoleWrappers.c
@@ -255,7 +255,9 @@ FileBasedSimpleTextOutQueryMode (
OUT UINTN *Rows
)
{
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *PassThruProtocol = ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)This)->OriginalSimpleTextOut;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *PassThruProtocol;
+
+ PassThruProtocol = ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)This)->OriginalSimpleTextOut;
// Pass the QueryMode call thru to the original SimpleTextOutProtocol
return (PassThruProtocol->QueryMode(
diff --git a/ShellPkg/Application/Shell/FileHandleWrappers.c b/ShellPkg/Application/Shell/FileHandleWrappers.c
index ef8293c1d..c67ddfc26 100644
--- a/ShellPkg/Application/Shell/FileHandleWrappers.c
+++ b/ShellPkg/Application/Shell/FileHandleWrappers.c
@@ -2,7 +2,7 @@
EFI_FILE_PROTOCOL wrappers for other items (Like Environment Variables,
StdIn, StdOut, StdErr, etc...).
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2013, Hewlett-Packard Development Company, L.P.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -973,7 +973,7 @@ FileInterfaceEnvClose(
Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
}
- if (!EFI_ERROR(Status)) {
+ if (!EFI_ERROR(Status) && NewBuffer != NULL) {
if (StrSize(NewBuffer) > 6)
{
diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c
index 1b52692ec..134ec587d 100644
--- a/ShellPkg/Application/Shell/Shell.c
+++ b/ShellPkg/Application/Shell/Shell.c
@@ -1,7 +1,7 @@
/** @file
This is THE shell (application)
- Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2013, Hewlett-Packard Development Company, L.P.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -71,6 +71,82 @@ STATIC CONST CHAR16 mExecutableExtensions[] = L".NSH;.EFI";
STATIC CONST CHAR16 mStartupScript[] = L"startup.nsh";
/**
+ Cleans off leading and trailing spaces and tabs.
+
+ @param[in] String pointer to the string to trim them off.
+**/
+EFI_STATUS
+EFIAPI
+TrimSpaces(
+ IN CHAR16 **String
+ )
+{
+ ASSERT(String != NULL);
+ ASSERT(*String!= NULL);
+ //
+ // Remove any spaces and tabs at the beginning of the (*String).
+ //
+ while (((*String)[0] == L' ') || ((*String)[0] == L'\t')) {
+ CopyMem((*String), (*String)+1, StrSize((*String)) - sizeof((*String)[0]));
+ }
+
+ //
+ // Remove any spaces and tabs at the end of the (*String).
+ //
+ while ((StrLen (*String) > 0) && (((*String)[StrLen((*String))-1] == L' ') || ((*String)[StrLen((*String))-1] == L'\t'))) {
+ (*String)[StrLen((*String))-1] = CHAR_NULL;
+ }
+
+ return (EFI_SUCCESS);
+}
+
+/**
+ Find a command line contains a split operation
+
+ @param[in] CmdLine The command line to parse.
+
+ @retval A pointer to the | character in CmdLine or NULL if not present.
+**/
+CONST CHAR16*
+EFIAPI
+FindSplit(
+ IN CONST CHAR16 *CmdLine
+ )
+{
+ CONST CHAR16 *TempSpot;
+ TempSpot = NULL;
+ if (StrStr(CmdLine, L"|") != NULL) {
+ for (TempSpot = CmdLine ; TempSpot != NULL && *TempSpot != CHAR_NULL ; TempSpot++) {
+ if (*TempSpot == L'^' && *(TempSpot+1) == L'|') {
+ TempSpot++;
+ } else if (*TempSpot == L'|') {
+ break;
+ }
+ }
+ }
+ return (TempSpot);
+}
+
+/**
+ Determine if a command line contains a split operation
+
+ @param[in] CmdLine The command line to parse.
+
+ @retval TRUE CmdLine has a valid split.
+ @retval FALSE CmdLine does not have a valid split.
+**/
+BOOLEAN
+EFIAPI
+ContainsSplit(
+ IN CONST CHAR16 *CmdLine
+ )
+{
+ CONST CHAR16 *TempSpot;
+ TempSpot = FindSplit(CmdLine);
+ return (BOOLEAN) ((TempSpot != NULL) && (*TempSpot != CHAR_NULL));
+}
+
+/**
Function to start monitoring for CTRL-S using SimpleTextInputEx. This
feature's enabled state was not known when the shell initially launched.
@@ -131,7 +207,7 @@ InternalEfiShellStartCtrlSMonitor(
SimpleEx,
&KeyData,
NotificationFunction,
- &ShellInfoObject.CtrlSNotifyHandle2);
+ &ShellInfoObject.CtrlSNotifyHandle3);
}
KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
if (!EFI_ERROR(Status)) {
@@ -139,7 +215,7 @@ InternalEfiShellStartCtrlSMonitor(
SimpleEx,
&KeyData,
NotificationFunction,
- &ShellInfoObject.CtrlSNotifyHandle2);
+ &ShellInfoObject.CtrlSNotifyHandle4);
}
return (Status);
}
@@ -914,7 +990,7 @@ DoStartupScript(
// If we got a file, run it
//
if (!EFI_ERROR(Status) && FileHandle != NULL) {
- Status = RunScriptFileHandle (FileHandle, mStartupScript);
+ Status = RunScriptFile (mStartupScript, FileHandle, L"", ShellInfoObject.NewShellParametersProtocol);
ShellInfoObject.NewEfiShellProtocol->CloseFile(FileHandle);
} else {
FileStringPath = ShellFindFilePath(mStartupScript);
@@ -925,7 +1001,7 @@ DoStartupScript(
Status = EFI_SUCCESS;
ASSERT(FileHandle == NULL);
} else {
- Status = RunScriptFile(FileStringPath);
+ Status = RunScriptFile(FileStringPath, NULL, L"", ShellInfoObject.NewShellParametersProtocol);
FreePool(FileStringPath);
}
}
@@ -991,7 +1067,7 @@ DoShellPrompt (
if (!EFI_ERROR (Status)) {
CmdLine[BufferSize / sizeof (CHAR16)] = CHAR_NULL;
Status = RunCommand(CmdLine);
- }
+ }
//
// Done with this command
@@ -1354,347 +1430,822 @@ RunSplitCommand(
}
/**
- Function will process and run a command line.
+ Take the original command line, substitute any variables, free
+ the original string, return the modified copy.
- This will determine if the command line represents an internal shell
- command or dispatch an external application.
+ @param[in] CmdLine pointer to the command line to update.
- @param[in] CmdLine The command line to parse.
-
- @retval EFI_SUCCESS The command was completed.
- @retval EFI_ABORTED The command's operation was aborted.
+ @retval EFI_SUCCESS the function was successful.
+ @retval EFI_OUT_OF_RESOURCES a memory allocation failed.
**/
EFI_STATUS
EFIAPI
-RunCommand(
- IN CONST CHAR16 *CmdLine
+ShellSubstituteVariables(
+ IN CHAR16 **CmdLine
)
{
- EFI_STATUS Status;
- EFI_STATUS StatusCode;
- CHAR16 *CommandName;
- SHELL_STATUS ShellStatus;
- UINTN Argc;
- CHAR16 **Argv;
- BOOLEAN LastError;
- CHAR16 LeString[19];
- CHAR16 *PostAliasCmdLine;
- UINTN PostAliasSize;
- CHAR16 *PostVariableCmdLine;
- CHAR16 *CommandWithPath;
- CONST EFI_DEVICE_PATH_PROTOCOL *DevPath;
- CONST CHAR16 *TempLocation;
- CONST CHAR16 *TempLocation2;
- SHELL_FILE_HANDLE OriginalStdIn;
- SHELL_FILE_HANDLE OriginalStdOut;
- SHELL_FILE_HANDLE OriginalStdErr;
- SYSTEM_TABLE_INFO OriginalSystemTableInfo;
- CHAR16 *TempLocation3;
- UINTN Count;
- UINTN Count2;
- CHAR16 *CleanOriginal;
- SPLIT_LIST *Split;
+ CHAR16 *NewCmdLine;
+ NewCmdLine = ShellConvertVariables(*CmdLine);
+ SHELL_FREE_NON_NULL(*CmdLine);
+ if (NewCmdLine == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
+ *CmdLine = NewCmdLine;
+ return (EFI_SUCCESS);
+}
+
+/**
+ Take the original command line, substitute any alias in the first group of space delimited characters, free
+ the original string, return the modified copy.
+
+ @param[in] CmdLine pointer to the command line to update.
+ @retval EFI_SUCCESS the function was successful.
+ @retval EFI_OUT_OF_RESOURCES a memory allocation failed.
+**/
+EFI_STATUS
+EFIAPI
+ShellSubstituteAliases(
+ IN CHAR16 **CmdLine
+ )
+{
+ CHAR16 *NewCmdLine;
+ CHAR16 *CommandName;
+ EFI_STATUS Status;
+ UINTN PostAliasSize;
ASSERT(CmdLine != NULL);
- if (StrLen(CmdLine) == 0) {
- return (EFI_SUCCESS);
- }
+ ASSERT(*CmdLine!= NULL);
- CommandName = NULL;
- PostVariableCmdLine = NULL;
- PostAliasCmdLine = NULL;
- CommandWithPath = NULL;
- DevPath = NULL;
- Status = EFI_SUCCESS;
- CleanOriginal = NULL;
- Split = NULL;
- CleanOriginal = StrnCatGrow(&CleanOriginal, NULL, CmdLine, 0);
- if (CleanOriginal == NULL) {
- return (EFI_OUT_OF_RESOURCES);
+ CommandName = NULL;
+ if (StrStr((*CmdLine), L" ") == NULL){
+ StrnCatGrow(&CommandName, NULL, (*CmdLine), 0);
+ } else {
+ StrnCatGrow(&CommandName, NULL, (*CmdLine), StrStr((*CmdLine), L" ") - (*CmdLine));
}
//
- // Remove any spaces and tabs at the beginning of the string.
+ // This cannot happen 'inline' since the CmdLine can need extra space.
//
- while ((CleanOriginal[0] == L' ') || (CleanOriginal[0] == L'\t')) {
- CopyMem(CleanOriginal, CleanOriginal+1, StrSize(CleanOriginal) - sizeof(CleanOriginal[0]));
+ NewCmdLine = NULL;
+ if (!ShellCommandIsCommandOnList(CommandName)) {
+ //
+ // Convert via alias
+ //
+ Status = ShellConvertAlias(&CommandName);
+ if (EFI_ERROR(Status)){
+ return (Status);
+ }
+ PostAliasSize = 0;
+ NewCmdLine = StrnCatGrow(&NewCmdLine, &PostAliasSize, CommandName, 0);
+ if (NewCmdLine == NULL) {
+ SHELL_FREE_NON_NULL(CommandName);
+ SHELL_FREE_NON_NULL(*CmdLine);
+ return (EFI_OUT_OF_RESOURCES);
+ }
+ NewCmdLine = StrnCatGrow(&NewCmdLine, &PostAliasSize, StrStr((*CmdLine), L" "), 0);
+ if (NewCmdLine == NULL) {
+ SHELL_FREE_NON_NULL(CommandName);
+ SHELL_FREE_NON_NULL(*CmdLine);
+ return (EFI_OUT_OF_RESOURCES);
+ }
+ } else {
+ NewCmdLine = StrnCatGrow(&NewCmdLine, NULL, (*CmdLine), 0);
}
+ SHELL_FREE_NON_NULL(*CmdLine);
+ SHELL_FREE_NON_NULL(CommandName);
+
//
- // Handle case that passed in command line is just 1 or more " " characters.
+ // re-assign the passed in double pointer to point to our newly allocated buffer
//
- if (StrLen (CleanOriginal) == 0) {
- if (CleanOriginal != NULL) {
- FreePool(CleanOriginal);
- CleanOriginal = NULL;
- }
- return (EFI_SUCCESS);
- }
+ *CmdLine = NewCmdLine;
+
+ return (EFI_SUCCESS);
+}
+/**
+ Takes the Argv[0] part of the command line and determine the meaning of it.
+
+ @param[in] CmdName pointer to the command line to update.
+
+ @retval Internal_Command The name is an internal command.
+ @retval File_Sys_Change the name is a file system change.
+ @retval Script_File_Name the name is a NSH script file.
+ @retval Unknown_Invalid the name is unknown.
+ @retval Efi_Application the name is an application (.EFI).
+**/
+SHELL_OPERATION_TYPES
+EFIAPI
+GetOperationType(
+ IN CONST CHAR16 *CmdName
+ )
+{
+ CHAR16* FileWithPath;
+ CONST CHAR16* TempLocation;
+ CONST CHAR16* TempLocation2;
+
+ FileWithPath = NULL;
//
- // Remove any spaces at the end of the string.
+ // test for an internal command.
//
- while (CleanOriginal[StrLen(CleanOriginal)-1] == L' ') {
- CleanOriginal[StrLen(CleanOriginal)-1] = CHAR_NULL;
+ if (ShellCommandIsCommandOnList(CmdName)) {
+ return (Internal_Command);
}
- CommandName = NULL;
- if (StrStr(CleanOriginal, L" ") == NULL){
- StrnCatGrow(&CommandName, NULL, CleanOriginal, 0);
- } else {
- StrnCatGrow(&CommandName, NULL, CleanOriginal, StrStr(CleanOriginal, L" ") - CleanOriginal);
+ //
+ // Test for file system change request. anything ending with : and cant have spaces.
+ //
+ if (CmdName[(StrLen(CmdName)-1)] == L':') {
+ if (StrStr(CmdName, L" ") != NULL) {
+ return (Unknown_Invalid);
+ }
+ return (File_Sys_Change);
}
- ASSERT(PostAliasCmdLine == NULL);
- if (!ShellCommandIsCommandOnList(CommandName)) {
+ //
+ // Test for a file
+ //
+ if ((FileWithPath = ShellFindFilePathEx(CmdName, mExecutableExtensions)) != NULL) {
//
- // Convert via alias
+ // See if that file has a script file extension
//
- Status = ShellConvertAlias(&CommandName);
- PostAliasSize = 0;
- PostAliasCmdLine = StrnCatGrow(&PostAliasCmdLine, &PostAliasSize, CommandName, 0);
- PostAliasCmdLine = StrnCatGrow(&PostAliasCmdLine, &PostAliasSize, StrStr(CleanOriginal, L" "), 0);
- ASSERT_EFI_ERROR(Status);
- } else {
- PostAliasCmdLine = StrnCatGrow(&PostAliasCmdLine, NULL, CleanOriginal, 0);
+ if (StrLen(FileWithPath) > 4) {
+ TempLocation = FileWithPath+StrLen(FileWithPath)-4;
+ TempLocation2 = mScriptExtension;
+ if (StringNoCaseCompare((VOID*)(&TempLocation), (VOID*)(&TempLocation2)) == 0) {
+ SHELL_FREE_NON_NULL(FileWithPath);
+ return (Script_File_Name);
+ }
+ }
+
+ //
+ // Was a file, but not a script. we treat this as an application.
+ //
+ SHELL_FREE_NON_NULL(FileWithPath);
+ return (Efi_Application);
}
+
+ SHELL_FREE_NON_NULL(FileWithPath);
+ //
+ // No clue what this is... return invalid flag...
+ //
+ return (Unknown_Invalid);
+}
+
+/**
+ Determine if the first item in a command line is valid.
+
+ @param[in] CmdLine The command line to parse.
- if (CleanOriginal != NULL) {
- FreePool(CleanOriginal);
- CleanOriginal = NULL;
+ @retval EFI_SUCCESS The item is valid.
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
+ @retval EFI_NOT_FOUND The operation type is unknown or invalid.
+**/
+EFI_STATUS
+EFIAPI
+IsValidSplit(
+ IN CONST CHAR16 *CmdLine
+ )
+{
+ CHAR16 *Temp;
+ CHAR16 *FirstParameter;
+ CHAR16 *TempWalker;
+ EFI_STATUS Status;
+
+ Temp = NULL;
+
+ Temp = StrnCatGrow(&Temp, NULL, CmdLine, 0);
+ if (Temp == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
}
- if (CommandName != NULL) {
- FreePool(CommandName);
- CommandName = NULL;
+ FirstParameter = StrStr(Temp, L"|");
+ if (FirstParameter != NULL) {
+ *FirstParameter = CHAR_NULL;
}
- PostVariableCmdLine = ShellConvertVariables(PostAliasCmdLine);
+ FirstParameter = NULL;
//
- // we can now free the modified by alias command line
+ // Process the command line
//
- if (PostAliasCmdLine != NULL) {
- FreePool(PostAliasCmdLine);
- PostAliasCmdLine = NULL;
+ Status = ProcessCommandLineToFinal(&Temp);
+
+ if (!EFI_ERROR(Status)) {
+ FirstParameter = AllocateZeroPool(StrSize(CmdLine));
+ if (FirstParameter == NULL) {
+ SHELL_FREE_NON_NULL(Temp);
+ return (EFI_OUT_OF_RESOURCES);
+ }
+ TempWalker = (CHAR16*)Temp;
+ GetNextParameter(&TempWalker, &FirstParameter);
+
+ if (GetOperationType(FirstParameter) == Unknown_Invalid) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
+ SetLastError(SHELL_NOT_FOUND);
+ Status = EFI_NOT_FOUND;
+ }
}
- if (PostVariableCmdLine == NULL) {
- return (EFI_OUT_OF_RESOURCES);
+ SHELL_FREE_NON_NULL(Temp);
+ SHELL_FREE_NON_NULL(FirstParameter);
+ return Status;
+}
+
+/**
+ Determine if a command line contains with a split contains only valid commands.
+
+ @param[in] CmdLine The command line to parse.
+
+ @retval EFI_SUCCESS CmdLine has only valid commands, application, or has no split.
+ @retval EFI_ABORTED CmdLine has at least one invalid command or application.
+**/
+EFI_STATUS
+EFIAPI
+VerifySplit(
+ IN CONST CHAR16 *CmdLine
+ )
+{
+ CONST CHAR16 *TempSpot;
+ EFI_STATUS Status;
+
+ //
+ // Verify up to the pipe or end character
+ //
+ Status = IsValidSplit(CmdLine);
+ if (EFI_ERROR(Status)) {
+ return (Status);
+ }
+
+ //
+ // If this was the only item, then get out
+ //
+ if (!ContainsSplit(CmdLine)) {
+ return (EFI_SUCCESS);
+ }
+
+ //
+ // recurse to verify the next item
+ //
+ TempSpot = FindSplit(CmdLine)+1;
+ return (VerifySplit(TempSpot));
+}
+
+/**
+ Process a split based operation.
+
+ @param[in] CmdLine pointer to the command line to process
+
+ @retval EFI_SUCCESS The operation was successful
+ @return an error occured.
+**/
+EFI_STATUS
+EFIAPI
+ProcessNewSplitCommandLine(
+ IN CONST CHAR16 *CmdLine
+ )
+{
+ SPLIT_LIST *Split;
+ EFI_STATUS Status;
+
+ Status = VerifySplit(CmdLine);
+ if (EFI_ERROR(Status)) {
+ return (Status);
}
- while (PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] == L' ') {
- PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] = CHAR_NULL;
+ Split = NULL;
+
+ //
+ // are we in an existing split???
+ //
+ if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
+ Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
}
- while (PostVariableCmdLine[0] == L' ') {
- CopyMem(PostVariableCmdLine, PostVariableCmdLine+1, StrSize(PostVariableCmdLine) - sizeof(PostVariableCmdLine[0]));
+
+ if (Split == NULL) {
+ Status = RunSplitCommand(CmdLine, NULL, NULL);
+ } else {
+ Status = RunSplitCommand(CmdLine, Split->SplitStdIn, Split->SplitStdOut);
}
+ if (EFI_ERROR(Status)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_SPLIT), ShellInfoObject.HiiHandle, CmdLine);
+ }
+ return (Status);
+}
+
+/**
+ Handle a request to change the current file system.
+
+ @param[in] CmdLine The passed in command line.
+
+ @retval EFI_SUCCESS The operation was successful.
+**/
+EFI_STATUS
+EFIAPI
+ChangeMappedDrive(
+ IN CONST CHAR16 *CmdLine
+ )
+{
+ EFI_STATUS Status;
+ Status = EFI_SUCCESS;
//
- // We dont do normal processing with a split command line (output from one command input to another)
+ // make sure we are the right operation
+ //
+ ASSERT(CmdLine[(StrLen(CmdLine)-1)] == L':' && StrStr(CmdLine, L" ") == NULL);
+
//
- TempLocation3 = NULL;
- if (StrStr(PostVariableCmdLine, L"|") != NULL) {
- for (TempLocation3 = PostVariableCmdLine ; TempLocation3 != NULL && *TempLocation3 != CHAR_NULL ; TempLocation3++) {
- if (*TempLocation3 == L'^' && *(TempLocation3+1) == L'|') {
- TempLocation3++;
- } else if (*TempLocation3 == L'|') {
+ // Call the protocol API to do the work
+ //
+ Status = ShellInfoObject.NewEfiShellProtocol->SetCurDir(NULL, CmdLine);
+
+ //
+ // Report any errors
+ //
+ if (EFI_ERROR(Status)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_MAPPING), ShellInfoObject.HiiHandle, CmdLine);
+ }
+
+ return (Status);
+}
+
+/**
+ Reprocess the command line to direct all -? to the help command.
+
+ if found, will add "help" as argv[0], and move the rest later.
+
+ @param[in,out] CmdLine pointer to the command line to update
+**/
+EFI_STATUS
+EFIAPI
+DoHelpUpdate(
+ IN OUT CHAR16 **CmdLine
+ )
+{
+ CHAR16 *CurrentParameter;
+ CHAR16 *Walker;
+ CHAR16 *LastWalker;
+ CHAR16 *NewCommandLine;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ CurrentParameter = AllocateZeroPool(StrSize(*CmdLine));
+ if (CurrentParameter == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
+
+ Walker = *CmdLine;
+ while(Walker != NULL && *Walker != CHAR_NULL) {
+ LastWalker = Walker;
+ GetNextParameter(&Walker, &CurrentParameter);
+ if (StrStr(CurrentParameter, L"-?") == CurrentParameter) {
+ LastWalker[0] = L' ';
+ LastWalker[1] = L' ';
+ NewCommandLine = AllocateZeroPool(StrSize(L"help ") + StrSize(*CmdLine));
+ if (NewCommandLine == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
break;
}
+ StrCpy(NewCommandLine, L"help ");
+ StrCat(NewCommandLine, *CmdLine);
+ SHELL_FREE_NON_NULL(*CmdLine);
+ *CmdLine = NewCommandLine;
+ break;
}
}
- if (TempLocation3 != NULL && *TempLocation3 != CHAR_NULL) {
+
+ SHELL_FREE_NON_NULL(CurrentParameter);
+
+ return (Status);
+}
+
+/**
+ Function to update the shell variable "lasterror".
+
+ @param[in] ErrorCode the error code to put into lasterror.
+**/
+EFI_STATUS
+EFIAPI
+SetLastError(
+ IN CONST SHELL_STATUS ErrorCode
+ )
+{
+ CHAR16 LeString[19];
+ if (sizeof(EFI_STATUS) == sizeof(UINT64)) {
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", ErrorCode);
+ } else {
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%x", ErrorCode);
+ }
+ DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););
+ InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);
+
+ return (EFI_SUCCESS);
+}
+
+/**
+ Converts the command line to it's post-processed form. this replaces variables and alias' per UEFI Shell spec.
+
+ @param[in,out] CmdLine pointer to the command line to update
+
+ @retval EFI_SUCCESS The operation was successful
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
+ @return some other error occured
+**/
+EFI_STATUS
+EFIAPI
+ProcessCommandLineToFinal(
+ IN OUT CHAR16 **CmdLine
+ )
+{
+ EFI_STATUS Status;
+ TrimSpaces(CmdLine);
+
+ Status = ShellSubstituteAliases(CmdLine);
+ if (EFI_ERROR(Status)) {
+ return (Status);
+ }
+
+ TrimSpaces(CmdLine);
+
+ Status = ShellSubstituteVariables(CmdLine);
+ if (EFI_ERROR(Status)) {
+ return (Status);
+ }
+
+ TrimSpaces(CmdLine);
+
+ //
+ // update for help parsing
+ //
+ if (StrStr(*CmdLine, L"?") != NULL) {
//
- // are we in an existing split???
+ // This may do nothing if the ? does not indicate help.
+ // Save all the details for in the API below.
//
- if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
- Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
- }
+ Status = DoHelpUpdate(CmdLine);
+ }
- if (Split == NULL) {
- Status = RunSplitCommand(PostVariableCmdLine, NULL, NULL);
- } else {
- Status = RunSplitCommand(PostVariableCmdLine, Split->SplitStdIn, Split->SplitStdOut);
- }
- if (EFI_ERROR(Status)) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_SPLIT), ShellInfoObject.HiiHandle, PostVariableCmdLine);
- }
- } else {
+ TrimSpaces(CmdLine);
+
+ return (EFI_SUCCESS);
+}
+
+/**
+ Run an internal shell command.
+
+ This API will upadate the shell's environment since these commands are libraries.
+
+ @param[in] CmdLine the command line to run.
+ @param[in] FirstParameter the first parameter on the command line
+ @param[in] ParamProtocol the shell parameters protocol pointer
+ @retval EFI_SUCCESS The command was completed.
+ @retval EFI_ABORTED The command's operation was aborted.
+**/
+EFI_STATUS
+EFIAPI
+RunInternalCommand(
+ IN CONST CHAR16 *CmdLine,
+ IN CHAR16 *FirstParameter,
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
+)
+{
+ EFI_STATUS Status;
+ UINTN Argc;
+ CHAR16 **Argv;
+ SHELL_STATUS CommandReturnedStatus;
+ BOOLEAN LastError;
+
+ //
+ // get the argc and argv updated for internal commands
+ //
+ Status = UpdateArgcArgv(ParamProtocol, CmdLine, &Argv, &Argc);
+ if (!EFI_ERROR(Status)) {
//
- // If this is a mapped drive change handle that...
+ // Run the internal command.
//
- if (PostVariableCmdLine[(StrLen(PostVariableCmdLine)-1)] == L':' && StrStr(PostVariableCmdLine, L" ") == NULL) {
- Status = ShellInfoObject.NewEfiShellProtocol->SetCurDir(NULL, PostVariableCmdLine);
- if (EFI_ERROR(Status)) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_MAPPING), ShellInfoObject.HiiHandle, PostVariableCmdLine);
+ Status = ShellCommandRunCommandHandler(FirstParameter, &CommandReturnedStatus, &LastError);
+
+ if (!EFI_ERROR(Status)) {
+ //
+ // Update last error status.
+ // some commands do not update last error.
+ //
+ if (LastError) {
+ SetLastError(CommandReturnedStatus);
+ }
+
+ //
+ // Pass thru the exitcode from the app.
+ //
+ if (ShellCommandGetExit()) {
+ //
+ // An Exit was requested ("exit" command), pass its value up.
+ //
+ Status = CommandReturnedStatus;
+ } else if (CommandReturnedStatus != SHELL_SUCCESS && IsScriptOnlyCommand(FirstParameter)) {
+ //
+ // Always abort when a script only command fails for any reason
+ //
+ Status = EFI_ABORTED;
+ } else if (ShellCommandGetCurrentScriptFile() != NULL && CommandReturnedStatus == SHELL_ABORTED) {
+ //
+ // Abort when in a script and a command aborted
+ //
+ Status = EFI_ABORTED;
}
- FreePool(PostVariableCmdLine);
- return (Status);
}
+ }
- ///@todo update this section to divide into 3 ways - run internal command, run split (above), and run an external file...
- /// We waste a lot of time doing processing like StdIn,StdOut,Argv,Argc for things that are external files...
+ //
+ // This is guarenteed to be called after UpdateArgcArgv no matter what else happened.
+ // This is safe even if the update API failed. In this case, it may be a no-op.
+ //
+ RestoreArgcArgv(ParamProtocol, &Argv, &Argc);
+ //
+ // If a script is running and the command is not a scipt only command, then
+ // change return value to success so the script won't halt (unless aborted).
+ //
+ // Script only commands have to be able halt the script since the script will
+ // not operate if they are failing.
+ //
+ if ( ShellCommandGetCurrentScriptFile() != NULL
+ && !IsScriptOnlyCommand(FirstParameter)
+ && Status != EFI_ABORTED
+ ) {
+ Status = EFI_SUCCESS;
+ }
+ return (Status);
+}
- Status = UpdateStdInStdOutStdErr(ShellInfoObject.NewShellParametersProtocol, PostVariableCmdLine, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);
- if (EFI_ERROR(Status)) {
- if (Status == EFI_NOT_FOUND) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_REDUNDA_REDIR), ShellInfoObject.HiiHandle);
- } else {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_REDIR), ShellInfoObject.HiiHandle);
- }
- } else {
- while (PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] == L' ') {
- PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] = CHAR_NULL;
- }
- while (PostVariableCmdLine[0] == L' ') {
- CopyMem(PostVariableCmdLine, PostVariableCmdLine+1, StrSize(PostVariableCmdLine) - sizeof(PostVariableCmdLine[0]));
- }
+/**
+ Function to run the command or file.
+ @param[in] Type the type of operation being run.
+ @param[in] CmdLine the command line to run.
+ @param[in] FirstParameter the first parameter on the command line
+ @param[in] ParamProtocol the shell parameters protocol pointer
+
+ @retval EFI_SUCCESS The command was completed.
+ @retval EFI_ABORTED The command's operation was aborted.
+**/
+EFI_STATUS
+EFIAPI
+RunCommandOrFile(
+ IN SHELL_OPERATION_TYPES Type,
+ IN CONST CHAR16 *CmdLine,
+ IN CHAR16 *FirstParameter,
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
+)
+{
+ EFI_STATUS Status;
+ EFI_STATUS StatusCode;
+ CHAR16 *CommandWithPath;
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+
+ Status = EFI_SUCCESS;
+ CommandWithPath = NULL;
+ DevPath = NULL;
+
+ switch (Type) {
+ case Internal_Command:
+ Status = RunInternalCommand(CmdLine, FirstParameter, ParamProtocol);
+ break;
+ case Script_File_Name:
+ case Efi_Application:
//
- // get the argc and argv updated for internal commands
+ // Process a fully qualified path
//
- Status = UpdateArgcArgv(ShellInfoObject.NewShellParametersProtocol, PostVariableCmdLine, &Argv, &Argc);
- ASSERT_EFI_ERROR(Status);
-
- for (Count = 0 ; Count < ShellInfoObject.NewShellParametersProtocol->Argc ; Count++) {
- if (StrStr(ShellInfoObject.NewShellParametersProtocol->Argv[Count], L"-?") == ShellInfoObject.NewShellParametersProtocol->Argv[Count]
- || (ShellInfoObject.NewShellParametersProtocol->Argv[0][0] == L'?' && ShellInfoObject.NewShellParametersProtocol->Argv[0][1] == CHAR_NULL)
- ) {
- //
- // We need to redo the arguments since a parameter was -?
- // move them all down 1 to the end, then up one then replace the first with help
- //
- FreePool(ShellInfoObject.NewShellParametersProtocol->Argv[Count]);
- ShellInfoObject.NewShellParametersProtocol->Argv[Count] = NULL;
- for (Count2 = Count ; (Count2 + 1) < ShellInfoObject.NewShellParametersProtocol->Argc ; Count2++) {
- ShellInfoObject.NewShellParametersProtocol->Argv[Count2] = ShellInfoObject.NewShellParametersProtocol->Argv[Count2+1];
- }
- ShellInfoObject.NewShellParametersProtocol->Argv[Count2] = NULL;
- for (Count2 = ShellInfoObject.NewShellParametersProtocol->Argc -1 ; Count2 > 0 ; Count2--) {
- ShellInfoObject.NewShellParametersProtocol->Argv[Count2] = ShellInfoObject.NewShellParametersProtocol->Argv[Count2-1];
- }
- ShellInfoObject.NewShellParametersProtocol->Argv[0] = NULL;
- ShellInfoObject.NewShellParametersProtocol->Argv[0] = StrnCatGrow(&ShellInfoObject.NewShellParametersProtocol->Argv[0], NULL, L"help", 0);
- break;
+ if (StrStr(FirstParameter, L":") != NULL) {
+ ASSERT (CommandWithPath == NULL);
+ if (ShellIsFile(FirstParameter) == EFI_SUCCESS) {
+ CommandWithPath = StrnCatGrow(&CommandWithPath, NULL, FirstParameter, 0);
}
}
//
- // command or file?
+ // Process a relative path and also check in the path environment variable
//
- if (ShellCommandIsCommandOnList(ShellInfoObject.NewShellParametersProtocol->Argv[0])) {
- //
- // Run the command (which was converted if it was an alias)
- //
- if (!EFI_ERROR(Status)) {
- Status = ShellCommandRunCommandHandler(ShellInfoObject.NewShellParametersProtocol->Argv[0], &ShellStatus, &LastError);
- ASSERT_EFI_ERROR(Status);
+ if (CommandWithPath == NULL) {
+ CommandWithPath = ShellFindFilePathEx(FirstParameter, mExecutableExtensions);
+ }
- if (sizeof(EFI_STATUS) == sizeof(UINT64)) {
- UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", ShellStatus);
- } else {
- UnicodeSPrint(LeString, sizeof(LeString), L"0x%x", ShellStatus);
- }
- DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););
- if (LastError) {
- InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);
- }
+ //
+ // This should be impossible now.
+ //
+ ASSERT(CommandWithPath != NULL);
+
+ //
+ // Make sure that path is not just a directory (or not found)
+ //
+ if (!EFI_ERROR(ShellIsDirectory(CommandWithPath))) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
+ SetLastError(SHELL_NOT_FOUND);
+ }
+ switch (Type) {
+ case Script_File_Name:
+ Status = RunScriptFile (CommandWithPath, NULL, CmdLine, ParamProtocol);
+ break;
+ case Efi_Application:
//
- // Pass thru the exitcode from the app.
+ // Get the device path of the application image
//
- if (ShellCommandGetExit()) {
- Status = ShellStatus;
- } else if (ShellStatus != 0 && IsScriptOnlyCommand(ShellInfoObject.NewShellParametersProtocol->Argv[0])) {
- Status = EFI_ABORTED;
- }
- }
- } else {
- //
- // run an external file (or script)
- //
- if (StrStr(ShellInfoObject.NewShellParametersProtocol->Argv[0], L":") != NULL) {
- ASSERT (CommandWithPath == NULL);
- if (ShellIsFile(ShellInfoObject.NewShellParametersProtocol->Argv[0]) == EFI_SUCCESS) {
- CommandWithPath = StrnCatGrow(&CommandWithPath, NULL, ShellInfoObject.NewShellParametersProtocol->Argv[0], 0);
+ DevPath = ShellInfoObject.NewEfiShellProtocol->GetDevicePathFromFilePath(CommandWithPath);
+ if (DevPath == NULL){
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
}
- }
- if (CommandWithPath == NULL) {
- CommandWithPath = ShellFindFilePathEx(ShellInfoObject.NewShellParametersProtocol->Argv[0], mExecutableExtensions);
- }
- if (CommandWithPath == NULL || ShellIsDirectory(CommandWithPath) == EFI_SUCCESS) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, ShellInfoObject.NewShellParametersProtocol->Argv[0]);
- if (sizeof(EFI_STATUS) == sizeof(UINT64)) {
- UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", EFI_NOT_FOUND);
- } else {
- UnicodeSPrint(LeString, sizeof(LeString), L"0x%x", EFI_NOT_FOUND);
- }
- DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););
- InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);
- } else {
//
- // Check if it's a NSH (script) file.
+ // Execute the device path
//
- TempLocation = CommandWithPath+StrLen(CommandWithPath)-4;
- TempLocation2 = mScriptExtension;
- if ((StrLen(CommandWithPath) > 4) && (StringNoCaseCompare((VOID*)(&TempLocation), (VOID*)(&TempLocation2)) == 0)) {
- Status = RunScriptFile (CommandWithPath);
- } else {
- DevPath = ShellInfoObject.NewEfiShellProtocol->GetDevicePathFromFilePath(CommandWithPath);
- ASSERT(DevPath != NULL);
- Status = InternalShellExecuteDevicePath(
- &gImageHandle,
- DevPath,
- PostVariableCmdLine,
- NULL,
- &StatusCode
- );
+ Status = InternalShellExecuteDevicePath(
+ &gImageHandle,
+ DevPath,
+ CmdLine,
+ NULL,
+ &StatusCode
+ );
- //
- // Update last error status.
- //
- if (sizeof(EFI_STATUS) == sizeof(UINT64)) {
- UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", StatusCode);
- } else {
- UnicodeSPrint(LeString, sizeof(LeString), L"0x%x", StatusCode);
- }
- DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););
- InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);
- }
- }
- }
+ SHELL_FREE_NON_NULL(DevPath);
+ //
+ // Update last error status.
+ //
+ SetLastError((SHELL_STATUS) StatusCode);
+ break;
+ default:
+ //
+ // Do nothing.
+ //
+ break;
+ }
+ break;
+ default:
//
- // Print some error info.
+ // Do nothing.
//
- if (EFI_ERROR(Status)) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID*)(Status));
- }
+ break;
+ }
- CommandName = StrnCatGrow(&CommandName, NULL, ShellInfoObject.NewShellParametersProtocol->Argv[0], 0);
+ SHELL_FREE_NON_NULL(CommandWithPath);
- RestoreArgcArgv(ShellInfoObject.NewShellParametersProtocol, &Argv, &Argc);
+ return (Status);
+}
- RestoreStdInStdOutStdErr(ShellInfoObject.NewShellParametersProtocol, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);
- }
- if (CommandName != NULL) {
- if (ShellCommandGetCurrentScriptFile() != NULL && !IsScriptOnlyCommand(CommandName)) {
- //
- // if this is NOT a scipt only command return success so the script won't quit.
- // prevent killing the script - this is the only place where we know the actual command name (after alias and variable replacement...)
- //
- Status = EFI_SUCCESS;
- }
- }
+/**
+ Function to setup StdIn, StdErr, StdOut, and then run the command or file.
+
+ @param[in] Type the type of operation being run.
+ @param[in] CmdLine the command line to run.
+ @param[in] FirstParameter the first parameter on the command line.
+ @param[in] ParamProtocol the shell parameters protocol pointer
+
+ @retval EFI_SUCCESS The command was completed.
+ @retval EFI_ABORTED The command's operation was aborted.
+**/
+EFI_STATUS
+EFIAPI
+SetupAndRunCommandOrFile(
+ IN SHELL_OPERATION_TYPES Type,
+ IN CHAR16 *CmdLine,
+ IN CHAR16 *FirstParameter,
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
+)
+{
+ EFI_STATUS Status;
+ SHELL_FILE_HANDLE OriginalStdIn;
+ SHELL_FILE_HANDLE OriginalStdOut;
+ SHELL_FILE_HANDLE OriginalStdErr;
+ SYSTEM_TABLE_INFO OriginalSystemTableInfo;
+
+ //
+ // Update the StdIn, StdOut, and StdErr for redirection to environment variables, files, etc... unicode and ASCII
+ //
+ Status = UpdateStdInStdOutStdErr(ParamProtocol, CmdLine, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);
+
+ //
+ // The StdIn, StdOut, and StdErr are set up.
+ // Now run the command, script, or application
+ //
+ if (!EFI_ERROR(Status)) {
+ Status = RunCommandOrFile(Type, CmdLine, FirstParameter, ParamProtocol);
}
- SHELL_FREE_NON_NULL(CommandName);
- SHELL_FREE_NON_NULL(CommandWithPath);
- SHELL_FREE_NON_NULL(PostVariableCmdLine);
+ //
+ // Now print errors
+ //
+ if (EFI_ERROR(Status)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID*)(Status));
+ }
+
+ //
+ // put back the original StdIn, StdOut, and StdErr
+ //
+ RestoreStdInStdOutStdErr(ParamProtocol, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);
+
+ return (Status);
+}
+
+/**
+ Function will process and run a command line.
+
+ This will determine if the command line represents an internal shell
+ command or dispatch an external application.
+
+ @param[in] CmdLine The command line to parse.
+
+ @retval EFI_SUCCESS The command was completed.
+ @retval EFI_ABORTED The command's operation was aborted.
+**/
+EFI_STATUS
+EFIAPI
+RunCommand(
+ IN CONST CHAR16 *CmdLine
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *CleanOriginal;
+ CHAR16 *FirstParameter;
+ CHAR16 *TempWalker;
+ SHELL_OPERATION_TYPES Type;
+
+ ASSERT(CmdLine != NULL);
+ if (StrLen(CmdLine) == 0) {
+ return (EFI_SUCCESS);
+ }
+
+ Status = EFI_SUCCESS;
+ CleanOriginal = NULL;
+
+ CleanOriginal = StrnCatGrow(&CleanOriginal, NULL, CmdLine, 0);
+ if (CleanOriginal == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
+
+ TrimSpaces(&CleanOriginal);
+
+ //
+ // Handle case that passed in command line is just 1 or more " " characters.
+ //
+ if (StrLen (CleanOriginal) == 0) {
+ SHELL_FREE_NON_NULL(CleanOriginal);
+ return (EFI_SUCCESS);
+ }
+
+ Status = ProcessCommandLineToFinal(&CleanOriginal);
+ if (EFI_ERROR(Status)) {
+ SHELL_FREE_NON_NULL(CleanOriginal);
+ return (Status);
+ }
+
+ //
+ // We dont do normal processing with a split command line (output from one command input to another)
+ //
+ if (ContainsSplit(CleanOriginal)) {
+ Status = ProcessNewSplitCommandLine(CleanOriginal);
+ SHELL_FREE_NON_NULL(CleanOriginal);
+ return (Status);
+ }
+
+ //
+ // We need the first parameter information so we can determine the operation type
+ //
+ FirstParameter = AllocateZeroPool(StrSize(CleanOriginal));
+ if (FirstParameter == NULL) {
+ SHELL_FREE_NON_NULL(CleanOriginal);
+ return (EFI_OUT_OF_RESOURCES);
+ }
+ TempWalker = CleanOriginal;
+ GetNextParameter(&TempWalker, &FirstParameter);
+
+ //
+ // Depending on the first parameter we change the behavior
+ //
+ switch (Type = GetOperationType(FirstParameter)) {
+ case File_Sys_Change:
+ Status = ChangeMappedDrive(CleanOriginal);
+ break;
+ case Internal_Command:
+ case Script_File_Name:
+ case Efi_Application:
+ Status = SetupAndRunCommandOrFile(Type, CleanOriginal, FirstParameter, ShellInfoObject.NewShellParametersProtocol);
+ break;
+ default:
+ //
+ // Whatever was typed, it was invalid.
+ //
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
+ SetLastError(SHELL_NOT_FOUND);
+ break;
+ }
+
+ SHELL_FREE_NON_NULL(CleanOriginal);
+ SHELL_FREE_NON_NULL(FirstParameter);
return (Status);
}
@@ -1811,11 +2362,13 @@ RunScriptFileHandle (
while(!ShellFileHandleEof(Handle)) {
CommandLine = ShellFileHandleReturnLine(Handle, &Ascii);
LineCount++;
- if (CommandLine == NULL || StrLen(CommandLine) == 0) {
+ if (CommandLine == NULL || StrLen(CommandLine) == 0 || CommandLine[0] == '#') {
+ SHELL_FREE_NON_NULL(CommandLine);
continue;
}
NewScriptFile->CurrentCommand = AllocateZeroPool(sizeof(SCRIPT_COMMAND_LIST));
if (NewScriptFile->CurrentCommand == NULL) {
+ SHELL_FREE_NON_NULL(CommandLine);
DeleteScriptFileStruct(NewScriptFile);
return (EFI_OUT_OF_RESOURCES);
}
@@ -2025,30 +2578,62 @@ RunScriptFileHandle (
Function to process a NSH script file.
@param[in] ScriptPath Pointer to the script file name (including file system path).
+ @param[in] Handle the handle of the script file already opened.
+ @param[in] CmdLine the command line to run.
+ @param[in] ParamProtocol the shell parameters protocol pointer
@retval EFI_SUCCESS the script completed sucessfully
**/
EFI_STATUS
EFIAPI
RunScriptFile (
- IN CONST CHAR16 *ScriptPath
+ IN CONST CHAR16 *ScriptPath,
+ IN SHELL_FILE_HANDLE Handle OPTIONAL,
+ IN CONST CHAR16 *CmdLine,
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
)
{
EFI_STATUS Status;
SHELL_FILE_HANDLE FileHandle;
+ UINTN Argc;
+ CHAR16 **Argv;
if (ShellIsFile(ScriptPath) != EFI_SUCCESS) {
return (EFI_INVALID_PARAMETER);
}
- Status = ShellOpenFileByName(ScriptPath, &FileHandle, EFI_FILE_MODE_READ, 0);
- if (EFI_ERROR(Status)) {
- return (Status);
- }
+ //
+ // get the argc and argv updated for scripts
+ //
+ Status = UpdateArgcArgv(ParamProtocol, CmdLine, &Argv, &Argc);
+ if (!EFI_ERROR(Status)) {
+
+ if (Handle == NULL) {
+ //
+ // open the file
+ //
+ Status = ShellOpenFileByName(ScriptPath, &FileHandle, EFI_FILE_MODE_READ, 0);
+ if (!EFI_ERROR(Status)) {
+ //
+ // run it
+ //
+ Status = RunScriptFileHandle(FileHandle, ScriptPath);
- Status = RunScriptFileHandle(FileHandle, ScriptPath);
+ //
+ // now close the file
+ //
+ ShellCloseFile(&FileHandle);
+ }
+ } else {
+ Status = RunScriptFileHandle(Handle, ScriptPath);
+ }
+ }
- ShellCloseFile(&FileHandle);
+ //
+ // This is guarenteed to be called after UpdateArgcArgv no matter what else happened.
+ // This is safe even if the update API failed. In this case, it may be a no-op.
+ //
+ RestoreArgcArgv(ParamProtocol, &Argv, &Argc);
return (Status);
}
diff --git a/ShellPkg/Application/Shell/Shell.h b/ShellPkg/Application/Shell/Shell.h
index 2ed05b8a1..1962dd639 100644
--- a/ShellPkg/Application/Shell/Shell.h
+++ b/ShellPkg/Application/Shell/Shell.h
@@ -1,7 +1,7 @@
/** @file
function definitions for internal to shell functions.
- Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 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
@@ -124,6 +124,40 @@ typedef struct {
extern SHELL_INFO ShellInfoObject;
+typedef enum {
+ Internal_Command,
+ Script_File_Name,
+ Efi_Application,
+ File_Sys_Change,
+ Unknown_Invalid
+} SHELL_OPERATION_TYPES;
+
+/**
+ Converts the command line to it's post-processed form. this replaces variables and alias' per UEFI Shell spec.
+
+ @param[in,out] CmdLine pointer to the command line to update
+
+ @retval EFI_SUCCESS The operation was successful
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
+ @return some other error occured
+**/
+EFI_STATUS
+EFIAPI
+ProcessCommandLineToFinal(
+ IN OUT CHAR16 **CmdLine
+ );
+
+/**
+ Function to update the shell variable "lasterror".
+
+ @param[in] ErrorCode the error code to put into lasterror
+**/
+EFI_STATUS
+EFIAPI
+SetLastError(
+ IN CONST SHELL_STATUS ErrorCode
+ );
+
/**
Sets all the alias' that were registered with the ShellCommandLib library.
@@ -293,13 +327,19 @@ RunScriptFileHandle (
Function to process a NSH script file.
@param[in] ScriptPath Pointer to the script file name (including file system path).
+ @param[in] Handle the handle of the script file already opened.
+ @param[in] CmdLine the command line to run.
+ @param[in] ParamProtocol the shell parameters protocol pointer
@retval EFI_SUCCESS the script completed sucessfully
**/
EFI_STATUS
EFIAPI
RunScriptFile (
- IN CONST CHAR16 *ScriptPath
+ IN CONST CHAR16 *ScriptPath,
+ IN SHELL_FILE_HANDLE Handle OPTIONAL,
+ IN CONST CHAR16 *CmdLine,
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
);
diff --git a/ShellPkg/Application/Shell/ShellManParser.c b/ShellPkg/Application/Shell/ShellManParser.c
index 8196a6ac9..525c9343b 100644
--- a/ShellPkg/Application/Shell/ShellManParser.c
+++ b/ShellPkg/Application/Shell/ShellManParser.c
@@ -492,19 +492,6 @@ ManFileFindTitleSection(
StrCpy(TitleString, L".TH ");
StrCat(TitleString, Command);
- //
- // If the "name" ends with .efi we can safely chop that off since "help foo.efi" and "help foo"
- // should produce the same results.
- //
- if ((StrLen(Command)> 4)
- && (TitleString[StrLen(TitleString)-1] == L'i' || TitleString[StrLen(TitleString)-1] == L'I')
- && (TitleString[StrLen(TitleString)-2] == L'f' || TitleString[StrLen(TitleString)-2] == L'F')
- && (TitleString[StrLen(TitleString)-3] == L'e' || TitleString[StrLen(TitleString)-2] == L'E')
- && (TitleString[StrLen(TitleString)-4] == L'.')
- ) {
- TitleString[StrLen(TitleString)-4] = CHAR_NULL;
- }
-
TitleLen = StrLen(TitleString);
for (;!ShellFileHandleEof(Handle);Size = 1024) {
Status = ShellFileHandleReadLine(Handle, ReadLine, &Size, TRUE, Ascii);
diff --git a/ShellPkg/Application/Shell/ShellParametersProtocol.c b/ShellPkg/Application/Shell/ShellParametersProtocol.c
index b6598c0cf..ab435a126 100644
--- a/ShellPkg/Application/Shell/ShellParametersProtocol.c
+++ b/ShellPkg/Application/Shell/ShellParametersProtocol.c
@@ -3,7 +3,7 @@
manipulation, and initialization of EFI_SHELL_PARAMETERS_PROTOCOL.
Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 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
@@ -568,6 +568,28 @@ FixVarName (
}
/**
+ Remove the unicode file tag from the begining of the file buffer since that will not be
+ used by StdIn.
+**/
+EFI_STATUS
+EFIAPI
+RemoveFileTag(
+ IN SHELL_FILE_HANDLE *Handle
+ )
+{
+ UINTN CharSize;
+ CHAR16 CharBuffer;
+
+ CharSize = sizeof(CHAR16);
+ CharBuffer = 0;
+ gEfiShellProtocol->ReadFile(*Handle, &CharSize, &CharBuffer);
+ if (CharBuffer != gUnicodeFileTag) {
+ gEfiShellProtocol->SetFilePosition(*Handle, 0);
+ }
+ return (EFI_SUCCESS);
+}
+
+/**
Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
structure by parsing NewCommandLine. The current values are returned to the
user.
@@ -1148,7 +1170,15 @@ UpdateStdInStdOutStdErr(
&TempHandle,
EFI_FILE_MODE_READ,
0);
- if (!InUnicode && !EFI_ERROR(Status)) {
+ if (InUnicode) {
+ //
+ // Chop off the 0xFEFF if it's there...
+ //
+ RemoveFileTag(&TempHandle);
+ } else if (!EFI_ERROR(Status)) {
+ //
+ // Create the ASCII->Unicode conversion layer
+ //
TempHandle = CreateFileInterfaceFile(TempHandle, FALSE);
}
if (!EFI_ERROR(Status)) {
@@ -1163,8 +1193,15 @@ UpdateStdInStdOutStdErr(
CalculateEfiHdrCrc(&gST->Hdr);
if (gST->ConIn == NULL ||gST->ConOut == NULL) {
- return (EFI_OUT_OF_RESOURCES);
+ Status = EFI_OUT_OF_RESOURCES;
}
+
+ if (Status == EFI_NOT_FOUND) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_REDUNDA_REDIR), ShellInfoObject.HiiHandle);
+ } else if (EFI_ERROR(Status)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_REDIR), ShellInfoObject.HiiHandle);
+ }
+
return (Status);
}
diff --git a/ShellPkg/Application/Shell/ShellProtocol.c b/ShellPkg/Application/Shell/ShellProtocol.c
index 89132969b..c619ba15a 100644
--- a/ShellPkg/Application/Shell/ShellProtocol.c
+++ b/ShellPkg/Application/Shell/ShellProtocol.c
@@ -2,7 +2,7 @@
Member functions of EFI_SHELL_PROTOCOL and functions for creation,
manipulation, and initialization of EFI_SHELL_PROTOCOL.
- Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 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
@@ -1619,6 +1619,8 @@ EfiShellFreeFileList(
RemoveEntryList(&ShellFileListItem->Link);
InternalFreeShellFileInfoNode(ShellFileListItem);
}
+ InternalFreeShellFileInfoNode(*FileList);
+ *FileList = NULL;
return(EFI_SUCCESS);
}
@@ -1714,7 +1716,6 @@ InternalDuplicateShellFileInfo(
@param[in] BasePath the Path to prepend onto filename for FullPath
@param[in] Status Status member initial value.
- @param[in] FullName FullName member initial value.
@param[in] FileName FileName member initial value.
@param[in] Handle Handle member initial value.
@param[in] Info Info struct to copy.
@@ -1727,7 +1728,6 @@ EFIAPI
CreateAndPopulateShellFileInfo(
IN CONST CHAR16 *BasePath,
IN CONST EFI_STATUS Status,
- IN CONST CHAR16 *FullName,
IN CONST CHAR16 *FileName,
IN CONST SHELL_FILE_HANDLE Handle,
IN CONST EFI_FILE_INFO *Info
@@ -1836,6 +1836,7 @@ EfiShellFindFilesInDir(
Size = 0;
TempString = StrnCatGrow(&TempString, &Size, ShellFileHandleGetPath(FileDirHandle), 0);
if (TempString == NULL) {
+ SHELL_FREE_NON_NULL(BasePath);
return (EFI_OUT_OF_RESOURCES);
}
TempSpot = StrStr(TempString, L";");
@@ -1846,8 +1847,10 @@ EfiShellFindFilesInDir(
TempString = StrnCatGrow(&TempString, &Size, BasePath, 0);
if (TempString == NULL) {
+ SHELL_FREE_NON_NULL(BasePath);
return (EFI_OUT_OF_RESOURCES);
}
+ SHELL_FREE_NON_NULL(BasePath);
BasePath = TempString;
}
@@ -1862,20 +1865,14 @@ EfiShellFindFilesInDir(
; !EFI_ERROR(Status) && !NoFile
; Status = FileHandleFindNextFile(FileDirHandle, FileInfo, &NoFile)
){
- TempString = NULL;
- Size = 0;
//
// allocate a new EFI_SHELL_FILE_INFO and populate it...
//
- ASSERT((TempString == NULL && Size == 0) || (TempString != NULL));
- TempString = StrnCatGrow(&TempString, &Size, BasePath, 0);
- TempString = StrnCatGrow(&TempString, &Size, FileInfo->FileName, 0);
ShellFileListItem = CreateAndPopulateShellFileInfo(
BasePath,
- EFI_SUCCESS, // success since we didnt fail to open it...
- TempString,
+ EFI_SUCCESS, // success since we didnt fail to open it...
FileInfo->FileName,
- NULL, // no handle since not open
+ NULL, // no handle since not open
FileInfo);
if (ShellFileList == NULL) {
@@ -2769,15 +2766,33 @@ EfiShellGetHelpText(
)
{
CONST CHAR16 *ManFileName;
+ CHAR16 *FixCommand;
+ EFI_STATUS Status;
ASSERT(HelpText != NULL);
+ FixCommand = NULL;
ManFileName = ShellCommandGetManFileNameHandler(Command);
if (ManFileName != NULL) {
return (ProcessManFile(ManFileName, Command, Sections, NULL, HelpText));
} else {
- return (ProcessManFile(Command, Command, Sections, NULL, HelpText));
+ if ((StrLen(Command)> 4)
+ && (Command[StrLen(Command)-1] == L'i' || Command[StrLen(Command)-1] == L'I')
+ && (Command[StrLen(Command)-2] == L'f' || Command[StrLen(Command)-2] == L'F')
+ && (Command[StrLen(Command)-3] == L'e' || Command[StrLen(Command)-3] == L'E')
+ && (Command[StrLen(Command)-4] == L'.')
+ ) {
+ FixCommand = AllocateZeroPool(StrSize(Command) - 4 * sizeof (CHAR16));
+ ASSERT(FixCommand != NULL);
+
+ StrnCpy(FixCommand, Command, StrLen(Command)-4);
+ Status = ProcessManFile(FixCommand, FixCommand, Sections, NULL, HelpText);
+ FreePool(FixCommand);
+ return Status;
+ } else {
+ return (ProcessManFile(Command, Command, Sections, NULL, HelpText));
+ }
}
}
@@ -3279,7 +3294,6 @@ NotificationFunction(
IN EFI_KEY_DATA *KeyData
)
{
- EFI_INPUT_KEY Key;
if ( ((KeyData->Key.UnicodeChar == L'c') &&
(KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED) || KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED))) ||
(KeyData->Key.UnicodeChar == 3)
@@ -3292,12 +3306,6 @@ NotificationFunction(
(KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED) || KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED))
){
ShellInfoObject.HaltOutput = TRUE;
-
- //
- // Make sure that there are no pending keystrokes to pervent the pause.
- //
- gST->ConIn->Reset(gST->ConIn, FALSE);
- while (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key)==EFI_SUCCESS);
}
return (EFI_SUCCESS);
}
diff --git a/ShellPkg/Application/Shell/ShellProtocol.h b/ShellPkg/Application/Shell/ShellProtocol.h
index 456aa2aff..7493c9f49 100644
--- a/ShellPkg/Application/Shell/ShellProtocol.h
+++ b/ShellPkg/Application/Shell/ShellProtocol.h
@@ -2,7 +2,7 @@
Member functions of EFI_SHELL_PROTOCOL and functions for creation,
manipulation, and initialization of EFI_SHELL_PROTOCOL.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 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
@@ -555,7 +555,6 @@ EfiShellRemoveDupInFileList(
@param[in] BasePath the Path to prepend onto filename for FullPath
@param[in] Status Status member initial value.
- @param[in] FullName FullName member initial value.
@param[in] FileName FileName member initial value.
@param[in] Handle Handle member initial value.
@param[in] Info Info struct to copy.
@@ -566,7 +565,6 @@ EFIAPI
CreateAndPopulateShellFileInfo(
IN CONST CHAR16 *BasePath,
IN CONST EFI_STATUS Status,
- IN CONST CHAR16 *FullName,
IN CONST CHAR16 *FileName,
IN CONST SHELL_FILE_HANDLE Handle,
IN CONST EFI_FILE_INFO *Info
diff --git a/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c b/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c
index 935e8397f..48be39f83 100644
--- a/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c
+++ b/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c
@@ -1,7 +1,7 @@
/** @file
Provides interface to shell internal functions for shell commands.
- Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 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
@@ -101,6 +101,37 @@ ShellCommandLibConstructor (
}
/**
+ Frees list of file handles.
+
+ @param[in] List The list to free.
+**/
+VOID
+EFIAPI
+FreeFileHandleList (
+ IN BUFFER_LIST *List
+ )
+{
+ BUFFER_LIST *BufferListEntry;
+
+ if (List == NULL){
+ return;
+ }
+ //
+ // enumerate through the buffer list and free all memory
+ //
+ for ( BufferListEntry = ( BUFFER_LIST *)GetFirstNode(&List->Link)
+ ; !IsListEmpty (&List->Link)
+ ; BufferListEntry = (BUFFER_LIST *)GetFirstNode(&List->Link)
+ ){
+ RemoveEntryList(&BufferListEntry->Link);
+ ASSERT(BufferListEntry->Buffer != NULL);
+ SHELL_FREE_NON_NULL(((SHELL_COMMAND_FILE_HANDLE*)(BufferListEntry->Buffer))->Path);
+ SHELL_FREE_NON_NULL(BufferListEntry->Buffer);
+ SHELL_FREE_NON_NULL(BufferListEntry);
+ }
+}
+
+/**
Destructor for the library. free any resources.
@param ImageHandle the image handle of the process
@@ -169,7 +200,7 @@ ShellCommandLibDestructor (
}
}
if (!IsListEmpty(&mFileHandleList.Link)){
- FreeBufferList(&mFileHandleList);
+ FreeFileHandleList(&mFileHandleList);
}
if (mProfileList != NULL) {
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/Bcfg.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/Bcfg.c
index 73831d267..b19d8d9fb 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Bcfg.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/Bcfg.c
@@ -48,16 +48,6 @@ typedef struct {
} BGFG_OPERATION;
/**
- Get the actual number of entries in EFI_KEY_OPTION.Keys, from 0-3.
-
- @param KeyOption Pointer to the EFI_KEY_OPTION structure.
-
- @return Actual number of entries in EFI_KEY_OPTION.Keys.
-**/
-#define KEY_OPTION_INPUT_KEY_COUNT(KeyOption) \
- (((KeyOption)->KeyData & EFI_KEY_OPTION_INPUT_KEY_COUNT_MASK) >> LowBitSet32 (EFI_KEY_OPTION_INPUT_KEY_COUNT_MASK))
-
-/**
Update the optional data for a boot or driver option.
If optional data exists it will be changed.
@@ -843,7 +833,7 @@ BcfgAddOptDebug1(
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Walker);
ShellStatus = SHELL_INVALID_PARAMETER;
}
- NewKeyOption.KeyData = (UINT32)Intermediate;
+ NewKeyOption.KeyData.PackedValue = (UINT32)Intermediate;
Temp = StrStr(Walker, L" ");
if (Temp != NULL) {
Walker = Temp;
@@ -858,13 +848,13 @@ BcfgAddOptDebug1(
// Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
// Re-allocate with the added information.
//
- KeyOptionBuffer = AllocateCopyPool(sizeof(EFI_KEY_OPTION) + (sizeof(EFI_KEY_DATA) * KEY_OPTION_INPUT_KEY_COUNT (&NewKeyOption)), &NewKeyOption);
+ KeyOptionBuffer = AllocateCopyPool(sizeof(EFI_KEY_OPTION) + (sizeof(EFI_KEY_DATA) * NewKeyOption.KeyData.Options.InputKeyCount), &NewKeyOption);
if (KeyOptionBuffer == NULL) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellDebug1HiiHandle);
ShellStatus = SHELL_OUT_OF_RESOURCES;
}
}
- for (LoopCounter = 0 ; ShellStatus == SHELL_SUCCESS && LoopCounter < KEY_OPTION_INPUT_KEY_COUNT (&NewKeyOption); LoopCounter++) {
+ for (LoopCounter = 0 ; ShellStatus == SHELL_SUCCESS && LoopCounter < NewKeyOption.KeyData.Options.InputKeyCount; LoopCounter++) {
//
// ScanCode
//
@@ -930,7 +920,7 @@ BcfgAddOptDebug1(
VariableName,
(EFI_GUID*)&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof(EFI_KEY_OPTION) + (sizeof(EFI_KEY_DATA) * KEY_OPTION_INPUT_KEY_COUNT (&NewKeyOption)),
+ sizeof(EFI_KEY_OPTION) + (sizeof(EFI_KEY_DATA) * NewKeyOption.KeyData.Options.InputKeyCount),
KeyOptionBuffer);
if (EFI_ERROR(Status)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellDebug1HiiHandle, VariableName, Status);
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
index 3445b7f7e..b41636c7e 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c
@@ -1,7 +1,7 @@
/** @file
Main file for DmpStore shell Debug1 function.
- Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2005 - 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
@@ -14,9 +14,24 @@
#include "UefiShellDebug1CommandsLib.h"
-
-#define INIT_NAME_BUFFER_SIZE 128
-#define INIT_DATA_BUFFER_SIZE 1024
+typedef enum {
+ DmpStoreDisplay,
+ DmpStoreDelete,
+ DmpStoreSave,
+ DmpStoreLoad
+} DMP_STORE_TYPE;
+
+typedef struct {
+ UINT32 Signature;
+ CHAR16 *Name;
+ EFI_GUID Guid;
+ UINT32 Attributes;
+ UINT32 DataSize;
+ UINT8 *Data;
+ LIST_ENTRY Link;
+} DMP_STORE_VARIABLE;
+
+#define DMP_STORE_VARIABLE_SIGNATURE SIGNATURE_32 ('_', 'd', 's', 's')
/**
Base on the input attribute value to return the attribute string.
@@ -67,11 +82,282 @@ GetAttrType (
}
/**
- Function to display or delete variables.
+ Load the variable data from file and set to variable data base.
+
+ @param[in] FileHandle The file to be read.
+ @param[in] Name The name of the variables to be loaded.
+ @param[in] Guid The guid of the variables to be loaded.
+ @param[out] Found TRUE when at least one variable was loaded and set.
+
+ @retval SHELL_DEVICE_ERROR Cannot access the file.
+ @retval SHELL_VOLUME_CORRUPTED The file is in bad format.
+ @retval SHELL_OUT_OF_RESOURCES There is not enough memory to perform the operation.
+ @retval SHELL_SUCCESS Successfully load and set the variables.
+**/
+SHELL_STATUS
+LoadVariablesFromFile (
+ IN SHELL_FILE_HANDLE FileHandle,
+ IN CONST CHAR16 *Name,
+ IN CONST EFI_GUID *Guid,
+ OUT BOOLEAN *Found
+ )
+{
+ EFI_STATUS Status;
+ SHELL_STATUS ShellStatus;
+ UINT32 NameSize;
+ UINT32 DataSize;
+ UINTN BufferSize;
+ UINTN RemainingSize;
+ UINT64 Position;
+ UINT64 FileSize;
+ LIST_ENTRY List;
+ DMP_STORE_VARIABLE *Variable;
+ LIST_ENTRY *Link;
+ CHAR16 *Attributes;
+ UINT8 *Buffer;
+ UINT32 Crc32;
+
+ Status = ShellGetFileSize (FileHandle, &FileSize);
+ if (EFI_ERROR (Status)) {
+ return SHELL_DEVICE_ERROR;
+ }
+
+ ShellStatus = SHELL_SUCCESS;
+
+ InitializeListHead (&List);
+
+ Position = 0;
+ while (Position < FileSize) {
+ //
+ // NameSize
+ //
+ BufferSize = sizeof (NameSize);
+ Status = ShellReadFile (FileHandle, &BufferSize, &NameSize);
+ if (EFI_ERROR (Status) || (BufferSize != sizeof (NameSize))) {
+ ShellStatus = SHELL_VOLUME_CORRUPTED;
+ break;
+ }
+
+ //
+ // DataSize
+ //
+ BufferSize = sizeof (DataSize);
+ Status = ShellReadFile (FileHandle, &BufferSize, &DataSize);
+ if (EFI_ERROR (Status) || (BufferSize != sizeof (DataSize))) {
+ ShellStatus = SHELL_VOLUME_CORRUPTED;
+ break;
+ }
- @param[in] VariableName The variable name of the EFI variable (or NULL).
+ //
+ // Name, Guid, Attributes, Data, Crc32
+ //
+ RemainingSize = NameSize + sizeof (EFI_GUID) + sizeof (UINT32) + DataSize + sizeof (Crc32);
+ BufferSize = sizeof (NameSize) + sizeof (DataSize) + RemainingSize;
+ Buffer = AllocatePool (BufferSize);
+ if (Buffer == NULL) {
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ break;
+ }
+ BufferSize = RemainingSize;
+ Status = ShellReadFile (FileHandle, &BufferSize, (UINT32 *) Buffer + 2);
+ if (EFI_ERROR (Status) || (BufferSize != RemainingSize)) {
+ ShellStatus = SHELL_VOLUME_CORRUPTED;
+ FreePool (Buffer);
+ break;
+ }
+
+ //
+ // Check Crc32
+ //
+ * (UINT32 *) Buffer = NameSize;
+ * ((UINT32 *) Buffer + 1) = DataSize;
+ BufferSize = RemainingSize + sizeof (NameSize) + sizeof (DataSize) - sizeof (Crc32);
+ gBS->CalculateCrc32 (
+ Buffer,
+ BufferSize,
+ &Crc32
+ );
+ if (Crc32 != * (UINT32 *) (Buffer + BufferSize)) {
+ FreePool (Buffer);
+ ShellStatus = SHELL_VOLUME_CORRUPTED;
+ break;
+ }
+
+ Position += BufferSize + sizeof (Crc32);
+
+ Variable = AllocateZeroPool (sizeof (*Variable) + NameSize + DataSize);
+ if (Variable == NULL) {
+ FreePool (Buffer);
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ break;
+ }
+ Variable->Signature = DMP_STORE_VARIABLE_SIGNATURE;
+ Variable->Name = (CHAR16 *) (Variable + 1);
+ Variable->DataSize = DataSize;
+ Variable->Data = (UINT8 *) Variable->Name + NameSize;
+ CopyMem (Variable->Name, Buffer + sizeof (NameSize) + sizeof (DataSize), NameSize);
+ CopyMem (&Variable->Guid, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize, sizeof (EFI_GUID));
+ CopyMem (&Variable->Attributes, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize + sizeof (EFI_GUID), sizeof (UINT32));
+ CopyMem (Variable->Data, Buffer + sizeof (NameSize) + sizeof (DataSize) + NameSize + sizeof (EFI_GUID) + sizeof (UINT32), DataSize);
+
+ InsertTailList (&List, &Variable->Link);
+ FreePool (Buffer);
+ }
+
+ if ((Position != FileSize) || (ShellStatus != SHELL_SUCCESS)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_BAD_FILE), gShellDebug1HiiHandle);
+ if (Position != FileSize) {
+ ShellStatus = SHELL_VOLUME_CORRUPTED;
+ }
+ }
+
+ for ( Link = GetFirstNode (&List)
+ ; !IsNull (&List, Link) && (ShellStatus == SHELL_SUCCESS)
+ ; Link = GetNextNode (&List, Link)
+ ) {
+ Variable = CR (Link, DMP_STORE_VARIABLE, Link, DMP_STORE_VARIABLE_SIGNATURE);
+
+ if (((Name == NULL) || gUnicodeCollation->MetaiMatch (gUnicodeCollation, Variable->Name, (CHAR16 *) Name)) &&
+ ((Guid == NULL) || CompareGuid (&Variable->Guid, Guid))
+ ) {
+ Attributes = GetAttrType (Variable->Attributes);
+ ShellPrintHiiEx (
+ -1, -1, NULL, STRING_TOKEN(STR_DMPSTORE_HEADER_LINE), gShellDebug1HiiHandle,
+ Attributes, &Variable->Guid, Variable->Name, Variable->DataSize
+ );
+ SHELL_FREE_NON_NULL(Attributes);
+
+ *Found = TRUE;
+ Status = gRT->SetVariable (
+ Variable->Name,
+ &Variable->Guid,
+ Variable->Attributes,
+ Variable->DataSize,
+ Variable->Data
+ );
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD_GEN_FAIL), gShellDebug1HiiHandle, Variable->Name, Status);
+ }
+ }
+ }
+
+ for (Link = GetFirstNode (&List); !IsNull (&List, Link); ) {
+ Variable = CR (Link, DMP_STORE_VARIABLE, Link, DMP_STORE_VARIABLE_SIGNATURE);
+ Link = RemoveEntryList (&Variable->Link);
+ FreePool (Variable);
+ }
+
+ return ShellStatus;
+}
+
+/**
+ Append one variable to file.
+
+ @param[in] FileHandle The file to be appended.
+ @param[in] Name The variable name.
+ @param[in] Guid The variable GUID.
+ @param[in] Attributes The variable attributes.
+ @param[in] DataSize The variable data size.
+ @param[in] Data The variable data.
+
+ @retval EFI_OUT_OF_RESOURCES There is not enough memory to perform the operation.
+ @retval EFI_SUCCESS The variable is appended to file successfully.
+ @retval others Failed to append the variable to file.
+**/
+EFI_STATUS
+AppendSingleVariableToFile (
+ IN SHELL_FILE_HANDLE FileHandle,
+ IN CONST CHAR16 *Name,
+ IN CONST EFI_GUID *Guid,
+ IN UINT32 Attributes,
+ IN UINT32 DataSize,
+ IN CONST UINT8 *Data
+ )
+{
+ UINT32 NameSize;
+ UINT8 *Buffer;
+ UINT8 *Ptr;
+ UINTN BufferSize;
+ EFI_STATUS Status;
+
+ NameSize = (UINT32) StrSize (Name);
+ BufferSize = sizeof (NameSize) + sizeof (DataSize)
+ + sizeof (*Guid)
+ + sizeof (Attributes)
+ + NameSize + DataSize
+ + sizeof (UINT32);
+
+ Buffer = AllocatePool (BufferSize);
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Ptr = Buffer;
+ //
+ // NameSize and DataSize
+ //
+ * (UINT32 *) Ptr = NameSize;
+ Ptr += sizeof (NameSize);
+ *(UINT32 *) Ptr = DataSize;
+ Ptr += sizeof (DataSize);
+
+ //
+ // Name
+ //
+ CopyMem (Ptr, Name, NameSize);
+ Ptr += NameSize;
+
+ //
+ // Guid
+ //
+ CopyMem (Ptr, Guid, sizeof (*Guid));
+ Ptr += sizeof (*Guid);
+
+ //
+ // Attributes
+ //
+ * (UINT32 *) Ptr = Attributes;
+ Ptr += sizeof (Attributes);
+
+ //
+ // Data
+ //
+ CopyMem (Ptr, Data, DataSize);
+ Ptr += DataSize;
+
+ //
+ // Crc32
+ //
+ gBS->CalculateCrc32 (Buffer, (UINTN) (Ptr - Buffer), (UINT32 *) Ptr);
+
+ Status = ShellWriteFile (FileHandle, &BufferSize, Buffer);
+ FreePool (Buffer);
+
+ if (!EFI_ERROR (Status) &&
+ (BufferSize != sizeof (NameSize) + sizeof (DataSize) + sizeof (*Guid) + sizeof (Attributes) + NameSize + DataSize)
+ ) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ return Status;
+}
+
+/**
+ Recursive function to display or delete variables.
+
+ This function will call itself to create a stack-based list of allt he variables to process,
+ then fromt he last to the first, they will do either printing or deleting.
+
+ This is necessary since once a delete happens GetNextVariableName() will work.
+
+ @param[in] Name The variable name of the EFI variable (or NULL).
@param[in] Guid The GUID of the variable set (or NULL).
- @param[in] Delete TRUE to delete, FALSE otherwise.
+ @param[in] Type The operation type.
+ @param[in] FileHandle The file to operate on (or NULL).
+ @param[in] PrevName The previous variable name from GetNextVariableName. L"" to start.
+ @param[in] FoundVarGuid The previous GUID from GetNextVariableName. ignored at start.
+ @param[in] FoundOne If a VariableName or Guid was specified and one was printed or
+ deleted, then set this to TRUE, otherwise ignored.
@retval SHELL_SUCCESS The operation was successful.
@retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.
@@ -81,169 +367,203 @@ GetAttrType (
**/
SHELL_STATUS
EFIAPI
-ProcessVariables (
- IN CONST CHAR16 *VariableName OPTIONAL,
- IN CONST EFI_GUID *Guid OPTIONAL,
- IN BOOLEAN Delete
+CascadeProcessVariables (
+ IN CONST CHAR16 *Name OPTIONAL,
+ IN CONST EFI_GUID *Guid OPTIONAL,
+ IN DMP_STORE_TYPE Type,
+ IN EFI_FILE_PROTOCOL *FileHandle OPTIONAL,
+ IN CONST CHAR16 * CONST PrevName,
+ IN EFI_GUID FoundVarGuid,
+ IN BOOLEAN *FoundOne
)
{
EFI_STATUS Status;
CHAR16 *FoundVarName;
- EFI_GUID FoundVarGuid;
UINT8 *DataBuffer;
UINTN DataSize;
UINT32 Atts;
SHELL_STATUS ShellStatus;
- BOOLEAN Found;
- UINTN NameBufferSize; // Allocated Name buffer size
UINTN NameSize;
- CHAR16 *OldName;
- UINTN OldNameBufferSize;
- UINTN DataBufferSize; // Allocated data buffer size
CHAR16 *RetString;
- Found = FALSE;
- ShellStatus = SHELL_SUCCESS;
- Status = EFI_SUCCESS;
-
- NameBufferSize = INIT_NAME_BUFFER_SIZE;
- DataBufferSize = INIT_DATA_BUFFER_SIZE;
- FoundVarName = AllocateZeroPool (NameBufferSize);
- if (FoundVarName == NULL) {
- return (SHELL_OUT_OF_RESOURCES);
- }
- DataBuffer = AllocatePool (DataBufferSize);
- if (DataBuffer == NULL) {
- FreePool (FoundVarName);
- return (SHELL_OUT_OF_RESOURCES);
+ if (ShellGetExecutionBreakFlag()) {
+ return (SHELL_ABORTED);
}
- for (;;){
- if (ShellGetExecutionBreakFlag()) {
- ShellStatus = SHELL_ABORTED;
- break;
- }
+ NameSize = 0;
+ FoundVarName = NULL;
- NameSize = NameBufferSize;
- Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- OldName = FoundVarName;
- OldNameBufferSize = NameBufferSize;
- //
- // Expand at least twice to avoid reallocate many times
- //
- NameBufferSize = NameSize > NameBufferSize * 2 ? NameSize : NameBufferSize * 2;
- FoundVarName = AllocateZeroPool (NameBufferSize);
- if (FoundVarName == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- FreePool (OldName);
- break;
+ if (PrevName!=NULL) {
+ StrnCatGrow(&FoundVarName, &NameSize, PrevName, 0);
+ } else {
+ FoundVarName = AllocateZeroPool(sizeof(CHAR16));
+ }
+
+ Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ SHELL_FREE_NON_NULL(FoundVarName);
+ FoundVarName = AllocateZeroPool (NameSize);
+ if (FoundVarName != NULL) {
+ if (PrevName != NULL) {
+ StrCpy(FoundVarName, PrevName);
}
- //
- // Preserve the original content to get correct iteration for GetNextVariableName() call
- //
- CopyMem (FoundVarName, OldName, OldNameBufferSize);
- FreePool (OldName);
- NameSize = NameBufferSize;
+
Status = gRT->GetNextVariableName (&NameSize, FoundVarName, &FoundVarGuid);
+ } else {
+ Status = EFI_OUT_OF_RESOURCES;
}
- if (Status == EFI_NOT_FOUND) {
- break;
- }
- ASSERT_EFI_ERROR(Status);
+ }
+ //
+ // No more is fine.
+ //
+ if (Status == EFI_NOT_FOUND) {
+ SHELL_FREE_NON_NULL(FoundVarName);
+ return (SHELL_SUCCESS);
+ } else if (EFI_ERROR(Status)) {
+ SHELL_FREE_NON_NULL(FoundVarName);
+ return (SHELL_DEVICE_ERROR);
+ }
+
+ //
+ // Recurse to the next iteration. We know "our" variable's name.
+ //
+ ShellStatus = CascadeProcessVariables(Name, Guid, Type, FileHandle, FoundVarName, FoundVarGuid, FoundOne);
+
+ //
+ // No matter what happened we process our own variable
+ // Only continue if Guid and VariableName are each either NULL or a match
+ //
+ if ( ( Name == NULL
+ || gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*) Name) )
+ && ( Guid == NULL
+ || CompareGuid(&FoundVarGuid, Guid) )
+ ) {
+ DataSize = 0;
+ DataBuffer = NULL;
//
- // Check if it matches
+ // do the print or delete
//
- if (VariableName != NULL) {
- if (!gUnicodeCollation->MetaiMatch(gUnicodeCollation, FoundVarName, (CHAR16*)VariableName)) {
- continue;
- }
- }
- if (Guid != NULL) {
- if (!CompareGuid(&FoundVarGuid, Guid)) {
- continue;
+ *FoundOne = TRUE;
+ Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ SHELL_FREE_NON_NULL (DataBuffer);
+ DataBuffer = AllocatePool (DataSize);
+ if (DataBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);
}
}
-
- DataSize = DataBufferSize;
- Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);
- if (Status == EFI_BUFFER_TOO_SMALL) {
+ if ((Type == DmpStoreDisplay) || (Type == DmpStoreSave)) {
//
- // Expand at least twice to avoid reallocate many times
+ // Last error check then print this variable out.
//
- FreePool (DataBuffer);
- DataBufferSize = DataSize > DataBufferSize * 2 ? DataSize : DataBufferSize * 2;
- DataBuffer = AllocatePool (DataBufferSize);
- if (DataBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- break;
+ if (!EFI_ERROR(Status) && (DataBuffer != NULL) && (FoundVarName != NULL)) {
+ RetString = GetAttrType(Atts);
+ ShellPrintHiiEx(
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN(STR_DMPSTORE_HEADER_LINE),
+ gShellDebug1HiiHandle,
+ RetString,
+ &FoundVarGuid,
+ FoundVarName,
+ DataSize);
+ if (Type == DmpStoreDisplay) {
+ DumpHex(2, 0, DataSize, DataBuffer);
+ } else {
+ Status = AppendSingleVariableToFile (
+ FileHandle,
+ FoundVarName,
+ &FoundVarGuid,
+ Atts,
+ (UINT32) DataSize,
+ DataBuffer
+ );
+ }
+ SHELL_FREE_NON_NULL(RetString);
}
- DataSize = DataBufferSize;
- Status = gRT->GetVariable (FoundVarName, &FoundVarGuid, &Atts, &DataSize, DataBuffer);
- }
- ASSERT_EFI_ERROR(Status);
-
- //
- // do the print or delete
- //
- Found = TRUE;
- RetString = GetAttrType(Atts);
- if (!Delete) {
- ShellPrintHiiEx(
- -1,
- -1,
- NULL,
- STRING_TOKEN(STR_DMPSTORE_HEADER_LINE),
- gShellDebug1HiiHandle,
- RetString,
- &FoundVarGuid,
- FoundVarName,
- DataSize);
- DumpHex(2, 0, DataSize, DataBuffer);
- } else {
- ShellPrintHiiEx(
+ } else if (Type == DmpStoreDelete) {
+ //
+ // We only need name to delete it...
+ //
+ ShellPrintHiiEx (
-1,
-1,
NULL,
STRING_TOKEN(STR_DMPSTORE_DELETE_LINE),
gShellDebug1HiiHandle,
&FoundVarGuid,
- FoundVarName);
- ShellPrintHiiEx(
- -1,
- -1,
- NULL,
- STRING_TOKEN(STR_DMPSTORE_DELETE_DONE),
- gShellDebug1HiiHandle,
- gRT->SetVariable(FoundVarName, &FoundVarGuid, Atts, 0, NULL));
- FoundVarName[0] = CHAR_NULL;
- }
-
- if (RetString != NULL) {
- FreePool (RetString);
+ FoundVarName,
+ gRT->SetVariable (FoundVarName, &FoundVarGuid, Atts, 0, NULL)
+ );
}
+ SHELL_FREE_NON_NULL(DataBuffer);
}
- if (FoundVarName != NULL) {
- FreePool(FoundVarName);
+ SHELL_FREE_NON_NULL(FoundVarName);
+
+ if (Status == EFI_DEVICE_ERROR) {
+ ShellStatus = SHELL_DEVICE_ERROR;
+ } else if (Status == EFI_SECURITY_VIOLATION) {
+ ShellStatus = SHELL_SECURITY_VIOLATION;
+ } else if (EFI_ERROR(Status)) {
+ ShellStatus = SHELL_NOT_READY;
}
- if (DataBuffer != NULL) {
- FreePool(DataBuffer);
+
+ return (ShellStatus);
+}
+
+/**
+ Function to display or delete variables. This will set up and call into the recursive function.
+
+ @param[in] Name The variable name of the EFI variable (or NULL).
+ @param[in] Guid The GUID of the variable set (or NULL).
+ @param[in] Type The operation type.
+ @param[in] FileHandle The file to save or load variables.
+
+ @retval SHELL_SUCCESS The operation was successful.
+ @retval SHELL_OUT_OF_RESOURCES A memorty allocation failed.
+ @retval SHELL_ABORTED The abort message was received.
+ @retval SHELL_DEVICE_ERROR UEFI Variable Services returned an error.
+ @retval SHELL_NOT_FOUND the Name/Guid pair could not be found.
+**/
+SHELL_STATUS
+EFIAPI
+ProcessVariables (
+ IN CONST CHAR16 *Name OPTIONAL,
+ IN CONST EFI_GUID *Guid OPTIONAL,
+ IN DMP_STORE_TYPE Type,
+ IN SHELL_FILE_HANDLE FileHandle OPTIONAL
+ )
+{
+ SHELL_STATUS ShellStatus;
+ BOOLEAN Found;
+ EFI_GUID FoundVarGuid;
+
+ Found = FALSE;
+ ShellStatus = SHELL_SUCCESS;
+ ZeroMem (&FoundVarGuid, sizeof(EFI_GUID));
+
+ if (Type == DmpStoreLoad) {
+ ShellStatus = LoadVariablesFromFile (FileHandle, Name, Guid, &Found);
+ } else {
+ ShellStatus = CascadeProcessVariables(Name, Guid, Type, FileHandle, NULL, FoundVarGuid, &Found);
}
+
if (!Found) {
- if (Status == EFI_OUT_OF_RESOURCES) {
+ if (ShellStatus == SHELL_OUT_OF_RESOURCES) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);
- return SHELL_OUT_OF_RESOURCES;
- }
-
- if (VariableName != NULL && Guid == NULL) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N), gShellDebug1HiiHandle, VariableName);
- } else if (VariableName != NULL && Guid != NULL) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN), gShellDebug1HiiHandle, Guid, VariableName);
- } else if (VariableName == NULL && Guid == NULL) {
+ return (ShellStatus);
+ } else if (Name != NULL && Guid == NULL) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_N), gShellDebug1HiiHandle, Name);
+ } else if (Name != NULL && Guid != NULL) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_GN), gShellDebug1HiiHandle, Guid, Name);
+ } else if (Name == NULL && Guid == NULL) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND), gShellDebug1HiiHandle);
- } else if (VariableName == NULL && Guid != NULL) {
+ } else if (Name == NULL && Guid != NULL) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_NO_VAR_FOUND_G), gShellDebug1HiiHandle, Guid);
}
return (SHELL_NOT_FOUND);
@@ -253,8 +573,8 @@ ProcessVariables (
STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
{L"-d", TypeFlag},
- {L"-l", TypeFlag},
- {L"-s", TypeFlag},
+ {L"-l", TypeValue},
+ {L"-s", TypeValue},
{L"-all", TypeFlag},
{L"-guid", TypeValue},
{NULL, TypeMax}
@@ -273,17 +593,24 @@ ShellCommandRunDmpStore (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- SHELL_STATUS ShellStatus;
- CONST CHAR16 *Temp;
- EFI_GUID *Guid;
- EFI_GUID GuidData;
- CONST CHAR16 *VariableName;
+ EFI_STATUS Status;
+ LIST_ENTRY *Package;
+ CHAR16 *ProblemParam;
+ SHELL_STATUS ShellStatus;
+ CONST CHAR16 *GuidStr;
+ CONST CHAR16 *File;
+ EFI_GUID *Guid;
+ EFI_GUID GuidData;
+ CONST CHAR16 *Name;
+ DMP_STORE_TYPE Type;
+ SHELL_FILE_HANDLE FileHandle;
+ EFI_FILE_INFO *FileInfo;
ShellStatus = SHELL_SUCCESS;
Package = NULL;
+ FileHandle = NULL;
+ File = NULL;
+ Type = DmpStoreDisplay;
Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
if (EFI_ERROR(Status)) {
@@ -301,34 +628,121 @@ ShellCommandRunDmpStore (
} else if (ShellCommandLineGetFlag(Package, L"-all") && ShellCommandLineGetFlag(Package, L"-guid")) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"-all", L"-guid");
ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if (ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-l")) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"-l", L"-s");
+ ShellStatus = SHELL_INVALID_PARAMETER;
} else if ((ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) && ShellCommandLineGetFlag(Package, L"-d")) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONFLICT), gShellDebug1HiiHandle, L"-l or -s", L"-d");
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
if (!ShellCommandLineGetFlag(Package, L"-all")) {
- Temp = ShellCommandLineGetValue(Package, L"-guid");
- if (Temp != NULL) {
- Status = ConvertStringToGuid(Temp, &GuidData);
+ GuidStr = ShellCommandLineGetValue(Package, L"-guid");
+ if (GuidStr != NULL) {
+ Status = ConvertStringToGuid(GuidStr, &GuidData);
if (EFI_ERROR(Status)) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, GuidStr);
ShellStatus = SHELL_INVALID_PARAMETER;
}
Guid = &GuidData;
} else {
Guid = &gEfiGlobalVariableGuid;
}
- VariableName = ShellCommandLineGetRawValue(Package, 1);
+ Name = ShellCommandLineGetRawValue(Package, 1);
} else {
- VariableName = NULL;
- Guid = NULL;
+ Name = NULL;
+ Guid = NULL;
}
if (ShellStatus == SHELL_SUCCESS) {
- if (ShellCommandLineGetFlag(Package, L"-s") || ShellCommandLineGetFlag(Package, L"-l")) {
- ///@todo fix this after lib ready...
- ShellPrintEx(-1, -1, L"Not implemeneted yet.\r\n");
- ShellStatus = SHELL_UNSUPPORTED;
- } else {
- ShellStatus = ProcessVariables (VariableName, Guid, ShellCommandLineGetFlag(Package, L"-d"));
+ if (ShellCommandLineGetFlag(Package, L"-s")) {
+ Type = DmpStoreSave;
+ File = ShellCommandLineGetValue(Package, L"-s");
+ if (File == NULL) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-s");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Delete existing file, but do not delete existing directory
+ //
+ FileInfo = ShellGetFileInfo (FileHandle);
+ if (FileInfo == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);
+ Status = EFI_DEVICE_ERROR;
+ } else {
+ if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, File);
+ Status = EFI_INVALID_PARAMETER;
+ } else {
+ Status = ShellDeleteFile (&FileHandle);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_DELETE_FAIL), gShellDebug1HiiHandle, File);
+ }
+ }
+ FreePool (FileInfo);
+ }
+ } else if (Status == EFI_NOT_FOUND) {
+ //
+ // Good when file doesn't exist
+ //
+ Status = EFI_SUCCESS;
+ } else {
+ //
+ // Otherwise it's bad.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);
+ }
+
+ if (!EFI_ERROR (Status)) {
+ Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+ }
+ } else if (ShellCommandLineGetFlag(Package, L"-l")) {
+ Type = DmpStoreLoad;
+ File = ShellCommandLineGetValue(Package, L"-l");
+ if (File == NULL) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-l");
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellOpenFileByName (File, &FileHandle, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ FileInfo = ShellGetFileInfo (FileHandle);
+ if (FileInfo == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, File);
+ ShellStatus = SHELL_DEVICE_ERROR;
+ } else {
+ if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_IS_DIRECTORY), gShellDebug1HiiHandle, File);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ }
+ FreePool (FileInfo);
+ }
+ }
+ }
+ } else if (ShellCommandLineGetFlag(Package, L"-d")) {
+ Type = DmpStoreDelete;
+ }
+ }
+
+ if (ShellStatus == SHELL_SUCCESS) {
+ if (Type == DmpStoreSave) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_SAVE), gShellDebug1HiiHandle, File);
+ } else if (Type == DmpStoreLoad) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMPSTORE_LOAD), gShellDebug1HiiHandle, File);
+ }
+ ShellStatus = ProcessVariables (Name, Guid, Type, FileHandle);
+ if ((Type == DmpStoreLoad) || (Type == DmpStoreSave)) {
+ ShellCloseFile (&FileHandle);
}
}
}
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c
index e67c93f95..d07ae1721 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c
@@ -2,7 +2,7 @@
Main file for Pci shell Debug1 function.
Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2005 - 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
@@ -1499,7 +1499,8 @@ EFI_STATUS
PciExplainData (
IN PCI_CONFIG_SPACE *ConfigSpace,
IN UINT64 Address,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
+ IN CONST UINT16 EnhancedDump
);
/**
@@ -1627,7 +1628,8 @@ EFI_STATUS
PciExplainCapabilityStruct (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
IN UINT64 Address,
- IN UINT8 CapPtr
+ IN UINT8 CapPtr,
+ IN CONST UINT16 EnhancedDump
);
/**
@@ -1641,7 +1643,8 @@ EFI_STATUS
PciExplainPciExpress (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
IN UINT64 Address,
- IN UINT8 CapabilityPtr
+ IN UINT8 CapabilityPtr,
+ IN CONST UINT16 EnhancedDump
);
/**
@@ -2049,6 +2052,8 @@ ShellCommandRunPci (
CHAR16 *ProblemParam;
SHELL_STATUS ShellStatus;
CONST CHAR16 *Temp;
+ UINT64 RetVal;
+ UINT16 EnhancedDump;
ShellStatus = SHELL_SUCCESS;
Status = EFI_SUCCESS;
@@ -2302,7 +2307,16 @@ ShellCommandRunPci (
Temp = ShellCommandLineGetValue(Package, L"-s");
if (Temp != NULL) {
- Segment = (UINT16) ShellStrToUintn (Temp);
+ //
+ // Input converted to hexadecimal number.
+ //
+ if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
+ Segment = (UINT16) RetVal;
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto Done;
+ }
}
//
@@ -2311,7 +2325,17 @@ ShellCommandRunPci (
//
Temp = ShellCommandLineGetRawValue(Package, 1);
if (Temp != NULL) {
- Bus = (UINT16)ShellStrToUintn(Temp);
+ //
+ // Input converted to hexadecimal number.
+ //
+ if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
+ Bus = (UINT16) RetVal;
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto Done;
+ }
+
if (Bus > MAX_BUS_NUMBER) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
ShellStatus = SHELL_INVALID_PARAMETER;
@@ -2320,7 +2344,17 @@ ShellCommandRunPci (
}
Temp = ShellCommandLineGetRawValue(Package, 2);
if (Temp != NULL) {
- Device = (UINT16) ShellStrToUintn(Temp);
+ //
+ // Input converted to hexadecimal number.
+ //
+ if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
+ Device = (UINT16) RetVal;
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto Done;
+ }
+
if (Device > MAX_DEVICE_NUMBER){
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
ShellStatus = SHELL_INVALID_PARAMETER;
@@ -2330,7 +2364,17 @@ ShellCommandRunPci (
Temp = ShellCommandLineGetRawValue(Package, 3);
if (Temp != NULL) {
- Func = (UINT16) ShellStrToUintn(Temp);
+ //
+ // Input converted to hexadecimal number.
+ //
+ if (!EFI_ERROR (ShellConvertStringToUint64 (Temp, &RetVal, TRUE, TRUE))) {
+ Func = (UINT16) RetVal;
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV_HEX), gShellDebug1HiiHandle);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto Done;
+ }
+
if (Func > MAX_FUNCTION_NUMBER){
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
ShellStatus = SHELL_INVALID_PARAMETER;
@@ -2414,7 +2458,15 @@ ShellCommandRunPci (
// If "-i" appears in command line, interpret data in configuration space
//
if (ExplainData) {
- Status = PciExplainData (&ConfigSpace, Address, IoDev);
+ EnhancedDump = 0;
+ if (ShellCommandLineGetFlag(Package, L"-_e")) {
+ EnhancedDump = 0xFFFF;
+ Temp = ShellCommandLineGetValue(Package, L"-_e");
+ if (Temp != NULL) {
+ EnhancedDump = (UINT16) ShellHexStrToUintn (Temp);
+ }
+ }
+ Status = PciExplainData (&ConfigSpace, Address, IoDev, EnhancedDump);
}
}
Done:
@@ -2615,7 +2667,8 @@ EFI_STATUS
PciExplainData (
IN PCI_CONFIG_SPACE *ConfigSpace,
IN UINT64 Address,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
+ IN CONST UINT16 EnhancedDump
)
{
PCI_COMMON_HEADER *Common;
@@ -2773,7 +2826,7 @@ PciExplainData (
// If Status bit4 is 1, dump or explain capability structure
//
if ((Common->Status) & EFI_PCI_STATUS_CAPABILITY) {
- PciExplainCapabilityStruct (IoDev, Address, CapPtr);
+ PciExplainCapabilityStruct (IoDev, Address, CapPtr, EnhancedDump);
}
return Status;
@@ -3747,7 +3800,8 @@ EFI_STATUS
PciExplainCapabilityStruct (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
IN UINT64 Address,
- IN UINT8 CapPtr
+ IN UINT8 CapPtr,
+ IN CONST UINT16 EnhancedDump
)
{
UINT8 CapabilityPtr;
@@ -3770,7 +3824,7 @@ PciExplainCapabilityStruct (
// Explain PciExpress data
//
if (EFI_PCI_CAPABILITY_ID_PCIEXP == CapabilityID) {
- PciExplainPciExpress (IoDev, Address, CapabilityPtr);
+ PciExplainPciExpress (IoDev, Address, CapabilityPtr, EnhancedDump);
return EFI_SUCCESS;
}
//
@@ -4550,6 +4604,723 @@ ExplainPcieRootStatus (
}
/**
+ Function to interpret and print out the link control structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityLinkControl (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL *Header;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_LINK_CONTROL),
+ gShellDebug1HiiHandle,
+ Header->RootComplexLinkCapabilities,
+ Header->RootComplexLinkControl,
+ Header->RootComplexLinkStatus
+ );
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_INTERNAL_LINK_CONTROL),
+ (VOID *) (HeaderAddress)
+ );
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the power budgeting structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityPowerBudgeting (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING *Header;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_POWER),
+ gShellDebug1HiiHandle,
+ Header->DataSelect,
+ Header->Data,
+ Header->PowerBudgetCapability
+ );
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_POWER_BUDGETING),
+ (VOID *) (HeaderAddress)
+ );
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the ACS structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityAcs (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED *Header;
+ UINT16 VectorSize;
+ UINT16 LoopCounter;
+
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED*)HeaderAddress;
+ VectorSize = 0;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_ACS),
+ gShellDebug1HiiHandle,
+ Header->AcsCapability,
+ Header->AcsControl
+ );
+ if (PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_GET_EGRES_CONTROL(Header)) {
+ VectorSize = PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_GET_EGRES_VECTOR_SIZE(Header);
+ if (VectorSize == 0) {
+ VectorSize = 256;
+ }
+ for (LoopCounter = 0 ; LoopCounter * 8 < VectorSize ; LoopCounter++) {
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_ACS2),
+ gShellDebug1HiiHandle,
+ LoopCounter + 1,
+ Header->EgressControlVectorArray[LoopCounter]
+ );
+ }
+ }
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ACS_EXTENDED) + (VectorSize / 8) - 1,
+ (VOID *) (HeaderAddress)
+ );
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the latency tolerance reporting structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityLatencyToleranceReporting (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING *Header;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_LAT),
+ gShellDebug1HiiHandle,
+ Header->MaxSnoopLatency,
+ Header->MaxNoSnoopLatency
+ );
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_LATENCE_TOLERANCE_REPORTING),
+ (VOID *) (HeaderAddress)
+ );
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the serial number structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilitySerialNumber (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER *Header;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_SN),
+ gShellDebug1HiiHandle,
+ Header->SerialNumber
+ );
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_SERIAL_NUMBER),
+ (VOID *) (HeaderAddress)
+ );
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the RCRB structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityRcrb (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER *Header;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_RCRB),
+ gShellDebug1HiiHandle,
+ Header->VendorId,
+ Header->DeviceId,
+ Header->RcrbCapabilities,
+ Header->RcrbControl
+ );
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_RCRB_HEADER),
+ (VOID *) (HeaderAddress)
+ );
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the vendor specific structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityVendorSpecific (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VENDOR_SPECIFIC *Header;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_VENDOR_SPECIFIC*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_VEN),
+ gShellDebug1HiiHandle,
+ Header->VendorSpecificHeader
+ );
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_GET_SIZE(Header),
+ (VOID *) (HeaderAddress)
+ );
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the Event Collector Endpoint Association structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityECEA (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION *Header;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_ECEA),
+ gShellDebug1HiiHandle,
+ Header->AssociationBitmap
+ );
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION),
+ (VOID *) (HeaderAddress)
+ );
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the ARI structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityAri (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY *Header;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_ARI),
+ gShellDebug1HiiHandle,
+ Header->AriCapability,
+ Header->AriControl
+ );
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ARI_CAPABILITY),
+ (VOID *) (HeaderAddress)
+ );
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the DPA structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityDynamicPowerAllocation (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION *Header;
+ UINT8 LinkCount;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_DPA),
+ gShellDebug1HiiHandle,
+ Header->DpaCapability,
+ Header->DpaLatencyIndicator,
+ Header->DpaStatus,
+ Header->DpaControl
+ );
+ for (LinkCount = 0 ; LinkCount < PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_GET_SUBSTATE_MAX(Header) + 1 ; LinkCount++) {
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_DPA2),
+ gShellDebug1HiiHandle,
+ LinkCount+1,
+ Header->DpaPowerAllocationArray[LinkCount]
+ );
+ }
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_DYNAMIC_POWER_ALLOCATION) - 1 + PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_GET_SUBSTATE_MAX(Header),
+ (VOID *) (HeaderAddress)
+ );
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the link declaration structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityLinkDeclaration (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION *Header;
+ UINT8 LinkCount;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_LINK_DECLAR),
+ gShellDebug1HiiHandle,
+ Header->ElementSelfDescription
+ );
+
+ for (LinkCount = 0 ; LinkCount < PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_GET_LINK_COUNT(Header) ; LinkCount++) {
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_LINK_DECLAR2),
+ gShellDebug1HiiHandle,
+ LinkCount+1,
+ Header->LinkEntry[LinkCount]
+ );
+ }
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_LINK_DECLARATION) + (PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_GET_LINK_COUNT(Header)-1)*sizeof(UINT32),
+ (VOID *) (HeaderAddress)
+ );
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the Advanced Error Reporting structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityAer (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING *Header;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_AER),
+ gShellDebug1HiiHandle,
+ Header->UncorrectableErrorStatus,
+ Header->UncorrectableErrorMask,
+ Header->UncorrectableErrorSeverity,
+ Header->CorrectableErrorStatus,
+ Header->CorrectableErrorMask,
+ Header->AdvancedErrorCapabilitiesAndControl,
+ Header->HeaderLog,
+ Header->RootErrorCommand,
+ Header->RootErrorStatus,
+ Header->ErrorSourceIdentification,
+ Header->CorrectableErrorSourceIdentification,
+ Header->TlpPrefixLog[0],
+ Header->TlpPrefixLog[1],
+ Header->TlpPrefixLog[2],
+ Header->TlpPrefixLog[3]
+ );
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_ADVANCED_ERROR_REPORTING),
+ (VOID *) (HeaderAddress)
+ );
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the multicast structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+ @param[in] PciExpressCapPtr The address of the PCIe capabilities structure.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityMulticast (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress,
+ IN CONST PCIE_CAP_STURCTURE *PciExpressCapPtr
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST *Header;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_MULTICAST),
+ gShellDebug1HiiHandle,
+ Header->MultiCastCapability,
+ Header->MulticastControl,
+ Header->McBaseAddress,
+ Header->McReceiveAddress,
+ Header->McBlockAll,
+ Header->McBlockUntranslated,
+ Header->McOverlayBar
+ );
+
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_MULTICAST),
+ (VOID *) (HeaderAddress)
+ );
+
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the virtual channel and multi virtual channel structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityVirtualChannel (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY *Header;
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_VC *CapabilityItem;
+ UINT32 ItemCount;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_VC_BASE),
+ gShellDebug1HiiHandle,
+ Header->ExtendedVcCount,
+ Header->PortVcCapability1,
+ Header->PortVcCapability2,
+ Header->VcArbTableOffset,
+ Header->PortVcControl,
+ Header->PortVcStatus
+ );
+ for (ItemCount = 0 ; ItemCount < Header->ExtendedVcCount ; ItemCount++) {
+ CapabilityItem = &Header->Capability[ItemCount];
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_VC_ITEM),
+ gShellDebug1HiiHandle,
+ ItemCount+1,
+ CapabilityItem->VcResourceCapability,
+ CapabilityItem->PortArbTableOffset,
+ CapabilityItem->VcResourceControl,
+ CapabilityItem->VcResourceStatus
+ );
+ }
+
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_VC) + (Header->ExtendedVcCount - 1) * sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_VIRTUAL_CHANNEL_CAPABILITY),
+ (VOID *) (HeaderAddress)
+ );
+
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the resizeable bar structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityResizeableBar (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR *Header;
+ UINT32 ItemCount;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR*)HeaderAddress;
+
+ for (ItemCount = 0 ; ItemCount < (UINT32)GET_NUMBER_RESIZABLE_BARS(Header) ; ItemCount++) {
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_RESIZE_BAR),
+ gShellDebug1HiiHandle,
+ ItemCount+1,
+ Header->Capability[ItemCount].ResizableBarCapability,
+ Header->Capability[ItemCount].ResizableBarControl
+ );
+ }
+
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ (UINT32)GET_NUMBER_RESIZABLE_BARS(Header) * sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY),
+ (VOID *) (HeaderAddress)
+ );
+
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the TPH structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilityTph (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH *Header;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_TPH),
+ gShellDebug1HiiHandle,
+ Header->TphRequesterCapability,
+ Header->TphRequesterControl
+ );
+ DumpHex (
+ 8,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)Header->TphStTable - (UINT8*)HeadersBaseAddress),
+ GET_TPH_TABLE_SIZE(Header),
+ (VOID *)Header->TphStTable
+ );
+
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH) + GET_TPH_TABLE_SIZE(Header) - sizeof(UINT16),
+ (VOID *) (HeaderAddress)
+ );
+
+ return (EFI_SUCCESS);
+}
+
+/**
+ Function to interpret and print out the secondary PCIe capability structure
+
+ @param[in] HeaderAddress The Address of this capability header.
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+ @param[in] PciExpressCapPtr The address of the PCIe capabilities structure.
+**/
+EFI_STATUS
+EFIAPI
+PrintInterpretedExtendedCompatibilitySecondary (
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress,
+ IN CONST PCIE_CAP_STURCTURE *PciExpressCapPtr
+ )
+{
+ CONST PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE *Header;
+ Header = (PCI_EXPRESS_EXTENDED_CAPABILITIES_SECONDARY_PCIE*)HeaderAddress;
+
+ ShellPrintHiiEx(
+ -1, -1, NULL,
+ STRING_TOKEN (STR_PCI_EXT_CAP_SECONDARY),
+ gShellDebug1HiiHandle,
+ Header->LinkControl3,
+ Header->LaneErrorStatus
+ );
+ DumpHex (
+ 8,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)Header->EqualizationControl - (UINT8*)HeadersBaseAddress),
+ PCIE_CAP_MAX_LINK_WIDTH(PciExpressCapPtr->LinkCap),
+ (VOID *)Header->EqualizationControl
+ );
+
+ DumpHex (
+ 4,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET + ((UINT8*)HeaderAddress - (UINT8*)HeadersBaseAddress),
+ sizeof(PCI_EXPRESS_EXTENDED_CAPABILITIES_TPH) - sizeof(Header->EqualizationControl) + PCIE_CAP_MAX_LINK_WIDTH(PciExpressCapPtr->LinkCap),
+ (VOID *) (HeaderAddress)
+ );
+
+ return (EFI_SUCCESS);
+}
+
+/**
+ Display Pcie extended capability details
+
+ @param[in] HeadersBaseAddress The address of all the extended capability headers.
+ @param[in] HeaderAddress The address of this capability header.
+ @param[in] PciExpressCapPtr The address of the PCIe capabilities structure.
+**/
+EFI_STATUS
+EFIAPI
+PrintPciExtendedCapabilityDetails(
+ IN CONST PCI_EXP_EXT_HDR *HeadersBaseAddress,
+ IN CONST PCI_EXP_EXT_HDR *HeaderAddress,
+ IN CONST PCIE_CAP_STURCTURE *PciExpressCapPtr
+ )
+{
+ switch (HeaderAddress->CapabilityId){
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_ADVANCED_ERROR_REPORTING_ID:
+ return PrintInterpretedExtendedCompatibilityAer(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_CONTROL_ID:
+ return PrintInterpretedExtendedCompatibilityLinkControl(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_LINK_DECLARATION_ID:
+ return PrintInterpretedExtendedCompatibilityLinkDeclaration(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_SERIAL_NUMBER_ID:
+ return PrintInterpretedExtendedCompatibilitySerialNumber(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_POWER_BUDGETING_ID:
+ return PrintInterpretedExtendedCompatibilityPowerBudgeting(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_ACS_EXTENDED_ID:
+ return PrintInterpretedExtendedCompatibilityAcs(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_LATENCE_TOLERANCE_REPORTING_ID:
+ return PrintInterpretedExtendedCompatibilityLatencyToleranceReporting(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_ARI_CAPABILITY_ID:
+ return PrintInterpretedExtendedCompatibilityAri(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_RCRB_HEADER_ID:
+ return PrintInterpretedExtendedCompatibilityRcrb(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID:
+ return PrintInterpretedExtendedCompatibilityVendorSpecific(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_DYNAMIC_POWER_ALLOCATION_ID:
+ return PrintInterpretedExtendedCompatibilityDynamicPowerAllocation(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_EVENT_COLLECTOR_ENDPOINT_ASSOCIATION_ID:
+ return PrintInterpretedExtendedCompatibilityECEA(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_VIRTUAL_CHANNEL_ID:
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_MULTI_FUNCTION_VIRTUAL_CHANNEL_ID:
+ return PrintInterpretedExtendedCompatibilityVirtualChannel(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_MULTICAST_ID:
+ //
+ // should only be present if PCIE_CAP_DEVICEPORT_TYPE(PciExpressCapPtr->PcieCapReg) == 0100b, 0101b, or 0110b
+ //
+ return PrintInterpretedExtendedCompatibilityMulticast(HeaderAddress, HeadersBaseAddress, PciExpressCapPtr);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_ID:
+ return PrintInterpretedExtendedCompatibilityResizeableBar(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_TPH_ID:
+ return PrintInterpretedExtendedCompatibilityTph(HeaderAddress, HeadersBaseAddress);
+ case PCI_EXPRESS_EXTENDED_CAPABILITY_SECONDARY_PCIE_ID:
+ return PrintInterpretedExtendedCompatibilitySecondary(HeaderAddress, HeadersBaseAddress, PciExpressCapPtr);
+ default:
+ ShellPrintEx (-1, -1,
+ L"Unknown PCIe extended capability ID (%04xh). No interpretation available.\r\n",
+ HeaderAddress->CapabilityId
+ );
+ return EFI_SUCCESS;
+ };
+
+}
+
+/**
Display Pcie device structure.
@param[in] IoDev The pointer to the root pci protocol.
@@ -4560,7 +5331,8 @@ EFI_STATUS
PciExplainPciExpress (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev,
IN UINT64 Address,
- IN UINT8 CapabilityPtr
+ IN UINT8 CapabilityPtr,
+ IN CONST UINT16 EnhancedDump
)
{
@@ -4577,6 +5349,7 @@ PciExplainPciExpress (
UINTN Index;
UINT8 *RegAddr;
UINTN RegValue;
+ PCI_EXP_EXT_HDR *ExtHdr;
CapRegAddress = Address + CapabilityPtr;
IoDev->Pci.Read (
@@ -4663,15 +5436,15 @@ PciExplainPciExpress (
Dev = (UINT8) (RShiftU64 (Address, 16));
Func = (UINT8) (RShiftU64 (Address, 8));
- Pciex_Address = CALC_EFI_PCIEX_ADDRESS (Bus, Dev, Func, 0x100);
+ Pciex_Address = CALC_EFI_PCIEX_ADDRESS (Bus, Dev, Func, EFI_PCIE_CAPABILITY_BASE_OFFSET);
- ExtendRegSize = 0x1000 - 0x100;
+ ExtendRegSize = 0x1000 - EFI_PCIE_CAPABILITY_BASE_OFFSET;
ExRegBuffer = (UINT8 *) AllocateZeroPool (ExtendRegSize);
//
// PciRootBridgeIo protocol should support pci express extend space IO
- // (Begins at offset 0x100)
+ // (Begins at offset EFI_PCIE_CAPABILITY_BASE_OFFSET)
//
Status = IoDev->Pci.Read (
IoDev,
@@ -4680,25 +5453,47 @@ PciExplainPciExpress (
(ExtendRegSize) / sizeof (UINT32),
(VOID *) (ExRegBuffer)
);
- if (EFI_ERROR (Status)) {
- FreePool ((VOID *) ExRegBuffer);
+ if (EFI_ERROR (Status) || ExRegBuffer == NULL) {
+ SHELL_FREE_NON_NULL(ExRegBuffer);
return EFI_UNSUPPORTED;
}
- //
- // Start outputing PciEx extend space( 0xFF-0xFFF)
- //
- ShellPrintEx (-1, -1, L"\r\n%HStart dumping PCIex extended configuration space (0x100 - 0xFFF).%N\r\n\r\n");
- if (ExRegBuffer != NULL) {
+ if (EnhancedDump == 0) {
+ //
+ // Print the PciEx extend space in raw bytes ( 0xFF-0xFFF)
+ //
+ ShellPrintEx (-1, -1, L"\r\n%HStart dumping PCIex extended configuration space (0x100 - 0xFFF).%N\r\n\r\n");
+
DumpHex (
2,
- 0x100,
+ EFI_PCIE_CAPABILITY_BASE_OFFSET,
ExtendRegSize,
(VOID *) (ExRegBuffer)
- );
+ );
+ } else {
+ ExtHdr = (PCI_EXP_EXT_HDR*)ExRegBuffer;
+ while (ExtHdr->CapabilityId != 0 && ExtHdr->CapabilityVersion != 0) {
+ //
+ // Process this item
+ //
+ if (EnhancedDump == 0xFFFF || EnhancedDump == ExtHdr->CapabilityId) {
+ //
+ // Print this item
+ //
+ PrintPciExtendedCapabilityDetails((PCI_EXP_EXT_HDR*)ExRegBuffer, ExtHdr, &PciExpressCap);
+ }
- FreePool ((VOID *) ExRegBuffer);
+ //
+ // Advance to the next item if it exists
+ //
+ if (ExtHdr->NextCapabilityOffset != 0) {
+ ExtHdr = (PCI_EXP_EXT_HDR*)((UINT8*)ExRegBuffer + ExtHdr->NextCapabilityOffset);
+ } else {
+ break;
+ }
+ }
}
+ SHELL_FREE_NON_NULL(ExRegBuffer);
Done:
return EFI_SUCCESS;
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni
index 2dfb808c0..65d058fc4 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni
Binary files differ
diff --git a/ShellPkg/Library/UefiShellInstall1CommandsLib/Bcfg.c b/ShellPkg/Library/UefiShellInstall1CommandsLib/Bcfg.c
index 543ae376e..b91b34ffa 100644
--- a/ShellPkg/Library/UefiShellInstall1CommandsLib/Bcfg.c
+++ b/ShellPkg/Library/UefiShellInstall1CommandsLib/Bcfg.c
@@ -48,16 +48,6 @@ typedef struct {
} BGFG_OPERATION;
/**
- Get the actual number of entries in EFI_KEY_OPTION.Keys, from 0-3.
-
- @param KeyOption Pointer to the EFI_KEY_OPTION structure.
-
- @return Actual number of entries in EFI_KEY_OPTION.Keys.
-**/
-#define KEY_OPTION_INPUT_KEY_COUNT(KeyOption) \
- (((KeyOption)->KeyData & EFI_KEY_OPTION_INPUT_KEY_COUNT_MASK) >> LowBitSet32 (EFI_KEY_OPTION_INPUT_KEY_COUNT_MASK))
-
-/**
Update the optional data for a boot or driver option.
If optional data exists it will be changed.
@@ -841,7 +831,7 @@ BcfgAddOptInstall1(
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellInstall1HiiHandle, Walker);
ShellStatus = SHELL_INVALID_PARAMETER;
}
- NewKeyOption.KeyData = (UINT32)Intermediate;
+ NewKeyOption.KeyData.PackedValue = (UINT32)Intermediate;
Temp = StrStr(Walker, L" ");
if (Temp != NULL) {
Walker = Temp;
@@ -856,13 +846,13 @@ BcfgAddOptInstall1(
// Now we know how many EFI_INPUT_KEY structs we need to attach to the end of the EFI_KEY_OPTION struct.
// Re-allocate with the added information.
//
- KeyOptionBuffer = AllocateCopyPool(sizeof(EFI_KEY_OPTION) + (sizeof(EFI_INPUT_KEY) * KEY_OPTION_INPUT_KEY_COUNT (&NewKeyOption)), &NewKeyOption);
+ KeyOptionBuffer = AllocateCopyPool(sizeof(EFI_KEY_OPTION) + (sizeof(EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount), &NewKeyOption);
if (KeyOptionBuffer == NULL) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_MEM), gShellInstall1HiiHandle);
ShellStatus = SHELL_OUT_OF_RESOURCES;
}
}
- for (LoopCounter = 0 ; ShellStatus == SHELL_SUCCESS && LoopCounter < KEY_OPTION_INPUT_KEY_COUNT (&NewKeyOption); LoopCounter++) {
+ for (LoopCounter = 0 ; ShellStatus == SHELL_SUCCESS && LoopCounter < NewKeyOption.KeyData.Options.InputKeyCount; LoopCounter++) {
//
// ScanCode
//
@@ -928,7 +918,7 @@ BcfgAddOptInstall1(
VariableName,
(EFI_GUID*)&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof(EFI_KEY_OPTION) + (sizeof(EFI_INPUT_KEY) * KEY_OPTION_INPUT_KEY_COUNT (&NewKeyOption)),
+ sizeof(EFI_KEY_OPTION) + (sizeof(EFI_INPUT_KEY) * NewKeyOption.KeyData.Options.InputKeyCount),
KeyOptionBuffer);
if (EFI_ERROR(Status)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_BCFG_SET_VAR_FAIL), gShellInstall1HiiHandle, VariableName, Status);
diff --git a/ShellPkg/Library/UefiShellLevel1CommandsLib/For.c b/ShellPkg/Library/UefiShellLevel1CommandsLib/For.c
index f0c4a23b2..46182f714 100644
--- a/ShellPkg/Library/UefiShellLevel1CommandsLib/For.c
+++ b/ShellPkg/Library/UefiShellLevel1CommandsLib/For.c
@@ -270,7 +270,7 @@ ReturnUintn(
{
UINT64 RetVal;
- if (!EFI_ERROR(ShellConvertStringToUint64(String, &RetVal, FALSE, FALSE))) {
+ if (!EFI_ERROR(ShellConvertStringToUint64(String, &RetVal, FALSE, TRUE))) {
return ((UINTN)RetVal);
}
return ((UINTN)(-1));
@@ -370,11 +370,7 @@ ShellCommandRunFor (
gEfiShellParametersProtocol->Argv[2]) == 0) {
for (LoopVar = 0x3 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
ASSERT((ArgSet == NULL && ArgSize == 0) || (ArgSet != NULL));
- if (ArgSet == NULL) {
- // ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L"\"", 0);
- } else {
- ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" \"", 0);
- }
+ ArgSet = StrnCatGrow(&ArgSet, &ArgSize, L" \"", 0);
if (StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"*") != NULL
||StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"?") != NULL
||StrStr(gEfiShellParametersProtocol->Argv[LoopVar], L"[") != NULL
diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c
index 4d0a1563e..cc4a9d4cf 100644
--- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c
+++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c
@@ -393,7 +393,6 @@ PrintLsOutput(
FreePool(CorrectedPath);
ShellCloseFileMetaArg(&ListHead);
- FreePool(ListHead);
return (ShellStatus);
}
diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c
index 590dbf79e..9e33286c9 100644
--- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c
+++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c
@@ -468,6 +468,9 @@ PerformSingleMappingDisplay(
}
} else {
Alias = StrnCatGrow(&Alias, 0, MapList, 0);
+ if (Alias == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
TempSpot = StrStr(Alias, CurrentName);
if (TempSpot != NULL) {
TempSpot2 = StrStr(TempSpot, L";");
@@ -484,6 +487,10 @@ PerformSingleMappingDisplay(
}
} else {
CurrentName = NULL;
+ CurrentName = StrnCatGrow(&CurrentName, 0, L"", 0);
+ if (CurrentName == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
}
DevPathString = ConvertDevicePathToText(DevPath, TRUE, FALSE);
if (!SFO) {
diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Rm.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Rm.c
index b85120b76..c1e01426f 100644
--- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Rm.c
+++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Rm.c
@@ -92,7 +92,6 @@ CascadeDelete(
if (!Quiet) {
Status = ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_RM_LOG_DELETE_CONF), gShellLevel2HiiHandle, Node->FullName);
Status = ShellPromptForResponse(ShellPromptResponseTypeYesNo, NULL, (VOID**)&Resp);
- ASSERT_EFI_ERROR(Status);
ASSERT(Resp != NULL);
if (EFI_ERROR(Status) || *Resp != ShellPromptResponseYes) {
SHELL_FREE_NON_NULL(Resp);
diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.c b/ShellPkg/Library/UefiShellLib/UefiShellLib.c
index 40b87fec3..9b5878675 100644
--- a/ShellPkg/Library/UefiShellLib/UefiShellLib.c
+++ b/ShellPkg/Library/UefiShellLib/UefiShellLib.c
@@ -1,7 +1,7 @@
/** @file
Provides interface to shell functionality for shell commands and applications.
- 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
which accompanies this distribution. The full text of the license may be found at
@@ -1598,6 +1598,7 @@ ShellCloseFileMetaArg (
FreePool(((EFI_SHELL_FILE_INFO_NO_CONST*)Node)->Info);
FreePool((EFI_SHELL_FILE_INFO_NO_CONST*)Node);
}
+ SHELL_FREE_NON_NULL(*ListHead);
return EFI_SUCCESS;
}
@@ -3296,6 +3297,10 @@ ShellPromptForResponse (
//
*Resp = ShellPromptResponseMax;
while (*Resp == ShellPromptResponseMax) {
+ if (ShellGetExecutionBreakFlag()) {
+ Status = EFI_ABORTED;
+ break;
+ }
gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
ASSERT_EFI_ERROR(Status);
@@ -3324,6 +3329,10 @@ ShellPromptForResponse (
//
*Resp = ShellPromptResponseMax;
while (*Resp == ShellPromptResponseMax) {
+ if (ShellGetExecutionBreakFlag()) {
+ Status = EFI_ABORTED;
+ break;
+ }
gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
ASSERT_EFI_ERROR(Status);
@@ -3358,6 +3367,10 @@ ShellPromptForResponse (
//
*Resp = ShellPromptResponseMax;
while (*Resp == ShellPromptResponseMax) {
+ if (ShellGetExecutionBreakFlag()) {
+ Status = EFI_ABORTED;
+ break;
+ }
gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
if (Type == ShellPromptResponseTypeEnterContinue) {
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
@@ -3385,6 +3398,10 @@ ShellPromptForResponse (
//
*Resp = ShellPromptResponseMax;
while (*Resp == ShellPromptResponseMax) {
+ if (ShellGetExecutionBreakFlag()) {
+ Status = EFI_ABORTED;
+ break;
+ }
gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
ASSERT_EFI_ERROR(Status);
@@ -3406,6 +3423,10 @@ ShellPromptForResponse (
ShellPrintEx(-1, -1, L"%s", Prompt);
}
while(1) {
+ if (ShellGetExecutionBreakFlag()) {
+ Status = EFI_ABORTED;
+ break;
+ }
gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
ASSERT_EFI_ERROR(Status);
@@ -3419,6 +3440,7 @@ ShellPromptForResponse (
break;
//
// This is the location to add new prompt types.
+ // If your new type loops remember to add ExecutionBreak support.
//
default:
ASSERT(FALSE);