X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ShellPkg%2FApplication%2FShell%2FShell.c;h=2adc99240c483f01e5282002122028e5df842e15;hp=0f1fb9c287b83c253b40e76e979e43782055c95a;hb=e7275d3ffd410943479a9658707ab04d3e9f75ba;hpb=c0bcd3433f33876c519bf5567e0ab69261b57fe9 diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c index 0f1fb9c287..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 - 2016, 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 @@ -80,7 +80,6 @@ CONST CHAR16 mNoNestingFalse[] = L"False"; @param[in] String pointer to the string to trim them off. **/ EFI_STATUS -EFIAPI TrimSpaces( IN CHAR16 **String ) @@ -113,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, @@ -202,7 +200,6 @@ IsValidEnvironmentVariableName( @retval FALSE CmdLine does not have a valid split. **/ BOOLEAN -EFIAPI ContainsSplit( IN CONST CHAR16 *CmdLine ) @@ -213,7 +210,7 @@ ContainsSplit( FirstQuote = FindNextInstance (CmdLine, L"\"", TRUE); SecondQuote = NULL; - TempSpot = ShellFindFirstCharacter(CmdLine, L"|", TRUE); + TempSpot = FindFirstCharacter(CmdLine, L"|", L'^'); if (FirstQuote == NULL || TempSpot == NULL || @@ -236,7 +233,7 @@ ContainsSplit( continue; } else { FirstQuote = FindNextInstance (SecondQuote + 1, L"\"", TRUE); - TempSpot = ShellFindFirstCharacter(TempSpot + 1, L"|", TRUE); + TempSpot = FindFirstCharacter(TempSpot + 1, L"|", L'^'); continue; } } @@ -252,7 +249,6 @@ ContainsSplit( @retval EFI_OUT_OF_RESOURCES There is not enough memory available. **/ EFI_STATUS -EFIAPI InternalEfiShellStartCtrlSMonitor( VOID ) @@ -667,7 +663,7 @@ FreeResources: if (ShellInfoObject.NewEfiShellProtocol->IsRootShell()){ InternalEfiShellSetEnv(L"cwd", NULL, TRUE); } - CleanUpShellProtocol(ShellInfoObject.NewEfiShellProtocol); + CleanUpShellEnvironment (ShellInfoObject.NewEfiShellProtocol); DEBUG_CODE(ShellInfoObject.NewEfiShellProtocol = NULL;); } @@ -716,7 +712,6 @@ FreeResources: } ShellFreeEnvVarList (); - ShellSetRawCmdLine (NULL); if (ShellCommandGetExit()) { return ((EFI_STATUS)ShellCommandGetExitCode()); @@ -730,8 +725,8 @@ FreeResources: @retval EFI_SUCCESS all init commands were run successfully. **/ EFI_STATUS -EFIAPI SetBuiltInAlias( + VOID ) { EFI_STATUS Status; @@ -769,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 @@ -790,7 +784,6 @@ IsCommand( @retval FALSE The command is not a script only command. **/ BOOLEAN -EFIAPI IsScriptOnlyCommand( IN CONST CHAR16 *CommandName ) @@ -821,7 +814,6 @@ IsScriptOnlyCommand( @sa HandleProtocol **/ EFI_STATUS -EFIAPI GetDevicePathsForImageAndFile ( IN OUT EFI_DEVICE_PATH_PROTOCOL **DevPath, IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath @@ -897,7 +889,6 @@ GetDevicePathsForImageAndFile ( @retval EFI_SUCCESS The variable is initialized. **/ EFI_STATUS -EFIAPI ProcessCommandLine( VOID ) @@ -1032,7 +1023,7 @@ ProcessCommandLine( } } else if (UnicodeCollation->StriColl ( UnicodeCollation, - L"-_exit", + L"-exit", CurrentArg ) == 0) { ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit = TRUE; @@ -1052,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; @@ -1065,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, @@ -1081,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); + } + } } } } @@ -1093,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. @@ -1104,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 @@ -1114,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) { // @@ -1186,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); } @@ -1252,7 +1299,6 @@ DoStartupScript( @retval RETURN_ABORTED **/ EFI_STATUS -EFIAPI DoShellPrompt ( VOID ) @@ -1319,7 +1365,6 @@ DoShellPrompt ( @param Buffer Something to pass to FreePool when the shell is exiting. **/ VOID* -EFIAPI AddBufferToFreeList ( VOID *Buffer ) @@ -1376,7 +1421,6 @@ RestoreBufferList ( @param Buffer The line buffer to add. **/ VOID -EFIAPI AddLineToCommandHistory( IN CONST CHAR16 *Buffer ) @@ -1438,7 +1482,6 @@ AddLineToCommandHistory( @retval EFI_OUT_OF_RESOURCES A memory allocation failed. **/ EFI_STATUS -EFIAPI ShellConvertAlias( IN OUT CHAR16 **CommandString ) @@ -1463,7 +1506,6 @@ ShellConvertAlias( @param[in,out] CmdLine The command line to update. **/ EFI_STATUS -EFIAPI StripUnreplacedEnvironmentVariables( IN OUT CHAR16 *CmdLine ) @@ -1536,7 +1578,6 @@ StripUnreplacedEnvironmentVariables( @return The new command line with no environment variables present. **/ CHAR16* -EFIAPI ShellConvertVariables ( IN CONST CHAR16 *OriginalCommandLine ) @@ -1606,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) { @@ -1615,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 @@ -1672,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; @@ -1685,7 +1727,7 @@ RunSplitCommand( UINTN Size1; UINTN Size2; SPLIT_LIST *Split; - SHELL_FILE_HANDLE *TempFileHandle; + SHELL_FILE_HANDLE TempFileHandle; BOOLEAN Unicode; ASSERT(StdOut == NULL); @@ -1751,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); @@ -1767,11 +1809,10 @@ RunSplitCommand( // Note that the original StdIn is now the StdOut... // if (Split->SplitStdOut != NULL) { - ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdOut)); + ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdOut); } if (Split->SplitStdIn != NULL) { - ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn)); - FreePool (Split->SplitStdIn); + ShellInfoObject.NewEfiShellProtocol->CloseFile (Split->SplitStdIn); } FreePool(Split); @@ -1791,7 +1832,6 @@ RunSplitCommand( @retval EFI_OUT_OF_RESOURCES a memory allocation failed. **/ EFI_STATUS -EFIAPI ShellSubstituteVariables( IN CHAR16 **CmdLine ) @@ -1816,7 +1856,6 @@ ShellSubstituteVariables( @retval EFI_OUT_OF_RESOURCES a memory allocation failed. **/ EFI_STATUS -EFIAPI ShellSubstituteAliases( IN CHAR16 **CmdLine ) @@ -1888,7 +1927,6 @@ ShellSubstituteAliases( @retval Efi_Application the name is an application (.EFI). **/ SHELL_OPERATION_TYPES -EFIAPI GetOperationType( IN CONST CHAR16 *CmdName ) @@ -1957,7 +1995,6 @@ GetOperationType( @retval EFI_NOT_FOUND The operation type is unknown or invalid. **/ EFI_STATUS -EFIAPI IsValidSplit( IN CONST CHAR16 *CmdLine ) @@ -1993,7 +2030,7 @@ IsValidSplit( return (EFI_OUT_OF_RESOURCES); } TempWalker = (CHAR16*)Temp; - if (!EFI_ERROR (ShellGetNextParameter (&TempWalker, FirstParameter, StrSize(CmdLine), TRUE))) { + if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CmdLine), TRUE))) { if (GetOperationType(FirstParameter) == Unknown_Invalid) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter); SetLastError(SHELL_NOT_FOUND); @@ -2016,7 +2053,6 @@ IsValidSplit( @retval EFI_ABORTED CmdLine has at least one invalid command or application. **/ EFI_STATUS -EFIAPI VerifySplit( IN CONST CHAR16 *CmdLine ) @@ -2042,7 +2078,7 @@ VerifySplit( // // recurse to verify the next item // - TempSpot = ShellFindFirstCharacter(CmdLine, L"|", TRUE) + 1; + TempSpot = FindFirstCharacter(CmdLine, L"|", L'^') + 1; if (*TempSpot == L'a' && (*(TempSpot + 1) == L' ' || *(TempSpot + 1) == CHAR_NULL) ) { @@ -2062,7 +2098,6 @@ VerifySplit( @return an error occurred. **/ EFI_STATUS -EFIAPI ProcessNewSplitCommandLine( IN CONST CHAR16 *CmdLine ) @@ -2103,7 +2138,6 @@ ProcessNewSplitCommandLine( @retval EFI_SUCCESS The operation was successful. **/ EFI_STATUS -EFIAPI ChangeMappedDrive( IN CONST CHAR16 *CmdLine ) @@ -2139,7 +2173,6 @@ ChangeMappedDrive( @param[in,out] CmdLine pointer to the command line to update **/ EFI_STATUS -EFIAPI DoHelpUpdate( IN OUT CHAR16 **CmdLine ) @@ -2159,7 +2192,7 @@ DoHelpUpdate( Walker = *CmdLine; while(Walker != NULL && *Walker != CHAR_NULL) { - if (!EFI_ERROR (ShellGetNextParameter (&Walker, CurrentParameter, StrSize(*CmdLine), TRUE))) { + if (!EFI_ERROR(GetNextParameter(&Walker, &CurrentParameter, StrSize(*CmdLine), TRUE))) { if (StrStr(CurrentParameter, L"-?") == CurrentParameter) { CurrentParameter[0] = L' '; CurrentParameter[1] = L' '; @@ -2193,7 +2226,6 @@ DoHelpUpdate( @param[in] ErrorCode the error code to put into lasterror. **/ EFI_STATUS -EFIAPI SetLastError( IN CONST SHELL_STATUS ErrorCode ) @@ -2220,7 +2252,6 @@ SetLastError( @return some other error occurred **/ EFI_STATUS -EFIAPI ProcessCommandLineToFinal( IN OUT CHAR16 **CmdLine ) @@ -2273,7 +2304,6 @@ ProcessCommandLineToFinal( @retval EFI_ABORTED The command's operation was aborted. **/ EFI_STATUS -EFIAPI RunInternalCommand( IN CONST CHAR16 *CmdLine, IN CHAR16 *FirstParameter, @@ -2386,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, @@ -2516,7 +2545,6 @@ RunCommandOrFile( @retval EFI_ABORTED The command's operation was aborted. **/ EFI_STATUS -EFIAPI SetupAndRunCommandOrFile( IN SHELL_OPERATION_TYPES Type, IN CHAR16 *CmdLine, @@ -2579,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 @@ -2590,7 +2617,7 @@ RunShellCommand( CHAR16 *FirstParameter; CHAR16 *TempWalker; SHELL_OPERATION_TYPES Type; - CHAR16 *OldCmdLine; + CONST CHAR16 *CurDir; ASSERT(CmdLine != NULL); if (StrLen(CmdLine) == 0) { @@ -2598,14 +2625,11 @@ RunShellCommand( } Status = EFI_SUCCESS; - FirstParameter = NULL; CleanOriginal = NULL; - OldCmdLine = NULL; CleanOriginal = StrnCatGrow(&CleanOriginal, NULL, CmdLine, 0); if (CleanOriginal == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; + return (EFI_OUT_OF_RESOURCES); } TrimSpaces(&CleanOriginal); @@ -2632,36 +2656,35 @@ RunShellCommand( // Handle case that passed in command line is just 1 or more " " characters. // if (StrLen (CleanOriginal) == 0) { - Status = EFI_SUCCESS; - goto Done; + SHELL_FREE_NON_NULL(CleanOriginal); + return (EFI_SUCCESS); } Status = ProcessCommandLineToFinal(&CleanOriginal); if (EFI_ERROR(Status)) { - goto Done; + SHELL_FREE_NON_NULL(CleanOriginal); + return (Status); } - OldCmdLine = ShellGetRawCmdLine (); - ShellSetRawCmdLine (CleanOriginal); - // // We don't do normal processing with a split command line (output from one command input to another) // if (ContainsSplit(CleanOriginal)) { Status = ProcessNewSplitCommandLine(CleanOriginal); - goto Done; - } + SHELL_FREE_NON_NULL(CleanOriginal); + return (Status); + } // // We need the first parameter information so we can determine the operation type // FirstParameter = AllocateZeroPool(StrSize(CleanOriginal)); if (FirstParameter == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; + SHELL_FREE_NON_NULL(CleanOriginal); + return (EFI_OUT_OF_RESOURCES); } TempWalker = CleanOriginal; - if (!EFI_ERROR (ShellGetNextParameter (&TempWalker, FirstParameter, StrSize(CleanOriginal), TRUE))) { + if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CleanOriginal), TRUE))) { // // Depending on the first parameter we change the behavior // @@ -2686,12 +2709,24 @@ 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; + } + } -Done: - ShellSetRawCmdLine (OldCmdLine); - SHELL_FREE_NON_NULL (OldCmdLine); - SHELL_FREE_NON_NULL (CleanOriginal); - SHELL_FREE_NON_NULL (FirstParameter); + SHELL_FREE_NON_NULL(CleanOriginal); + SHELL_FREE_NON_NULL(FirstParameter); return (Status); } @@ -2708,7 +2743,6 @@ Done: @retval EFI_ABORTED The command's operation was aborted. **/ EFI_STATUS -EFIAPI RunCommand( IN CONST CHAR16 *CmdLine ) @@ -2728,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 ) @@ -2758,7 +2791,6 @@ IsValidCommandName( @retval EFI_SUCCESS the script completed successfully **/ EFI_STATUS -EFIAPI RunScriptFileHandle ( IN SHELL_FILE_HANDLE Handle, IN CONST CHAR16 *Name @@ -3076,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, @@ -3129,3 +3160,36 @@ RunScriptFile ( return (Status); } +/** + Return the pointer to the first occurrence of any character from a list of characters. + + @param[in] String the string to parse + @param[in] CharacterList the list of character to look for + @param[in] EscapeCharacter An escape character to skip + + @return the location of the first character in the string + @retval CHAR_NULL no instance of any character in CharacterList was found in String +**/ +CONST CHAR16* +FindFirstCharacter( + IN CONST CHAR16 *String, + IN CONST CHAR16 *CharacterList, + IN CONST CHAR16 EscapeCharacter + ) +{ + UINT32 WalkChar; + UINT32 WalkStr; + + for (WalkStr = 0; WalkStr < StrLen(String); WalkStr++) { + if (String[WalkStr] == EscapeCharacter) { + WalkStr++; + continue; + } + for (WalkChar = 0; WalkChar < StrLen(CharacterList); WalkChar++) { + if (String[WalkStr] == CharacterList[WalkChar]) { + return (&String[WalkStr]); + } + } + } + return (String + StrLen(String)); +}