)\r
{\r
EFI_STATUS Status;\r
+ EFI_STATUS CalleeStatus;\r
UINTN Delay;\r
EFI_INPUT_KEY Key;\r
SHELL_FILE_HANDLE FileHandle;\r
StrnCatS(FileStringPath, NewSize/sizeof(CHAR16), L" ", NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1);\r
StrnCatS(FileStringPath, NewSize/sizeof(CHAR16), ShellInfoObject.ShellInitSettings.FileOptions, NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1);\r
}\r
- Status = RunCommand(FileStringPath);\r
+ Status = RunShellCommand(FileStringPath, &CalleeStatus);\r
+ if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit == TRUE) {\r
+ ShellCommandRegisterExit(gEfiShellProtocol->BatchIsActive(), (CONST UINT64)CalleeStatus);\r
+ }\r
FreePool(FileStringPath);\r
return (Status);\r
\r
@param[in] CmdLine the command line to run.\r
@param[in] FirstParameter the first parameter on the command line\r
@param[in] ParamProtocol the shell parameters protocol pointer\r
+ @param[out] CommandStatus the status from the command line.\r
\r
@retval EFI_SUCCESS The command was completed.\r
@retval EFI_ABORTED The command's operation was aborted.\r
RunInternalCommand(\r
IN CONST CHAR16 *CmdLine,\r
IN CHAR16 *FirstParameter,\r
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol\r
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,\r
+ OUT EFI_STATUS *CommandStatus\r
)\r
{\r
EFI_STATUS Status;\r
Status = ShellCommandRunCommandHandler(FirstParameter, &CommandReturnedStatus, &LastError);\r
\r
if (!EFI_ERROR(Status)) {\r
+ if (CommandStatus != NULL) {\r
+ if (CommandReturnedStatus != SHELL_SUCCESS) {\r
+ *CommandStatus = (EFI_STATUS)(CommandReturnedStatus | MAX_BIT);\r
+ } else {\r
+ *CommandStatus = EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
//\r
// Update last error status.\r
// some commands do not update last error.\r
@param[in] CmdLine the command line to run.\r
@param[in] FirstParameter the first parameter on the command line\r
@param[in] ParamProtocol the shell parameters protocol pointer\r
+ @param[out] CommandStatus the status from the command line.\r
\r
@retval EFI_SUCCESS The command was completed.\r
@retval EFI_ABORTED The command's operation was aborted.\r
IN SHELL_OPERATION_TYPES Type,\r
IN CONST CHAR16 *CmdLine,\r
IN CHAR16 *FirstParameter,\r
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol\r
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,\r
+ OUT EFI_STATUS *CommandStatus\r
)\r
{\r
EFI_STATUS Status;\r
\r
switch (Type) {\r
case Internal_Command:\r
- Status = RunInternalCommand(CmdLine, FirstParameter, ParamProtocol);\r
+ Status = RunInternalCommand(CmdLine, FirstParameter, ParamProtocol, CommandStatus);\r
break;\r
case Script_File_Name:\r
case Efi_Application:\r
CalleeExitStatus = (SHELL_STATUS) StartStatus;\r
}\r
\r
+ if (CommandStatus != NULL) {\r
+ *CommandStatus = CalleeExitStatus;\r
+ }\r
+\r
//\r
// Update last error status.\r
//\r
@param[in] CmdLine the command line to run.\r
@param[in] FirstParameter the first parameter on the command line.\r
@param[in] ParamProtocol the shell parameters protocol pointer\r
+ @param[out] CommandStatus the status from the command line.\r
\r
@retval EFI_SUCCESS The command was completed.\r
@retval EFI_ABORTED The command's operation was aborted.\r
EFI_STATUS\r
EFIAPI\r
SetupAndRunCommandOrFile(\r
- IN SHELL_OPERATION_TYPES Type,\r
- IN CHAR16 *CmdLine,\r
- IN CHAR16 *FirstParameter,\r
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol\r
+ IN SHELL_OPERATION_TYPES Type,\r
+ IN CHAR16 *CmdLine,\r
+ IN CHAR16 *FirstParameter,\r
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol,\r
+ OUT EFI_STATUS *CommandStatus\r
)\r
{\r
EFI_STATUS Status;\r
//\r
if (!EFI_ERROR(Status)) {\r
TrimSpaces(&CmdLine);\r
- Status = RunCommandOrFile(Type, CmdLine, FirstParameter, ParamProtocol);\r
+ Status = RunCommandOrFile(Type, CmdLine, FirstParameter, ParamProtocol, CommandStatus);\r
}\r
\r
//\r
command or dispatch an external application.\r
\r
@param[in] CmdLine The command line to parse.\r
+ @param[out] CommandStatus The status from the command line.\r
\r
@retval EFI_SUCCESS The command was completed.\r
@retval EFI_ABORTED The command's operation was aborted.\r
**/\r
EFI_STATUS\r
EFIAPI\r
-RunCommand(\r
- IN CONST CHAR16 *CmdLine\r
+RunShellCommand(\r
+ IN CONST CHAR16 *CmdLine,\r
+ OUT EFI_STATUS *CommandStatus\r
)\r
{\r
EFI_STATUS Status;\r
case Internal_Command:\r
case Script_File_Name:\r
case Efi_Application:\r
- Status = SetupAndRunCommandOrFile(Type, CleanOriginal, FirstParameter, ShellInfoObject.NewShellParametersProtocol);\r
+ Status = SetupAndRunCommandOrFile(Type, CleanOriginal, FirstParameter, ShellInfoObject.NewShellParametersProtocol, CommandStatus);\r
break;\r
default:\r
//\r
return (Status);\r
}\r
\r
+/**\r
+ Function will process and run a command line.\r
+\r
+ This will determine if the command line represents an internal shell \r
+ command or dispatch an external application.\r
+\r
+ @param[in] CmdLine The command line to parse.\r
+\r
+ @retval EFI_SUCCESS The command was completed.\r
+ @retval EFI_ABORTED The command's operation was aborted.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RunCommand(\r
+ IN CONST CHAR16 *CmdLine\r
+ )\r
+{\r
+ return (RunShellCommand(CmdLine, NULL));\r
+}\r
+\r
+\r
STATIC CONST UINT16 InvalidChars[] = {L'*', L'?', L'<', L'>', L'\\', L'/', L'\"', 0x0001, 0x0002};\r
/**\r
Function determines if the CommandName COULD be a valid command. It does not determine whether\r
CHAR16 *Temp;\r
EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
UINTN Size;\r
-\r
+ EFI_STATUS CalleeStatusCode;\r
+ \r
if ((PcdGet8(PcdShellSupportLevel) < 1)) {\r
return (EFI_UNSUPPORTED);\r
}\r
\r
- DevPath = AppendDevicePath (ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath);\r
+ if (Environment != NULL) {\r
+ // If Environment isn't null, load a new image of the shell with its own\r
+ // environment\r
+ DevPath = AppendDevicePath (ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath);\r
+ \r
+ DEBUG_CODE_BEGIN();\r
+ Temp = ConvertDevicePathToText(ShellInfoObject.FileDevPath, TRUE, TRUE);\r
+ FreePool(Temp);\r
+ Temp = ConvertDevicePathToText(ShellInfoObject.ImageDevPath, TRUE, TRUE);\r
+ FreePool(Temp);\r
+ Temp = ConvertDevicePathToText(DevPath, TRUE, TRUE);\r
+ FreePool(Temp);\r
+ DEBUG_CODE_END();\r
+\r
+ Temp = NULL;\r
+ Size = 0;\r
+ ASSERT((Temp == NULL && Size == 0) || (Temp != NULL));\r
+ StrnCatGrow(&Temp, &Size, L"Shell.efi -_exit ", 0);\r
+ StrnCatGrow(&Temp, &Size, CommandLine, 0);\r
\r
- DEBUG_CODE_BEGIN();\r
- Temp = ConvertDevicePathToText(ShellInfoObject.FileDevPath, TRUE, TRUE);\r
- FreePool(Temp);\r
- Temp = ConvertDevicePathToText(ShellInfoObject.ImageDevPath, TRUE, TRUE);\r
- FreePool(Temp);\r
- Temp = ConvertDevicePathToText(DevPath, TRUE, TRUE);\r
- FreePool(Temp);\r
- DEBUG_CODE_END();\r
+ Status = InternalShellExecuteDevicePath(\r
+ ParentImageHandle,\r
+ DevPath,\r
+ Temp,\r
+ (CONST CHAR16**)Environment,\r
+ StatusCode);\r
\r
- Temp = NULL;\r
- Size = 0;\r
- ASSERT((Temp == NULL && Size == 0) || (Temp != NULL));\r
- StrnCatGrow(&Temp, &Size, L"Shell.efi -_exit ", 0);\r
- StrnCatGrow(&Temp, &Size, CommandLine, 0);\r
+ //\r
+ // de-allocate and return\r
+ //\r
+ FreePool(DevPath);\r
+ FreePool(Temp);\r
+ } else {\r
+ // If Environment is NULL, we are free to use and mutate the current shell\r
+ // environment. This is much faster as uses much less memory.\r
\r
- Status = InternalShellExecuteDevicePath(\r
- ParentImageHandle,\r
- DevPath,\r
- Temp,\r
- (CONST CHAR16**)Environment,\r
- StatusCode);\r
+ if (CommandLine == NULL) {\r
+ CommandLine = L"";\r
+ }\r
+\r
+ Status = RunShellCommand (CommandLine, &CalleeStatusCode);\r
+\r
+ // Pass up the command's exit code if the caller wants it\r
+ if (StatusCode != NULL) {\r
+ *StatusCode = (EFI_STATUS) CalleeStatusCode;\r
+ }\r
+ }\r
\r
- //\r
- // de-allocate and return\r
- //\r
- FreePool(DevPath);\r
- FreePool(Temp);\r
return(Status);\r
}\r
\r