summaryrefslogtreecommitdiffstats
path: root/ShellPkg/Application/Shell/Shell.c
diff options
context:
space:
mode:
Diffstat (limited to 'ShellPkg/Application/Shell/Shell.c')
-rw-r--r--ShellPkg/Application/Shell/Shell.c1945
1 files changed, 0 insertions, 1945 deletions
diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c
deleted file mode 100644
index 35ffae8e9c..0000000000
--- a/ShellPkg/Application/Shell/Shell.c
+++ /dev/null
@@ -1,1945 +0,0 @@
-/** @file
- This is THE shell (application)
-
- Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "Shell.h"
-
-//
-// Initialize the global structure
-//
-SHELL_INFO ShellInfoObject = {
- NULL,
- NULL,
- FALSE,
- FALSE,
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- NULL,
- NULL
- },
- {0,0},
- {
- {0,0},
- 0,
- 0,
- TRUE
- },
- NULL,
- 0,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- {0,0,NULL,NULL},
- {0,0},
- NULL,
- NULL,
- NULL,
- NULL,
- FALSE
-};
-
-STATIC CONST CHAR16 mScriptExtension[] = L".NSH";
-STATIC CONST CHAR16 mExecutableExtensions[] = L".NSH;.EFI";
-STATIC CONST CHAR16 mStartupScript[] = L"startup.nsh";
-
-/**
- Function to start monitoring for CTRL-S using SimpleTextInputEx. This
- feature's enabled state was not known when the shell initially launched.
-
- @retval EFI_SUCCESS The feature is enabled.
- @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
-**/
-EFI_STATUS
-EFIAPI
-InternalEfiShellStartCtrlSMonitor(
- VOID
- )
-{
- EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;
- EFI_KEY_DATA KeyData;
- EFI_STATUS Status;
-
- Status = gBS->OpenProtocol(
- gST->ConsoleInHandle,
- &gEfiSimpleTextInputExProtocolGuid,
- (VOID**)&SimpleEx,
- gImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL);
- if (EFI_ERROR(Status)) {
- ShellPrintHiiEx(
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_SHELL_NO_IN_EX),
- ShellInfoObject.HiiHandle);
- return (EFI_SUCCESS);
- }
-
- KeyData.KeyState.KeyToggleState = 0;
- KeyData.Key.ScanCode = 0;
- KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;
- KeyData.Key.UnicodeChar = L's';
-
- Status = SimpleEx->RegisterKeyNotify(
- SimpleEx,
- &KeyData,
- NotificationFunction,
- &ShellInfoObject.CtrlSNotifyHandle1);
-
- KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
- if (!EFI_ERROR(Status)) {
- Status = SimpleEx->RegisterKeyNotify(
- SimpleEx,
- &KeyData,
- NotificationFunction,
- &ShellInfoObject.CtrlSNotifyHandle2);
- }
- KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;
- KeyData.Key.UnicodeChar = 19;
-
- if (!EFI_ERROR(Status)) {
- Status = SimpleEx->RegisterKeyNotify(
- SimpleEx,
- &KeyData,
- NotificationFunction,
- &ShellInfoObject.CtrlSNotifyHandle2);
- }
- KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
- if (!EFI_ERROR(Status)) {
- Status = SimpleEx->RegisterKeyNotify(
- SimpleEx,
- &KeyData,
- NotificationFunction,
- &ShellInfoObject.CtrlSNotifyHandle2);
- }
- return (Status);
-}
-
-
-
-/**
- The entry point for the application.
-
- @param[in] ImageHandle The firmware allocated handle for the EFI image.
- @param[in] SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The entry point is executed successfully.
- @retval other Some error occurs when executing this entry point.
-
-**/
-EFI_STATUS
-EFIAPI
-UefiMain (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- CHAR16 *TempString;
- UINTN Size;
- EFI_HANDLE ConInHandle;
- EFI_SIMPLE_TEXT_INPUT_PROTOCOL *OldConIn;
-
- if (PcdGet8(PcdShellSupportLevel) > 3) {
- return (EFI_UNSUPPORTED);
- }
-
- //
- // Clear the screen
- //
- Status = gST->ConOut->ClearScreen(gST->ConOut);
- if (EFI_ERROR(Status)) {
- return (Status);
- }
-
- //
- // Populate the global structure from PCDs
- //
- ShellInfoObject.ImageDevPath = NULL;
- ShellInfoObject.FileDevPath = NULL;
- ShellInfoObject.PageBreakEnabled = PcdGetBool(PcdShellPageBreakDefault);
- ShellInfoObject.ViewingSettings.InsertMode = PcdGetBool(PcdShellInsertModeDefault);
- ShellInfoObject.LogScreenCount = PcdGet8 (PcdShellScreenLogCount );
-
- //
- // verify we dont allow for spec violation
- //
- ASSERT(ShellInfoObject.LogScreenCount >= 3);
-
- //
- // Initialize the LIST ENTRY objects...
- //
- InitializeListHead(&ShellInfoObject.BufferToFreeList.Link);
- InitializeListHead(&ShellInfoObject.ViewingSettings.CommandHistory.Link);
- InitializeListHead(&ShellInfoObject.SplitList.Link);
-
- //
- // Check PCDs for optional features that are not implemented yet.
- //
- if ( PcdGetBool(PcdShellSupportOldProtocols)
- || !FeaturePcdGet(PcdShellRequireHiiPlatform)
- || FeaturePcdGet(PcdShellSupportFrameworkHii)
- ) {
- return (EFI_UNSUPPORTED);
- }
-
- //
- // turn off the watchdog timer
- //
- gBS->SetWatchdogTimer (0, 0, 0, NULL);
-
- //
- // install our console logger. This will keep a log of the output for back-browsing
- //
- Status = ConsoleLoggerInstall(ShellInfoObject.LogScreenCount, &ShellInfoObject.ConsoleInfo);
- if (!EFI_ERROR(Status)) {
- //
- // Enable the cursor to be visible
- //
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);
-
- //
- // If supporting EFI 1.1 we need to install HII protocol
- // only do this if PcdShellRequireHiiPlatform == FALSE
- //
- // remove EFI_UNSUPPORTED check above when complete.
- ///@todo add support for Framework HII
-
- //
- // install our (solitary) HII package
- //
- ShellInfoObject.HiiHandle = HiiAddPackages (&gEfiCallerIdGuid, gImageHandle, ShellStrings, NULL);
- if (ShellInfoObject.HiiHandle == NULL) {
- if (PcdGetBool(PcdShellSupportFrameworkHii)) {
- ///@todo Add our package into Framework HII
- }
- if (ShellInfoObject.HiiHandle == NULL) {
- return (EFI_NOT_STARTED);
- }
- }
-
- //
- // create and install the EfiShellParametersProtocol
- //
- Status = CreatePopulateInstallShellParametersProtocol(&ShellInfoObject.NewShellParametersProtocol, &ShellInfoObject.RootShellInstance);
- ASSERT_EFI_ERROR(Status);
- ASSERT(ShellInfoObject.NewShellParametersProtocol != NULL);
-
- //
- // create and install the EfiShellProtocol
- //
- Status = CreatePopulateInstallShellProtocol(&ShellInfoObject.NewEfiShellProtocol);
- ASSERT_EFI_ERROR(Status);
- ASSERT(ShellInfoObject.NewEfiShellProtocol != NULL);
-
- //
- // Now initialize the shell library (it requires Shell Parameters protocol)
- //
- Status = ShellInitialize();
- ASSERT_EFI_ERROR(Status);
-
- Status = CommandInit();
- ASSERT_EFI_ERROR(Status);
-
- //
- // Check the command line
- //
- Status = ProcessCommandLine();
-
- //
- // If shell support level is >= 1 create the mappings and paths
- //
- if (PcdGet8(PcdShellSupportLevel) >= 1) {
- Status = ShellCommandCreateInitialMappingsAndPaths();
- }
-
- //
- // 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
- //
- Status = GetDevicePathsForImageAndFile(&ShellInfoObject.ImageDevPath, &ShellInfoObject.FileDevPath);
- ASSERT_EFI_ERROR(Status);
-
- //
- // Display the version
- //
- if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion) {
- ShellPrintHiiEx (
- 0,
- gST->ConOut->Mode->CursorRow,
- NULL,
- STRING_TOKEN (STR_VER_OUTPUT_MAIN),
- ShellInfoObject.HiiHandle,
- SupportLevel[PcdGet8(PcdShellSupportLevel)],
- gEfiShellProtocol->MajorVersion,
- gEfiShellProtocol->MinorVersion,
- (gST->Hdr.Revision&0xffff0000)>>16,
- (gST->Hdr.Revision&0x0000ffff),
- gST->FirmwareVendor,
- gST->FirmwareRevision
- );
- }
-
- //
- // Display the mapping
- //
- if (PcdGet8(PcdShellSupportLevel) >= 2 && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap) {
- Status = RunCommand(L"map");
- ASSERT_EFI_ERROR(Status);
- }
-
- //
- // init all the built in alias'
- //
- Status = SetBuiltInAlias();
- ASSERT_EFI_ERROR(Status);
-
- //
- // Initialize environment variables
- //
- if (ShellCommandGetProfileList() != NULL) {
- Status = InternalEfiShellSetEnv(L"profiles", ShellCommandGetProfileList(), TRUE);
- ASSERT_EFI_ERROR(Status);
- }
-
- Size = 100;
- TempString = AllocateZeroPool(Size);
-
- UnicodeSPrint(TempString, Size, L"%d", PcdGet8(PcdShellSupportLevel));
- Status = InternalEfiShellSetEnv(L"uefishellsupport", TempString, TRUE);
- ASSERT_EFI_ERROR(Status);
-
- UnicodeSPrint(TempString, Size, L"%d.%d", ShellInfoObject.NewEfiShellProtocol->MajorVersion, ShellInfoObject.NewEfiShellProtocol->MinorVersion);
- Status = InternalEfiShellSetEnv(L"uefishellversion", TempString, TRUE);
- ASSERT_EFI_ERROR(Status);
-
- UnicodeSPrint(TempString, Size, L"%d.%d", (gST->Hdr.Revision & 0xFFFF0000) >> 16, gST->Hdr.Revision & 0x0000FFFF);
- Status = InternalEfiShellSetEnv(L"uefiversion", TempString, TRUE);
- ASSERT_EFI_ERROR(Status);
-
- FreePool(TempString);
-
- if (!EFI_ERROR(Status)) {
- if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt) {
- //
- // Set up the event for CTRL-C monitoring...
- //
- Status = InernalEfiShellStartMonitor();
- }
-
- if (!EFI_ERROR(Status) && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {
- //
- // Set up the event for CTRL-S monitoring...
- //
- Status = InternalEfiShellStartCtrlSMonitor();
- }
-
- if (!EFI_ERROR(Status) && ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {
- //
- // close off the gST->ConIn
- //
- OldConIn = gST->ConIn;
- ConInHandle = gST->ConsoleInHandle;
- gST->ConIn = CreateSimpleTextInOnFile((SHELL_FILE_HANDLE)&FileInterfaceNulFile, &gST->ConsoleInHandle);
- } else {
- OldConIn = NULL;
- ConInHandle = NULL;
- }
-
- if (!EFI_ERROR(Status) && PcdGet8(PcdShellSupportLevel) >= 1) {
- //
- // process the startup script or launch the called app.
- //
- Status = DoStartupScript(ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath);
- }
-
- if (!ShellCommandGetExit() && (PcdGet8(PcdShellSupportLevel) >= 3 || PcdGetBool(PcdShellForceConsole)) && !EFI_ERROR(Status) && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {
- //
- // begin the UI waiting loop
- //
- do {
- //
- // clean out all the memory allocated for CONST <something> * return values
- // between each shell prompt presentation
- //
- if (!IsListEmpty(&ShellInfoObject.BufferToFreeList.Link)){
- FreeBufferList(&ShellInfoObject.BufferToFreeList);
- }
-
- //
- // Reset page break back to default.
- //
- ShellInfoObject.PageBreakEnabled = PcdGetBool(PcdShellPageBreakDefault);
- ShellInfoObject.ConsoleInfo->Enabled = TRUE;
- ShellInfoObject.ConsoleInfo->RowCounter = 0;
-
- //
- // Reset the CTRL-C event (yes we ignore the return values)
- //
- Status = gBS->CheckEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak);
-
- //
- // Display Prompt
- //
- Status = DoShellPrompt();
- } while (!ShellCommandGetExit());
- }
- if (OldConIn != NULL && ConInHandle != NULL) {
- CloseSimpleTextInOnFile (gST->ConIn);
- gST->ConIn = OldConIn;
- gST->ConsoleInHandle = ConInHandle;
- }
- }
- }
-
- //
- // uninstall protocols / free memory / etc...
- //
- if (ShellInfoObject.UserBreakTimer != NULL) {
- gBS->CloseEvent(ShellInfoObject.UserBreakTimer);
- DEBUG_CODE(ShellInfoObject.UserBreakTimer = NULL;);
- }
- if (ShellInfoObject.ImageDevPath != NULL) {
- FreePool(ShellInfoObject.ImageDevPath);
- DEBUG_CODE(ShellInfoObject.ImageDevPath = NULL;);
- }
- if (ShellInfoObject.FileDevPath != NULL) {
- FreePool(ShellInfoObject.FileDevPath);
- DEBUG_CODE(ShellInfoObject.FileDevPath = NULL;);
- }
- if (ShellInfoObject.NewShellParametersProtocol != NULL) {
- CleanUpShellParametersProtocol(ShellInfoObject.NewShellParametersProtocol);
- DEBUG_CODE(ShellInfoObject.NewShellParametersProtocol = NULL;);
- }
- if (ShellInfoObject.NewEfiShellProtocol != NULL){
- if (ShellInfoObject.NewEfiShellProtocol->IsRootShell()){
- ShellInfoObject.NewEfiShellProtocol->SetEnv(L"cwd", L"", TRUE);
- }
- CleanUpShellProtocol(ShellInfoObject.NewEfiShellProtocol);
- DEBUG_CODE(ShellInfoObject.NewEfiShellProtocol = NULL;);
- }
-
- if (!IsListEmpty(&ShellInfoObject.BufferToFreeList.Link)){
- FreeBufferList(&ShellInfoObject.BufferToFreeList);
- }
-
- if (!IsListEmpty(&ShellInfoObject.SplitList.Link)){
- ASSERT(FALSE); ///@todo finish this de-allocation.
- }
-
- if (ShellInfoObject.ShellInitSettings.FileName != NULL) {
- FreePool(ShellInfoObject.ShellInitSettings.FileName);
- DEBUG_CODE(ShellInfoObject.ShellInitSettings.FileName = NULL;);
- }
-
- if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {
- FreePool(ShellInfoObject.ShellInitSettings.FileOptions);
- DEBUG_CODE(ShellInfoObject.ShellInitSettings.FileOptions = NULL;);
- }
-
- if (ShellInfoObject.HiiHandle != NULL) {
- HiiRemovePackages(ShellInfoObject.HiiHandle);
- DEBUG_CODE(ShellInfoObject.HiiHandle = NULL;);
- }
-
- if (!IsListEmpty(&ShellInfoObject.ViewingSettings.CommandHistory.Link)){
- FreeBufferList(&ShellInfoObject.ViewingSettings.CommandHistory);
- }
-
- ASSERT(ShellInfoObject.ConsoleInfo != NULL);
- if (ShellInfoObject.ConsoleInfo != NULL) {
- ConsoleLoggerUninstall(ShellInfoObject.ConsoleInfo);
- FreePool(ShellInfoObject.ConsoleInfo);
- DEBUG_CODE(ShellInfoObject.ConsoleInfo = NULL;);
- }
-
- if (ShellCommandGetExit()) {
- return ((EFI_STATUS)ShellCommandGetExitCode());
- }
- return (Status);
-}
-
-/**
- Sets all the alias' that were registered with the ShellCommandLib library.
-
- @retval EFI_SUCCESS all init commands were run sucessfully.
-**/
-EFI_STATUS
-EFIAPI
-SetBuiltInAlias(
- )
-{
- EFI_STATUS Status;
- CONST ALIAS_LIST *List;
- ALIAS_LIST *Node;
-
- //
- // Get all the commands we want to run
- //
- List = ShellCommandGetInitAliasList();
-
- //
- // for each command in the List
- //
- for ( Node = (ALIAS_LIST*)GetFirstNode(&List->Link)
- ; !IsNull (&List->Link, &Node->Link)
- ; Node = (ALIAS_LIST *)GetNextNode(&List->Link, &Node->Link)
- ){
- //
- // install the alias'
- //
- Status = InternalSetAlias(Node->CommandString, Node->Alias, TRUE);
- ASSERT_EFI_ERROR(Status);
- }
- return (EFI_SUCCESS);
-}
-
-/**
- Internal function to determine if 2 command names are really the same.
-
- @param[in] Command1 The pointer to the first command name.
- @param[in] Command2 The pointer to the second command name.
-
- @retval TRUE The 2 command names are the same.
- @retval FALSE The 2 command names are not the same.
-**/
-BOOLEAN
-EFIAPI
-IsCommand(
- IN CONST CHAR16 *Command1,
- IN CONST CHAR16 *Command2
- )
-{
- if (StringNoCaseCompare(&Command1, &Command2) == 0) {
- return (TRUE);
- }
- return (FALSE);
-}
-
-/**
- Internal function to determine if a command is a script only command.
-
- @param[in] CommandName The pointer to the command name.
-
- @retval TRUE The command is a script only command.
- @retval FALSE The command is not a script only command.
-**/
-BOOLEAN
-EFIAPI
-IsScriptOnlyCommand(
- IN CONST CHAR16 *CommandName
- )
-{
- if (IsCommand(CommandName, L"for")
- ||IsCommand(CommandName, L"endfor")
- ||IsCommand(CommandName, L"if")
- ||IsCommand(CommandName, L"else")
- ||IsCommand(CommandName, L"endif")
- ||IsCommand(CommandName, L"goto")) {
- return (TRUE);
- }
- return (FALSE);
-}
-
-/**
- This function will populate the 2 device path protocol parameters based on the
- global gImageHandle. The DevPath will point to the device path for the handle that has
- loaded image protocol installed on it. The FilePath will point to the device path
- for the file that was loaded.
-
- @param[in, out] DevPath On a sucessful return the device path to the loaded image.
- @param[in, out] FilePath On a sucessful return the device path to the file.
-
- @retval EFI_SUCCESS The 2 device paths were sucessfully returned.
- @retval other A error from gBS->HandleProtocol.
-
- @sa HandleProtocol
-**/
-EFI_STATUS
-EFIAPI
-GetDevicePathsForImageAndFile (
- IN OUT EFI_DEVICE_PATH_PROTOCOL **DevPath,
- IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath
- )
-{
- EFI_STATUS Status;
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
- EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
-
- ASSERT(DevPath != NULL);
- ASSERT(FilePath != NULL);
-
- Status = gBS->OpenProtocol (
- gImageHandle,
- &gEfiLoadedImageProtocolGuid,
- (VOID**)&LoadedImage,
- gImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (!EFI_ERROR (Status)) {
- Status = gBS->OpenProtocol (
- LoadedImage->DeviceHandle,
- &gEfiDevicePathProtocolGuid,
- (VOID**)&ImageDevicePath,
- gImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (!EFI_ERROR (Status)) {
- *DevPath = DuplicateDevicePath (ImageDevicePath);
- *FilePath = DuplicateDevicePath (LoadedImage->FilePath);
- gBS->CloseProtocol(
- LoadedImage->DeviceHandle,
- &gEfiDevicePathProtocolGuid,
- gImageHandle,
- NULL);
- }
- gBS->CloseProtocol(
- gImageHandle,
- &gEfiLoadedImageProtocolGuid,
- gImageHandle,
- NULL);
- }
- return (Status);
-}
-
-STATIC CONST SHELL_PARAM_ITEM mShellParamList[] = {
- {L"-nostartup", TypeFlag},
- {L"-startup", TypeFlag},
- {L"-noconsoleout", TypeFlag},
- {L"-noconsolein", TypeFlag},
- {L"-nointerrupt", TypeFlag},
- {L"-nomap", TypeFlag},
- {L"-noversion", TypeFlag},
- {L"-startup", TypeFlag},
- {L"-delay", TypeValue},
- {NULL, TypeMax}
- };
-
-/**
- Process all Uefi Shell 2.0 command line options.
-
- see Uefi Shell 2.0 section 3.2 for full details.
-
- the command line must resemble the following:
-
- shell.efi [ShellOpt-options] [options] [file-name [file-name-options]]
-
- ShellOpt-options Options which control the initialization behavior of the shell.
- These options are read from the EFI global variable "ShellOpt"
- and are processed before options or file-name.
-
- options Options which control the initialization behavior of the shell.
-
- file-name The name of a UEFI shell application or script to be executed
- after initialization is complete. By default, if file-name is
- specified, then -nostartup is implied. Scripts are not supported
- by level 0.
-
- file-name-options The command-line options that are passed to file-name when it
- is invoked.
-
- This will initialize the ShellInfoObject.ShellInitSettings global variable.
-
- @retval EFI_SUCCESS The variable is initialized.
-**/
-EFI_STATUS
-EFIAPI
-ProcessCommandLine(
- VOID
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Package;
- UINTN Size;
- CONST CHAR16 *TempConst;
- UINTN Count;
- UINTN LoopVar;
- CHAR16 *ProblemParam;
- UINT64 Intermediate;
-
- Package = NULL;
- ProblemParam = NULL;
-
- Status = ShellCommandLineParse (mShellParamList, &Package, NULL, FALSE);
-
- Count = 1;
- Size = 0;
- TempConst = ShellCommandLineGetRawValue(Package, Count++);
- if (TempConst != NULL && StrLen(TempConst)) {
- ShellInfoObject.ShellInitSettings.FileName = AllocateZeroPool(StrSize(TempConst));
- if (ShellInfoObject.ShellInitSettings.FileName == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
- StrCpy(ShellInfoObject.ShellInitSettings.FileName, TempConst);
- ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = 1;
- for (LoopVar = 0 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) {
- if (StrCmp(gEfiShellParametersProtocol->Argv[LoopVar], ShellInfoObject.ShellInitSettings.FileName)==0) {
- LoopVar++;
- //
- // We found the file... add the rest of the params...
- //
- for ( ; 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);
- }
- StrnCatGrow(&ShellInfoObject.ShellInitSettings.FileOptions,
- &Size,
- gEfiShellParametersProtocol->Argv[LoopVar],
- 0);
- if (ShellInfoObject.ShellInitSettings.FileOptions == NULL) {
- SHELL_FREE_NON_NULL(ShellInfoObject.ShellInitSettings.FileName);
- return (EFI_OUT_OF_RESOURCES);
- }
- }
- }
- }
- } else {
- ShellCommandLineFreeVarList(Package);
- Package = NULL;
- Status = ShellCommandLineParse (mShellParamList, &Package, &ProblemParam, FALSE);
- if (EFI_ERROR(Status)) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), ShellInfoObject.HiiHandle, ProblemParam);
- FreePool(ProblemParam);
- ShellCommandLineFreeVarList(Package);
- return (EFI_INVALID_PARAMETER);
- }
- }
-
- ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup = ShellCommandLineGetFlag(Package, L"-startup");
- ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = ShellCommandLineGetFlag(Package, L"-nostartup");
- ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut = ShellCommandLineGetFlag(Package, L"-noconsoleout");
- ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn = ShellCommandLineGetFlag(Package, L"-noconsolein");
- ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt = ShellCommandLineGetFlag(Package, L"-nointerrupt");
- ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap = ShellCommandLineGetFlag(Package, L"-nomap");
- ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion = ShellCommandLineGetFlag(Package, L"-noversion");
- ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay = ShellCommandLineGetFlag(Package, L"-delay");
-
- ShellInfoObject.ShellInitSettings.Delay = 5;
-
- if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoInterrupt) {
- ShellInfoObject.ShellInitSettings.Delay = 0;
- } else if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay) {
- TempConst = ShellCommandLineGetValue(Package, L"-delay");
- if (TempConst != NULL && *TempConst == L':') {
- TempConst++;
- }
- if (TempConst != NULL && !EFI_ERROR(ShellConvertStringToUint64(TempConst, &Intermediate, FALSE, FALSE))) {
- ShellInfoObject.ShellInitSettings.Delay = (UINTN)Intermediate;
- }
- }
- ShellCommandLineFreeVarList(Package);
-
- return (Status);
-}
-
-/**
- Handles all interaction with the default startup script.
-
- this will check that the correct command line parameters were passed, handle the delay, and then start running the script.
-
- @param ImagePath the path to the image for shell. first place to look for the startup script
- @param FilePath the path to the file for shell. second place to look for the startup script.
-
- @retval EFI_SUCCESS the variable is initialized.
-**/
-EFI_STATUS
-EFIAPI
-DoStartupScript(
- EFI_DEVICE_PATH_PROTOCOL *ImagePath,
- EFI_DEVICE_PATH_PROTOCOL *FilePath
- )
-{
- EFI_STATUS Status;
- 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) {
- //
- // launch something else instead
- //
- NewSize = StrSize(ShellInfoObject.ShellInitSettings.FileName);
- if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {
- NewSize += StrSize(ShellInfoObject.ShellInitSettings.FileOptions) + sizeof(CHAR16);
- }
- FileStringPath = AllocateZeroPool(NewSize);
- if (FileStringPath == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
- StrCpy(FileStringPath, ShellInfoObject.ShellInitSettings.FileName);
- if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) {
- StrCat(FileStringPath, L" ");
- StrCat(FileStringPath, ShellInfoObject.ShellInitSettings.FileOptions);
- }
- Status = RunCommand(FileStringPath);
- FreePool(FileStringPath);
- return (Status);
-
- }
-
- //
- // for shell level 0 we do no scripts
- // Without the Startup bit overriding we allow for nostartup to prevent scripts
- //
- if ( (PcdGet8(PcdShellSupportLevel) < 1)
- || (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.Startup)
- ){
- return (EFI_SUCCESS);
- }
-
- gST->ConOut->EnableCursor(gST->ConOut, FALSE);
- //
- // print out our warning and see if they press a key
- //
- for ( Status = EFI_UNSUPPORTED, Delay = ShellInfoObject.ShellInitSettings.Delay * 10
- ; Delay != 0 && EFI_ERROR(Status)
- ; Delay--
- ){
- ShellPrintHiiEx(0, gST->ConOut->Mode->CursorRow, NULL, STRING_TOKEN (STR_SHELL_STARTUP_QUESTION), ShellInfoObject.HiiHandle, Delay/10);
- gBS->Stall (100000);
- if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {
- Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
- }
- }
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_CRLF), ShellInfoObject.HiiHandle);
- gST->ConOut->EnableCursor(gST->ConOut, TRUE);
-
- //
- // ESC was pressed
- //
- if (Status == EFI_SUCCESS && Key.UnicodeChar == 0 && Key.ScanCode == SCAN_ESC) {
- 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);
-
- //
- // Try the location
- //
- 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 = RunScriptFileHandle (FileHandle, mStartupScript);
- ShellInfoObject.NewEfiShellProtocol->CloseFile(FileHandle);
- } else {
- FileStringPath = ShellFindFilePath(mStartupScript);
- if (FileStringPath == NULL) {
- //
- // we return success since we dont need to have a startup script
- //
- Status = EFI_SUCCESS;
- ASSERT(FileHandle == NULL);
- } else {
- Status = RunScriptFile(FileStringPath);
- FreePool(FileStringPath);
- }
- }
-
-
- return (Status);
-}
-
-/**
- Function to perform the shell prompt looping. It will do a single prompt,
- dispatch the result, and then return. It is expected that the caller will
- call this function in a loop many times.
-
- @retval EFI_SUCCESS
- @retval RETURN_ABORTED
-**/
-EFI_STATUS
-EFIAPI
-DoShellPrompt (
- VOID
- )
-{
- UINTN Column;
- UINTN Row;
- CHAR16 *CmdLine;
- CONST CHAR16 *CurDir;
- UINTN BufferSize;
- EFI_STATUS Status;
-
- CurDir = NULL;
-
- //
- // Get screen setting to decide size of the command line buffer
- //
- gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Column, &Row);
- BufferSize = Column * Row * sizeof (CHAR16);
- CmdLine = AllocateZeroPool (BufferSize);
- if (CmdLine == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- CurDir = ShellInfoObject.NewEfiShellProtocol->GetEnv(L"cwd");
-
- //
- // Prompt for input
- //
- gST->ConOut->SetCursorPosition (gST->ConOut, 0, gST->ConOut->Mode->CursorRow);
-
- if (CurDir != NULL && StrLen(CurDir) > 1) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_CURDIR), ShellInfoObject.HiiHandle, CurDir);
- } else {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_SHELL), ShellInfoObject.HiiHandle);
- }
-
- //
- // Read a line from the console
- //
- Status = ShellInfoObject.NewEfiShellProtocol->ReadFile(ShellInfoObject.NewShellParametersProtocol->StdIn, &BufferSize, CmdLine);
-
- //
- // Null terminate the string and parse it
- //
- if (!EFI_ERROR (Status)) {
- CmdLine[BufferSize / sizeof (CHAR16)] = CHAR_NULL;
- Status = RunCommand(CmdLine);
- }
-
- //
- // Done with this command
- //
- FreePool (CmdLine);
- return Status;
-}
-
-/**
- Add a buffer to the Buffer To Free List for safely returning buffers to other
- places without risking letting them modify internal shell information.
-
- @param Buffer Something to pass to FreePool when the shell is exiting.
-**/
-VOID*
-EFIAPI
-AddBufferToFreeList(
- VOID *Buffer
- )
-{
- BUFFER_LIST *BufferListEntry;
-
- if (Buffer == NULL) {
- return (NULL);
- }
-
- BufferListEntry = AllocateZeroPool(sizeof(BUFFER_LIST));
- ASSERT(BufferListEntry != NULL);
- BufferListEntry->Buffer = Buffer;
- InsertTailList(&ShellInfoObject.BufferToFreeList.Link, &BufferListEntry->Link);
- return (Buffer);
-}
-
-/**
- Add a buffer to the Line History List
-
- @param Buffer The line buffer to add.
-**/
-VOID
-EFIAPI
-AddLineToCommandHistory(
- IN CONST CHAR16 *Buffer
- )
-{
- BUFFER_LIST *Node;
-
- Node = AllocateZeroPool(sizeof(BUFFER_LIST));
- ASSERT(Node != NULL);
- Node->Buffer = AllocateZeroPool(StrSize(Buffer));
- ASSERT(Node->Buffer != NULL);
- StrCpy(Node->Buffer, Buffer);
-
- InsertTailList(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link);
-}
-
-/**
- Checks if a string is an alias for another command. If yes, then it replaces the alias name
- with the correct command name.
-
- @param[in, out] CommandString Upon entry the potential alias. Upon return the
- command name if it was an alias. If it was not
- an alias it will be unchanged. This function may
- change the buffer to fit the command name.
-
- @retval EFI_SUCCESS The name was changed.
- @retval EFI_SUCCESS The name was not an alias.
- @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
-**/
-EFI_STATUS
-EFIAPI
-ShellConvertAlias(
- IN OUT CHAR16 **CommandString
- )
-{
- CONST CHAR16 *NewString;
-
- NewString = ShellInfoObject.NewEfiShellProtocol->GetAlias(*CommandString, NULL);
- if (NewString == NULL) {
- return (EFI_SUCCESS);
- }
- FreePool(*CommandString);
- *CommandString = AllocateZeroPool(StrSize(NewString));
- if (*CommandString == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
- StrCpy(*CommandString, NewString);
- return (EFI_SUCCESS);
-}
-
-/**
- Function allocates a new command line and replaces all instances of environment
- variable names that are correctly preset to their values.
-
- If the return value is not NULL the memory must be caller freed.
-
- @param[in] OriginalCommandLine The original command line
-
- @retval NULL An error ocurred.
- @return The new command line with no environment variables present.
-**/
-CHAR16*
-EFIAPI
-ShellConvertVariables (
- IN CONST CHAR16 *OriginalCommandLine
- )
-{
- CONST CHAR16 *MasterEnvList;
- UINTN NewSize;
- CHAR16 *NewCommandLine1;
- CHAR16 *NewCommandLine2;
- CHAR16 *Temp;
- UINTN ItemSize;
- CHAR16 *ItemTemp;
- SCRIPT_FILE *CurrentScriptFile;
- ALIAS_LIST *AliasListNode;
-
- ASSERT(OriginalCommandLine != NULL);
-
- ItemSize = 0;
- NewSize = StrSize(OriginalCommandLine);
- CurrentScriptFile = ShellCommandGetCurrentScriptFile();
- Temp = NULL;
-
- ///@todo update this to handle the %0 - %9 for scripting only (borrow from line 1256 area) ? ? ?
-
- //
- // calculate the size required for the post-conversion string...
- //
- if (CurrentScriptFile != NULL) {
- for (AliasListNode = (ALIAS_LIST*)GetFirstNode(&CurrentScriptFile->SubstList)
- ; !IsNull(&CurrentScriptFile->SubstList, &AliasListNode->Link)
- ; AliasListNode = (ALIAS_LIST*)GetNextNode(&CurrentScriptFile->SubstList, &AliasListNode->Link)
- ){
- for (Temp = StrStr(OriginalCommandLine, AliasListNode->Alias)
- ; Temp != NULL
- ; Temp = StrStr(Temp+1, AliasListNode->Alias)
- ){
- //
- // we need a preceeding and if there is space no ^ preceeding (if no space ignore)
- //
- if ((((Temp-OriginalCommandLine)>2) && *(Temp-2) != L'^') || ((Temp-OriginalCommandLine)<=2)) {
- NewSize += StrSize(AliasListNode->CommandString);
- }
- }
- }
- }
-
- for (MasterEnvList = EfiShellGetEnv(NULL)
- ; MasterEnvList != NULL && *MasterEnvList != CHAR_NULL //&& *(MasterEnvList+1) != CHAR_NULL
- ; MasterEnvList += StrLen(MasterEnvList) + 1
- ){
- if (StrSize(MasterEnvList) > ItemSize) {
- ItemSize = StrSize(MasterEnvList);
- }
- for (Temp = StrStr(OriginalCommandLine, MasterEnvList)
- ; Temp != NULL
- ; Temp = StrStr(Temp+1, MasterEnvList)
- ){
- //
- // we need a preceeding and following % and if there is space no ^ preceeding (if no space ignore)
- //
- if (*(Temp-1) == L'%' && *(Temp+StrLen(MasterEnvList)) == L'%' &&
- ((((Temp-OriginalCommandLine)>2) && *(Temp-2) != L'^') || ((Temp-OriginalCommandLine)<=2))) {
- NewSize+=StrSize(EfiShellGetEnv(MasterEnvList));
- }
- }
- }
-
- //
- // Quick out if none were found...
- //
- if (NewSize == StrSize(OriginalCommandLine)) {
- ASSERT(Temp == NULL);
- Temp = StrnCatGrow(&Temp, NULL, OriginalCommandLine, 0);
- return (Temp);
- }
-
- //
- // now do the replacements...
- //
- NewCommandLine1 = AllocateZeroPool(NewSize);
- NewCommandLine2 = AllocateZeroPool(NewSize);
- ItemTemp = AllocateZeroPool(ItemSize+(2*sizeof(CHAR16)));
- if (NewCommandLine1 == NULL || NewCommandLine2 == NULL || ItemTemp == NULL) {
- SHELL_FREE_NON_NULL(NewCommandLine1);
- SHELL_FREE_NON_NULL(NewCommandLine2);
- SHELL_FREE_NON_NULL(ItemTemp);
- return (NULL);
- }
- StrCpy(NewCommandLine1, OriginalCommandLine);
- for (MasterEnvList = EfiShellGetEnv(NULL)
- ; MasterEnvList != NULL && *MasterEnvList != CHAR_NULL //&& *(MasterEnvList+1) != CHAR_NULL
- ; MasterEnvList += StrLen(MasterEnvList) + 1
- ){
- StrCpy(ItemTemp, L"%");
- StrCat(ItemTemp, MasterEnvList);
- StrCat(ItemTemp, L"%");
- ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, ItemTemp, EfiShellGetEnv(MasterEnvList), TRUE, FALSE);
- StrCpy(NewCommandLine1, NewCommandLine2);
- }
- if (CurrentScriptFile != NULL) {
- for (AliasListNode = (ALIAS_LIST*)GetFirstNode(&CurrentScriptFile->SubstList)
- ; !IsNull(&CurrentScriptFile->SubstList, &AliasListNode->Link)
- ; AliasListNode = (ALIAS_LIST*)GetNextNode(&CurrentScriptFile->SubstList, &AliasListNode->Link)
- ){
- ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, AliasListNode->Alias, AliasListNode->CommandString, TRUE, FALSE);
- StrCpy(NewCommandLine1, NewCommandLine2);
- }
- }
-
- FreePool(NewCommandLine2);
- FreePool(ItemTemp);
-
- return (NewCommandLine1);
-}
-
-/**
- Internal function to run a command line with pipe usage.
-
- @param[in] CmdLine The pointer to the command line.
- @param[in] StdIn The pointer to the Standard input.
- @param[in] StdOut The pointer to the Standard output.
-
- @retval EFI_SUCCESS The split command is executed successfully.
- @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
- )
-{
- EFI_STATUS Status;
- CHAR16 *NextCommandLine;
- CHAR16 *OurCommandLine;
- UINTN Size1;
- UINTN Size2;
- SPLIT_LIST *Split;
- SHELL_FILE_HANDLE *TempFileHandle;
- BOOLEAN Unicode;
-
- ASSERT(StdOut == NULL);
-
- ASSERT(StrStr(CmdLine, L"|") != NULL);
-
- Status = EFI_SUCCESS;
- NextCommandLine = NULL;
- OurCommandLine = NULL;
- Size1 = 0;
- Size2 = 0;
-
- NextCommandLine = StrnCatGrow(&NextCommandLine, &Size1, StrStr(CmdLine, L"|")+1, 0);
- OurCommandLine = StrnCatGrow(&OurCommandLine , &Size2, CmdLine , StrStr(CmdLine, L"|") - CmdLine);
-
- if (NextCommandLine == NULL || OurCommandLine == NULL) {
- SHELL_FREE_NON_NULL(OurCommandLine);
- SHELL_FREE_NON_NULL(NextCommandLine);
- return (EFI_OUT_OF_RESOURCES);
- } else if (StrStr(OurCommandLine, L"|") != NULL || Size1 == 0 || Size2 == 0) {
- SHELL_FREE_NON_NULL(OurCommandLine);
- SHELL_FREE_NON_NULL(NextCommandLine);
- return (EFI_INVALID_PARAMETER);
- } else if (NextCommandLine[0] != CHAR_NULL &&
- NextCommandLine[0] == L'a' &&
- NextCommandLine[1] == L' '
- ){
- CopyMem(NextCommandLine, NextCommandLine+1, StrSize(NextCommandLine) - sizeof(NextCommandLine[0]));
- Unicode = FALSE;
- } else {
- Unicode = TRUE;
- }
-
-
- //
- // make a SPLIT_LIST item and add to list
- //
- Split = AllocateZeroPool(sizeof(SPLIT_LIST));
- ASSERT(Split != NULL);
- Split->SplitStdIn = StdIn;
- Split->SplitStdOut = ConvertEfiFileProtocolToShellHandle(CreateFileInterfaceMem(Unicode), NULL);
- ASSERT(Split->SplitStdOut != NULL);
- InsertHeadList(&ShellInfoObject.SplitList.Link, &Split->Link);
-
- Status = RunCommand(OurCommandLine);
-
- //
- // move the output from the first to the in to the second.
- //
- TempFileHandle = Split->SplitStdOut;
- if (Split->SplitStdIn == StdIn) {
- Split->SplitStdOut = NULL;
- } else {
- Split->SplitStdOut = Split->SplitStdIn;
- }
- Split->SplitStdIn = TempFileHandle;
- ShellInfoObject.NewEfiShellProtocol->SetFilePosition(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn), 0);
-
- if (!EFI_ERROR(Status)) {
- Status = RunCommand(NextCommandLine);
- }
-
- //
- // remove the top level from the ScriptList
- //
- ASSERT((SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link) == Split);
- RemoveEntryList(&Split->Link);
-
- //
- // Note that the original StdIn is now the StdOut...
- //
- if (Split->SplitStdOut != NULL && Split->SplitStdOut != StdIn) {
- ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdOut));
- }
- if (Split->SplitStdIn != NULL) {
- ShellInfoObject.NewEfiShellProtocol->CloseFile(ConvertShellHandleToEfiFileProtocol(Split->SplitStdIn));
- }
-
- FreePool(Split);
- FreePool(NextCommandLine);
- FreePool(OurCommandLine);
-
- return (Status);
-}
-
-/**
- Function will process and run a command line.
-
- This will determine if the command line represents an internal shell
- command or dispatch an external application.
-
- @param[in] CmdLine The command line to parse.
-
- @retval EFI_SUCCESS The command was completed.
- @retval EFI_ABORTED The command's operation was aborted.
-**/
-EFI_STATUS
-EFIAPI
-RunCommand(
- IN CONST CHAR16 *CmdLine
- )
-{
- EFI_STATUS Status;
- EFI_STATUS StatusCode;
- CHAR16 *CommandName;
- SHELL_STATUS ShellStatus;
- UINTN Argc;
- CHAR16 **Argv;
- BOOLEAN LastError;
- CHAR16 LeString[11];
- CHAR16 *PostAliasCmdLine;
- UINTN PostAliasSize;
- CHAR16 *PostVariableCmdLine;
- CHAR16 *CommandWithPath;
- CONST EFI_DEVICE_PATH_PROTOCOL *DevPath;
- CONST CHAR16 *TempLocation;
- CONST CHAR16 *TempLocation2;
- SHELL_FILE_HANDLE OriginalStdIn;
- SHELL_FILE_HANDLE OriginalStdOut;
- SHELL_FILE_HANDLE OriginalStdErr;
- SYSTEM_TABLE_INFO OriginalSystemTableInfo;
- CHAR16 *TempLocation3;
- UINTN Count;
- UINTN Count2;
- CHAR16 *CleanOriginal;
- SPLIT_LIST *Split;
-
- ASSERT(CmdLine != NULL);
- if (StrLen(CmdLine) == 0) {
- return (EFI_SUCCESS);
- }
-
- CommandName = NULL;
- PostVariableCmdLine = NULL;
- PostAliasCmdLine = NULL;
- CommandWithPath = NULL;
- DevPath = NULL;
- Status = EFI_SUCCESS;
- CleanOriginal = NULL;
- Split = NULL;
-
- CleanOriginal = StrnCatGrow(&CleanOriginal, NULL, CmdLine, 0);
- if (CleanOriginal == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
- while (CleanOriginal[StrLen(CleanOriginal)-1] == L' ') {
- CleanOriginal[StrLen(CleanOriginal)-1] = CHAR_NULL;
- }
- while (CleanOriginal[0] == L' ') {
- CopyMem(CleanOriginal, CleanOriginal+1, StrSize(CleanOriginal) - sizeof(CleanOriginal[0]));
- }
-
- CommandName = NULL;
- if (StrStr(CleanOriginal, L" ") == NULL){
- StrnCatGrow(&CommandName, NULL, CleanOriginal, 0);
- } else {
- StrnCatGrow(&CommandName, NULL, CleanOriginal, StrStr(CleanOriginal, L" ") - CleanOriginal);
- }
-
- ASSERT(PostAliasCmdLine == NULL);
- if (!ShellCommandIsCommandOnList(CommandName)) {
- //
- // Convert via alias
- //
- Status = ShellConvertAlias(&CommandName);
- PostAliasSize = 0;
- PostAliasCmdLine = StrnCatGrow(&PostAliasCmdLine, &PostAliasSize, CommandName, 0);
- PostAliasCmdLine = StrnCatGrow(&PostAliasCmdLine, &PostAliasSize, StrStr(CleanOriginal, L" "), 0);
- ASSERT_EFI_ERROR(Status);
- } else {
- PostAliasCmdLine = StrnCatGrow(&PostAliasCmdLine, NULL, CleanOriginal, 0);
- }
-
- if (CleanOriginal != NULL) {
- FreePool(CleanOriginal);
- CleanOriginal = NULL;
- }
-
- if (CommandName != NULL) {
- FreePool(CommandName);
- CommandName = NULL;
- }
-
- PostVariableCmdLine = ShellConvertVariables(PostAliasCmdLine);
-
- //
- // we can now free the modified by alias command line
- //
- if (PostAliasCmdLine != NULL) {
- FreePool(PostAliasCmdLine);
- PostAliasCmdLine = NULL;
- }
-
- if (PostVariableCmdLine == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
-
- while (PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] == L' ') {
- PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] = CHAR_NULL;
- }
- while (PostVariableCmdLine[0] == L' ') {
- CopyMem(PostVariableCmdLine, PostVariableCmdLine+1, StrSize(PostVariableCmdLine) - sizeof(PostVariableCmdLine[0]));
- }
-
- //
- // We dont do normal processing with a split command line (output from one command input to another)
- //
- TempLocation3 = NULL;
- if (StrStr(PostVariableCmdLine, L"|") != NULL) {
- for (TempLocation3 = PostVariableCmdLine ; TempLocation3 != NULL && *TempLocation3 != CHAR_NULL ; TempLocation3++) {
- if (*TempLocation3 == L'^' && *(TempLocation3+1) == L'|') {
- TempLocation3++;
- } else if (*TempLocation3 == L'|') {
- break;
- }
- }
- }
- if (TempLocation3 != NULL && *TempLocation3 != CHAR_NULL) {
- //
- // are we in an existing split???
- //
- if (!IsListEmpty(&ShellInfoObject.SplitList.Link)) {
- Split = (SPLIT_LIST*)GetFirstNode(&ShellInfoObject.SplitList.Link);
- }
-
- if (Split == NULL) {
- Status = RunSplitCommand(PostVariableCmdLine, NULL, NULL);
- } else {
- Status = RunSplitCommand(PostVariableCmdLine, Split->SplitStdIn, Split->SplitStdOut);
- }
- if (EFI_ERROR(Status)) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_SPLIT), ShellInfoObject.HiiHandle, PostVariableCmdLine);
- }
- } else {
-
- //
- // If this is a mapped drive change handle that...
- //
- if (PostVariableCmdLine[(StrLen(PostVariableCmdLine)-1)] == L':' && StrStr(PostVariableCmdLine, L" ") == NULL) {
- Status = ShellInfoObject.NewEfiShellProtocol->SetCurDir(NULL, PostVariableCmdLine);
- if (EFI_ERROR(Status)) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_MAPPING), ShellInfoObject.HiiHandle, PostVariableCmdLine);
- }
- FreePool(PostVariableCmdLine);
- return (Status);
- }
-
- ///@todo update this section to divide into 3 ways - run internal command, run split (above), and run an external file...
- /// We waste a lot of time doing processing like StdIn,StdOut,Argv,Argc for things that are external files...
-
-
-
- Status = UpdateStdInStdOutStdErr(ShellInfoObject.NewShellParametersProtocol, PostVariableCmdLine, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);
- if (EFI_ERROR(Status)) {
- if (Status == EFI_NOT_FOUND) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_REDUNDA_REDIR), ShellInfoObject.HiiHandle);
- } else {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_REDIR), ShellInfoObject.HiiHandle);
- }
- } else {
- while (PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] == L' ') {
- PostVariableCmdLine[StrLen(PostVariableCmdLine)-1] = CHAR_NULL;
- }
- while (PostVariableCmdLine[0] == L' ') {
- CopyMem(PostVariableCmdLine, PostVariableCmdLine+1, StrSize(PostVariableCmdLine) - sizeof(PostVariableCmdLine[0]));
- }
-
- //
- // get the argc and argv updated for internal commands
- //
- Status = UpdateArgcArgv(ShellInfoObject.NewShellParametersProtocol, PostVariableCmdLine, &Argv, &Argc);
- ASSERT_EFI_ERROR(Status);
-
- for (Count = 0 ; Count < ShellInfoObject.NewShellParametersProtocol->Argc ; Count++) {
- if (StrStr(ShellInfoObject.NewShellParametersProtocol->Argv[Count], L"-?") == ShellInfoObject.NewShellParametersProtocol->Argv[Count]
- || (ShellInfoObject.NewShellParametersProtocol->Argv[0][0] == L'?' && ShellInfoObject.NewShellParametersProtocol->Argv[0][1] == CHAR_NULL)
- ) {
- //
- // We need to redo the arguments since a parameter was -?
- // move them all down 1 to the end, then up one then replace the first with help
- //
- FreePool(ShellInfoObject.NewShellParametersProtocol->Argv[Count]);
- ShellInfoObject.NewShellParametersProtocol->Argv[Count] = NULL;
- for (Count2 = Count ; (Count2 + 1) < ShellInfoObject.NewShellParametersProtocol->Argc ; Count2++) {
- ShellInfoObject.NewShellParametersProtocol->Argv[Count2] = ShellInfoObject.NewShellParametersProtocol->Argv[Count2+1];
- }
- ShellInfoObject.NewShellParametersProtocol->Argv[Count2] = NULL;
- for (Count2 = ShellInfoObject.NewShellParametersProtocol->Argc -1 ; Count2 > 0 ; Count2--) {
- ShellInfoObject.NewShellParametersProtocol->Argv[Count2] = ShellInfoObject.NewShellParametersProtocol->Argv[Count2-1];
- }
- ShellInfoObject.NewShellParametersProtocol->Argv[0] = NULL;
- ShellInfoObject.NewShellParametersProtocol->Argv[0] = StrnCatGrow(&ShellInfoObject.NewShellParametersProtocol->Argv[0], NULL, L"help", 0);
- break;
- }
- }
-
- //
- // command or file?
- //
- if (ShellCommandIsCommandOnList(ShellInfoObject.NewShellParametersProtocol->Argv[0])) {
- //
- // Run the command (which was converted if it was an alias)
- //
- if (!EFI_ERROR(Status)) {
- Status = ShellCommandRunCommandHandler(ShellInfoObject.NewShellParametersProtocol->Argv[0], &ShellStatus, &LastError);
- ASSERT_EFI_ERROR(Status);
- UnicodeSPrint(LeString, sizeof(LeString)*sizeof(LeString[0]), L"0x%08x", ShellStatus);
- DEBUG_CODE(InternalEfiShellSetEnv(L"DebugLasterror", LeString, TRUE););
- if (LastError) {
- InternalEfiShellSetEnv(L"Lasterror", LeString, TRUE);
- }
- //
- // Pass thru the exitcode from the app.
- //
- if (ShellCommandGetExit()) {
- Status = ShellStatus;
- } else if (ShellStatus != 0 && IsScriptOnlyCommand(ShellInfoObject.NewShellParametersProtocol->Argv[0])) {
- Status = EFI_ABORTED;
- }
- }
- } else {
- //
- // run an external file (or script)
- //
- if (StrStr(ShellInfoObject.NewShellParametersProtocol->Argv[0], L":") != NULL) {
- ASSERT (CommandWithPath == NULL);
- if (ShellIsFile(ShellInfoObject.NewShellParametersProtocol->Argv[0]) == EFI_SUCCESS) {
- CommandWithPath = StrnCatGrow(&CommandWithPath, NULL, ShellInfoObject.NewShellParametersProtocol->Argv[0], 0);
- }
- }
- if (CommandWithPath == NULL) {
- CommandWithPath = ShellFindFilePathEx(ShellInfoObject.NewShellParametersProtocol->Argv[0], mExecutableExtensions);
- }
- if (CommandWithPath == NULL || ShellIsDirectory(CommandWithPath) == EFI_SUCCESS) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, ShellInfoObject.NewShellParametersProtocol->Argv[0]);
- } else {
- //
- // Check if it's a NSH (script) file.
- //
- TempLocation = CommandWithPath+StrLen(CommandWithPath)-4;
- TempLocation2 = mScriptExtension;
- if ((StrLen(CommandWithPath) > 4) && (StringNoCaseCompare((VOID*)(&TempLocation), (VOID*)(&TempLocation2)) == 0)) {
- Status = RunScriptFile (CommandWithPath);
- } else {
- DevPath = ShellInfoObject.NewEfiShellProtocol->GetDevicePathFromFilePath(CommandWithPath);
- ASSERT(DevPath != NULL);
- Status = InternalShellExecuteDevicePath(
- &gImageHandle,
- DevPath,
- PostVariableCmdLine,
- NULL,
- &StatusCode
- );
-
- //
- // Updatet last error status.
- //
- UnicodeSPrint(LeString, sizeof(LeString)*sizeof(LeString[0]), L"0x%08x", StatusCode);
- DEBUG_CODE(InternalEfiShellSetEnv(L"DebugLasterror", LeString, TRUE););
- InternalEfiShellSetEnv(L"Lasterror", LeString, TRUE);
- }
- }
- }
-
- //
- // Print some error info.
- //
- if (EFI_ERROR(Status)) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID*)(Status));
- }
-
- CommandName = StrnCatGrow(&CommandName, NULL, ShellInfoObject.NewShellParametersProtocol->Argv[0], 0);
-
- RestoreArgcArgv(ShellInfoObject.NewShellParametersProtocol, &Argv, &Argc);
-
- RestoreStdInStdOutStdErr(ShellInfoObject.NewShellParametersProtocol, &OriginalStdIn, &OriginalStdOut, &OriginalStdErr, &OriginalSystemTableInfo);
- }
- if (CommandName != NULL) {
- if (ShellCommandGetCurrentScriptFile() != NULL && !IsScriptOnlyCommand(CommandName)) {
- //
- // if this is NOT a scipt only command return success so the script won't quit.
- // prevent killing the script - this is the only place where we know the actual command name (after alias and variable replacement...)
- //
- Status = EFI_SUCCESS;
- }
- }
- }
-
- SHELL_FREE_NON_NULL(CommandName);
- SHELL_FREE_NON_NULL(CommandWithPath);
- SHELL_FREE_NON_NULL(PostVariableCmdLine);
-
- return (Status);
-}
-
-STATIC CONST UINT16 InvalidChars[] = {L'*', L'?', L'<', L'>', L'\\', L'/', L'\"', 0x0001, 0x0002};
-/**
- Function determins if the CommandName COULD be a valid command. It does not determine whether
- this is a valid command. It only checks for invalid characters.
-
- @param[in] CommandName The name to check
-
- @retval TRUE CommandName could be a command name
- @retval FALSE CommandName could not be a valid command name
-**/
-BOOLEAN
-EFIAPI
-IsValidCommandName(
- IN CONST CHAR16 *CommandName
- )
-{
- UINTN Count;
- if (CommandName == NULL) {
- ASSERT(FALSE);
- return (FALSE);
- }
- for ( Count = 0
- ; Count < sizeof(InvalidChars) / sizeof(InvalidChars[0])
- ; Count++
- ){
- if (ScanMem16(CommandName, StrSize(CommandName), InvalidChars[Count]) != NULL) {
- return (FALSE);
- }
- }
- return (TRUE);
-}
-
-/**
- Function to process a NSH script file via SHELL_FILE_HANDLE.
-
- @param[in] Handle The handle to the already opened file.
- @param[in] Name The name of the script file.
-
- @retval EFI_SUCCESS the script completed sucessfully
-**/
-EFI_STATUS
-EFIAPI
-RunScriptFileHandle (
- IN SHELL_FILE_HANDLE Handle,
- IN CONST CHAR16 *Name
- )
-{
- EFI_STATUS Status;
- SCRIPT_FILE *NewScriptFile;
- UINTN LoopVar;
- CHAR16 *CommandLine;
- CHAR16 *CommandLine2;
- CHAR16 *CommandLine3;
- SCRIPT_COMMAND_LIST *LastCommand;
- BOOLEAN Ascii;
- BOOLEAN PreScriptEchoState;
- BOOLEAN PreCommandEchoState;
- CONST CHAR16 *CurDir;
- UINTN LineCount;
- CHAR16 LeString[50];
-
- ASSERT(!ShellCommandGetScriptExit());
-
- PreScriptEchoState = ShellCommandGetEchoState();
-
- NewScriptFile = (SCRIPT_FILE*)AllocateZeroPool(sizeof(SCRIPT_FILE));
- if (NewScriptFile == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
-
- //
- // Set up the name
- //
- ASSERT(NewScriptFile->ScriptName == NULL);
- NewScriptFile->ScriptName = StrnCatGrow(&NewScriptFile->ScriptName, NULL, Name, 0);
- if (NewScriptFile->ScriptName == NULL) {
- DeleteScriptFileStruct(NewScriptFile);
- return (EFI_OUT_OF_RESOURCES);
- }
-
- //
- // Save the parameters (used to replace %0 to %9 later on)
- //
- NewScriptFile->Argc = ShellInfoObject.NewShellParametersProtocol->Argc;
- if (NewScriptFile->Argc != 0) {
- NewScriptFile->Argv = (CHAR16**)AllocateZeroPool(NewScriptFile->Argc * sizeof(CHAR16*));
- if (NewScriptFile->Argv == NULL) {
- DeleteScriptFileStruct(NewScriptFile);
- return (EFI_OUT_OF_RESOURCES);
- }
- for (LoopVar = 0 ; LoopVar < 10 && LoopVar < NewScriptFile->Argc; LoopVar++) {
- ASSERT(NewScriptFile->Argv[LoopVar] == NULL);
- NewScriptFile->Argv[LoopVar] = StrnCatGrow(&NewScriptFile->Argv[LoopVar], NULL, ShellInfoObject.NewShellParametersProtocol->Argv[LoopVar], 0);
- if (NewScriptFile->Argv[LoopVar] == NULL) {
- DeleteScriptFileStruct(NewScriptFile);
- return (EFI_OUT_OF_RESOURCES);
- }
- }
- } else {
- NewScriptFile->Argv = NULL;
- }
-
- InitializeListHead(&NewScriptFile->CommandList);
- InitializeListHead(&NewScriptFile->SubstList);
-
- //
- // Now build the list of all script commands.
- //
- LineCount = 0;
- while(!ShellFileHandleEof(Handle)) {
- CommandLine = ShellFileHandleReturnLine(Handle, &Ascii);
- LineCount++;
- if (CommandLine == NULL || StrLen(CommandLine) == 0) {
- continue;
- }
- NewScriptFile->CurrentCommand = AllocateZeroPool(sizeof(SCRIPT_COMMAND_LIST));
- if (NewScriptFile->CurrentCommand == NULL) {
- DeleteScriptFileStruct(NewScriptFile);
- return (EFI_OUT_OF_RESOURCES);
- }
-
- NewScriptFile->CurrentCommand->Cl = CommandLine;
- NewScriptFile->CurrentCommand->Data = NULL;
- NewScriptFile->CurrentCommand->Line = LineCount;
-
- InsertTailList(&NewScriptFile->CommandList, &NewScriptFile->CurrentCommand->Link);
- }
-
- //
- // Add this as the topmost script file
- //
- ShellCommandSetNewScript (NewScriptFile);
-
- //
- // Now enumerate through the commands and run each one.
- //
- CommandLine = AllocateZeroPool(PcdGet16(PcdShellPrintBufferSize));
- if (CommandLine == NULL) {
- DeleteScriptFileStruct(NewScriptFile);
- return (EFI_OUT_OF_RESOURCES);
- }
- CommandLine2 = AllocateZeroPool(PcdGet16(PcdShellPrintBufferSize));
- if (CommandLine2 == NULL) {
- FreePool(CommandLine);
- DeleteScriptFileStruct(NewScriptFile);
- return (EFI_OUT_OF_RESOURCES);
- }
-
- for ( NewScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)GetFirstNode(&NewScriptFile->CommandList)
- ; !IsNull(&NewScriptFile->CommandList, &NewScriptFile->CurrentCommand->Link)
- ; // conditional increment in the body of the loop
- ){
- ASSERT(CommandLine2 != NULL);
- StrCpy(CommandLine2, NewScriptFile->CurrentCommand->Cl);
-
- //
- // NULL out comments
- //
- for (CommandLine3 = CommandLine2 ; CommandLine3 != NULL && *CommandLine3 != CHAR_NULL ; CommandLine3++) {
- if (*CommandLine3 == L'^') {
- if (*(CommandLine3+1) == L'#' || *(CommandLine3+1) == L':') {
- CopyMem(CommandLine3, CommandLine3+1, StrSize(CommandLine3) - sizeof(CommandLine3[0]));
- }
- } else if (*CommandLine3 == L'#') {
- *CommandLine3 = CHAR_NULL;
- }
- }
-
- if (CommandLine2 != NULL && StrLen(CommandLine2) >= 1) {
- //
- // Due to variability in starting the find and replace action we need to have both buffers the same.
- //
- StrCpy(CommandLine, CommandLine2);
-
- //
- // Remove the %0 to %9 from the command line (if we have some arguments)
- //
- if (NewScriptFile->Argv != NULL) {
- switch (NewScriptFile->Argc) {
- default:
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", NewScriptFile->Argv[9], FALSE, TRUE);
- ASSERT_EFI_ERROR(Status);
- case 9:
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%8", NewScriptFile->Argv[8], FALSE, TRUE);
- ASSERT_EFI_ERROR(Status);
- case 8:
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%7", NewScriptFile->Argv[7], FALSE, TRUE);
- ASSERT_EFI_ERROR(Status);
- case 7:
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%6", NewScriptFile->Argv[6], FALSE, TRUE);
- ASSERT_EFI_ERROR(Status);
- case 6:
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%5", NewScriptFile->Argv[5], FALSE, TRUE);
- ASSERT_EFI_ERROR(Status);
- case 5:
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%4", NewScriptFile->Argv[4], FALSE, TRUE);
- ASSERT_EFI_ERROR(Status);
- case 4:
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%3", NewScriptFile->Argv[3], FALSE, TRUE);
- ASSERT_EFI_ERROR(Status);
- case 3:
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%2", NewScriptFile->Argv[2], FALSE, TRUE);
- ASSERT_EFI_ERROR(Status);
- case 2:
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%1", NewScriptFile->Argv[1], FALSE, TRUE);
- ASSERT_EFI_ERROR(Status);
- case 1:
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%0", NewScriptFile->Argv[0], FALSE, TRUE);
- ASSERT_EFI_ERROR(Status);
- break;
- case 0:
- break;
- }
- }
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%1", L"\"\"", FALSE, FALSE);
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%2", L"\"\"", FALSE, FALSE);
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%3", L"\"\"", FALSE, FALSE);
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%4", L"\"\"", FALSE, FALSE);
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%5", L"\"\"", FALSE, FALSE);
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%6", L"\"\"", FALSE, FALSE);
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%7", L"\"\"", FALSE, FALSE);
- Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%8", L"\"\"", FALSE, FALSE);
- Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", L"\"\"", FALSE, FALSE);
-
- StrCpy(CommandLine2, CommandLine);
-
- LastCommand = NewScriptFile->CurrentCommand;
-
- for (CommandLine3 = CommandLine2 ; CommandLine3[0] == L' ' ; CommandLine3++);
-
- if (CommandLine3 != NULL && CommandLine3[0] == L':' ) {
- //
- // This line is a goto target / label
- //
- } else {
- if (CommandLine3 != NULL && StrLen(CommandLine3) > 0) {
- if (CommandLine3[0] == L'@') {
- //
- // We need to save the current echo state
- // and disable echo for just this command.
- //
- PreCommandEchoState = ShellCommandGetEchoState();
- ShellCommandSetEchoState(FALSE);
- Status = RunCommand(CommandLine3+1);
-
- //
- // Now restore the pre-'@' echo state.
- //
- ShellCommandSetEchoState(PreCommandEchoState);
- } else {
- if (ShellCommandGetEchoState()) {
- CurDir = ShellInfoObject.NewEfiShellProtocol->GetEnv(L"cwd");
- if (CurDir != NULL && StrLen(CurDir) > 1) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_CURDIR), ShellInfoObject.HiiHandle, CurDir);
- } else {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_SHELL), ShellInfoObject.HiiHandle);
- }
- ShellPrintEx(-1, -1, L"%s\r\n", CommandLine2);
- }
- Status = RunCommand(CommandLine3);
- }
- }
-
- if (ShellCommandGetScriptExit()) {
- UnicodeSPrint(LeString, sizeof(LeString)*sizeof(LeString[0]), L"0x%Lx", ShellCommandGetExitCode());
- DEBUG_CODE(InternalEfiShellSetEnv(L"DebugLasterror", LeString, TRUE););
- InternalEfiShellSetEnv(L"Lasterror", LeString, TRUE);
-
- ShellCommandRegisterExit(FALSE, 0);
- Status = EFI_SUCCESS;
- break;
- }
- if (EFI_ERROR(Status)) {
- break;
- }
- if (ShellCommandGetExit()) {
- break;
- }
- }
- //
- // If that commend did not update the CurrentCommand then we need to advance it...
- //
- if (LastCommand == NewScriptFile->CurrentCommand) {
- NewScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)GetNextNode(&NewScriptFile->CommandList, &NewScriptFile->CurrentCommand->Link);
- if (!IsNull(&NewScriptFile->CommandList, &NewScriptFile->CurrentCommand->Link)) {
- NewScriptFile->CurrentCommand->Reset = TRUE;
- }
- }
- } else {
- NewScriptFile->CurrentCommand = (SCRIPT_COMMAND_LIST *)GetNextNode(&NewScriptFile->CommandList, &NewScriptFile->CurrentCommand->Link);
- if (!IsNull(&NewScriptFile->CommandList, &NewScriptFile->CurrentCommand->Link)) {
- NewScriptFile->CurrentCommand->Reset = TRUE;
- }
- }
- }
-
-
- FreePool(CommandLine);
- FreePool(CommandLine2);
- ShellCommandSetNewScript (NULL);
-
- //
- // Only if this was the last script reset the state.
- //
- if (ShellCommandGetCurrentScriptFile()==NULL) {
- ShellCommandSetEchoState(PreScriptEchoState);
- }
- return (EFI_SUCCESS);
-}
-
-/**
- Function to process a NSH script file.
-
- @param[in] ScriptPath Pointer to the script file name (including file system path).
-
- @retval EFI_SUCCESS the script completed sucessfully
-**/
-EFI_STATUS
-EFIAPI
-RunScriptFile (
- IN CONST CHAR16 *ScriptPath
- )
-{
- EFI_STATUS Status;
- SHELL_FILE_HANDLE FileHandle;
-
- if (ShellIsFile(ScriptPath) != EFI_SUCCESS) {
- return (EFI_INVALID_PARAMETER);
- }
-
- Status = ShellOpenFileByName(ScriptPath, &FileHandle, EFI_FILE_MODE_READ, 0);
- if (EFI_ERROR(Status)) {
- return (Status);
- }
-
- Status = RunScriptFileHandle(FileHandle, ScriptPath);
-
- ShellCloseFile(&FileHandle);
-
- return (Status);
-}