/** @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
)\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
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
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
}\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