From cd39fe082c886243b934b1ff4170ab32bbd0db2c Mon Sep 17 00:00:00 2001 From: Olivier Martin Date: Tue, 13 May 2014 21:16:42 +0000 Subject: [PATCH] ShellPkg: Do not mix status when executing a command The function InternalShellExecuteDevicePath() did not differentiate an error occuring during the preparation of an image and an error occurring during its execution. A use case of the issue was when a EFI application was called in a EFI Shell script. If the EFI application was returning an error then the NSH script stopped its execution. While the EFI Shell specification says the script should continue its execution (see 4.2 Error Handling). Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin Reviewed-by: Jaben Carsey git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15523 6f19259b-4bc3-4df7-8a09-765794883524 --- ShellPkg/Application/Shell/Shell.c | 4 +++- ShellPkg/Application/Shell/ShellProtocol.c | 10 +++++++--- ShellPkg/Application/Shell/ShellProtocol.h | 7 ++++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c index 056d66d09e..951d31e82b 100644 --- a/ShellPkg/Application/Shell/Shell.c +++ b/ShellPkg/Application/Shell/Shell.c @@ -2231,6 +2231,7 @@ RunCommandOrFile( ) { EFI_STATUS Status; + EFI_STATUS StartStatus; CHAR16 *CommandWithPath; EFI_DEVICE_PATH_PROTOCOL *DevPath; SHELL_STATUS CalleeExitStatus; @@ -2308,6 +2309,7 @@ RunCommandOrFile( DevPath, CmdLine, NULL, + &StartStatus, NULL, NULL ); @@ -2317,7 +2319,7 @@ RunCommandOrFile( if(EFI_ERROR (Status)) { CalleeExitStatus = (SHELL_STATUS) (Status & (~MAX_BIT)); } else { - CalleeExitStatus = SHELL_SUCCESS; + CalleeExitStatus = (SHELL_STATUS) StartStatus; } // diff --git a/ShellPkg/Application/Shell/ShellProtocol.c b/ShellPkg/Application/Shell/ShellProtocol.c index ec4559480d..cfe2f409e4 100644 --- a/ShellPkg/Application/Shell/ShellProtocol.c +++ b/ShellPkg/Application/Shell/ShellProtocol.c @@ -1386,11 +1386,13 @@ InternalShellExecuteDevicePath( IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONST CHAR16 *CommandLine OPTIONAL, IN CONST CHAR16 **Environment OPTIONAL, + OUT EFI_STATUS *StartImageStatus OPTIONAL, OUT UINTN *ExitDataSize OPTIONAL, OUT CHAR16 **ExitData OPTIONAL ) { EFI_STATUS Status; + EFI_STATUS StartStatus; EFI_STATUS CleanupStatus; EFI_HANDLE NewHandle; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; @@ -1504,11 +1506,14 @@ InternalShellExecuteDevicePath( // now start the image, passing up exit data if the caller requested it // if (!EFI_ERROR(Status)) { - Status = gBS->StartImage( + StartStatus = gBS->StartImage( NewHandle, ExitDataSizePtr, ExitData ); + if (StartImageStatus != NULL) { + *StartImageStatus = StartStatus; + } CleanupStatus = gBS->UninstallProtocolInterface( NewHandle, @@ -1620,6 +1625,7 @@ EfiShellExecute( DevPath, Temp, (CONST CHAR16**)Environment, + StatusCode, &ExitDataSize, &ExitData); @@ -1644,8 +1650,6 @@ EfiShellExecute( } FreePool (ExitData); Status = EFI_SUCCESS; - } else if ((StatusCode != NULL) && !EFI_ERROR(Status)) { - *StatusCode = EFI_SUCCESS; } // diff --git a/ShellPkg/Application/Shell/ShellProtocol.h b/ShellPkg/Application/Shell/ShellProtocol.h index ff123277c2..7cc1b01947 100644 --- a/ShellPkg/Application/Shell/ShellProtocol.h +++ b/ShellPkg/Application/Shell/ShellProtocol.h @@ -455,10 +455,11 @@ EfiShellEnablePageBreak ( EFI_STATUS EFIAPI InternalShellExecuteDevicePath( - IN CONST EFI_HANDLE *ParentImageHandle, + IN CONST EFI_HANDLE *ParentImageHandle, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN CONST CHAR16 *CommandLine OPTIONAL, - IN CONST CHAR16 **Environment OPTIONAL, + IN CONST CHAR16 *CommandLine OPTIONAL, + IN CONST CHAR16 **Environment OPTIONAL, + OUT EFI_STATUS *StartImageStatus OPTIONAL, OUT UINTN *ExitDataSize OPTIONAL, OUT CHAR16 **ExitData OPTIONAL ); -- 2.39.2