/** @file\r
This is THE shell (application)\r
\r
- Copyright (c) 2009 - 2016, 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
**/\r
EFI_STATUS\r
SetBuiltInAlias(\r
+ VOID\r
)\r
{\r
EFI_STATUS Status;\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
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
//\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
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
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
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