/** @file\r
This is THE shell (application)\r
\r
- Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2013-2014 Hewlett-Packard Development Company, L.P.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
}\r
\r
/**\r
- Parse for the next instance of one string within another string. Can optionally make sure that \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
)\r
{\r
CONST CHAR16 *Walker;\r
- \r
+\r
Walker = NULL;\r
\r
ASSERT (BeginPercent != NULL);\r
ASSERT (EndPercent != NULL);\r
ASSERT (BeginPercent < EndPercent);\r
- \r
+\r
if ((BeginPercent + 1) == EndPercent) {\r
return FALSE;\r
}\r
SecondQuote = NULL;\r
TempSpot = FindFirstCharacter(CmdLine, L"|", L'^');\r
\r
- if (FirstQuote == NULL || \r
- TempSpot == NULL || \r
- TempSpot == CHAR_NULL || \r
+ if (FirstQuote == NULL ||\r
+ TempSpot == NULL ||\r
+ TempSpot == CHAR_NULL ||\r
FirstQuote > TempSpot\r
) {\r
return (BOOLEAN) ((TempSpot != NULL) && (*TempSpot != CHAR_NULL));\r
while ((TempSpot != NULL) && (*TempSpot != CHAR_NULL)) {\r
if (FirstQuote == NULL || FirstQuote > TempSpot) {\r
break;\r
- } \r
+ }\r
SecondQuote = FindNextInstance (FirstQuote + 1, L"\"", TRUE);\r
if (SecondQuote == NULL) {\r
break;\r
FirstQuote = FindNextInstance (SecondQuote + 1, L"\"", TRUE);\r
TempSpot = FindFirstCharacter(TempSpot + 1, L"|", L'^');\r
continue;\r
- } \r
+ }\r
}\r
- \r
+\r
return (BOOLEAN) ((TempSpot != NULL) && (*TempSpot != CHAR_NULL));\r
}\r
\r
/**\r
- Function to start monitoring for CTRL-S using SimpleTextInputEx. This \r
+ Function to start monitoring for CTRL-S using SimpleTextInputEx. This\r
feature's enabled state was not known when the shell initially launched.\r
\r
@retval EFI_SUCCESS The feature is enabled.\r
EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
if (EFI_ERROR(Status)) {\r
ShellPrintHiiEx(\r
- -1, \r
- -1, \r
+ -1,\r
+ -1,\r
NULL,\r
STRING_TOKEN (STR_SHELL_NO_IN_EX),\r
ShellInfoObject.HiiHandle);\r
&KeyData,\r
NotificationFunction,\r
&ShellInfoObject.CtrlSNotifyHandle1);\r
- \r
+\r
KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;\r
if (!EFI_ERROR(Status)) {\r
Status = SimpleEx->RegisterKeyNotify(\r
&KeyData,\r
NotificationFunction,\r
&ShellInfoObject.CtrlSNotifyHandle3);\r
- } \r
+ }\r
KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;\r
if (!EFI_ERROR(Status)) {\r
Status = SimpleEx->RegisterKeyNotify(\r
ShellInfoObject.ConsoleInfo->Enabled = TRUE;\r
ShellInfoObject.ConsoleInfo->RowCounter = 0;\r
\r
- //\r
- // Reset the CTRL-C event (yes we ignore the return values)\r
- //\r
- Status = gBS->CheckEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak);\r
-\r
//\r
// Display Prompt\r
//\r
**/\r
EFI_STATUS\r
SetBuiltInAlias(\r
+ VOID\r
)\r
{\r
EFI_STATUS Status;\r
\r
/**\r
Function try to find location of the Startup.nsh file.\r
- \r
+\r
The buffer is callee allocated and should be freed by the caller.\r
\r
@param ImageDevicePath The path to the image for shell. first place to look for the startup script\r
// Try to find 'Startup.nsh' in the directory where the shell itself was launched.\r
//\r
MapName = ShellInfoObject.NewEfiShellProtocol->GetMapFromDevicePath (&ImageDevicePath);\r
- if (MapName != NULL) { \r
+ if (MapName != NULL) {\r
StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, MapName, 0);\r
if (StartupScriptPath == NULL) {\r
//\r
if (FileStringPath != NULL) {\r
Status = RunScriptFile (FileStringPath, NULL, L"", ShellInfoObject.NewShellParametersProtocol);\r
FreePool (FileStringPath);\r
+ } else {\r
+ //\r
+ // we return success since startup script is not mandatory.\r
+ //\r
+ Status = EFI_SUCCESS;\r
}\r
\r
return (Status);\r
// Null terminate the string and parse it\r
//\r
if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Reset the CTRL-C event just before running the command (yes we ignore the return values)\r
+ //\r
+ Status = gBS->CheckEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak);\r
+\r
CmdLine[BufferSize / sizeof (CHAR16)] = CHAR_NULL;\r
Status = RunCommand(CmdLine);\r
- }\r
+ }\r
\r
//\r
// Done with this command\r
\r
\r
/**\r
- Create a new buffer list and stores the old one to OldBufferList \r
+ Create a new buffer list and stores the old one to OldBufferList\r
\r
@param OldBufferList The temporary list head used to store the nodes in BufferToFreeList.\r
**/\r
\r
Count = 0;\r
MaxHistoryCmdCount = PcdGet16(PcdShellMaxHistoryCommandCount);\r
- \r
+\r
if (MaxHistoryCmdCount == 0) {\r
return ;\r
}\r
}\r
continue;\r
}\r
- \r
+\r
if (FirstQuote == NULL || SecondPercent < FirstQuote) {\r
if (IsValidEnvironmentVariableName(FirstPercent, SecondPercent)) {\r
//\r
//\r
// now do the replacements...\r
//\r
- NewCommandLine1 = AllocateCopyPool(NewSize, OriginalCommandLine);\r
+ NewCommandLine1 = AllocateZeroPool (NewSize);\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
+ CopyMem (NewCommandLine1, OriginalCommandLine, StrSize (OriginalCommandLine));\r
+\r
for (MasterEnvList = EfiShellGetEnv(NULL)\r
; MasterEnvList != NULL && *MasterEnvList != CHAR_NULL\r
; MasterEnvList += StrLen(MasterEnvList) + 1\r
){\r
- StrCpyS( ItemTemp, \r
- ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16)), \r
+ StrCpyS( ItemTemp,\r
+ ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16)),\r
L"%"\r
);\r
- StrCatS( ItemTemp, \r
- ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16)), \r
+ StrCatS( ItemTemp,\r
+ ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16)),\r
MasterEnvList\r
);\r
- StrCatS( ItemTemp, \r
- ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16)), \r
+ StrCatS( ItemTemp,\r
+ ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16)),\r
L"%"\r
);\r
ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, ItemTemp, EfiShellGetEnv(MasterEnvList), TRUE, FALSE);\r
//\r
ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, L"^%", L"%", TRUE, FALSE);\r
StrCpyS(NewCommandLine1, NewSize/sizeof(CHAR16), NewCommandLine2);\r
- \r
+\r
FreePool(NewCommandLine2);\r
FreePool(ItemTemp);\r
\r
EFI_STATUS\r
RunSplitCommand(\r
IN CONST CHAR16 *CmdLine,\r
- IN SHELL_FILE_HANDLE *StdIn,\r
- IN SHELL_FILE_HANDLE *StdOut\r
+ IN SHELL_FILE_HANDLE StdIn,\r
+ IN SHELL_FILE_HANDLE StdOut\r
)\r
{\r
EFI_STATUS Status;\r
UINTN Size1;\r
UINTN Size2;\r
SPLIT_LIST *Split;\r
- SHELL_FILE_HANDLE *TempFileHandle;\r
+ SHELL_FILE_HANDLE TempFileHandle;\r
BOOLEAN Unicode;\r
\r
ASSERT(StdOut == NULL);\r
Split->SplitStdOut = Split->SplitStdIn;\r
}\r
Split->SplitStdIn = TempFileHandle;\r
- ShellInfoObject.NewEfiShellProtocol->SetFilePosition(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn), 0);\r
+ ShellInfoObject.NewEfiShellProtocol->SetFilePosition (Split->SplitStdIn, 0);\r
\r
if (!EFI_ERROR(Status)) {\r
Status = RunCommand(NextCommandLine);\r
// Note that the original StdIn is now the StdOut...\r
//\r
if (Split->SplitStdOut != NULL) {\r
- ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdOut));\r
+ ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdOut);\r
}\r
if (Split->SplitStdIn != NULL) {\r
- ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn));\r
- FreePool (Split->SplitStdIn);\r
+ ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdIn);\r
}\r
\r
FreePool(Split);\r
}\r
\r
/**\r
- Take the original command line, substitute any variables, free \r
+ Take the original command line, substitute any variables, free\r
the original string, return the modified copy.\r
\r
@param[in] CmdLine pointer to the command line to update.\r
}\r
\r
/**\r
- Take the original command line, substitute any alias in the first group of space delimited characters, free \r
+ Take the original command line, substitute any alias in the first group of space delimited characters, free\r
the original string, return the modified copy.\r
\r
@param[in] CmdLine pointer to the command line to update.\r
\r
SHELL_FREE_NON_NULL(*CmdLine);\r
SHELL_FREE_NON_NULL(CommandName);\r
- \r
+\r
//\r
// re-assign the passed in double pointer to point to our newly allocated buffer\r
//\r
Takes the Argv[0] part of the command line and determine the meaning of it.\r
\r
@param[in] CmdName pointer to the command line to update.\r
- \r
+\r
@retval Internal_Command The name is an internal command.\r
@retval File_Sys_Change the name is a file system change.\r
@retval Script_File_Name the name is a NSH script file.\r
// Test for file system change request. anything ending with first : and cant have spaces.\r
//\r
if (CmdName[(StrLen(CmdName)-1)] == L':') {\r
- if ( StrStr(CmdName, L" ") != NULL \r
+ if ( StrStr(CmdName, L" ") != NULL\r
|| StrLen(StrStr(CmdName, L":")) > 1\r
) {\r
return (Unknown_Invalid);\r
SHELL_FREE_NON_NULL(FileWithPath);\r
return (Efi_Application);\r
}\r
- \r
+\r
SHELL_FREE_NON_NULL(FileWithPath);\r
//\r
// No clue what this is... return invalid flag...\r
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
@retval EFI_NOT_FOUND The operation type is unknown or invalid.\r
**/\r
-EFI_STATUS \r
+EFI_STATUS\r
IsValidSplit(\r
IN CONST CHAR16 *CmdLine\r
)\r
// recurse to verify the next item\r
//\r
TempSpot = FindFirstCharacter(CmdLine, L"|", L'^') + 1;\r
- if (*TempSpot == L'a' && \r
+ if (*TempSpot == L'a' &&\r
(*(TempSpot + 1) == L' ' || *(TempSpot + 1) == CHAR_NULL)\r
) {\r
// If it's an ASCII pipe '|a'\r
TempSpot += 1;\r
}\r
- \r
+\r
return (VerifySplit(TempSpot));\r
}\r
\r
// make sure we are the right operation\r
//\r
ASSERT(CmdLine[(StrLen(CmdLine)-1)] == L':' && StrStr(CmdLine, L" ") == NULL);\r
- \r
+\r
//\r
// Call the protocol API to do the work\r
//\r
Run an internal shell command.\r
\r
This API will update the shell's environment since these commands are libraries.\r
- \r
+\r
@param[in] CmdLine the command line to run.\r
@param[in] FirstParameter the first parameter on the command line\r
@param[in] ParamProtocol the shell parameters protocol pointer\r
SHELL_STATUS CommandReturnedStatus;\r
BOOLEAN LastError;\r
CHAR16 *Walker;\r
- CHAR16 *NewCmdLine; \r
+ CHAR16 *NewCmdLine;\r
\r
NewCmdLine = AllocateCopyPool (StrSize (CmdLine), CmdLine);\r
if (NewCmdLine == NULL) {\r
/**\r
Function will process and run a command line.\r
\r
- This will determine if the command line represents an internal shell \r
+ This will determine if the command line represents an internal shell\r
command or dispatch an external application.\r
\r
@param[in] CmdLine The command line to parse.\r
CHAR16 *FirstParameter;\r
CHAR16 *TempWalker;\r
SHELL_OPERATION_TYPES Type;\r
+ CONST CHAR16 *CurDir;\r
\r
ASSERT(CmdLine != NULL);\r
if (StrLen(CmdLine) == 0) {\r
Status = ProcessNewSplitCommandLine(CleanOriginal);\r
SHELL_FREE_NON_NULL(CleanOriginal);\r
return (Status);\r
- } \r
+ }\r
\r
//\r
// We need the first parameter information so we can determine the operation type\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);\r
SetLastError(SHELL_NOT_FOUND);\r
}\r
- \r
+ //\r
+ // Check whether the current file system still exists. If not exist, we need update "cwd" and gShellCurMapping.\r
+ //\r
+ CurDir = EfiShellGetCurDir (NULL);\r
+ if (CurDir != NULL) {\r
+ if (EFI_ERROR(ShellFileExists (CurDir))) {\r
+ //\r
+ // EfiShellSetCurDir() cannot set current directory to NULL.\r
+ // EfiShellSetEnv() is not allowed to set the "cwd" variable.\r
+ // Only InternalEfiShellSetEnv () is allowed setting the "cwd" variable.\r
+ //\r
+ InternalEfiShellSetEnv (L"cwd", NULL, TRUE);\r
+ gShellCurMapping = NULL;\r
+ }\r
+ }\r
+\r
SHELL_FREE_NON_NULL(CleanOriginal);\r
SHELL_FREE_NON_NULL(FirstParameter);\r
\r
/**\r
Function will process and run a command line.\r
\r
- This will determine if the command line represents an internal shell \r
+ This will determine if the command line represents an internal shell\r
command or dispatch an external application.\r
\r
@param[in] CmdLine The command line to parse.\r
; // conditional increment in the body of the loop\r
){\r
ASSERT(CommandLine2 != NULL);\r
- StrnCpyS( CommandLine2, \r
- PrintBuffSize/sizeof(CHAR16), \r
+ StrnCpyS( CommandLine2,\r
+ PrintBuffSize/sizeof(CHAR16),\r
NewScriptFile->CurrentCommand->Cl,\r
PrintBuffSize/sizeof(CHAR16) - 1\r
);\r
//\r
// Due to variability in starting the find and replace action we need to have both buffers the same.\r
//\r
- StrnCpyS( CommandLine, \r
- PrintBuffSize/sizeof(CHAR16), \r
+ StrnCpyS( CommandLine,\r
+ PrintBuffSize/sizeof(CHAR16),\r
CommandLine2,\r
PrintBuffSize/sizeof(CHAR16) - 1\r
);\r
Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PrintBuffSize, L"%8", L"\"\"", FALSE, FALSE);\r
Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PrintBuffSize, L"%9", L"\"\"", FALSE, FALSE);\r
\r
- StrnCpyS( CommandLine2, \r
- PrintBuffSize/sizeof(CHAR16), \r
+ StrnCpyS( CommandLine2,\r
+ PrintBuffSize/sizeof(CHAR16),\r
CommandLine,\r
PrintBuffSize/sizeof(CHAR16) - 1\r
);\r