/** @file\r
This is THE shell (application)\r
\r
- Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2013-2014, Hewlett-Packard Development Company, L.P.\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
return (EFI_SUCCESS);\r
}\r
\r
+/**\r
+ Parse for the next instance of one string within another string. Can optionally make sure that \r
+ the string was not escaped (^ character) per the shell specification.\r
+\r
+ @param[in] SourceString The string to search within\r
+ @param[in] FindString The string to look for\r
+ @param[in] CheckForEscapeCharacter TRUE to skip escaped instances of FinfString, otherwise will return even escaped instances\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+FindNextInstance(\r
+ IN CONST CHAR16 *SourceString,\r
+ IN CONST CHAR16 *FindString,\r
+ IN CONST BOOLEAN CheckForEscapeCharacter\r
+ )\r
+{\r
+ CHAR16 *Temp;\r
+ if (SourceString == NULL) {\r
+ return (NULL);\r
+ }\r
+ Temp = StrStr(SourceString, FindString);\r
+\r
+ //\r
+ // If nothing found, or we dont care about escape characters\r
+ //\r
+ if (Temp == NULL || !CheckForEscapeCharacter) {\r
+ return (Temp);\r
+ }\r
+\r
+ //\r
+ // If we found an escaped character, try again on the remainder of the string\r
+ //\r
+ if ((Temp > (SourceString)) && *(Temp-1) == L'^') {\r
+ return FindNextInstance(Temp+1, FindString, CheckForEscapeCharacter);\r
+ }\r
+\r
+ //\r
+ // we found the right character\r
+ //\r
+ return (Temp);\r
+}\r
+\r
+/**\r
+ Check whether the string between a pair of % is a valid envifronment variable name.\r
+\r
+ @param[in] BeginPercent pointer to the first percent.\r
+ @param[in] EndPercent pointer to the last percent.\r
+\r
+ @retval TRUE is a valid environment variable name.\r
+ @retval FALSE is NOT a valid environment variable name.\r
+**/\r
+BOOLEAN\r
+IsValidEnvironmentVariableName(\r
+ IN CONST CHAR16 *BeginPercent,\r
+ IN CONST CHAR16 *EndPercent\r
+ )\r
+{\r
+ CONST CHAR16 *Walker;\r
+ \r
+ Walker = NULL;\r
+\r
+ ASSERT (BeginPercent != NULL);\r
+ ASSERT (EndPercent != NULL);\r
+ ASSERT (BeginPercent < EndPercent);\r
+ \r
+ if ((BeginPercent + 1) == EndPercent) {\r
+ return FALSE;\r
+ }\r
+\r
+ for (Walker = BeginPercent + 1; Walker < EndPercent; Walker++) {\r
+ if (\r
+ (*Walker >= L'0' && *Walker <= L'9') ||\r
+ (*Walker >= L'A' && *Walker <= L'Z') ||\r
+ (*Walker >= L'a' && *Walker <= L'z') ||\r
+ (*Walker == L'_')\r
+ ) {\r
+ if (Walker == BeginPercent + 1 && (*Walker >= L'0' && *Walker <= L'9')) {\r
+ return FALSE;\r
+ } else {\r
+ continue;\r
+ }\r
+ } else {\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
/**\r
Find a command line contains a split operation\r
\r
)\r
{\r
CONST CHAR16 *TempSpot;\r
- TempSpot = FindSplit(CmdLine);\r
+ CONST CHAR16 *FirstQuote;\r
+ CONST CHAR16 *SecondQuote;\r
+\r
+ FirstQuote = FindNextInstance (CmdLine, L"\"", TRUE);\r
+ SecondQuote = NULL;\r
+ TempSpot = FindSplit(CmdLine);\r
+\r
+ if (FirstQuote == NULL || \r
+ TempSpot == NULL || \r
+ TempSpot == CHAR_NULL || \r
+ FirstQuote > TempSpot\r
+ ) {\r
+ return (BOOLEAN) ((TempSpot != NULL) && (*TempSpot != CHAR_NULL));\r
+ }\r
+\r
+ while ((TempSpot != NULL) && (*TempSpot != CHAR_NULL)) {\r
+ if (FirstQuote == NULL || FirstQuote > TempSpot) {\r
+ break;\r
+ } \r
+ SecondQuote = FindNextInstance (FirstQuote + 1, L"\"", TRUE);\r
+ if (SecondQuote == NULL) {\r
+ break;\r
+ }\r
+ if (SecondQuote < TempSpot) {\r
+ FirstQuote = FindNextInstance (SecondQuote + 1, L"\"", TRUE);\r
+ continue;\r
+ } else {\r
+ FirstQuote = FindNextInstance (SecondQuote + 1, L"\"", TRUE);\r
+ TempSpot = FindSplit(TempSpot + 1);\r
+ continue;\r
+ } \r
+ }\r
+ \r
return (BOOLEAN) ((TempSpot != NULL) && (*TempSpot != CHAR_NULL));\r
}\r
\r
UINTN Size;\r
EFI_HANDLE ConInHandle;\r
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *OldConIn;\r
- UINTN ExitDataSize;\r
- CHAR16 *ExitData;\r
- SHELL_STATUS ExitStatus;\r
\r
if (PcdGet8(PcdShellSupportLevel) > 3) {\r
return (EFI_UNSUPPORTED);\r
// install our console logger. This will keep a log of the output for back-browsing\r
//\r
Status = ConsoleLoggerInstall(ShellInfoObject.LogScreenCount, &ShellInfoObject.ConsoleInfo);\r
- if(EFI_ERROR (Status)) {\r
- ExitStatus = (SHELL_STATUS) (Status & (~MAX_BIT));\r
- } else {\r
- ExitStatus = SHELL_SUCCESS;\r
- }\r
- \r
if (!EFI_ERROR(Status)) {\r
//\r
// Enable the cursor to be visible\r
// Display the mapping\r
//\r
if (PcdGet8(PcdShellSupportLevel) >= 2 && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap) {\r
- Status = RunCommand(L"map", NULL);\r
+ Status = RunCommand(L"map");\r
ASSERT_EFI_ERROR(Status);\r
}\r
\r
//\r
// process the startup script or launch the called app.\r
//\r
- Status = DoStartupScript(\r
- ShellInfoObject.ImageDevPath,\r
- ShellInfoObject.FileDevPath,\r
- &ExitStatus\r
- );\r
+ Status = DoStartupScript(ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath);\r
}\r
\r
if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit && !ShellCommandGetExit() && (PcdGet8(PcdShellSupportLevel) >= 3 || PcdGetBool(PcdShellForceConsole)) && !EFI_ERROR(Status) && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {\r
//\r
Status = DoShellPrompt();\r
} while (!ShellCommandGetExit());\r
- ExitStatus = (SHELL_STATUS) ShellCommandGetExitCode();\r
}\r
if (OldConIn != NULL && ConInHandle != NULL) {\r
CloseSimpleTextInOnFile (gST->ConIn);\r
DEBUG_CODE(ShellInfoObject.ConsoleInfo = NULL;);\r
}\r
\r
- if (!EFI_ERROR (Status)) {\r
- // If the command exited with an error, we pass this error out in the ExitData\r
- // so that it can be retrieved by the EfiShellExecute function (which may\r
- // start the shell with gBS->StartImage)\r
- if (ExitStatus != SHELL_SUCCESS) {\r
- // Allocate a buffer for exit data to pass to gBS->Exit().\r
- // This buffer will contain the empty string immediately followed by\r
- // the shell's exit status. (The empty string is required by the UEFI spec)\r
- ExitDataSize = (sizeof (CHAR16) + sizeof (SHELL_STATUS));\r
- ExitData = AllocatePool (ExitDataSize);\r
- if (ExitData == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- ExitData[0] = '\0';\r
- // Use CopyMem to avoid alignment faults\r
- CopyMem ((ExitData + 1), &ExitStatus, sizeof (ExitStatus));\r
-\r
- gBS->Exit (ImageHandle, EFI_ABORTED, ExitDataSize, ExitData);\r
-\r
- ASSERT (FALSE);\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_SUCCESS;\r
- }\r
- } else {\r
- return Status;\r
+ if (ShellCommandGetExit()) {\r
+ return ((EFI_STATUS)ShellCommandGetExitCode());\r
}\r
+ return (Status);\r
}\r
\r
/**\r
continue;\r
}\r
\r
- ShellInfoObject.ShellInitSettings.FileName = AllocateZeroPool(StrSize(CurrentArg));\r
+ ShellInfoObject.ShellInitSettings.FileName = AllocateCopyPool(StrSize(CurrentArg), CurrentArg);\r
if (ShellInfoObject.ShellInitSettings.FileName == NULL) {\r
return (EFI_OUT_OF_RESOURCES);\r
}\r
// We found `file-name`.\r
//\r
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = 1;\r
-\r
- StrCpy (ShellInfoObject.ShellInitSettings.FileName, CurrentArg);\r
LoopVar++;\r
\r
// Add `file-name-options`\r
@param ImagePath the path to the image for shell. first place to look for the startup script\r
@param FilePath the path to the file for shell. second place to look for the startup script.\r
\r
- @param[out] ExitStatus The exit code of the script. Ignored if NULL.\r
-\r
@retval EFI_SUCCESS the variable is initialized.\r
**/\r
EFI_STATUS\r
EFIAPI\r
DoStartupScript(\r
- IN EFI_DEVICE_PATH_PROTOCOL *ImagePath,\r
- IN EFI_DEVICE_PATH_PROTOCOL *FilePath,\r
- OUT SHELL_STATUS *ExitStatus\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ImagePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath\r
)\r
{\r
EFI_STATUS Status;\r
if (FileStringPath == NULL) {\r
return (EFI_OUT_OF_RESOURCES);\r
}\r
- StrCpy(FileStringPath, ShellInfoObject.ShellInitSettings.FileName);\r
+ StrnCpy(FileStringPath, ShellInfoObject.ShellInitSettings.FileName, NewSize/sizeof(CHAR16) -1);\r
if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {\r
- StrCat(FileStringPath, L" ");\r
- StrCat(FileStringPath, ShellInfoObject.ShellInitSettings.FileOptions);\r
+ StrnCat(FileStringPath, L" ", NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1);\r
+ StrnCat(FileStringPath, ShellInfoObject.ShellInitSettings.FileOptions, NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1);\r
}\r
- Status = RunCommand(FileStringPath, ExitStatus);\r
+ Status = RunCommand(FileStringPath);\r
FreePool(FileStringPath);\r
return (Status);\r
\r
// If we got a file, run it\r
//\r
if (!EFI_ERROR(Status) && FileHandle != NULL) {\r
- Status = RunScriptFile (\r
- mStartupScript,\r
- FileHandle,\r
- L"",\r
- ShellInfoObject.NewShellParametersProtocol,\r
- ExitStatus\r
- );\r
+ Status = RunScriptFile (mStartupScript, FileHandle, L"", ShellInfoObject.NewShellParametersProtocol);\r
ShellInfoObject.NewEfiShellProtocol->CloseFile(FileHandle);\r
} else {\r
FileStringPath = ShellFindFilePath(mStartupScript);\r
Status = EFI_SUCCESS;\r
ASSERT(FileHandle == NULL);\r
} else {\r
- Status = RunScriptFile(\r
- FileStringPath,\r
- NULL,\r
- L"",\r
- ShellInfoObject.NewShellParametersProtocol,\r
- ExitStatus\r
- );\r
+ Status = RunScriptFile(FileStringPath, NULL, L"", ShellInfoObject.NewShellParametersProtocol);\r
FreePool(FileStringPath);\r
}\r
}\r
//\r
if (!EFI_ERROR (Status)) {\r
CmdLine[BufferSize / sizeof (CHAR16)] = CHAR_NULL;\r
- Status = RunCommand(CmdLine, NULL);\r
+ Status = RunCommand(CmdLine);\r
}\r
\r
//\r
\r
Node = AllocateZeroPool(sizeof(BUFFER_LIST));\r
ASSERT(Node != NULL);\r
- Node->Buffer = AllocateZeroPool(StrSize(Buffer));\r
+ Node->Buffer = AllocateCopyPool(StrSize(Buffer), Buffer);\r
ASSERT(Node->Buffer != NULL);\r
- StrCpy(Node->Buffer, Buffer);\r
\r
InsertTailList(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link);\r
}\r
return (EFI_SUCCESS);\r
}\r
FreePool(*CommandString);\r
- *CommandString = AllocateZeroPool(StrSize(NewString));\r
+ *CommandString = AllocateCopyPool(StrSize(NewString), NewString);\r
if (*CommandString == NULL) {\r
return (EFI_OUT_OF_RESOURCES);\r
}\r
- StrCpy(*CommandString, NewString);\r
return (EFI_SUCCESS);\r
}\r
\r
-/**\r
- Parse for the next instance of one string within another string. Can optionally make sure that \r
- the string was not escaped (^ character) per the shell specification.\r
-\r
- @param[in] SourceString The string to search within\r
- @param[in] FindString The string to look for\r
- @param[in] CheckForEscapeCharacter TRUE to skip escaped instances of FinfString, otherwise will return even escaped instances\r
-**/\r
-CHAR16*\r
-EFIAPI\r
-FindNextInstance(\r
- IN CONST CHAR16 *SourceString,\r
- IN CONST CHAR16 *FindString,\r
- IN CONST BOOLEAN CheckForEscapeCharacter\r
- )\r
-{\r
- CHAR16 *Temp;\r
- if (SourceString == NULL) {\r
- return (NULL);\r
- }\r
- Temp = StrStr(SourceString, FindString);\r
-\r
- //\r
- // If nothing found, or we dont care about escape characters\r
- //\r
- if (Temp == NULL || !CheckForEscapeCharacter) {\r
- return (Temp);\r
- }\r
-\r
- //\r
- // If we found an escaped character, try again on the remainder of the string\r
- //\r
- if ((Temp > (SourceString)) && *(Temp-1) == L'^') {\r
- return FindNextInstance(Temp+1, FindString, CheckForEscapeCharacter);\r
- }\r
-\r
- //\r
- // we found the right character\r
- //\r
- return (Temp);\r
-}\r
-\r
/**\r
This function will eliminate unreplaced (and therefore non-found) environment variables.\r
\r
break;\r
}\r
\r
- if (FirstQuote < FirstPercent) {\r
- SecondQuote = FirstQuote!= NULL?FindNextInstance(FirstQuote+1, L"\"", TRUE):NULL;\r
+ if (FirstQuote!= NULL && FirstQuote < FirstPercent) {\r
+ SecondQuote = FindNextInstance(FirstQuote+1, L"\"", TRUE);\r
//\r
// Quote is first found\r
//\r
}\r
continue;\r
}\r
- ASSERT(FirstPercent < FirstQuote);\r
- if (SecondPercent < FirstQuote) {\r
- FirstPercent[0] = L'\"';\r
- SecondPercent[0] = L'\"';\r
-\r
- //\r
- // We need to remove from FirstPercent to SecondPercent\r
- //\r
- CopyMem(FirstPercent + 1, SecondPercent, StrSize(SecondPercent));\r
- CurrentLocator = FirstPercent + 2;\r
+ \r
+ if (FirstQuote == NULL || SecondPercent < FirstQuote) {\r
+ if (IsValidEnvironmentVariableName(FirstPercent, SecondPercent)) {\r
+ //\r
+ // We need to remove from FirstPercent to SecondPercent\r
+ //\r
+ CopyMem(FirstPercent, SecondPercent + 1, StrSize(SecondPercent + 1));\r
+ //\r
+ // dont need to update the locator. both % characters are gone.\r
+ //\r
+ } else {\r
+ CurrentLocator = SecondPercent + 1;\r
+ }\r
continue;\r
}\r
- ASSERT(FirstQuote < SecondPercent);\r
CurrentLocator = FirstQuote;\r
}\r
return (EFI_SUCCESS);\r
//\r
// now do the replacements...\r
//\r
- NewCommandLine1 = AllocateZeroPool(NewSize);\r
+ NewCommandLine1 = AllocateCopyPool(NewSize, OriginalCommandLine);\r
NewCommandLine2 = AllocateZeroPool(NewSize);\r
ItemTemp = AllocateZeroPool(ItemSize+(2*sizeof(CHAR16)));\r
if (NewCommandLine1 == NULL || NewCommandLine2 == NULL || ItemTemp == NULL) {\r
SHELL_FREE_NON_NULL(ItemTemp);\r
return (NULL);\r
}\r
- StrCpy(NewCommandLine1, OriginalCommandLine);\r
for (MasterEnvList = EfiShellGetEnv(NULL)\r
- ; MasterEnvList != NULL && *MasterEnvList != CHAR_NULL //&& *(MasterEnvList+1) != CHAR_NULL\r
+ ; MasterEnvList != NULL && *MasterEnvList != CHAR_NULL\r
; MasterEnvList += StrLen(MasterEnvList) + 1\r
){\r
- StrCpy(ItemTemp, L"%");\r
- StrCat(ItemTemp, MasterEnvList);\r
- StrCat(ItemTemp, L"%");\r
+ StrnCpy(ItemTemp, L"%", ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16))-1);\r
+ StrnCat(ItemTemp, MasterEnvList, ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16))-1 - StrLen(ItemTemp));\r
+ StrnCat(ItemTemp, L"%", ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16))-1 - StrLen(ItemTemp));\r
ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, ItemTemp, EfiShellGetEnv(MasterEnvList), TRUE, FALSE);\r
- StrCpy(NewCommandLine1, NewCommandLine2);\r
+ StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1);\r
}\r
if (CurrentScriptFile != NULL) {\r
for (AliasListNode = (ALIAS_LIST*)GetFirstNode(&CurrentScriptFile->SubstList)\r
; AliasListNode = (ALIAS_LIST*)GetNextNode(&CurrentScriptFile->SubstList, &AliasListNode->Link)\r
){\r
ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, AliasListNode->Alias, AliasListNode->CommandString, TRUE, FALSE);\r
- StrCpy(NewCommandLine1, NewCommandLine2);\r
+ StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1);\r
}\r
-\r
- //\r
- // Remove non-existant environment variables in scripts only\r
- //\r
- StripUnreplacedEnvironmentVariables(NewCommandLine1);\r
}\r
\r
+ //\r
+ // Remove non-existant environment variables\r
+ //\r
+ StripUnreplacedEnvironmentVariables(NewCommandLine1);\r
+\r
//\r
// Now cleanup any straggler intentionally ignored "%" characters\r
//\r
ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, L"^%", L"%", TRUE, FALSE);\r
- StrCpy(NewCommandLine1, NewCommandLine2);\r
+ StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1);\r
\r
FreePool(NewCommandLine2);\r
FreePool(ItemTemp);\r
@param[in] StdIn The pointer to the Standard input.\r
@param[in] StdOut The pointer to the Standard output.\r
\r
- @param[out] ExitStatus The exit code of the last command in the pipeline.\r
- Ignored if NULL.\r
-\r
@retval EFI_SUCCESS The split command is executed successfully.\r
@retval other Some error occurs when executing the split command.\r
**/\r
RunSplitCommand(\r
IN CONST CHAR16 *CmdLine,\r
IN SHELL_FILE_HANDLE *StdIn,\r
- IN SHELL_FILE_HANDLE *StdOut,\r
- OUT SHELL_STATUS *ExitStatus\r
+ IN SHELL_FILE_HANDLE *StdOut\r
)\r
{\r
EFI_STATUS Status;\r
ASSERT(Split->SplitStdOut != NULL);\r
InsertHeadList(&ShellInfoObject.SplitList.Link, &Split->Link);\r
\r
- Status = RunCommand(OurCommandLine, NULL);\r
+ Status = RunCommand(OurCommandLine);\r
\r
//\r
// move the output from the first to the in to the second.\r
ShellInfoObject.NewEfiShellProtocol->SetFilePosition(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn), 0);\r
\r
if (!EFI_ERROR(Status)) {\r
- Status = RunCommand(NextCommandLine, ExitStatus);\r
+ Status = RunCommand(NextCommandLine);\r
}\r
\r
//\r
return (EFI_OUT_OF_RESOURCES);\r
}\r
TempWalker = (CHAR16*)Temp;\r
- GetNextParameter(&TempWalker, &FirstParameter);\r
-\r
- if (GetOperationType(FirstParameter) == Unknown_Invalid) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
- SetLastError(SHELL_NOT_FOUND);\r
- Status = EFI_NOT_FOUND;\r
+ if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CmdLine)))) {\r
+ if (GetOperationType(FirstParameter) == Unknown_Invalid) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
+ SetLastError(SHELL_NOT_FOUND);\r
+ Status = EFI_NOT_FOUND;\r
+ }\r
}\r
}\r
\r
/**\r
Process a split based operation.\r
\r
- @param[in] CmdLine Pointer to the command line to process\r
- @param[out] ExitStatus The exit status of the command. Ignored if NULL.\r
- Invalid if this function returns an error.\r
+ @param[in] CmdLine pointer to the command line to process\r
\r
@retval EFI_SUCCESS The operation was successful\r
@return an error occured.\r
EFI_STATUS\r
EFIAPI\r
ProcessNewSplitCommandLine(\r
- IN CONST CHAR16 *CmdLine,\r
- OUT SHELL_STATUS *ExitStatus\r
+ IN CONST CHAR16 *CmdLine\r
)\r
{\r
SPLIT_LIST *Split;\r
}\r
\r
if (Split == NULL) {\r
- Status = RunSplitCommand(CmdLine, NULL, NULL, ExitStatus);\r
+ Status = RunSplitCommand(CmdLine, NULL, NULL);\r
} else {\r
- Status = RunSplitCommand(\r
- CmdLine,\r
- Split->SplitStdIn,\r
- Split->SplitStdOut,\r
- ExitStatus\r
- );\r
+ Status = RunSplitCommand(CmdLine, Split->SplitStdIn, Split->SplitStdOut);\r
}\r
if (EFI_ERROR(Status)) {\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_SPLIT), ShellInfoObject.HiiHandle, CmdLine);\r
Walker = *CmdLine;\r
while(Walker != NULL && *Walker != CHAR_NULL) {\r
LastWalker = Walker;\r
- GetNextParameter(&Walker, &CurrentParameter);\r
- if (StrStr(CurrentParameter, L"-?") == CurrentParameter) {\r
- LastWalker[0] = L' ';\r
- LastWalker[1] = L' ';\r
- NewCommandLine = AllocateZeroPool(StrSize(L"help ") + StrSize(*CmdLine));\r
- if (NewCommandLine == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
+ if (!EFI_ERROR(GetNextParameter(&Walker, &CurrentParameter, StrSize(*CmdLine)))) {\r
+ if (StrStr(CurrentParameter, L"-?") == CurrentParameter) {\r
+ LastWalker[0] = L' ';\r
+ LastWalker[1] = L' ';\r
+ NewCommandLine = AllocateZeroPool(StrSize(L"help ") + StrSize(*CmdLine));\r
+ if (NewCommandLine == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // We know the space is sufficient since we just calculated it.\r
+ //\r
+ StrnCpy(NewCommandLine, L"help ", 5);\r
+ StrnCat(NewCommandLine, *CmdLine, StrLen(*CmdLine));\r
+ SHELL_FREE_NON_NULL(*CmdLine);\r
+ *CmdLine = NewCommandLine;\r
break;\r
}\r
- StrCpy(NewCommandLine, L"help ");\r
- StrCat(NewCommandLine, *CmdLine);\r
- SHELL_FREE_NON_NULL(*CmdLine);\r
- *CmdLine = NewCommandLine;\r
- break;\r
}\r
}\r
\r
@param[in] FirstParameter the first parameter on the command line\r
@param[in] ParamProtocol the shell parameters protocol pointer\r
\r
- @param[out] ExitStatus The exit code of the command. Ignored if NULL.\r
-\r
@retval EFI_SUCCESS The command was completed.\r
@retval EFI_ABORTED The command's operation was aborted.\r
**/\r
RunInternalCommand(\r
IN CONST CHAR16 *CmdLine,\r
IN CHAR16 *FirstParameter,\r
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,\r
- OUT SHELL_STATUS *ExitStatus OPTIONAL\r
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol\r
)\r
{\r
EFI_STATUS Status;\r
CHAR16 **Argv;\r
SHELL_STATUS CommandReturnedStatus;\r
BOOLEAN LastError;\r
+ CHAR16 *Walker;\r
+ CHAR16 *NewCmdLine; \r
+\r
+ NewCmdLine = AllocateCopyPool (StrSize (CmdLine), CmdLine);\r
+ if (NewCmdLine == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ for (Walker = NewCmdLine; Walker != NULL && *Walker != CHAR_NULL ; Walker++) {\r
+ if (*Walker == L'^' && *(Walker+1) == L'#') {\r
+ CopyMem(Walker, Walker+1, StrSize(Walker) - sizeof(Walker[0]));\r
+ }\r
+ }\r
\r
//\r
// get the argc and argv updated for internal commands\r
//\r
- Status = UpdateArgcArgv(ParamProtocol, CmdLine, &Argv, &Argc);\r
+ Status = UpdateArgcArgv(ParamProtocol, NewCmdLine, &Argv, &Argc);\r
if (!EFI_ERROR(Status)) {\r
//\r
// Run the internal command.\r
if (LastError) {\r
SetLastError(CommandReturnedStatus);\r
}\r
- if (ExitStatus != NULL) {\r
- *ExitStatus = CommandReturnedStatus;\r
- }\r
\r
//\r
// Pass thru the exitcode from the app.\r
Status = EFI_SUCCESS;\r
}\r
\r
+ FreePool (NewCmdLine);\r
return (Status);\r
}\r
\r
@param[in] FirstParameter the first parameter on the command line\r
@param[in] ParamProtocol the shell parameters protocol pointer\r
\r
- @param[out] ExitStatus The exit code of the command or file.\r
- Ignored if NULL.\r
-\r
@retval EFI_SUCCESS The command was completed.\r
@retval EFI_ABORTED The command's operation was aborted.\r
**/\r
IN SHELL_OPERATION_TYPES Type,\r
IN CONST CHAR16 *CmdLine,\r
IN CHAR16 *FirstParameter,\r
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,\r
- OUT SHELL_STATUS *ExitStatus\r
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol\r
)\r
{\r
EFI_STATUS Status;\r
\r
switch (Type) {\r
case Internal_Command:\r
- Status = RunInternalCommand(\r
- CmdLine,\r
- FirstParameter,\r
- ParamProtocol,\r
- &CalleeExitStatus\r
- );\r
+ Status = RunInternalCommand(CmdLine, FirstParameter, ParamProtocol);\r
break;\r
case Script_File_Name:\r
case Efi_Application:\r
}\r
switch (Type) {\r
case Script_File_Name:\r
- Status = RunScriptFile (\r
- CommandWithPath,\r
- NULL,\r
- CmdLine,\r
- ParamProtocol,\r
- &CalleeExitStatus\r
- );\r
+ Status = RunScriptFile (CommandWithPath, NULL, CmdLine, ParamProtocol);\r
break;\r
case Efi_Application:\r
//\r
DevPath,\r
CmdLine,\r
NULL,\r
- &StartStatus,\r
- NULL,\r
- NULL\r
+ &StartStatus\r
);\r
\r
SHELL_FREE_NON_NULL(DevPath);\r
\r
SHELL_FREE_NON_NULL(CommandWithPath);\r
\r
- if (ExitStatus != NULL) {\r
- *ExitStatus = CalleeExitStatus;\r
- }\r
-\r
return (Status);\r
}\r
\r
@param[in] FirstParameter the first parameter on the command line.\r
@param[in] ParamProtocol the shell parameters protocol pointer\r
\r
- @param[out] ExitStatus The exit code of the command or file.\r
- Ignored if NULL.\r
-\r
@retval EFI_SUCCESS The command was completed.\r
@retval EFI_ABORTED The command's operation was aborted.\r
**/\r
EFI_STATUS\r
EFIAPI\r
SetupAndRunCommandOrFile(\r
- IN SHELL_OPERATION_TYPES Type,\r
- IN CHAR16 *CmdLine,\r
- IN CHAR16 *FirstParameter,\r
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,\r
- OUT SHELL_STATUS *ExitStatus\r
+ IN SHELL_OPERATION_TYPES Type,\r
+ IN CHAR16 *CmdLine,\r
+ IN CHAR16 *FirstParameter,\r
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol\r
)\r
{\r
EFI_STATUS Status;\r
// Now run the command, script, or application\r
//\r
if (!EFI_ERROR(Status)) {\r
- Status = RunCommandOrFile(\r
- Type,\r
- CmdLine,\r
- FirstParameter,\r
- ParamProtocol,\r
- ExitStatus\r
- );\r
+ TrimSpaces(&CmdLine);\r
+ Status = RunCommandOrFile(Type, CmdLine, FirstParameter, ParamProtocol);\r
}\r
\r
//\r
command or dispatch an external application.\r
\r
@param[in] CmdLine The command line to parse.\r
- @param[out] ExitStatus The exit code of the command. Ignored if NULL.\r
\r
@retval EFI_SUCCESS The command was completed.\r
@retval EFI_ABORTED The command's operation was aborted.\r
EFI_STATUS\r
EFIAPI\r
RunCommand(\r
- IN CONST CHAR16 *CmdLine,\r
- OUT SHELL_STATUS *ExitStatus\r
+ IN CONST CHAR16 *CmdLine\r
)\r
{\r
EFI_STATUS Status;\r
for (TempWalker = CleanOriginal; TempWalker != NULL && *TempWalker != CHAR_NULL; TempWalker++) {\r
if (*TempWalker == L'^') {\r
if (*(TempWalker + 1) == L'#') {\r
- CopyMem (TempWalker, TempWalker + 1, StrSize (TempWalker) - sizeof (TempWalker[0]));\r
+ TempWalker++;\r
}\r
} else if (*TempWalker == L'#') {\r
*TempWalker = CHAR_NULL;\r
// We dont do normal processing with a split command line (output from one command input to another)\r
//\r
if (ContainsSplit(CleanOriginal)) {\r
- Status = ProcessNewSplitCommandLine(CleanOriginal, ExitStatus);\r
+ Status = ProcessNewSplitCommandLine(CleanOriginal);\r
SHELL_FREE_NON_NULL(CleanOriginal);\r
return (Status);\r
} \r
return (EFI_OUT_OF_RESOURCES);\r
}\r
TempWalker = CleanOriginal;\r
- GetNextParameter(&TempWalker, &FirstParameter);\r
-\r
- //\r
- // Depending on the first parameter we change the behavior\r
- //\r
- switch (Type = GetOperationType(FirstParameter)) {\r
- case File_Sys_Change:\r
- Status = ChangeMappedDrive (FirstParameter);\r
- break;\r
- case Internal_Command:\r
- case Script_File_Name:\r
- case Efi_Application:\r
- Status = SetupAndRunCommandOrFile(\r
- Type,\r
- CleanOriginal,\r
- FirstParameter,\r
- ShellInfoObject.NewShellParametersProtocol,\r
- ExitStatus\r
- );\r
- break;\r
- default:\r
- //\r
- // Whatever was typed, it was invalid.\r
- //\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
- SetLastError(SHELL_NOT_FOUND);\r
- break;\r
+ if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CleanOriginal)))) {\r
+ //\r
+ // Depending on the first parameter we change the behavior\r
+ //\r
+ switch (Type = GetOperationType(FirstParameter)) {\r
+ case File_Sys_Change:\r
+ Status = ChangeMappedDrive (FirstParameter);\r
+ break;\r
+ case Internal_Command:\r
+ case Script_File_Name:\r
+ case Efi_Application:\r
+ Status = SetupAndRunCommandOrFile(Type, CleanOriginal, FirstParameter, ShellInfoObject.NewShellParametersProtocol);\r
+ break;\r
+ default:\r
+ //\r
+ // Whatever was typed, it was invalid.\r
+ //\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
+ SetLastError(SHELL_NOT_FOUND);\r
+ break;\r
+ }\r
+ } else {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
+ SetLastError(SHELL_NOT_FOUND);\r
}\r
\r
SHELL_FREE_NON_NULL(CleanOriginal);\r
@param[in] Handle The handle to the already opened file.\r
@param[in] Name The name of the script file.\r
\r
- @param[out] ExitStatus The exit code of the script. Ignored if NULL.\r
-\r
@retval EFI_SUCCESS the script completed sucessfully\r
**/\r
EFI_STATUS\r
EFIAPI\r
RunScriptFileHandle (\r
- IN SHELL_FILE_HANDLE Handle,\r
- IN CONST CHAR16 *Name,\r
- OUT SHELL_STATUS *ExitStatus\r
+ IN SHELL_FILE_HANDLE Handle,\r
+ IN CONST CHAR16 *Name\r
)\r
{\r
EFI_STATUS Status;\r
CONST CHAR16 *CurDir;\r
UINTN LineCount;\r
CHAR16 LeString[50];\r
- SHELL_STATUS CalleeExitStatus;\r
\r
ASSERT(!ShellCommandGetScriptExit());\r
- \r
- CalleeExitStatus = SHELL_SUCCESS;\r
\r
PreScriptEchoState = ShellCommandGetEchoState();\r
\r
; // conditional increment in the body of the loop\r
){\r
ASSERT(CommandLine2 != NULL);\r
- StrCpy(CommandLine2, NewScriptFile->CurrentCommand->Cl);\r
+ StrnCpy(CommandLine2, NewScriptFile->CurrentCommand->Cl, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1);\r
\r
//\r
// NULL out comments\r
//\r
for (CommandLine3 = CommandLine2 ; CommandLine3 != NULL && *CommandLine3 != CHAR_NULL ; CommandLine3++) {\r
if (*CommandLine3 == L'^') {\r
- if (*(CommandLine3+1) == L'#' || *(CommandLine3+1) == L':') {\r
+ if ( *(CommandLine3+1) == L':') {\r
CopyMem(CommandLine3, CommandLine3+1, StrSize(CommandLine3) - sizeof(CommandLine3[0]));\r
+ } else if (*(CommandLine3+1) == L'#') {\r
+ CommandLine3++;\r
}\r
} else if (*CommandLine3 == L'#') {\r
*CommandLine3 = CHAR_NULL;\r
//\r
// Due to variability in starting the find and replace action we need to have both buffers the same.\r
//\r
- StrCpy(CommandLine, CommandLine2);\r
+ StrnCpy(CommandLine, CommandLine2, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1);\r
\r
//\r
// Remove the %0 to %9 from the command line (if we have some arguments)\r
if (NewScriptFile->Argv != NULL) {\r
switch (NewScriptFile->Argc) {\r
default:\r
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", NewScriptFile->Argv[9], FALSE, TRUE);\r
+ Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", NewScriptFile->Argv[9], FALSE, FALSE);\r
ASSERT_EFI_ERROR(Status);\r
case 9:\r
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%8", NewScriptFile->Argv[8], FALSE, TRUE);\r
+ Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%8", NewScriptFile->Argv[8], FALSE, FALSE);\r
ASSERT_EFI_ERROR(Status);\r
case 8:\r
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%7", NewScriptFile->Argv[7], FALSE, TRUE);\r
+ Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%7", NewScriptFile->Argv[7], FALSE, FALSE);\r
ASSERT_EFI_ERROR(Status);\r
case 7:\r
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%6", NewScriptFile->Argv[6], FALSE, TRUE);\r
+ Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%6", NewScriptFile->Argv[6], FALSE, FALSE);\r
ASSERT_EFI_ERROR(Status);\r
case 6:\r
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%5", NewScriptFile->Argv[5], FALSE, TRUE);\r
+ Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%5", NewScriptFile->Argv[5], FALSE, FALSE);\r
ASSERT_EFI_ERROR(Status);\r
case 5:\r
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%4", NewScriptFile->Argv[4], FALSE, TRUE);\r
+ Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%4", NewScriptFile->Argv[4], FALSE, FALSE);\r
ASSERT_EFI_ERROR(Status);\r
case 4:\r
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%3", NewScriptFile->Argv[3], FALSE, TRUE);\r
+ Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%3", NewScriptFile->Argv[3], FALSE, FALSE);\r
ASSERT_EFI_ERROR(Status);\r
case 3:\r
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%2", NewScriptFile->Argv[2], FALSE, TRUE);\r
+ Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%2", NewScriptFile->Argv[2], FALSE, FALSE);\r
ASSERT_EFI_ERROR(Status);\r
case 2:\r
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%1", NewScriptFile->Argv[1], FALSE, TRUE);\r
+ Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%1", NewScriptFile->Argv[1], FALSE, FALSE);\r
ASSERT_EFI_ERROR(Status);\r
case 1:\r
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%0", NewScriptFile->Argv[0], FALSE, TRUE);\r
+ Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%0", NewScriptFile->Argv[0], FALSE, FALSE);\r
ASSERT_EFI_ERROR(Status);\r
break;\r
case 0:\r
Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%8", L"\"\"", FALSE, FALSE);\r
Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", L"\"\"", FALSE, FALSE);\r
\r
- StrCpy(CommandLine2, CommandLine);\r
+ StrnCpy(CommandLine2, CommandLine, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1);\r
\r
LastCommand = NewScriptFile->CurrentCommand;\r
\r
//\r
PreCommandEchoState = ShellCommandGetEchoState();\r
ShellCommandSetEchoState(FALSE);\r
- Status = RunCommand(CommandLine3+1, NULL);\r
+ Status = RunCommand(CommandLine3+1);\r
\r
//\r
// If command was "@echo -off" or "@echo -on" then don't restore echo state\r
}\r
ShellPrintEx(-1, -1, L"%s\r\n", CommandLine2);\r
}\r
- Status = RunCommand(CommandLine3, NULL);\r
+ Status = RunCommand(CommandLine3);\r
}\r
}\r
\r
//\r
// ShellCommandGetExitCode() always returns a UINT64\r
//\r
- CalleeExitStatus = (SHELL_STATUS) ShellCommandGetExitCode();\r
- UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", CalleeExitStatus);\r
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", ShellCommandGetExitCode());\r
DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););\r
InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);\r
\r
break;\r
}\r
if (EFI_ERROR(Status)) {\r
- CalleeExitStatus = (SHELL_STATUS) Status;\r
break;\r
}\r
if (ShellCommandGetExit()) {\r
- CalleeExitStatus = (SHELL_STATUS) ShellCommandGetExitCode();\r
break;\r
}\r
}\r
if (ShellCommandGetCurrentScriptFile()==NULL) {\r
ShellCommandSetEchoState(PreScriptEchoState);\r
}\r
-\r
- if (ExitStatus != NULL) {\r
- *ExitStatus = CalleeExitStatus;\r
- }\r
-\r
return (EFI_SUCCESS);\r
}\r
\r
@param[in] CmdLine the command line to run.\r
@param[in] ParamProtocol the shell parameters protocol pointer\r
\r
- @param[out] ExitStatus The exit code of the script. Ignored if NULL.\r
-\r
@retval EFI_SUCCESS the script completed sucessfully\r
**/\r
EFI_STATUS\r
EFIAPI\r
RunScriptFile (\r
- IN CONST CHAR16 *ScriptPath,\r
- IN SHELL_FILE_HANDLE Handle OPTIONAL,\r
- IN CONST CHAR16 *CmdLine,\r
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,\r
- OUT SHELL_STATUS *ExitStatus\r
+ IN CONST CHAR16 *ScriptPath,\r
+ IN SHELL_FILE_HANDLE Handle OPTIONAL,\r
+ IN CONST CHAR16 *CmdLine,\r
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol\r
)\r
{\r
EFI_STATUS Status;\r
//\r
// run it\r
//\r
- Status = RunScriptFileHandle(FileHandle, ScriptPath, ExitStatus);\r
+ Status = RunScriptFileHandle(FileHandle, ScriptPath);\r
\r
//\r
// now close the file\r
ShellCloseFile(&FileHandle);\r
}\r
} else {\r
- Status = RunScriptFileHandle(Handle, ScriptPath, ExitStatus);\r
+ Status = RunScriptFileHandle(Handle, ScriptPath);\r
}\r
}\r
\r