/** @file\r
This is THE shell (application)\r
\r
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2013, Hewlett-Packard Development Company, L.P.\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
FALSE,\r
FALSE,\r
{\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
+ {{\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0\r
+ }},\r
0,\r
NULL,\r
NULL\r
},\r
- {0,0},\r
+ {{NULL, NULL}, NULL},\r
{\r
- {0,0},\r
+ {{NULL, NULL}, NULL},\r
0,\r
0,\r
TRUE\r
NULL,\r
NULL,\r
NULL,\r
- {0,0,NULL,NULL},\r
- {0,0},\r
+ {{NULL, NULL}, NULL, NULL},\r
+ {{NULL, NULL}, NULL, NULL},\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
NULL,\r
NULL,\r
NULL,\r
0,\r
gST->ConOut->Mode->CursorRow,\r
NULL,\r
- STRING_TOKEN (STR_VER_OUTPUT_MAIN),\r
+ STRING_TOKEN (STR_VER_OUTPUT_MAIN_SHELL),\r
ShellInfoObject.HiiHandle,\r
SupportLevel[PcdGet8(PcdShellSupportLevel)],\r
gEfiShellProtocol->MajorVersion,\r
- gEfiShellProtocol->MinorVersion,\r
+ gEfiShellProtocol->MinorVersion\r
+ );\r
+\r
+ ShellPrintHiiEx (\r
+ -1,\r
+ -1,\r
+ NULL,\r
+ STRING_TOKEN (STR_VER_OUTPUT_MAIN_SUPPLIER),\r
+ ShellInfoObject.HiiHandle,\r
+ (CHAR16 *) PcdGetPtr (PcdShellSupplier)\r
+ );\r
+\r
+ ShellPrintHiiEx (\r
+ -1,\r
+ -1,\r
+ NULL,\r
+ STRING_TOKEN (STR_VER_OUTPUT_MAIN_UEFI),\r
+ ShellInfoObject.HiiHandle,\r
(gST->Hdr.Revision&0xffff0000)>>16,\r
(gST->Hdr.Revision&0x0000ffff),\r
gST->FirmwareVendor,\r
Status = DoStartupScript(ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath);\r
}\r
\r
- if (!ShellCommandGetExit() && (PcdGet8(PcdShellSupportLevel) >= 3 || PcdGetBool(PcdShellForceConsole)) && !EFI_ERROR(Status) && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {\r
+ if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit && !ShellCommandGetExit() && (PcdGet8(PcdShellSupportLevel) >= 3 || PcdGetBool(PcdShellForceConsole)) && !EFI_ERROR(Status) && !ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {\r
//\r
// begin the UI waiting loop\r
//\r
}\r
if (ShellInfoObject.NewEfiShellProtocol != NULL){\r
if (ShellInfoObject.NewEfiShellProtocol->IsRootShell()){\r
- ShellInfoObject.NewEfiShellProtocol->SetEnv(L"cwd", L"", TRUE);\r
+ InternalEfiShellSetEnv(L"cwd", NULL, TRUE);\r
}\r
CleanUpShellProtocol(ShellInfoObject.NewEfiShellProtocol);\r
DEBUG_CODE(ShellInfoObject.NewEfiShellProtocol = NULL;);\r
{L"-noversion", TypeFlag},\r
{L"-startup", TypeFlag},\r
{L"-delay", TypeValue},\r
+ {L"-_exit", TypeFlag},\r
{NULL, TypeMax}\r
};\r
\r
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoMap = ShellCommandLineGetFlag(Package, L"-nomap");\r
ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoVersion = ShellCommandLineGetFlag(Package, L"-noversion");\r
ShellInfoObject.ShellInitSettings.BitUnion.Bits.Delay = ShellCommandLineGetFlag(Package, L"-delay");\r
+ ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit = ShellCommandLineGetFlag(Package, L"-_exit");\r
\r
ShellInfoObject.ShellInitSettings.Delay = 5;\r
\r
return (EFI_SUCCESS);\r
}\r
\r
+ gST->ConOut->EnableCursor(gST->ConOut, FALSE);\r
//\r
// print out our warning and see if they press a key\r
//\r
- for ( Status = EFI_UNSUPPORTED, Delay = ShellInfoObject.ShellInitSettings.Delay * 10\r
+ for ( Status = EFI_UNSUPPORTED, Delay = ShellInfoObject.ShellInitSettings.Delay\r
; Delay != 0 && EFI_ERROR(Status)\r
; Delay--\r
){\r
- ShellPrintHiiEx(0, gST->ConOut->Mode->CursorRow, NULL, STRING_TOKEN (STR_SHELL_STARTUP_QUESTION), ShellInfoObject.HiiHandle, Delay/10);\r
- gBS->Stall (100000);\r
+ ShellPrintHiiEx(0, gST->ConOut->Mode->CursorRow, NULL, STRING_TOKEN (STR_SHELL_STARTUP_QUESTION), ShellInfoObject.HiiHandle, Delay);\r
+ gBS->Stall (1000000);\r
if (!ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleIn) {\r
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
}\r
}\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_CRLF), ShellInfoObject.HiiHandle);\r
+ gST->ConOut->EnableCursor(gST->ConOut, TRUE);\r
\r
//\r
// ESC was pressed\r
CHAR16 *NewCommandLine1;\r
CHAR16 *NewCommandLine2;\r
CHAR16 *Temp;\r
+ CHAR16 *Temp2;\r
UINTN ItemSize;\r
CHAR16 *ItemTemp;\r
SCRIPT_FILE *CurrentScriptFile;\r
}\r
}\r
\r
- //\r
- // Quick out if none were found...\r
- //\r
- if (NewSize == StrSize(OriginalCommandLine)) {\r
- ASSERT(Temp == NULL);\r
- Temp = StrnCatGrow(&Temp, NULL, OriginalCommandLine, 0);\r
- return (Temp);\r
- }\r
-\r
//\r
// now do the replacements...\r
//\r
ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, AliasListNode->Alias, AliasListNode->CommandString, TRUE, FALSE);\r
StrCpy(NewCommandLine1, NewCommandLine2);\r
}\r
+\r
+ //\r
+ // Remove non-existant environment variables in scripts only\r
+ //\r
+ for (Temp = NewCommandLine1 ; Temp != NULL ; ) {\r
+ Temp = StrStr(Temp, L"%");\r
+ if (Temp == NULL) {\r
+ break;\r
+ }\r
+ while (*(Temp - 1) == L'^') {\r
+ Temp = StrStr(Temp + 1, L"%");\r
+ if (Temp == NULL) {\r
+ break;\r
+ }\r
+ }\r
+ if (Temp == NULL) {\r
+ break;\r
+ }\r
+ \r
+ Temp2 = StrStr(Temp + 1, L"%");\r
+ if (Temp2 == NULL) {\r
+ break;\r
+ }\r
+ while (*(Temp2 - 1) == L'^') {\r
+ Temp2 = StrStr(Temp2 + 1, L"%");\r
+ if (Temp2 == NULL) {\r
+ break;\r
+ }\r
+ }\r
+ if (Temp2 == NULL) {\r
+ break;\r
+ }\r
+ \r
+ Temp2++;\r
+ CopyMem(Temp, Temp2, StrSize(Temp2));\r
+ }\r
+\r
}\r
\r
+ //\r
+ // Now cleanup any straggler intentionally ignored "%" characters\r
+ //\r
+ ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, L"^%", L"%", TRUE, FALSE);\r
+ StrCpy(NewCommandLine1, NewCommandLine2);\r
+ \r
FreePool(NewCommandLine2);\r
FreePool(ItemTemp);\r
\r
SHELL_FREE_NON_NULL(OurCommandLine);\r
SHELL_FREE_NON_NULL(NextCommandLine);\r
return (EFI_OUT_OF_RESOURCES);\r
- }\r
- if (NextCommandLine[0] != CHAR_NULL &&\r
+ } else if (StrStr(OurCommandLine, L"|") != NULL || Size1 == 0 || Size2 == 0) {\r
+ SHELL_FREE_NON_NULL(OurCommandLine);\r
+ SHELL_FREE_NON_NULL(NextCommandLine);\r
+ return (EFI_INVALID_PARAMETER);\r
+ } else if (NextCommandLine[0] != CHAR_NULL &&\r
NextCommandLine[0] == L'a' &&\r
NextCommandLine[1] == L' '\r
){\r
ASSERT(Split->SplitStdOut != NULL);\r
InsertHeadList(&ShellInfoObject.SplitList.Link, &Split->Link);\r
\r
- ASSERT(StrStr(OurCommandLine, L"|") == NULL);\r
Status = RunCommand(OurCommandLine);\r
\r
//\r
)\r
{\r
EFI_STATUS Status;\r
+ EFI_STATUS StatusCode;\r
CHAR16 *CommandName;\r
SHELL_STATUS ShellStatus;\r
UINTN Argc;\r
CHAR16 **Argv;\r
BOOLEAN LastError;\r
- CHAR16 LeString[11];\r
+ CHAR16 LeString[19];\r
CHAR16 *PostAliasCmdLine;\r
UINTN PostAliasSize;\r
CHAR16 *PostVariableCmdLine;\r
if (CleanOriginal == NULL) {\r
return (EFI_OUT_OF_RESOURCES);\r
}\r
+\r
+ //\r
+ // Remove any spaces and tabs at the beginning of the string.\r
+ //\r
+ while ((CleanOriginal[0] == L' ') || (CleanOriginal[0] == L'\t')) {\r
+ CopyMem(CleanOriginal, CleanOriginal+1, StrSize(CleanOriginal) - sizeof(CleanOriginal[0]));\r
+ }\r
+\r
+ //\r
+ // Handle case that passed in command line is just 1 or more " " characters.\r
+ //\r
+ if (StrLen (CleanOriginal) == 0) {\r
+ if (CleanOriginal != NULL) {\r
+ FreePool(CleanOriginal);\r
+ CleanOriginal = NULL;\r
+ }\r
+ return (EFI_SUCCESS);\r
+ }\r
+\r
+ //\r
+ // Remove any spaces at the end of the string.\r
+ //\r
while (CleanOriginal[StrLen(CleanOriginal)-1] == L' ') {\r
CleanOriginal[StrLen(CleanOriginal)-1] = CHAR_NULL;\r
}\r
- while (CleanOriginal[0] == L' ') {\r
- CopyMem(CleanOriginal, CleanOriginal+1, StrSize(CleanOriginal) - sizeof(CleanOriginal[0]));\r
- }\r
\r
CommandName = NULL;\r
if (StrStr(CleanOriginal, L" ") == NULL){\r
} else {\r
Status = RunSplitCommand(PostVariableCmdLine, Split->SplitStdIn, Split->SplitStdOut);\r
}\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_INVALID_SPLIT), ShellInfoObject.HiiHandle, PostVariableCmdLine);\r
+ }\r
} else {\r
\r
//\r
if (!EFI_ERROR(Status)) {\r
Status = ShellCommandRunCommandHandler(ShellInfoObject.NewShellParametersProtocol->Argv[0], &ShellStatus, &LastError);\r
ASSERT_EFI_ERROR(Status);\r
- UnicodeSPrint(LeString, sizeof(LeString)*sizeof(LeString[0]), L"0x%08x", ShellStatus);\r
- DEBUG_CODE(InternalEfiShellSetEnv(L"DebugLasterror", LeString, TRUE););\r
+\r
+ if (sizeof(EFI_STATUS) == sizeof(UINT64)) {\r
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", ShellStatus);\r
+ } else {\r
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%x", ShellStatus);\r
+ }\r
+ DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););\r
if (LastError) {\r
- InternalEfiShellSetEnv(L"Lasterror", LeString, TRUE);\r
+ InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);\r
}\r
//\r
// Pass thru the exitcode from the app.\r
}\r
if (CommandWithPath == NULL || ShellIsDirectory(CommandWithPath) == EFI_SUCCESS) {\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, ShellInfoObject.NewShellParametersProtocol->Argv[0]);\r
+\r
+ if (sizeof(EFI_STATUS) == sizeof(UINT64)) {\r
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", EFI_NOT_FOUND);\r
+ } else {\r
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%x", EFI_NOT_FOUND);\r
+ }\r
+ DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););\r
+ InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);\r
} else {\r
//\r
// Check if it's a NSH (script) file.\r
DevPath,\r
PostVariableCmdLine,\r
NULL,\r
- NULL\r
+ &StatusCode\r
);\r
+\r
+ //\r
+ // Update last error status.\r
+ //\r
+ if (sizeof(EFI_STATUS) == sizeof(UINT64)) {\r
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", StatusCode);\r
+ } else {\r
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%x", StatusCode);\r
+ }\r
+ DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););\r
+ InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);\r
}\r
}\r
}\r
+\r
+ //\r
+ // Print some error info.\r
+ //\r
+ if (EFI_ERROR(Status)) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_ERROR), ShellInfoObject.HiiHandle, (VOID*)(Status));\r
+ }\r
+\r
CommandName = StrnCatGrow(&CommandName, NULL, ShellInfoObject.NewShellParametersProtocol->Argv[0], 0);\r
\r
RestoreArgcArgv(ShellInfoObject.NewShellParametersProtocol, &Argv, &Argc);\r
//\r
} else {\r
if (CommandLine3 != NULL && StrLen(CommandLine3) > 0) {\r
- if (ShellCommandGetEchoState()) {\r
- CurDir = ShellInfoObject.NewEfiShellProtocol->GetEnv(L"cwd");\r
- if (CurDir != NULL && StrLen(CurDir) > 1) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_CURDIR), ShellInfoObject.HiiHandle, CurDir);\r
- } else {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_SHELL), ShellInfoObject.HiiHandle);\r
- }\r
- ShellPrintEx(-1, -1, L"%s\r\n", CommandLine2);\r
- }\r
if (CommandLine3[0] == L'@') {\r
//\r
// We need to save the current echo state\r
Status = RunCommand(CommandLine3+1);\r
\r
//\r
- // Now restore the pre-'@' echo state.\r
+ // If command was "@echo -off" or "@echo -on" then don't restore echo state\r
//\r
- ShellCommandSetEchoState(PreCommandEchoState);\r
+ if (StrCmp (L"@echo -off", CommandLine3) != 0 &&\r
+ StrCmp (L"@echo -on", CommandLine3) != 0) {\r
+ //\r
+ // Now restore the pre-'@' echo state.\r
+ //\r
+ ShellCommandSetEchoState(PreCommandEchoState);\r
+ }\r
} else {\r
+ if (ShellCommandGetEchoState()) {\r
+ CurDir = ShellInfoObject.NewEfiShellProtocol->GetEnv(L"cwd");\r
+ if (CurDir != NULL && StrLen(CurDir) > 1) {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_CURDIR), ShellInfoObject.HiiHandle, CurDir);\r
+ } else {\r
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_SHELL), ShellInfoObject.HiiHandle);\r
+ }\r
+ ShellPrintEx(-1, -1, L"%s\r\n", CommandLine2);\r
+ }\r
Status = RunCommand(CommandLine3);\r
}\r
}\r
\r
if (ShellCommandGetScriptExit()) {\r
- UnicodeSPrint(LeString, sizeof(LeString)*sizeof(LeString[0]), L"0x%Lx", ShellCommandGetExitCode());\r
- DEBUG_CODE(InternalEfiShellSetEnv(L"DebugLasterror", LeString, TRUE););\r
- InternalEfiShellSetEnv(L"Lasterror", LeString, TRUE);\r
+ //\r
+ // ShellCommandGetExitCode() always returns a UINT64\r
+ //\r
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", ShellCommandGetExitCode());\r
+ DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););\r
+ InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);\r
\r
ShellCommandRegisterExit(FALSE, 0);\r
Status = EFI_SUCCESS;\r
break;\r
}\r
+ if (ShellGetExecutionBreakFlag()) {\r
+ break;\r
+ }\r
if (EFI_ERROR(Status)) {\r
break;\r
}\r