/** @file\r
This is THE shell (application)\r
\r
- Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2017, 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
0,\r
0,\r
0,\r
+ 0,\r
0\r
}},\r
0,\r
STATIC CONST CHAR16 mScriptExtension[] = L".NSH";\r
STATIC CONST CHAR16 mExecutableExtensions[] = L".NSH;.EFI";\r
STATIC CONST CHAR16 mStartupScript[] = L"startup.nsh";\r
+CONST CHAR16 mNoNestingEnvVarName[] = L"nonesting";\r
+CONST CHAR16 mNoNestingTrue[] = L"True";\r
+CONST CHAR16 mNoNestingFalse[] = L"False";\r
\r
/**\r
Cleans off leading and trailing spaces and tabs.\r
@param[in] String pointer to the string to trim them off.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
TrimSpaces(\r
IN CHAR16 **String\r
)\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
@retval FALSE CmdLine does not have a valid split.\r
**/\r
BOOLEAN\r
-EFIAPI\r
ContainsSplit(\r
IN CONST CHAR16 *CmdLine\r
)\r
@retval EFI_OUT_OF_RESOURCES There is not enough memory available.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
InternalEfiShellStartCtrlSMonitor(\r
VOID\r
)\r
UINTN Size;\r
EFI_HANDLE ConInHandle;\r
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *OldConIn;\r
+ SPLIT_LIST *Split;\r
\r
if (PcdGet8(PcdShellSupportLevel) > 3) {\r
return (EFI_UNSUPPORTED);\r
Status = CommandInit();\r
ASSERT_EFI_ERROR(Status);\r
\r
+ Status = ShellInitEnvVarList ();\r
+\r
//\r
// Check the command line\r
//\r
Status = ShellCommandCreateInitialMappingsAndPaths();\r
}\r
\r
+ //\r
+ // Set the environment variable for nesting support\r
+ //\r
+ Size = 0;\r
+ TempString = NULL;\r
+ if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest) {\r
+ //\r
+ // No change. require nesting in Shell Protocol Execute()\r
+ //\r
+ StrnCatGrow(&TempString,\r
+ &Size,\r
+ L"False",\r
+ 0);\r
+ } else {\r
+ StrnCatGrow(&TempString,\r
+ &Size,\r
+ mNoNestingTrue,\r
+ 0);\r
+ }\r
+ Status = InternalEfiShellSetEnv(mNoNestingEnvVarName, TempString, TRUE);\r
+ SHELL_FREE_NON_NULL(TempString);\r
+ Size = 0;\r
+\r
//\r
// save the device path for the loaded image and the device path for the filepath (under loaded image)\r
// These are where to look for the startup.nsh file\r
if (ShellInfoObject.NewEfiShellProtocol->IsRootShell()){\r
InternalEfiShellSetEnv(L"cwd", NULL, TRUE);\r
}\r
- CleanUpShellProtocol(ShellInfoObject.NewEfiShellProtocol);\r
+ CleanUpShellEnvironment (ShellInfoObject.NewEfiShellProtocol);\r
DEBUG_CODE(ShellInfoObject.NewEfiShellProtocol = NULL;);\r
}\r
\r
}\r
\r
if (!IsListEmpty(&ShellInfoObject.SplitList.Link)){\r
- ASSERT(FALSE); ///@todo finish this de-allocation.\r
+ ASSERT(FALSE); ///@todo finish this de-allocation (free SplitStdIn/Out when needed).\r
+\r
+ for ( Split = (SPLIT_LIST*)GetFirstNode (&ShellInfoObject.SplitList.Link)\r
+ ; !IsNull (&ShellInfoObject.SplitList.Link, &Split->Link)\r
+ ; Split = (SPLIT_LIST *)GetNextNode (&ShellInfoObject.SplitList.Link, &Split->Link)\r
+ ) {\r
+ RemoveEntryList (&Split->Link);\r
+ FreePool (Split);\r
+ }\r
+\r
+ DEBUG_CODE (InitializeListHead (&ShellInfoObject.SplitList.Link););\r
}\r
\r
if (ShellInfoObject.ShellInitSettings.FileName != NULL) {\r
DEBUG_CODE(ShellInfoObject.ConsoleInfo = NULL;);\r
}\r
\r
+ ShellFreeEnvVarList ();\r
+\r
if (ShellCommandGetExit()) {\r
return ((EFI_STATUS)ShellCommandGetExitCode());\r
}\r
@retval EFI_SUCCESS all init commands were run successfully.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
SetBuiltInAlias(\r
)\r
{\r
@retval FALSE The 2 command names are not the same.\r
**/\r
BOOLEAN\r
-EFIAPI\r
IsCommand(\r
IN CONST CHAR16 *Command1,\r
IN CONST CHAR16 *Command2\r
@retval FALSE The command is not a script only command.\r
**/\r
BOOLEAN\r
-EFIAPI\r
IsScriptOnlyCommand(\r
IN CONST CHAR16 *CommandName\r
)\r
@sa HandleProtocol\r
**/\r
EFI_STATUS\r
-EFIAPI\r
GetDevicePathsForImageAndFile (\r
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevPath,\r
IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath\r
@retval EFI_SUCCESS The variable is initialized.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
ProcessCommandLine(\r
VOID\r
)\r
// like a shell option (which is assumed to be `file-name`).\r
\r
Status = gBS->LocateProtocol (\r
- &gEfiUnicodeCollationProtocolGuid,\r
+ &gEfiUnicodeCollation2ProtocolGuid,\r
NULL,\r
(VOID **) &UnicodeCollation\r
);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiUnicodeCollationProtocolGuid,\r
+ NULL,\r
+ (VOID **) &UnicodeCollation\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
}\r
\r
// Set default options\r
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion = FALSE;\r
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay = FALSE;\r
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit = FALSE;\r
+ ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest = FALSE;\r
ShellInfoObject.ShellInitSettings.Delay = 5;\r
\r
//\r
) == 0) {\r
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion = TRUE;\r
}\r
+ else if (UnicodeCollation->StriColl (\r
+ UnicodeCollation,\r
+ L"-nonest",\r
+ CurrentArg\r
+ ) == 0) {\r
+ ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest = TRUE;\r
+ }\r
else if (UnicodeCollation->StriColl (\r
UnicodeCollation,\r
L"-delay",\r
}\r
} else if (UnicodeCollation->StriColl (\r
UnicodeCollation,\r
- L"-_exit",\r
+ L"-exit",\r
CurrentArg\r
) == 0) {\r
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit = TRUE;\r
continue;\r
}\r
\r
- ShellInfoObject.ShellInitSettings.FileName = AllocateCopyPool(StrSize(CurrentArg), CurrentArg);\r
+ ShellInfoObject.ShellInitSettings.FileName = NULL;\r
+ Size = 0;\r
+ //\r
+ // If first argument contains a space, then add double quotes before the argument\r
+ //\r
+ if (StrStr (CurrentArg, L" ") != NULL) {\r
+ StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileName, &Size, L"\"", 0);\r
+ if (ShellInfoObject.ShellInitSettings.FileName == NULL) {\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+ }\r
+ StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileName, &Size, CurrentArg, 0);\r
if (ShellInfoObject.ShellInitSettings.FileName == NULL) {\r
return (EFI_OUT_OF_RESOURCES);\r
}\r
//\r
+ // If first argument contains a space, then add double quotes after the argument\r
+ //\r
+ if (StrStr (CurrentArg, L" ") != NULL) {\r
+ StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileName, &Size, L"\"", 0);\r
+ if (ShellInfoObject.ShellInitSettings.FileName == NULL) {\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+ }\r
+ //\r
// We found `file-name`.\r
//\r
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = 1;\r
// Add `file-name-options`\r
for (Size = 0 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {\r
ASSERT((ShellInfoObject.ShellInitSettings.FileOptions == NULL && Size == 0) || (ShellInfoObject.ShellInitSettings.FileOptions != NULL));\r
- StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,\r
- &Size,\r
- L" ",\r
- 0);\r
- if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {\r
- SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);\r
- return (EFI_OUT_OF_RESOURCES);\r
+ //\r
+ // Add a space between arguments\r
+ //\r
+ if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {\r
+ StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions, &Size, L" ", 0);\r
+ if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {\r
+ SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+ }\r
+ //\r
+ // If an argumnent contains a space, then add double quotes before the argument\r
+ //\r
+ if (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L" ") != NULL) {\r
+ StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,\r
+ &Size,\r
+ L"\"",\r
+ 0);\r
+ if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {\r
+ SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
}\r
StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,\r
&Size,\r
SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);\r
return (EFI_OUT_OF_RESOURCES);\r
}\r
+ //\r
+ // If an argumnent contains a space, then add double quotes after the argument\r
+ //\r
+ if (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L" ") != NULL) {\r
+ StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,\r
+ &Size,\r
+ L"\"",\r
+ 0);\r
+ if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {\r
+ SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);\r
+ return (EFI_OUT_OF_RESOURCES);\r
+ }\r
+ }\r
}\r
}\r
}\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Function try to find location of the Startup.nsh file.\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
+ @param FileDevicePath The path to the file for shell. second place to look for the startup script.\r
+\r
+ @retval NULL No Startup.nsh file was found.\r
+ @return !=NULL Pointer to NULL-terminated path.\r
+**/\r
+CHAR16 *\r
+LocateStartupScript (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *FileDevicePath\r
+ )\r
+{\r
+ CHAR16 *StartupScriptPath;\r
+ CHAR16 *TempSpot;\r
+ CONST CHAR16 *MapName;\r
+ UINTN Size;\r
+\r
+ StartupScriptPath = NULL;\r
+ Size = 0;\r
+\r
+ //\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
+ StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, MapName, 0);\r
+ if (StartupScriptPath == NULL) {\r
+ //\r
+ // Do not locate the startup script in sys path when out of resource.\r
+ //\r
+ return NULL;\r
+ }\r
+ TempSpot = StrStr (StartupScriptPath, L";");\r
+ if (TempSpot != NULL) {\r
+ *TempSpot = CHAR_NULL;\r
+ }\r
+\r
+ StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, ((FILEPATH_DEVICE_PATH *)FileDevicePath)->PathName, 0);\r
+ PathRemoveLastItem (StartupScriptPath);\r
+ StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, mStartupScript, 0);\r
+ }\r
+\r
+ //\r
+ // Try to find 'Startup.nsh' in the execution path defined by the envrionment variable PATH.\r
+ //\r
+ if ((StartupScriptPath == NULL) || EFI_ERROR (ShellIsFile (StartupScriptPath))) {\r
+ SHELL_FREE_NON_NULL (StartupScriptPath);\r
+ StartupScriptPath = ShellFindFilePath (mStartupScript);\r
+ }\r
+\r
+ return StartupScriptPath;\r
+}\r
+\r
/**\r
Handles all interaction with the default startup script.\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
EFI_STATUS CalleeStatus;\r
UINTN Delay;\r
EFI_INPUT_KEY Key;\r
- SHELL_FILE_HANDLE FileHandle;\r
- EFI_DEVICE_PATH_PROTOCOL *NewPath;\r
- EFI_DEVICE_PATH_PROTOCOL *NamePath;\r
CHAR16 *FileStringPath;\r
- CHAR16 *TempSpot;\r
UINTN NewSize;\r
- CONST CHAR16 *MapName;\r
\r
Key.UnicodeChar = CHAR_NULL;\r
Key.ScanCode = 0;\r
- FileHandle = NULL;\r
\r
if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup && ShellInfoObject.ShellInitSettings.FileName != NULL) {\r
//\r
return (EFI_SUCCESS);\r
}\r
\r
- //\r
- // Try the first location (must be file system)\r
- //\r
- MapName = ShellInfoObject.NewEfiShellProtocol->GetMapFromDevicePath(&ImagePath);\r
- if (MapName != NULL) {\r
- FileStringPath = NULL;\r
- NewSize = 0;\r
- FileStringPath = StrnCatGrow(&FileStringPath, &NewSize, MapName, 0);\r
- if (FileStringPath == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- } else {\r
- TempSpot = StrStr(FileStringPath, L";");\r
- if (TempSpot != NULL) {\r
- *TempSpot = CHAR_NULL;\r
- }\r
- FileStringPath = StrnCatGrow(&FileStringPath, &NewSize, ((FILEPATH_DEVICE_PATH*)FilePath)->PathName, 0);\r
- PathRemoveLastItem(FileStringPath);\r
- FileStringPath = StrnCatGrow(&FileStringPath, &NewSize, mStartupScript, 0);\r
- Status = ShellInfoObject.NewEfiShellProtocol->OpenFileByName(FileStringPath, &FileHandle, EFI_FILE_MODE_READ);\r
- FreePool(FileStringPath);\r
- }\r
- }\r
- if (EFI_ERROR(Status)) {\r
- NamePath = FileDevicePath (NULL, mStartupScript);\r
- NewPath = AppendDevicePathNode (ImagePath, NamePath);\r
- FreePool(NamePath);\r
-\r
+ FileStringPath = LocateStartupScript (ImagePath, FilePath);\r
+ if (FileStringPath != NULL) {\r
+ Status = RunScriptFile (FileStringPath, NULL, L"", ShellInfoObject.NewShellParametersProtocol);\r
+ FreePool (FileStringPath);\r
+ } else {\r
//\r
- // Try the location\r
+ // we return success since startup script is not mandatory.\r
//\r
- Status = InternalOpenFileDevicePath(NewPath, &FileHandle, EFI_FILE_MODE_READ, 0);\r
- FreePool(NewPath);\r
- }\r
- //\r
- // If we got a file, run it\r
- //\r
- if (!EFI_ERROR(Status) && FileHandle != NULL) {\r
- Status = RunScriptFile (mStartupScript, FileHandle, L"", ShellInfoObject.NewShellParametersProtocol);\r
- ShellInfoObject.NewEfiShellProtocol->CloseFile(FileHandle);\r
- } else {\r
- FileStringPath = ShellFindFilePath(mStartupScript);\r
- if (FileStringPath == NULL) {\r
- //\r
- // we return success since we don't need to have a startup script\r
- //\r
- Status = EFI_SUCCESS;\r
- ASSERT(FileHandle == NULL);\r
- } else {\r
- Status = RunScriptFile(FileStringPath, NULL, L"", ShellInfoObject.NewShellParametersProtocol);\r
- FreePool(FileStringPath);\r
- }\r
+ Status = EFI_SUCCESS;\r
}\r
\r
-\r
return (Status);\r
}\r
\r
@retval RETURN_ABORTED\r
**/\r
EFI_STATUS\r
-EFIAPI\r
DoShellPrompt (\r
VOID\r
)\r
CONST CHAR16 *CurDir;\r
UINTN BufferSize;\r
EFI_STATUS Status;\r
+ LIST_ENTRY OldBufferList;\r
\r
CurDir = NULL;\r
\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
+ SaveBufferList(&OldBufferList);\r
CurDir = ShellInfoObject.NewEfiShellProtocol->GetEnv(L"cwd");\r
\r
//\r
//\r
// Done with this command\r
//\r
+ RestoreBufferList(&OldBufferList);\r
FreePool (CmdLine);\r
return Status;\r
}\r
@param Buffer Something to pass to FreePool when the shell is exiting.\r
**/\r
VOID*\r
-EFIAPI\r
-AddBufferToFreeList(\r
+AddBufferToFreeList (\r
VOID *Buffer\r
)\r
{\r
return (NULL);\r
}\r
\r
- BufferListEntry = AllocateZeroPool(sizeof(BUFFER_LIST));\r
- ASSERT(BufferListEntry != NULL);\r
+ BufferListEntry = AllocateZeroPool (sizeof (BUFFER_LIST));\r
+ if (BufferListEntry == NULL) {\r
+ return NULL;\r
+ }\r
+\r
BufferListEntry->Buffer = Buffer;\r
- InsertTailList(&ShellInfoObject.BufferToFreeList.Link, &BufferListEntry->Link);\r
+ InsertTailList (&ShellInfoObject.BufferToFreeList.Link, &BufferListEntry->Link);\r
return (Buffer);\r
}\r
\r
+\r
+/**\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
+VOID\r
+SaveBufferList (\r
+ OUT LIST_ENTRY *OldBufferList\r
+ )\r
+{\r
+ CopyMem (OldBufferList, &ShellInfoObject.BufferToFreeList.Link, sizeof (LIST_ENTRY));\r
+ InitializeListHead (&ShellInfoObject.BufferToFreeList.Link);\r
+}\r
+\r
+/**\r
+ Restore previous nodes into BufferToFreeList .\r
+\r
+ @param OldBufferList The temporary list head used to store the nodes in BufferToFreeList.\r
+**/\r
+VOID\r
+RestoreBufferList (\r
+ IN OUT LIST_ENTRY *OldBufferList\r
+ )\r
+{\r
+ FreeBufferList (&ShellInfoObject.BufferToFreeList);\r
+ CopyMem (&ShellInfoObject.BufferToFreeList.Link, OldBufferList, sizeof (LIST_ENTRY));\r
+}\r
+\r
+\r
/**\r
Add a buffer to the Line History List\r
\r
@param Buffer The line buffer to add.\r
**/\r
VOID\r
-EFIAPI\r
AddLineToCommandHistory(\r
IN CONST CHAR16 *Buffer\r
)\r
{\r
BUFFER_LIST *Node;\r
+ BUFFER_LIST *Walker;\r
+ UINT16 MaxHistoryCmdCount;\r
+ UINT16 Count;\r
+\r
+ Count = 0;\r
+ MaxHistoryCmdCount = PcdGet16(PcdShellMaxHistoryCommandCount);\r
+ \r
+ if (MaxHistoryCmdCount == 0) {\r
+ return ;\r
+ }\r
+\r
\r
Node = AllocateZeroPool(sizeof(BUFFER_LIST));\r
- ASSERT(Node != NULL);\r
- Node->Buffer = AllocateCopyPool(StrSize(Buffer), Buffer);\r
- ASSERT(Node->Buffer != NULL);\r
+ if (Node == NULL) {\r
+ return;\r
+ }\r
\r
- InsertTailList(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link);\r
+ Node->Buffer = AllocateCopyPool (StrSize (Buffer), Buffer);\r
+ if (Node->Buffer == NULL) {\r
+ FreePool (Node);\r
+ return;\r
+ }\r
+\r
+ for ( Walker = (BUFFER_LIST*)GetFirstNode(&ShellInfoObject.ViewingSettings.CommandHistory.Link)\r
+ ; !IsNull(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Walker->Link)\r
+ ; Walker = (BUFFER_LIST*)GetNextNode(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Walker->Link)\r
+ ){\r
+ Count++;\r
+ }\r
+ if (Count < MaxHistoryCmdCount){\r
+ InsertTailList(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link);\r
+ } else {\r
+ Walker = (BUFFER_LIST*)GetFirstNode(&ShellInfoObject.ViewingSettings.CommandHistory.Link);\r
+ RemoveEntryList(&Walker->Link);\r
+ if (Walker->Buffer != NULL) {\r
+ FreePool(Walker->Buffer);\r
+ }\r
+ FreePool(Walker);\r
+ InsertTailList(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link);\r
+ }\r
}\r
\r
/**\r
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
ShellConvertAlias(\r
IN OUT CHAR16 **CommandString\r
)\r
@param[in,out] CmdLine The command line to update.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
StripUnreplacedEnvironmentVariables(\r
IN OUT CHAR16 *CmdLine\r
)\r
@return The new command line with no environment variables present.\r
**/\r
CHAR16*\r
-EFIAPI\r
ShellConvertVariables (\r
IN CONST CHAR16 *OriginalCommandLine\r
)\r
@retval other Some error occurs when executing the split command.\r
**/\r
EFI_STATUS\r
-EFIAPI\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
// make a SPLIT_LIST item and add to list\r
//\r
Split = AllocateZeroPool(sizeof(SPLIT_LIST));\r
- ASSERT(Split != NULL);\r
+ if (Split == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
Split->SplitStdIn = StdIn;\r
Split->SplitStdOut = ConvertEfiFileProtocolToShellHandle(CreateFileInterfaceMem(Unicode), NULL);\r
ASSERT(Split->SplitStdOut != 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
//\r
// Note that the original StdIn is now the StdOut...\r
//\r
- if (Split->SplitStdOut != NULL && Split->SplitStdOut != StdIn) {\r
- ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdOut));\r
+ if (Split->SplitStdOut != NULL) {\r
+ ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdOut);\r
}\r
if (Split->SplitStdIn != NULL) {\r
- ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn));\r
+ ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdIn);\r
+ FreePool (Split->SplitStdIn);\r
}\r
\r
FreePool(Split);\r
@retval EFI_OUT_OF_RESOURCES a memory allocation failed.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
ShellSubstituteVariables(\r
IN CHAR16 **CmdLine\r
)\r
@retval EFI_OUT_OF_RESOURCES a memory allocation failed.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
ShellSubstituteAliases(\r
IN CHAR16 **CmdLine\r
)\r
@retval Efi_Application the name is an application (.EFI).\r
**/\r
SHELL_OPERATION_TYPES\r
-EFIAPI\r
GetOperationType(\r
IN CONST CHAR16 *CmdName\r
)\r
@retval EFI_NOT_FOUND The operation type is unknown or invalid.\r
**/\r
EFI_STATUS \r
-EFIAPI\r
IsValidSplit(\r
IN CONST CHAR16 *CmdLine\r
)\r
@retval EFI_ABORTED CmdLine has at least one invalid command or application.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
VerifySplit(\r
IN CONST CHAR16 *CmdLine\r
)\r
@return an error occurred.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
ProcessNewSplitCommandLine(\r
IN CONST CHAR16 *CmdLine\r
)\r
@retval EFI_SUCCESS The operation was successful.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
ChangeMappedDrive(\r
IN CONST CHAR16 *CmdLine\r
)\r
@param[in,out] CmdLine pointer to the command line to update\r
**/\r
EFI_STATUS\r
-EFIAPI\r
DoHelpUpdate(\r
IN OUT CHAR16 **CmdLine\r
)\r
@param[in] ErrorCode the error code to put into lasterror.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
SetLastError(\r
IN CONST SHELL_STATUS ErrorCode\r
)\r
@return some other error occurred\r
**/\r
EFI_STATUS\r
-EFIAPI\r
ProcessCommandLineToFinal(\r
IN OUT CHAR16 **CmdLine\r
)\r
@retval EFI_ABORTED The command's operation was aborted.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
RunInternalCommand(\r
IN CONST CHAR16 *CmdLine,\r
IN CHAR16 *FirstParameter,\r
@retval EFI_ABORTED The command's operation was aborted.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
RunCommandOrFile(\r
IN SHELL_OPERATION_TYPES Type,\r
IN CONST CHAR16 *CmdLine,\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 EFI_STATUS *CommandStatus\r
+ OUT EFI_STATUS *CommandStatus\r
)\r
{\r
EFI_STATUS Status;\r
SHELL_FILE_HANDLE OriginalStdOut;\r
SHELL_FILE_HANDLE OriginalStdErr;\r
SYSTEM_TABLE_INFO OriginalSystemTableInfo;\r
+ CONST SCRIPT_FILE *ConstScriptFile;\r
\r
//\r
// Update the StdIn, StdOut, and StdErr for redirection to environment variables, files, etc... unicode and ASCII\r
// Now print errors\r
//\r
if (EFI_ERROR(Status)) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID*)(Status));\r
+ ConstScriptFile = ShellCommandGetCurrentScriptFile();\r
+ if (ConstScriptFile == NULL || ConstScriptFile->CurrentCommand == NULL) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID*)(Status));\r
+ } else {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR_SCRIPT), ShellInfoObject.HiiHandle, (VOID*)(Status), ConstScriptFile->CurrentCommand->Line);\r
+ }\r
}\r
\r
//\r
@retval EFI_ABORTED The command's operation was aborted.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
RunShellCommand(\r
IN CONST CHAR16 *CmdLine,\r
OUT EFI_STATUS *CommandStatus\r
@retval EFI_ABORTED The command's operation was aborted.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
RunCommand(\r
IN CONST CHAR16 *CmdLine\r
)\r
@retval FALSE CommandName could not be a valid command name\r
**/\r
BOOLEAN\r
-EFIAPI\r
IsValidCommandName(\r
IN CONST CHAR16 *CommandName\r
)\r
@retval EFI_SUCCESS the script completed successfully\r
**/\r
EFI_STATUS\r
-EFIAPI\r
RunScriptFileHandle (\r
IN SHELL_FILE_HANDLE Handle,\r
IN CONST CHAR16 *Name\r
CONST CHAR16 *CurDir;\r
UINTN LineCount;\r
CHAR16 LeString[50];\r
+ LIST_ENTRY OldBufferList;\r
\r
ASSERT(!ShellCommandGetScriptExit());\r
\r
PrintBuffSize/sizeof(CHAR16) - 1\r
);\r
\r
+ SaveBufferList(&OldBufferList);\r
+\r
//\r
// NULL out comments\r
//\r
\r
ShellCommandRegisterExit(FALSE, 0);\r
Status = EFI_SUCCESS;\r
+ RestoreBufferList(&OldBufferList);\r
break;\r
}\r
if (ShellGetExecutionBreakFlag()) {\r
+ RestoreBufferList(&OldBufferList);\r
break;\r
}\r
if (EFI_ERROR(Status)) {\r
+ RestoreBufferList(&OldBufferList);\r
break;\r
}\r
if (ShellCommandGetExit()) {\r
+ RestoreBufferList(&OldBufferList);\r
break;\r
}\r
}\r
NewScriptFile->CurrentCommand->Reset = TRUE;\r
}\r
}\r
+ RestoreBufferList(&OldBufferList);\r
}\r
\r
\r
@retval EFI_SUCCESS the script completed successfully\r
**/\r
EFI_STATUS\r
-EFIAPI\r
RunScriptFile (\r
IN CONST CHAR16 *ScriptPath,\r
IN SHELL_FILE_HANDLE Handle OPTIONAL,\r
@retval CHAR_NULL no instance of any character in CharacterList was found in String\r
**/\r
CONST CHAR16*\r
-EFIAPI\r
FindFirstCharacter(\r
IN CONST CHAR16 *String,\r
IN CONST CHAR16 *CharacterList,\r