X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ShellPkg%2FApplication%2FShell%2FShell.c;h=2adc99240c483f01e5282002122028e5df842e15;hp=465f4f3974c12bfaf7469cf88a3bcf2fa2cb82c9;hb=e7275d3ffd410943479a9658707ab04d3e9f75ba;hpb=14810d6b644d367d4f195b3e953145a27493538c
diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c
index 465f4f3974..2adc99240c 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 - 2015, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2017, 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
@@ -33,6 +33,7 @@ SHELL_INFO ShellInfoObject = {
0,
0,
0,
+ 0,
0
}},
0,
@@ -69,6 +70,9 @@ SHELL_INFO ShellInfoObject = {
STATIC CONST CHAR16 mScriptExtension[] = L".NSH";
STATIC CONST CHAR16 mExecutableExtensions[] = L".NSH;.EFI";
STATIC CONST CHAR16 mStartupScript[] = L"startup.nsh";
+CONST CHAR16 mNoNestingEnvVarName[] = L"nonesting";
+CONST CHAR16 mNoNestingTrue[] = L"True";
+CONST CHAR16 mNoNestingFalse[] = L"False";
/**
Cleans off leading and trailing spaces and tabs.
@@ -76,7 +80,6 @@ STATIC CONST CHAR16 mStartupScript[] = L"startup.nsh";
@param[in] String pointer to the string to trim them off.
**/
EFI_STATUS
-EFIAPI
TrimSpaces(
IN CHAR16 **String
)
@@ -109,7 +112,6 @@ TrimSpaces(
@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,
@@ -198,7 +200,6 @@ IsValidEnvironmentVariableName(
@retval FALSE CmdLine does not have a valid split.
**/
BOOLEAN
-EFIAPI
ContainsSplit(
IN CONST CHAR16 *CmdLine
)
@@ -248,7 +249,6 @@ ContainsSplit(
@retval EFI_OUT_OF_RESOURCES There is not enough memory available.
**/
EFI_STATUS
-EFIAPI
InternalEfiShellStartCtrlSMonitor(
VOID
)
@@ -338,6 +338,7 @@ UefiMain (
UINTN Size;
EFI_HANDLE ConInHandle;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *OldConIn;
+ SPLIT_LIST *Split;
if (PcdGet8(PcdShellSupportLevel) > 3) {
return (EFI_UNSUPPORTED);
@@ -441,6 +442,8 @@ UefiMain (
Status = CommandInit();
ASSERT_EFI_ERROR(Status);
+ Status = ShellInitEnvVarList ();
+
//
// Check the command line
//
@@ -456,6 +459,29 @@ UefiMain (
Status = ShellCommandCreateInitialMappingsAndPaths();
}
+ //
+ // Set the environment variable for nesting support
+ //
+ Size = 0;
+ TempString = NULL;
+ if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest) {
+ //
+ // No change. require nesting in Shell Protocol Execute()
+ //
+ StrnCatGrow(&TempString,
+ &Size,
+ L"False",
+ 0);
+ } else {
+ StrnCatGrow(&TempString,
+ &Size,
+ mNoNestingTrue,
+ 0);
+ }
+ Status = InternalEfiShellSetEnv(mNoNestingEnvVarName, TempString, TRUE);
+ SHELL_FREE_NON_NULL(TempString);
+ Size = 0;
+
//
// save the device path for the loaded image and the device path for the filepath (under loaded image)
// These are where to look for the startup.nsh file
@@ -637,7 +663,7 @@ FreeResources:
if (ShellInfoObject.NewEfiShellProtocol->IsRootShell()){
InternalEfiShellSetEnv(L"cwd", NULL, TRUE);
}
- CleanUpShellProtocol(ShellInfoObject.NewEfiShellProtocol);
+ CleanUpShellEnvironment (ShellInfoObject.NewEfiShellProtocol);
DEBUG_CODE(ShellInfoObject.NewEfiShellProtocol = NULL;);
}
@@ -646,7 +672,17 @@ FreeResources:
}
if (!IsListEmpty(&ShellInfoObject.SplitList.Link)){
- ASSERT(FALSE); ///@todo finish this de-allocation.
+ ASSERT(FALSE); ///@todo finish this de-allocation (free SplitStdIn/Out when needed).
+
+ for ( Split = (SPLIT_LIST*)GetFirstNode (&ShellInfoObject.SplitList.Link)
+ ; !IsNull (&ShellInfoObject.SplitList.Link, &Split->Link)
+ ; Split = (SPLIT_LIST *)GetNextNode (&ShellInfoObject.SplitList.Link, &Split->Link)
+ ) {
+ RemoveEntryList (&Split->Link);
+ FreePool (Split);
+ }
+
+ DEBUG_CODE (InitializeListHead (&ShellInfoObject.SplitList.Link););
}
if (ShellInfoObject.ShellInitSettings.FileName != NULL) {
@@ -675,6 +711,8 @@ FreeResources:
DEBUG_CODE(ShellInfoObject.ConsoleInfo = NULL;);
}
+ ShellFreeEnvVarList ();
+
if (ShellCommandGetExit()) {
return ((EFI_STATUS)ShellCommandGetExitCode());
}
@@ -687,8 +725,8 @@ FreeResources:
@retval EFI_SUCCESS all init commands were run successfully.
**/
EFI_STATUS
-EFIAPI
SetBuiltInAlias(
+ VOID
)
{
EFI_STATUS Status;
@@ -726,7 +764,6 @@ SetBuiltInAlias(
@retval FALSE The 2 command names are not the same.
**/
BOOLEAN
-EFIAPI
IsCommand(
IN CONST CHAR16 *Command1,
IN CONST CHAR16 *Command2
@@ -747,7 +784,6 @@ IsCommand(
@retval FALSE The command is not a script only command.
**/
BOOLEAN
-EFIAPI
IsScriptOnlyCommand(
IN CONST CHAR16 *CommandName
)
@@ -778,7 +814,6 @@ IsScriptOnlyCommand(
@sa HandleProtocol
**/
EFI_STATUS
-EFIAPI
GetDevicePathsForImageAndFile (
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevPath,
IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath
@@ -854,7 +889,6 @@ GetDevicePathsForImageAndFile (
@retval EFI_SUCCESS The variable is initialized.
**/
EFI_STATUS
-EFIAPI
ProcessCommandLine(
VOID
)
@@ -873,12 +907,19 @@ ProcessCommandLine(
// like a shell option (which is assumed to be `file-name`).
Status = gBS->LocateProtocol (
- &gEfiUnicodeCollationProtocolGuid,
+ &gEfiUnicodeCollation2ProtocolGuid,
NULL,
(VOID **) &UnicodeCollation
);
if (EFI_ERROR (Status)) {
- return Status;
+ Status = gBS->LocateProtocol (
+ &gEfiUnicodeCollationProtocolGuid,
+ NULL,
+ (VOID **) &UnicodeCollation
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
}
// Set default options
@@ -891,6 +932,7 @@ ProcessCommandLine(
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion = FALSE;
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay = FALSE;
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit = FALSE;
+ ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest = FALSE;
ShellInfoObject.ShellInitSettings.Delay = 5;
//
@@ -950,6 +992,13 @@ ProcessCommandLine(
) == 0) {
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion = TRUE;
}
+ else if (UnicodeCollation->StriColl (
+ UnicodeCollation,
+ L"-nonest",
+ CurrentArg
+ ) == 0) {
+ ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoNest = TRUE;
+ }
else if (UnicodeCollation->StriColl (
UnicodeCollation,
L"-delay",
@@ -974,7 +1023,7 @@ ProcessCommandLine(
}
} else if (UnicodeCollation->StriColl (
UnicodeCollation,
- L"-_exit",
+ L"-exit",
CurrentArg
) == 0) {
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit = TRUE;
@@ -994,11 +1043,31 @@ ProcessCommandLine(
continue;
}
- ShellInfoObject.ShellInitSettings.FileName = AllocateCopyPool(StrSize(CurrentArg), CurrentArg);
+ ShellInfoObject.ShellInitSettings.FileName = NULL;
+ Size = 0;
+ //
+ // If first argument contains a space, then add double quotes before the argument
+ //
+ if (StrStr (CurrentArg, L" ") != NULL) {
+ StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileName, &Size, L"\"", 0);
+ if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
+ }
+ StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileName, &Size, CurrentArg, 0);
if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
return (EFI_OUT_OF_RESOURCES);
}
//
+ // If first argument contains a space, then add double quotes after the argument
+ //
+ if (StrStr (CurrentArg, L" ") != NULL) {
+ StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileName, &Size, L"\"", 0);
+ if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
+ }
+ //
// We found `file-name`.
//
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = 1;
@@ -1007,13 +1076,28 @@ ProcessCommandLine(
// Add `file-name-options`
for (Size = 0 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
ASSERT((ShellInfoObject.ShellInitSettings.FileOptions == NULL && Size == 0) || (ShellInfoObject.ShellInitSettings.FileOptions != NULL));
- StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,
- &Size,
- L" ",
- 0);
- if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
- SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);
- return (EFI_OUT_OF_RESOURCES);
+ //
+ // Add a space between arguments
+ //
+ if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {
+ StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions, &Size, L" ", 0);
+ if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
+ SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);
+ return (EFI_OUT_OF_RESOURCES);
+ }
+ }
+ //
+ // If an argumnent contains a space, then add double quotes before the argument
+ //
+ if (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L" ") != NULL) {
+ StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,
+ &Size,
+ L"\"",
+ 0);
+ if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
+ SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);
+ return (EFI_OUT_OF_RESOURCES);
+ }
}
StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,
&Size,
@@ -1023,6 +1107,19 @@ ProcessCommandLine(
SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);
return (EFI_OUT_OF_RESOURCES);
}
+ //
+ // If an argumnent contains a space, then add double quotes after the argument
+ //
+ if (StrStr (gEfiShellParametersProtocol->Argv[LoopVar], L" ") != NULL) {
+ StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,
+ &Size,
+ L"\"",
+ 0);
+ if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
+ SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);
+ return (EFI_OUT_OF_RESOURCES);
+ }
+ }
}
}
}
@@ -1035,6 +1132,64 @@ ProcessCommandLine(
return EFI_SUCCESS;
}
+/**
+ Function try to find location of the Startup.nsh file.
+
+ The buffer is callee allocated and should be freed by the caller.
+
+ @param ImageDevicePath The path to the image for shell. first place to look for the startup script
+ @param FileDevicePath The path to the file for shell. second place to look for the startup script.
+
+ @retval NULL No Startup.nsh file was found.
+ @return !=NULL Pointer to NULL-terminated path.
+**/
+CHAR16 *
+LocateStartupScript (
+ IN EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath,
+ IN EFI_DEVICE_PATH_PROTOCOL *FileDevicePath
+ )
+{
+ CHAR16 *StartupScriptPath;
+ CHAR16 *TempSpot;
+ CONST CHAR16 *MapName;
+ UINTN Size;
+
+ StartupScriptPath = NULL;
+ Size = 0;
+
+ //
+ // Try to find 'Startup.nsh' in the directory where the shell itself was launched.
+ //
+ MapName = ShellInfoObject.NewEfiShellProtocol->GetMapFromDevicePath (&ImageDevicePath);
+ if (MapName != NULL) {
+ StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, MapName, 0);
+ if (StartupScriptPath == NULL) {
+ //
+ // Do not locate the startup script in sys path when out of resource.
+ //
+ return NULL;
+ }
+ TempSpot = StrStr (StartupScriptPath, L";");
+ if (TempSpot != NULL) {
+ *TempSpot = CHAR_NULL;
+ }
+
+ StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, ((FILEPATH_DEVICE_PATH *)FileDevicePath)->PathName, 0);
+ PathRemoveLastItem (StartupScriptPath);
+ StartupScriptPath = StrnCatGrow (&StartupScriptPath, &Size, mStartupScript, 0);
+ }
+
+ //
+ // Try to find 'Startup.nsh' in the execution path defined by the envrionment variable PATH.
+ //
+ if ((StartupScriptPath == NULL) || EFI_ERROR (ShellIsFile (StartupScriptPath))) {
+ SHELL_FREE_NON_NULL (StartupScriptPath);
+ StartupScriptPath = ShellFindFilePath (mStartupScript);
+ }
+
+ return StartupScriptPath;
+}
+
/**
Handles all interaction with the default startup script.
@@ -1046,7 +1201,6 @@ ProcessCommandLine(
@retval EFI_SUCCESS the variable is initialized.
**/
EFI_STATUS
-EFIAPI
DoStartupScript(
IN EFI_DEVICE_PATH_PROTOCOL *ImagePath,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath
@@ -1056,17 +1210,11 @@ DoStartupScript(
EFI_STATUS CalleeStatus;
UINTN Delay;
EFI_INPUT_KEY Key;
- SHELL_FILE_HANDLE FileHandle;
- EFI_DEVICE_PATH_PROTOCOL *NewPath;
- EFI_DEVICE_PATH_PROTOCOL *NamePath;
CHAR16 *FileStringPath;
- CHAR16 *TempSpot;
UINTN NewSize;
- CONST CHAR16 *MapName;
Key.UnicodeChar = CHAR_NULL;
Key.ScanCode = 0;
- FileHandle = NULL;
if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup && ShellInfoObject.ShellInitSettings.FileName != NULL) {
//
@@ -1128,60 +1276,17 @@ DoStartupScript(
return (EFI_SUCCESS);
}
- //
- // Try the first location (must be file system)
- //
- MapName = ShellInfoObject.NewEfiShellProtocol->GetMapFromDevicePath(&ImagePath);
- if (MapName != NULL) {
- FileStringPath = NULL;
- NewSize = 0;
- FileStringPath = StrnCatGrow(&FileStringPath, &NewSize, MapName, 0);
- if (FileStringPath == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- } else {
- TempSpot = StrStr(FileStringPath, L";");
- if (TempSpot != NULL) {
- *TempSpot = CHAR_NULL;
- }
- FileStringPath = StrnCatGrow(&FileStringPath, &NewSize, ((FILEPATH_DEVICE_PATH*)FilePath)->PathName, 0);
- PathRemoveLastItem(FileStringPath);
- FileStringPath = StrnCatGrow(&FileStringPath, &NewSize, mStartupScript, 0);
- Status = ShellInfoObject.NewEfiShellProtocol->OpenFileByName(FileStringPath, &FileHandle, EFI_FILE_MODE_READ);
- FreePool(FileStringPath);
- }
- }
- if (EFI_ERROR(Status)) {
- NamePath = FileDevicePath (NULL, mStartupScript);
- NewPath = AppendDevicePathNode (ImagePath, NamePath);
- FreePool(NamePath);
-
+ FileStringPath = LocateStartupScript (ImagePath, FilePath);
+ if (FileStringPath != NULL) {
+ Status = RunScriptFile (FileStringPath, NULL, L"", ShellInfoObject.NewShellParametersProtocol);
+ FreePool (FileStringPath);
+ } else {
//
- // Try the location
+ // we return success since startup script is not mandatory.
//
- Status = InternalOpenFileDevicePath(NewPath, &FileHandle, EFI_FILE_MODE_READ, 0);
- FreePool(NewPath);
- }
- //
- // If we got a file, run it
- //
- if (!EFI_ERROR(Status) && FileHandle != NULL) {
- Status = RunScriptFile (mStartupScript, FileHandle, L"", ShellInfoObject.NewShellParametersProtocol);
- ShellInfoObject.NewEfiShellProtocol->CloseFile(FileHandle);
- } else {
- FileStringPath = ShellFindFilePath(mStartupScript);
- if (FileStringPath == NULL) {
- //
- // we return success since we don't need to have a startup script
- //
- Status = EFI_SUCCESS;
- ASSERT(FileHandle == NULL);
- } else {
- Status = RunScriptFile(FileStringPath, NULL, L"", ShellInfoObject.NewShellParametersProtocol);
- FreePool(FileStringPath);
- }
+ Status = EFI_SUCCESS;
}
-
return (Status);
}
@@ -1194,7 +1299,6 @@ DoStartupScript(
@retval RETURN_ABORTED
**/
EFI_STATUS
-EFIAPI
DoShellPrompt (
VOID
)
@@ -1205,6 +1309,7 @@ DoShellPrompt (
CONST CHAR16 *CurDir;
UINTN BufferSize;
EFI_STATUS Status;
+ LIST_ENTRY OldBufferList;
CurDir = NULL;
@@ -1218,6 +1323,7 @@ DoShellPrompt (
return EFI_OUT_OF_RESOURCES;
}
+ SaveBufferList(&OldBufferList);
CurDir = ShellInfoObject.NewEfiShellProtocol->GetEnv(L"cwd");
//
@@ -1247,6 +1353,7 @@ DoShellPrompt (
//
// Done with this command
//
+ RestoreBufferList(&OldBufferList);
FreePool (CmdLine);
return Status;
}
@@ -1258,8 +1365,7 @@ DoShellPrompt (
@param Buffer Something to pass to FreePool when the shell is exiting.
**/
VOID*
-EFIAPI
-AddBufferToFreeList(
+AddBufferToFreeList (
VOID *Buffer
)
{
@@ -1269,10 +1375,13 @@ AddBufferToFreeList(
return (NULL);
}
- BufferListEntry = AllocateZeroPool(sizeof(BUFFER_LIST));
- ASSERT(BufferListEntry != NULL);
+ BufferListEntry = AllocateZeroPool (sizeof (BUFFER_LIST));
+ if (BufferListEntry == NULL) {
+ return NULL;
+ }
+
BufferListEntry->Buffer = Buffer;
- InsertTailList(&ShellInfoObject.BufferToFreeList.Link, &BufferListEntry->Link);
+ InsertTailList (&ShellInfoObject.BufferToFreeList.Link, &BufferListEntry->Link);
return (Buffer);
}
@@ -1312,7 +1421,6 @@ RestoreBufferList (
@param Buffer The line buffer to add.
**/
VOID
-EFIAPI
AddLineToCommandHistory(
IN CONST CHAR16 *Buffer
)
@@ -1321,7 +1429,7 @@ AddLineToCommandHistory(
BUFFER_LIST *Walker;
UINT16 MaxHistoryCmdCount;
UINT16 Count;
-
+
Count = 0;
MaxHistoryCmdCount = PcdGet16(PcdShellMaxHistoryCommandCount);
@@ -1331,9 +1439,15 @@ AddLineToCommandHistory(
Node = AllocateZeroPool(sizeof(BUFFER_LIST));
- ASSERT(Node != NULL);
- Node->Buffer = AllocateCopyPool(StrSize(Buffer), Buffer);
- ASSERT(Node->Buffer != NULL);
+ if (Node == NULL) {
+ return;
+ }
+
+ Node->Buffer = AllocateCopyPool (StrSize (Buffer), Buffer);
+ if (Node->Buffer == NULL) {
+ FreePool (Node);
+ return;
+ }
for ( Walker = (BUFFER_LIST*)GetFirstNode(&ShellInfoObject.ViewingSettings.CommandHistory.Link)
; !IsNull(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Walker->Link)
@@ -1368,7 +1482,6 @@ AddLineToCommandHistory(
@retval EFI_OUT_OF_RESOURCES A memory allocation failed.
**/
EFI_STATUS
-EFIAPI
ShellConvertAlias(
IN OUT CHAR16 **CommandString
)
@@ -1393,7 +1506,6 @@ ShellConvertAlias(
@param[in,out] CmdLine The command line to update.
**/
EFI_STATUS
-EFIAPI
StripUnreplacedEnvironmentVariables(
IN OUT CHAR16 *CmdLine
)
@@ -1466,7 +1578,6 @@ StripUnreplacedEnvironmentVariables(
@return The new command line with no environment variables present.
**/
CHAR16*
-EFIAPI
ShellConvertVariables (
IN CONST CHAR16 *OriginalCommandLine
)
@@ -1536,7 +1647,7 @@ ShellConvertVariables (
//
// now do the replacements...
//
- NewCommandLine1 = AllocateCopyPool(NewSize, OriginalCommandLine);
+ NewCommandLine1 = AllocateZeroPool (NewSize);
NewCommandLine2 = AllocateZeroPool(NewSize);
ItemTemp = AllocateZeroPool(ItemSize+(2*sizeof(CHAR16)));
if (NewCommandLine1 == NULL || NewCommandLine2 == NULL || ItemTemp == NULL) {
@@ -1545,6 +1656,8 @@ ShellConvertVariables (
SHELL_FREE_NON_NULL(ItemTemp);
return (NULL);
}
+ CopyMem (NewCommandLine1, OriginalCommandLine, StrSize (OriginalCommandLine));
+
for (MasterEnvList = EfiShellGetEnv(NULL)
; MasterEnvList != NULL && *MasterEnvList != CHAR_NULL
; MasterEnvList += StrLen(MasterEnvList) + 1
@@ -1602,11 +1715,10 @@ ShellConvertVariables (
@retval other Some error occurs when executing the split command.
**/
EFI_STATUS
-EFIAPI
RunSplitCommand(
IN CONST CHAR16 *CmdLine,
- IN SHELL_FILE_HANDLE *StdIn,
- IN SHELL_FILE_HANDLE *StdOut
+ IN SHELL_FILE_HANDLE StdIn,
+ IN SHELL_FILE_HANDLE StdOut
)
{
EFI_STATUS Status;
@@ -1615,7 +1727,7 @@ RunSplitCommand(
UINTN Size1;
UINTN Size2;
SPLIT_LIST *Split;
- SHELL_FILE_HANDLE *TempFileHandle;
+ SHELL_FILE_HANDLE TempFileHandle;
BOOLEAN Unicode;
ASSERT(StdOut == NULL);
@@ -1661,7 +1773,9 @@ RunSplitCommand(
// make a SPLIT_LIST item and add to list
//
Split = AllocateZeroPool(sizeof(SPLIT_LIST));
- ASSERT(Split != NULL);
+ if (Split == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
Split->SplitStdIn = StdIn;
Split->SplitStdOut = ConvertEfiFileProtocolToShellHandle(CreateFileInterfaceMem(Unicode), NULL);
ASSERT(Split->SplitStdOut != NULL);
@@ -1679,7 +1793,7 @@ RunSplitCommand(
Split->SplitStdOut = Split->SplitStdIn;
}
Split->SplitStdIn = TempFileHandle;
- ShellInfoObject.NewEfiShellProtocol->SetFilePosition(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn), 0);
+ ShellInfoObject.NewEfiShellProtocol->SetFilePosition (Split->SplitStdIn, 0);
if (!EFI_ERROR(Status)) {
Status = RunCommand(NextCommandLine);
@@ -1694,11 +1808,11 @@ RunSplitCommand(
//
// Note that the original StdIn is now the StdOut...
//
- if (Split->SplitStdOut != NULL && Split->SplitStdOut != StdIn) {
- ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdOut));
+ if (Split->SplitStdOut != NULL) {
+ ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdOut);
}
if (Split->SplitStdIn != NULL) {
- ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn));
+ ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdIn);
}
FreePool(Split);
@@ -1718,7 +1832,6 @@ RunSplitCommand(
@retval EFI_OUT_OF_RESOURCES a memory allocation failed.
**/
EFI_STATUS
-EFIAPI
ShellSubstituteVariables(
IN CHAR16 **CmdLine
)
@@ -1743,7 +1856,6 @@ ShellSubstituteVariables(
@retval EFI_OUT_OF_RESOURCES a memory allocation failed.
**/
EFI_STATUS
-EFIAPI
ShellSubstituteAliases(
IN CHAR16 **CmdLine
)
@@ -1815,7 +1927,6 @@ ShellSubstituteAliases(
@retval Efi_Application the name is an application (.EFI).
**/
SHELL_OPERATION_TYPES
-EFIAPI
GetOperationType(
IN CONST CHAR16 *CmdName
)
@@ -1884,7 +1995,6 @@ GetOperationType(
@retval EFI_NOT_FOUND The operation type is unknown or invalid.
**/
EFI_STATUS
-EFIAPI
IsValidSplit(
IN CONST CHAR16 *CmdLine
)
@@ -1943,7 +2053,6 @@ IsValidSplit(
@retval EFI_ABORTED CmdLine has at least one invalid command or application.
**/
EFI_STATUS
-EFIAPI
VerifySplit(
IN CONST CHAR16 *CmdLine
)
@@ -1989,7 +2098,6 @@ VerifySplit(
@return an error occurred.
**/
EFI_STATUS
-EFIAPI
ProcessNewSplitCommandLine(
IN CONST CHAR16 *CmdLine
)
@@ -2030,7 +2138,6 @@ ProcessNewSplitCommandLine(
@retval EFI_SUCCESS The operation was successful.
**/
EFI_STATUS
-EFIAPI
ChangeMappedDrive(
IN CONST CHAR16 *CmdLine
)
@@ -2066,7 +2173,6 @@ ChangeMappedDrive(
@param[in,out] CmdLine pointer to the command line to update
**/
EFI_STATUS
-EFIAPI
DoHelpUpdate(
IN OUT CHAR16 **CmdLine
)
@@ -2120,7 +2226,6 @@ DoHelpUpdate(
@param[in] ErrorCode the error code to put into lasterror.
**/
EFI_STATUS
-EFIAPI
SetLastError(
IN CONST SHELL_STATUS ErrorCode
)
@@ -2147,7 +2252,6 @@ SetLastError(
@return some other error occurred
**/
EFI_STATUS
-EFIAPI
ProcessCommandLineToFinal(
IN OUT CHAR16 **CmdLine
)
@@ -2200,7 +2304,6 @@ ProcessCommandLineToFinal(
@retval EFI_ABORTED The command's operation was aborted.
**/
EFI_STATUS
-EFIAPI
RunInternalCommand(
IN CONST CHAR16 *CmdLine,
IN CHAR16 *FirstParameter,
@@ -2313,7 +2416,6 @@ RunInternalCommand(
@retval EFI_ABORTED The command's operation was aborted.
**/
EFI_STATUS
-EFIAPI
RunCommandOrFile(
IN SHELL_OPERATION_TYPES Type,
IN CONST CHAR16 *CmdLine,
@@ -2443,13 +2545,12 @@ RunCommandOrFile(
@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 EFI_STATUS *CommandStatus
+ OUT EFI_STATUS *CommandStatus
)
{
EFI_STATUS Status;
@@ -2457,6 +2558,7 @@ SetupAndRunCommandOrFile(
SHELL_FILE_HANDLE OriginalStdOut;
SHELL_FILE_HANDLE OriginalStdErr;
SYSTEM_TABLE_INFO OriginalSystemTableInfo;
+ CONST SCRIPT_FILE *ConstScriptFile;
//
// Update the StdIn, StdOut, and StdErr for redirection to environment variables, files, etc... unicode and ASCII
@@ -2476,7 +2578,12 @@ SetupAndRunCommandOrFile(
// Now print errors
//
if (EFI_ERROR(Status)) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID*)(Status));
+ ConstScriptFile = ShellCommandGetCurrentScriptFile();
+ if (ConstScriptFile == NULL || ConstScriptFile->CurrentCommand == NULL) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID*)(Status));
+ } else {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR_SCRIPT), ShellInfoObject.HiiHandle, (VOID*)(Status), ConstScriptFile->CurrentCommand->Line);
+ }
}
//
@@ -2500,7 +2607,6 @@ SetupAndRunCommandOrFile(
@retval EFI_ABORTED The command's operation was aborted.
**/
EFI_STATUS
-EFIAPI
RunShellCommand(
IN CONST CHAR16 *CmdLine,
OUT EFI_STATUS *CommandStatus
@@ -2511,6 +2617,7 @@ RunShellCommand(
CHAR16 *FirstParameter;
CHAR16 *TempWalker;
SHELL_OPERATION_TYPES Type;
+ CONST CHAR16 *CurDir;
ASSERT(CmdLine != NULL);
if (StrLen(CmdLine) == 0) {
@@ -2602,7 +2709,22 @@ RunShellCommand(
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter);
SetLastError(SHELL_NOT_FOUND);
}
-
+ //
+ // Check whether the current file system still exists. If not exist, we need update "cwd" and gShellCurMapping.
+ //
+ CurDir = EfiShellGetCurDir (NULL);
+ if (CurDir != NULL) {
+ if (EFI_ERROR(ShellFileExists (CurDir))) {
+ //
+ // EfiShellSetCurDir() cannot set current directory to NULL.
+ // EfiShellSetEnv() is not allowed to set the "cwd" variable.
+ // Only InternalEfiShellSetEnv () is allowed setting the "cwd" variable.
+ //
+ InternalEfiShellSetEnv (L"cwd", NULL, TRUE);
+ gShellCurMapping = NULL;
+ }
+ }
+
SHELL_FREE_NON_NULL(CleanOriginal);
SHELL_FREE_NON_NULL(FirstParameter);
@@ -2621,7 +2743,6 @@ RunShellCommand(
@retval EFI_ABORTED The command's operation was aborted.
**/
EFI_STATUS
-EFIAPI
RunCommand(
IN CONST CHAR16 *CmdLine
)
@@ -2641,7 +2762,6 @@ STATIC CONST UINT16 InvalidChars[] = {L'*', L'?', L'<', L'>', L'\\', L'/', L'\"'
@retval FALSE CommandName could not be a valid command name
**/
BOOLEAN
-EFIAPI
IsValidCommandName(
IN CONST CHAR16 *CommandName
)
@@ -2671,7 +2791,6 @@ IsValidCommandName(
@retval EFI_SUCCESS the script completed successfully
**/
EFI_STATUS
-EFIAPI
RunScriptFileHandle (
IN SHELL_FILE_HANDLE Handle,
IN CONST CHAR16 *Name
@@ -2989,7 +3108,6 @@ RunScriptFileHandle (
@retval EFI_SUCCESS the script completed successfully
**/
EFI_STATUS
-EFIAPI
RunScriptFile (
IN CONST CHAR16 *ScriptPath,
IN SHELL_FILE_HANDLE Handle OPTIONAL,
@@ -3053,7 +3171,6 @@ RunScriptFile (
@retval CHAR_NULL no instance of any character in CharacterList was found in String
**/
CONST CHAR16*
-EFIAPI
FindFirstCharacter(
IN CONST CHAR16 *String,
IN CONST CHAR16 *CharacterList,