X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ShellPkg%2FApplication%2FShell%2FShell.c;h=7eaccb747cccb65088eb6e9243039fa3ffe0129f;hb=14030c5c854ea40487a853344fc763d808c1a88b;hp=4abeafcd44474f08a9c45e05ff263bf4ada4d3f0;hpb=0c41d28e598356f083c308f359d435e63a6e0ef9;p=mirror_edk2.git
diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c
index 4abeafcd44..7eaccb747c 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 - 2014, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
(C) Copyright 2013-2014, 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
@@ -100,6 +100,95 @@ TrimSpaces(
return (EFI_SUCCESS);
}
+/**
+ Parse for the next instance of one string within another string. Can optionally make sure that
+ the string was not escaped (^ character) per the shell specification.
+
+ @param[in] SourceString The string to search within
+ @param[in] FindString The string to look for
+ @param[in] CheckForEscapeCharacter TRUE to skip escaped instances of FinfString, otherwise will return even escaped instances
+**/
+CHAR16*
+EFIAPI
+FindNextInstance(
+ IN CONST CHAR16 *SourceString,
+ IN CONST CHAR16 *FindString,
+ IN CONST BOOLEAN CheckForEscapeCharacter
+ )
+{
+ CHAR16 *Temp;
+ if (SourceString == NULL) {
+ return (NULL);
+ }
+ Temp = StrStr(SourceString, FindString);
+
+ //
+ // If nothing found, or we dont care about escape characters
+ //
+ if (Temp == NULL || !CheckForEscapeCharacter) {
+ return (Temp);
+ }
+
+ //
+ // If we found an escaped character, try again on the remainder of the string
+ //
+ if ((Temp > (SourceString)) && *(Temp-1) == L'^') {
+ return FindNextInstance(Temp+1, FindString, CheckForEscapeCharacter);
+ }
+
+ //
+ // we found the right character
+ //
+ return (Temp);
+}
+
+/**
+ Check whether the string between a pair of % is a valid envifronment variable name.
+
+ @param[in] BeginPercent pointer to the first percent.
+ @param[in] EndPercent pointer to the last percent.
+
+ @retval TRUE is a valid environment variable name.
+ @retval FALSE is NOT a valid environment variable name.
+**/
+BOOLEAN
+IsValidEnvironmentVariableName(
+ IN CONST CHAR16 *BeginPercent,
+ IN CONST CHAR16 *EndPercent
+ )
+{
+ CONST CHAR16 *Walker;
+
+ Walker = NULL;
+
+ ASSERT (BeginPercent != NULL);
+ ASSERT (EndPercent != NULL);
+ ASSERT (BeginPercent < EndPercent);
+
+ if ((BeginPercent + 1) == EndPercent) {
+ return FALSE;
+ }
+
+ for (Walker = BeginPercent + 1; Walker < EndPercent; Walker++) {
+ if (
+ (*Walker >= L'0' && *Walker <= L'9') ||
+ (*Walker >= L'A' && *Walker <= L'Z') ||
+ (*Walker >= L'a' && *Walker <= L'z') ||
+ (*Walker == L'_')
+ ) {
+ if (Walker == BeginPercent + 1 && (*Walker >= L'0' && *Walker <= L'9')) {
+ return FALSE;
+ } else {
+ continue;
+ }
+ } else {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
/**
Find a command line contains a split operation
@@ -142,7 +231,39 @@ ContainsSplit(
)
{
CONST CHAR16 *TempSpot;
- TempSpot = FindSplit(CmdLine);
+ CONST CHAR16 *FirstQuote;
+ CONST CHAR16 *SecondQuote;
+
+ FirstQuote = FindNextInstance (CmdLine, L"\"", TRUE);
+ SecondQuote = NULL;
+ TempSpot = FindSplit(CmdLine);
+
+ if (FirstQuote == NULL ||
+ TempSpot == NULL ||
+ TempSpot == CHAR_NULL ||
+ FirstQuote > TempSpot
+ ) {
+ return (BOOLEAN) ((TempSpot != NULL) && (*TempSpot != CHAR_NULL));
+ }
+
+ while ((TempSpot != NULL) && (*TempSpot != CHAR_NULL)) {
+ if (FirstQuote == NULL || FirstQuote > TempSpot) {
+ break;
+ }
+ SecondQuote = FindNextInstance (FirstQuote + 1, L"\"", TRUE);
+ if (SecondQuote == NULL) {
+ break;
+ }
+ if (SecondQuote < TempSpot) {
+ FirstQuote = FindNextInstance (SecondQuote + 1, L"\"", TRUE);
+ continue;
+ } else {
+ FirstQuote = FindNextInstance (SecondQuote + 1, L"\"", TRUE);
+ TempSpot = FindSplit(TempSpot + 1);
+ continue;
+ }
+ }
+
return (BOOLEAN) ((TempSpot != NULL) && (*TempSpot != CHAR_NULL));
}
@@ -244,9 +365,6 @@ UefiMain (
UINTN Size;
EFI_HANDLE ConInHandle;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *OldConIn;
- UINTN ExitDataSize;
- CHAR16 *ExitData;
- SHELL_STATUS ExitStatus;
if (PcdGet8(PcdShellSupportLevel) > 3) {
return (EFI_UNSUPPORTED);
@@ -300,12 +418,6 @@ UefiMain (
// install our console logger. This will keep a log of the output for back-browsing
//
Status = ConsoleLoggerInstall(ShellInfoObject.LogScreenCount, &ShellInfoObject.ConsoleInfo);
- if(EFI_ERROR (Status)) {
- ExitStatus = (SHELL_STATUS) (Status & (~MAX_BIT));
- } else {
- ExitStatus = SHELL_SUCCESS;
- }
-
if (!EFI_ERROR(Status)) {
//
// Enable the cursor to be visible
@@ -419,7 +531,7 @@ UefiMain (
// Display the mapping
//
if (PcdGet8(PcdShellSupportLevel) >= 2 && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap) {
- Status = RunCommand(L"map", NULL);
+ Status = RunCommand(L"map");
ASSERT_EFI_ERROR(Status);
}
@@ -485,11 +597,7 @@ UefiMain (
//
// process the startup script or launch the called app.
//
- Status = DoStartupScript(
- ShellInfoObject.ImageDevPath,
- ShellInfoObject.FileDevPath,
- &ExitStatus
- );
+ Status = DoStartupScript(ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath);
}
if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit && !ShellCommandGetExit() && (PcdGet8(PcdShellSupportLevel) >= 3 || PcdGetBool(PcdShellForceConsole)) && !EFI_ERROR(Status) && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {
@@ -509,6 +617,7 @@ UefiMain (
// Reset page break back to default.
//
ShellInfoObject.PageBreakEnabled = PcdGetBool(PcdShellPageBreakDefault);
+ ASSERT (ShellInfoObject.ConsoleInfo != NULL);
ShellInfoObject.ConsoleInfo->Enabled = TRUE;
ShellInfoObject.ConsoleInfo->RowCounter = 0;
@@ -522,7 +631,6 @@ UefiMain (
//
Status = DoShellPrompt();
} while (!ShellCommandGetExit());
- ExitStatus = (SHELL_STATUS) ShellCommandGetExitCode();
}
if (OldConIn != NULL && ConInHandle != NULL) {
CloseSimpleTextInOnFile (gST->ConIn);
@@ -594,33 +702,10 @@ FreeResources:
DEBUG_CODE(ShellInfoObject.ConsoleInfo = NULL;);
}
- if (!EFI_ERROR (Status)) {
- // If the command exited with an error, we pass this error out in the ExitData
- // so that it can be retrieved by the EfiShellExecute function (which may
- // start the shell with gBS->StartImage)
- if (ExitStatus != SHELL_SUCCESS) {
- // Allocate a buffer for exit data to pass to gBS->Exit().
- // This buffer will contain the empty string immediately followed by
- // the shell's exit status. (The empty string is required by the UEFI spec)
- ExitDataSize = (sizeof (CHAR16) + sizeof (SHELL_STATUS));
- ExitData = AllocatePool (ExitDataSize);
- if (ExitData == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- ExitData[0] = '\0';
- // Use CopyMem to avoid alignment faults
- CopyMem ((ExitData + 1), &ExitStatus, sizeof (ExitStatus));
-
- gBS->Exit (ImageHandle, EFI_ABORTED, ExitDataSize, ExitData);
-
- ASSERT (FALSE);
- return EFI_SUCCESS;
- } else {
- return EFI_SUCCESS;
- }
- } else {
- return Status;
+ if (ShellCommandGetExit()) {
+ return ((EFI_STATUS)ShellCommandGetExitCode());
}
+ return (Status);
}
/**
@@ -936,7 +1021,7 @@ ProcessCommandLine(
continue;
}
- ShellInfoObject.ShellInitSettings.FileName = AllocateZeroPool(StrSize(CurrentArg));
+ ShellInfoObject.ShellInitSettings.FileName = AllocateCopyPool(StrSize(CurrentArg), CurrentArg);
if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
return (EFI_OUT_OF_RESOURCES);
}
@@ -944,8 +1029,6 @@ ProcessCommandLine(
// We found `file-name`.
//
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = 1;
-
- StrCpy (ShellInfoObject.ShellInitSettings.FileName, CurrentArg);
LoopVar++;
// Add `file-name-options`
@@ -987,16 +1070,13 @@ ProcessCommandLine(
@param ImagePath the path to the image for shell. first place to look for the startup script
@param FilePath the path to the file for shell. second place to look for the startup script.
- @param[out] ExitStatus The exit code of the script. Ignored if NULL.
-
@retval EFI_SUCCESS the variable is initialized.
**/
EFI_STATUS
EFIAPI
DoStartupScript(
- IN EFI_DEVICE_PATH_PROTOCOL *ImagePath,
- IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
- OUT SHELL_STATUS *ExitStatus
+ IN EFI_DEVICE_PATH_PROTOCOL *ImagePath,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath
)
{
EFI_STATUS Status;
@@ -1026,12 +1106,12 @@ DoStartupScript(
if (FileStringPath == NULL) {
return (EFI_OUT_OF_RESOURCES);
}
- StrCpy(FileStringPath, ShellInfoObject.ShellInitSettings.FileName);
+ StrnCpy(FileStringPath, ShellInfoObject.ShellInitSettings.FileName, NewSize/sizeof(CHAR16) -1);
if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {
- StrCat(FileStringPath, L" ");
- StrCat(FileStringPath, ShellInfoObject.ShellInitSettings.FileOptions);
+ StrnCat(FileStringPath, L" ", NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1);
+ StrnCat(FileStringPath, ShellInfoObject.ShellInitSettings.FileOptions, NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1);
}
- Status = RunCommand(FileStringPath, ExitStatus);
+ Status = RunCommand(FileStringPath);
FreePool(FileStringPath);
return (Status);
@@ -1108,13 +1188,7 @@ DoStartupScript(
// If we got a file, run it
//
if (!EFI_ERROR(Status) && FileHandle != NULL) {
- Status = RunScriptFile (
- mStartupScript,
- FileHandle,
- L"",
- ShellInfoObject.NewShellParametersProtocol,
- ExitStatus
- );
+ Status = RunScriptFile (mStartupScript, FileHandle, L"", ShellInfoObject.NewShellParametersProtocol);
ShellInfoObject.NewEfiShellProtocol->CloseFile(FileHandle);
} else {
FileStringPath = ShellFindFilePath(mStartupScript);
@@ -1125,13 +1199,7 @@ DoStartupScript(
Status = EFI_SUCCESS;
ASSERT(FileHandle == NULL);
} else {
- Status = RunScriptFile(
- FileStringPath,
- NULL,
- L"",
- ShellInfoObject.NewShellParametersProtocol,
- ExitStatus
- );
+ Status = RunScriptFile(FileStringPath, NULL, L"", ShellInfoObject.NewShellParametersProtocol);
FreePool(FileStringPath);
}
}
@@ -1196,7 +1264,7 @@ DoShellPrompt (
//
if (!EFI_ERROR (Status)) {
CmdLine[BufferSize / sizeof (CHAR16)] = CHAR_NULL;
- Status = RunCommand(CmdLine, NULL);
+ Status = RunCommand(CmdLine);
}
//
@@ -1246,9 +1314,8 @@ AddLineToCommandHistory(
Node = AllocateZeroPool(sizeof(BUFFER_LIST));
ASSERT(Node != NULL);
- Node->Buffer = AllocateZeroPool(StrSize(Buffer));
+ Node->Buffer = AllocateCopyPool(StrSize(Buffer), Buffer);
ASSERT(Node->Buffer != NULL);
- StrCpy(Node->Buffer, Buffer);
InsertTailList(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link);
}
@@ -1279,56 +1346,13 @@ ShellConvertAlias(
return (EFI_SUCCESS);
}
FreePool(*CommandString);
- *CommandString = AllocateZeroPool(StrSize(NewString));
+ *CommandString = AllocateCopyPool(StrSize(NewString), NewString);
if (*CommandString == NULL) {
return (EFI_OUT_OF_RESOURCES);
}
- StrCpy(*CommandString, NewString);
return (EFI_SUCCESS);
}
-/**
- Parse for the next instance of one string within another string. Can optionally make sure that
- the string was not escaped (^ character) per the shell specification.
-
- @param[in] SourceString The string to search within
- @param[in] FindString The string to look for
- @param[in] CheckForEscapeCharacter TRUE to skip escaped instances of FinfString, otherwise will return even escaped instances
-**/
-CHAR16*
-EFIAPI
-FindNextInstance(
- IN CONST CHAR16 *SourceString,
- IN CONST CHAR16 *FindString,
- IN CONST BOOLEAN CheckForEscapeCharacter
- )
-{
- CHAR16 *Temp;
- if (SourceString == NULL) {
- return (NULL);
- }
- Temp = StrStr(SourceString, FindString);
-
- //
- // If nothing found, or we dont care about escape characters
- //
- if (Temp == NULL || !CheckForEscapeCharacter) {
- return (Temp);
- }
-
- //
- // If we found an escaped character, try again on the remainder of the string
- //
- if ((Temp > (SourceString)) && *(Temp-1) == L'^') {
- return FindNextInstance(Temp+1, FindString, CheckForEscapeCharacter);
- }
-
- //
- // we found the right character
- //
- return (Temp);
-}
-
/**
This function will eliminate unreplaced (and therefore non-found) environment variables.
@@ -1357,8 +1381,8 @@ StripUnreplacedEnvironmentVariables(
break;
}
- if (FirstQuote < FirstPercent) {
- SecondQuote = FirstQuote!= NULL?FindNextInstance(FirstQuote+1, L"\"", TRUE):NULL;
+ if (FirstQuote!= NULL && FirstQuote < FirstPercent) {
+ SecondQuote = FindNextInstance(FirstQuote+1, L"\"", TRUE);
//
// Quote is first found
//
@@ -1376,19 +1400,21 @@ StripUnreplacedEnvironmentVariables(
}
continue;
}
- ASSERT(FirstPercent < FirstQuote);
- if (SecondPercent < FirstQuote) {
- FirstPercent[0] = L'\"';
- SecondPercent[0] = L'\"';
-
- //
- // We need to remove from FirstPercent to SecondPercent
- //
- CopyMem(FirstPercent + 1, SecondPercent, StrSize(SecondPercent));
- CurrentLocator = FirstPercent + 2;
+
+ if (FirstQuote == NULL || SecondPercent < FirstQuote) {
+ if (IsValidEnvironmentVariableName(FirstPercent, SecondPercent)) {
+ //
+ // We need to remove from FirstPercent to SecondPercent
+ //
+ CopyMem(FirstPercent, SecondPercent + 1, StrSize(SecondPercent + 1));
+ //
+ // dont need to update the locator. both % characters are gone.
+ //
+ } else {
+ CurrentLocator = SecondPercent + 1;
+ }
continue;
}
- ASSERT(FirstQuote < SecondPercent);
CurrentLocator = FirstQuote;
}
return (EFI_SUCCESS);
@@ -1476,7 +1502,7 @@ ShellConvertVariables (
//
// now do the replacements...
//
- NewCommandLine1 = AllocateZeroPool(NewSize);
+ NewCommandLine1 = AllocateCopyPool(NewSize, OriginalCommandLine);
NewCommandLine2 = AllocateZeroPool(NewSize);
ItemTemp = AllocateZeroPool(ItemSize+(2*sizeof(CHAR16)));
if (NewCommandLine1 == NULL || NewCommandLine2 == NULL || ItemTemp == NULL) {
@@ -1485,16 +1511,15 @@ ShellConvertVariables (
SHELL_FREE_NON_NULL(ItemTemp);
return (NULL);
}
- StrCpy(NewCommandLine1, OriginalCommandLine);
for (MasterEnvList = EfiShellGetEnv(NULL)
- ; MasterEnvList != NULL && *MasterEnvList != CHAR_NULL //&& *(MasterEnvList+1) != CHAR_NULL
+ ; MasterEnvList != NULL && *MasterEnvList != CHAR_NULL
; MasterEnvList += StrLen(MasterEnvList) + 1
){
- StrCpy(ItemTemp, L"%");
- StrCat(ItemTemp, MasterEnvList);
- StrCat(ItemTemp, L"%");
+ StrnCpy(ItemTemp, L"%", ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16))-1);
+ StrnCat(ItemTemp, MasterEnvList, ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16))-1 - StrLen(ItemTemp));
+ StrnCat(ItemTemp, L"%", ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16))-1 - StrLen(ItemTemp));
ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, ItemTemp, EfiShellGetEnv(MasterEnvList), TRUE, FALSE);
- StrCpy(NewCommandLine1, NewCommandLine2);
+ StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1);
}
if (CurrentScriptFile != NULL) {
for (AliasListNode = (ALIAS_LIST*)GetFirstNode(&CurrentScriptFile->SubstList)
@@ -1502,20 +1527,20 @@ ShellConvertVariables (
; AliasListNode = (ALIAS_LIST*)GetNextNode(&CurrentScriptFile->SubstList, &AliasListNode->Link)
){
ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, AliasListNode->Alias, AliasListNode->CommandString, TRUE, FALSE);
- StrCpy(NewCommandLine1, NewCommandLine2);
+ StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1);
}
-
- //
- // Remove non-existant environment variables in scripts only
- //
- StripUnreplacedEnvironmentVariables(NewCommandLine1);
}
+ //
+ // Remove non-existant environment variables
+ //
+ StripUnreplacedEnvironmentVariables(NewCommandLine1);
+
//
// Now cleanup any straggler intentionally ignored "%" characters
//
ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, L"^%", L"%", TRUE, FALSE);
- StrCpy(NewCommandLine1, NewCommandLine2);
+ StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1);
FreePool(NewCommandLine2);
FreePool(ItemTemp);
@@ -1530,9 +1555,6 @@ ShellConvertVariables (
@param[in] StdIn The pointer to the Standard input.
@param[in] StdOut The pointer to the Standard output.
- @param[out] ExitStatus The exit code of the last command in the pipeline.
- Ignored if NULL.
-
@retval EFI_SUCCESS The split command is executed successfully.
@retval other Some error occurs when executing the split command.
**/
@@ -1541,8 +1563,7 @@ EFIAPI
RunSplitCommand(
IN CONST CHAR16 *CmdLine,
IN SHELL_FILE_HANDLE *StdIn,
- IN SHELL_FILE_HANDLE *StdOut,
- OUT SHELL_STATUS *ExitStatus
+ IN SHELL_FILE_HANDLE *StdOut
)
{
EFI_STATUS Status;
@@ -1596,7 +1617,7 @@ RunSplitCommand(
ASSERT(Split->SplitStdOut != NULL);
InsertHeadList(&ShellInfoObject.SplitList.Link, &Split->Link);
- Status = RunCommand(OurCommandLine, NULL);
+ Status = RunCommand(OurCommandLine);
//
// move the output from the first to the in to the second.
@@ -1611,7 +1632,7 @@ RunSplitCommand(
ShellInfoObject.NewEfiShellProtocol->SetFilePosition(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn), 0);
if (!EFI_ERROR(Status)) {
- Status = RunCommand(NextCommandLine, ExitStatus);
+ Status = RunCommand(NextCommandLine);
}
//
@@ -1849,12 +1870,12 @@ IsValidSplit(
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 (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CmdLine)))) {
+ 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;
+ }
}
}
@@ -1905,9 +1926,7 @@ VerifySplit(
/**
Process a split based operation.
- @param[in] CmdLine Pointer to the command line to process
- @param[out] ExitStatus The exit status of the command. Ignored if NULL.
- Invalid if this function returns an error.
+ @param[in] CmdLine pointer to the command line to process
@retval EFI_SUCCESS The operation was successful
@return an error occured.
@@ -1915,8 +1934,7 @@ VerifySplit(
EFI_STATUS
EFIAPI
ProcessNewSplitCommandLine(
- IN CONST CHAR16 *CmdLine,
- OUT SHELL_STATUS *ExitStatus
+ IN CONST CHAR16 *CmdLine
)
{
SPLIT_LIST *Split;
@@ -1937,14 +1955,9 @@ ProcessNewSplitCommandLine(
}
if (Split == NULL) {
- Status = RunSplitCommand(CmdLine, NULL, NULL, ExitStatus);
+ Status = RunSplitCommand(CmdLine, NULL, NULL);
} else {
- Status = RunSplitCommand(
- CmdLine,
- Split->SplitStdIn,
- Split->SplitStdOut,
- ExitStatus
- );
+ Status = RunSplitCommand(CmdLine, Split->SplitStdIn, Split->SplitStdOut);
}
if (EFI_ERROR(Status)) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_SPLIT), ShellInfoObject.HiiHandle, CmdLine);
@@ -2017,20 +2030,25 @@ DoHelpUpdate(
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;
+ if (!EFI_ERROR(GetNextParameter(&Walker, &CurrentParameter, StrSize(*CmdLine)))) {
+ 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;
+ }
+
+ //
+ // We know the space is sufficient since we just calculated it.
+ //
+ StrnCpy(NewCommandLine, L"help ", 5);
+ StrnCat(NewCommandLine, *CmdLine, StrLen(*CmdLine));
+ SHELL_FREE_NON_NULL(*CmdLine);
+ *CmdLine = NewCommandLine;
break;
}
- StrCpy(NewCommandLine, L"help ");
- StrCat(NewCommandLine, *CmdLine);
- SHELL_FREE_NON_NULL(*CmdLine);
- *CmdLine = NewCommandLine;
- break;
}
}
@@ -2091,6 +2109,7 @@ ProcessCommandLineToFinal(
if (EFI_ERROR(Status)) {
return (Status);
}
+ ASSERT (*CmdLine != NULL);
TrimSpaces(CmdLine);
@@ -2119,8 +2138,6 @@ ProcessCommandLineToFinal(
@param[in] FirstParameter the first parameter on the command line
@param[in] ParamProtocol the shell parameters protocol pointer
- @param[out] ExitStatus The exit code of the command. Ignored if NULL.
-
@retval EFI_SUCCESS The command was completed.
@retval EFI_ABORTED The command's operation was aborted.
**/
@@ -2129,8 +2146,7 @@ EFIAPI
RunInternalCommand(
IN CONST CHAR16 *CmdLine,
IN CHAR16 *FirstParameter,
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,
- OUT SHELL_STATUS *ExitStatus OPTIONAL
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
)
{
EFI_STATUS Status;
@@ -2138,11 +2154,24 @@ RunInternalCommand(
CHAR16 **Argv;
SHELL_STATUS CommandReturnedStatus;
BOOLEAN LastError;
+ CHAR16 *Walker;
+ CHAR16 *NewCmdLine;
+
+ NewCmdLine = AllocateCopyPool (StrSize (CmdLine), CmdLine);
+ if (NewCmdLine == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (Walker = NewCmdLine; Walker != NULL && *Walker != CHAR_NULL ; Walker++) {
+ if (*Walker == L'^' && *(Walker+1) == L'#') {
+ CopyMem(Walker, Walker+1, StrSize(Walker) - sizeof(Walker[0]));
+ }
+ }
//
// get the argc and argv updated for internal commands
//
- Status = UpdateArgcArgv(ParamProtocol, CmdLine, &Argv, &Argc);
+ Status = UpdateArgcArgv(ParamProtocol, NewCmdLine, &Argv, &Argc);
if (!EFI_ERROR(Status)) {
//
// Run the internal command.
@@ -2157,9 +2186,6 @@ RunInternalCommand(
if (LastError) {
SetLastError(CommandReturnedStatus);
}
- if (ExitStatus != NULL) {
- *ExitStatus = CommandReturnedStatus;
- }
//
// Pass thru the exitcode from the app.
@@ -2203,6 +2229,7 @@ RunInternalCommand(
Status = EFI_SUCCESS;
}
+ FreePool (NewCmdLine);
return (Status);
}
@@ -2214,9 +2241,6 @@ RunInternalCommand(
@param[in] FirstParameter the first parameter on the command line
@param[in] ParamProtocol the shell parameters protocol pointer
- @param[out] ExitStatus The exit code of the command or file.
- Ignored if NULL.
-
@retval EFI_SUCCESS The command was completed.
@retval EFI_ABORTED The command's operation was aborted.
**/
@@ -2226,8 +2250,7 @@ RunCommandOrFile(
IN SHELL_OPERATION_TYPES Type,
IN CONST CHAR16 *CmdLine,
IN CHAR16 *FirstParameter,
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,
- OUT SHELL_STATUS *ExitStatus
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
)
{
EFI_STATUS Status;
@@ -2243,12 +2266,7 @@ RunCommandOrFile(
switch (Type) {
case Internal_Command:
- Status = RunInternalCommand(
- CmdLine,
- FirstParameter,
- ParamProtocol,
- &CalleeExitStatus
- );
+ Status = RunInternalCommand(CmdLine, FirstParameter, ParamProtocol);
break;
case Script_File_Name:
case Efi_Application:
@@ -2283,13 +2301,7 @@ RunCommandOrFile(
}
switch (Type) {
case Script_File_Name:
- Status = RunScriptFile (
- CommandWithPath,
- NULL,
- CmdLine,
- ParamProtocol,
- &CalleeExitStatus
- );
+ Status = RunScriptFile (CommandWithPath, NULL, CmdLine, ParamProtocol);
break;
case Efi_Application:
//
@@ -2309,9 +2321,7 @@ RunCommandOrFile(
DevPath,
CmdLine,
NULL,
- &StartStatus,
- NULL,
- NULL
+ &StartStatus
);
SHELL_FREE_NON_NULL(DevPath);
@@ -2344,10 +2354,6 @@ RunCommandOrFile(
SHELL_FREE_NON_NULL(CommandWithPath);
- if (ExitStatus != NULL) {
- *ExitStatus = CalleeExitStatus;
- }
-
return (Status);
}
@@ -2359,20 +2365,16 @@ RunCommandOrFile(
@param[in] FirstParameter the first parameter on the command line.
@param[in] ParamProtocol the shell parameters protocol pointer
- @param[out] ExitStatus The exit code of the command or file.
- Ignored if NULL.
-
@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,
- OUT SHELL_STATUS *ExitStatus
+ IN SHELL_OPERATION_TYPES Type,
+ IN CHAR16 *CmdLine,
+ IN CHAR16 *FirstParameter,
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
)
{
EFI_STATUS Status;
@@ -2391,13 +2393,8 @@ SetupAndRunCommandOrFile(
// Now run the command, script, or application
//
if (!EFI_ERROR(Status)) {
- Status = RunCommandOrFile(
- Type,
- CmdLine,
- FirstParameter,
- ParamProtocol,
- ExitStatus
- );
+ TrimSpaces(&CmdLine);
+ Status = RunCommandOrFile(Type, CmdLine, FirstParameter, ParamProtocol);
}
//
@@ -2422,7 +2419,6 @@ SetupAndRunCommandOrFile(
command or dispatch an external application.
@param[in] CmdLine The command line to parse.
- @param[out] ExitStatus The exit code of the command. Ignored if NULL.
@retval EFI_SUCCESS The command was completed.
@retval EFI_ABORTED The command's operation was aborted.
@@ -2430,8 +2426,7 @@ SetupAndRunCommandOrFile(
EFI_STATUS
EFIAPI
RunCommand(
- IN CONST CHAR16 *CmdLine,
- OUT SHELL_STATUS *ExitStatus
+ IN CONST CHAR16 *CmdLine
)
{
EFI_STATUS Status;
@@ -2455,6 +2450,24 @@ RunCommand(
TrimSpaces(&CleanOriginal);
+ //
+ // NULL out comments (leveraged from RunScriptFileHandle() ).
+ // The # character on a line is used to denote that all characters on the same line
+ // and to the right of the # are to be ignored by the shell.
+ // Afterward, again remove spaces, in case any were between the last command-parameter and '#'.
+ //
+ for (TempWalker = CleanOriginal; TempWalker != NULL && *TempWalker != CHAR_NULL; TempWalker++) {
+ if (*TempWalker == L'^') {
+ if (*(TempWalker + 1) == L'#') {
+ TempWalker++;
+ }
+ } else if (*TempWalker == L'#') {
+ *TempWalker = CHAR_NULL;
+ }
+ }
+
+ TrimSpaces(&CleanOriginal);
+
//
// Handle case that passed in command line is just 1 or more " " characters.
//
@@ -2473,7 +2486,7 @@ RunCommand(
// We dont do normal processing with a split command line (output from one command input to another)
//
if (ContainsSplit(CleanOriginal)) {
- Status = ProcessNewSplitCommandLine(CleanOriginal, ExitStatus);
+ Status = ProcessNewSplitCommandLine(CleanOriginal);
SHELL_FREE_NON_NULL(CleanOriginal);
return (Status);
}
@@ -2487,33 +2500,30 @@ RunCommand(
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 (FirstParameter);
- break;
- case Internal_Command:
- case Script_File_Name:
- case Efi_Application:
- Status = SetupAndRunCommandOrFile(
- Type,
- CleanOriginal,
- FirstParameter,
- ShellInfoObject.NewShellParametersProtocol,
- ExitStatus
- );
- 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;
+ if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CleanOriginal)))) {
+ //
+ // Depending on the first parameter we change the behavior
+ //
+ switch (Type = GetOperationType(FirstParameter)) {
+ case File_Sys_Change:
+ Status = ChangeMappedDrive (FirstParameter);
+ 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;
+ }
+ } else {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
+ SetLastError(SHELL_NOT_FOUND);
}
SHELL_FREE_NON_NULL(CleanOriginal);
@@ -2560,16 +2570,13 @@ IsValidCommandName(
@param[in] Handle The handle to the already opened file.
@param[in] Name The name of the script file.
- @param[out] ExitStatus The exit code of the script. Ignored if NULL.
-
@retval EFI_SUCCESS the script completed sucessfully
**/
EFI_STATUS
EFIAPI
RunScriptFileHandle (
- IN SHELL_FILE_HANDLE Handle,
- IN CONST CHAR16 *Name,
- OUT SHELL_STATUS *ExitStatus
+ IN SHELL_FILE_HANDLE Handle,
+ IN CONST CHAR16 *Name
)
{
EFI_STATUS Status;
@@ -2585,11 +2592,8 @@ RunScriptFileHandle (
CONST CHAR16 *CurDir;
UINTN LineCount;
CHAR16 LeString[50];
- SHELL_STATUS CalleeExitStatus;
ASSERT(!ShellCommandGetScriptExit());
-
- CalleeExitStatus = SHELL_SUCCESS;
PreScriptEchoState = ShellCommandGetEchoState();
@@ -2683,15 +2687,17 @@ RunScriptFileHandle (
; // conditional increment in the body of the loop
){
ASSERT(CommandLine2 != NULL);
- StrCpy(CommandLine2, NewScriptFile->CurrentCommand->Cl);
+ StrnCpy(CommandLine2, NewScriptFile->CurrentCommand->Cl, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1);
//
// NULL out comments
//
for (CommandLine3 = CommandLine2 ; CommandLine3 != NULL && *CommandLine3 != CHAR_NULL ; CommandLine3++) {
if (*CommandLine3 == L'^') {
- if (*(CommandLine3+1) == L'#' || *(CommandLine3+1) == L':') {
+ if ( *(CommandLine3+1) == L':') {
CopyMem(CommandLine3, CommandLine3+1, StrSize(CommandLine3) - sizeof(CommandLine3[0]));
+ } else if (*(CommandLine3+1) == L'#') {
+ CommandLine3++;
}
} else if (*CommandLine3 == L'#') {
*CommandLine3 = CHAR_NULL;
@@ -2702,7 +2708,7 @@ RunScriptFileHandle (
//
// Due to variability in starting the find and replace action we need to have both buffers the same.
//
- StrCpy(CommandLine, CommandLine2);
+ StrnCpy(CommandLine, CommandLine2, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1);
//
// Remove the %0 to %9 from the command line (if we have some arguments)
@@ -2710,34 +2716,34 @@ RunScriptFileHandle (
if (NewScriptFile->Argv != NULL) {
switch (NewScriptFile->Argc) {
default:
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", NewScriptFile->Argv[9], FALSE, TRUE);
+ Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", NewScriptFile->Argv[9], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 9:
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%8", NewScriptFile->Argv[8], FALSE, TRUE);
+ Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%8", NewScriptFile->Argv[8], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 8:
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%7", NewScriptFile->Argv[7], FALSE, TRUE);
+ Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%7", NewScriptFile->Argv[7], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 7:
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%6", NewScriptFile->Argv[6], FALSE, TRUE);
+ Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%6", NewScriptFile->Argv[6], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 6:
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%5", NewScriptFile->Argv[5], FALSE, TRUE);
+ Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%5", NewScriptFile->Argv[5], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 5:
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%4", NewScriptFile->Argv[4], FALSE, TRUE);
+ Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%4", NewScriptFile->Argv[4], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 4:
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%3", NewScriptFile->Argv[3], FALSE, TRUE);
+ Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%3", NewScriptFile->Argv[3], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 3:
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%2", NewScriptFile->Argv[2], FALSE, TRUE);
+ Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%2", NewScriptFile->Argv[2], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 2:
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%1", NewScriptFile->Argv[1], FALSE, TRUE);
+ Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%1", NewScriptFile->Argv[1], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 1:
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%0", NewScriptFile->Argv[0], FALSE, TRUE);
+ Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%0", NewScriptFile->Argv[0], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
break;
case 0:
@@ -2754,7 +2760,7 @@ RunScriptFileHandle (
Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%8", L"\"\"", FALSE, FALSE);
Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", L"\"\"", FALSE, FALSE);
- StrCpy(CommandLine2, CommandLine);
+ StrnCpy(CommandLine2, CommandLine, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1);
LastCommand = NewScriptFile->CurrentCommand;
@@ -2773,7 +2779,7 @@ RunScriptFileHandle (
//
PreCommandEchoState = ShellCommandGetEchoState();
ShellCommandSetEchoState(FALSE);
- Status = RunCommand(CommandLine3+1, NULL);
+ Status = RunCommand(CommandLine3+1);
//
// If command was "@echo -off" or "@echo -on" then don't restore echo state
@@ -2795,7 +2801,7 @@ RunScriptFileHandle (
}
ShellPrintEx(-1, -1, L"%s\r\n", CommandLine2);
}
- Status = RunCommand(CommandLine3, NULL);
+ Status = RunCommand(CommandLine3);
}
}
@@ -2803,8 +2809,7 @@ RunScriptFileHandle (
//
// ShellCommandGetExitCode() always returns a UINT64
//
- CalleeExitStatus = (SHELL_STATUS) ShellCommandGetExitCode();
- UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", CalleeExitStatus);
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", ShellCommandGetExitCode());
DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););
InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);
@@ -2816,11 +2821,9 @@ RunScriptFileHandle (
break;
}
if (EFI_ERROR(Status)) {
- CalleeExitStatus = (SHELL_STATUS) Status;
break;
}
if (ShellCommandGetExit()) {
- CalleeExitStatus = (SHELL_STATUS) ShellCommandGetExitCode();
break;
}
}
@@ -2852,11 +2855,6 @@ RunScriptFileHandle (
if (ShellCommandGetCurrentScriptFile()==NULL) {
ShellCommandSetEchoState(PreScriptEchoState);
}
-
- if (ExitStatus != NULL) {
- *ExitStatus = CalleeExitStatus;
- }
-
return (EFI_SUCCESS);
}
@@ -2868,18 +2866,15 @@ RunScriptFileHandle (
@param[in] CmdLine the command line to run.
@param[in] ParamProtocol the shell parameters protocol pointer
- @param[out] ExitStatus The exit code of the script. Ignored if NULL.
-
@retval EFI_SUCCESS the script completed sucessfully
**/
EFI_STATUS
EFIAPI
RunScriptFile (
- IN CONST CHAR16 *ScriptPath,
- IN SHELL_FILE_HANDLE Handle OPTIONAL,
- IN CONST CHAR16 *CmdLine,
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,
- OUT SHELL_STATUS *ExitStatus
+ IN CONST CHAR16 *ScriptPath,
+ IN SHELL_FILE_HANDLE Handle OPTIONAL,
+ IN CONST CHAR16 *CmdLine,
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol
)
{
EFI_STATUS Status;
@@ -2906,7 +2901,7 @@ RunScriptFile (
//
// run it
//
- Status = RunScriptFileHandle(FileHandle, ScriptPath, ExitStatus);
+ Status = RunScriptFileHandle(FileHandle, ScriptPath);
//
// now close the file
@@ -2914,7 +2909,7 @@ RunScriptFile (
ShellCloseFile(&FileHandle);
}
} else {
- Status = RunScriptFileHandle(Handle, ScriptPath, ExitStatus);
+ Status = RunScriptFileHandle(Handle, ScriptPath);
}
}