summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrendan Jackman <Brendan.Jackman@arm.com>2014-02-11 22:45:18 +0000
committerjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>2014-02-11 22:45:18 +0000
commit3e2b20a1ad4b777d2834075bcd9a38f364e42c99 (patch)
treeff1be5adf35b1e4f279e2ee71b0720eb4c64f231
parentda92bf853f573d244278ab944720005598fa0450 (diff)
downloadedk2-3e2b20a1ad4b777d2834075bcd9a38f364e42c99.tar.gz
edk2-3e2b20a1ad4b777d2834075bcd9a38f364e42c99.tar.bz2
edk2-3e2b20a1ad4b777d2834075bcd9a38f364e42c99.zip
ShellPkg: Make Argv[0] the full file path of the command
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Brendan Jackman <Brendan.Jackman@arm.com> Reviewed-by: Olivier Martin <olivier.martin@arm.com> Reviewed-by: Jaben Carsey <jaben.carsey@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15223 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--ShellPkg/Application/Shell/ShellProtocol.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/ShellPkg/Application/Shell/ShellProtocol.c b/ShellPkg/Application/Shell/ShellProtocol.c
index 9260d9b021..5027137705 100644
--- a/ShellPkg/Application/Shell/ShellProtocol.c
+++ b/ShellPkg/Application/Shell/ShellProtocol.c
@@ -1396,6 +1396,7 @@ InternalShellExecuteDevicePath(
EFI_SHELL_PARAMETERS_PROTOCOL ShellParamsProtocol;
UINTN InternalExitDataSize;
UINTN *ExitDataSizePtr;
+ CHAR16 *ImagePath;
// ExitDataSize is not OPTIONAL for gBS->BootServices, provide somewhere for
// it to be dumped if the caller doesn't want it.
@@ -1464,6 +1465,33 @@ InternalShellExecuteDevicePath(
ShellParamsProtocol.StdErr = ShellInfoObject.NewShellParametersProtocol->StdErr;
Status = UpdateArgcArgv(&ShellParamsProtocol, CommandLine, NULL, NULL);
ASSERT_EFI_ERROR(Status);
+ //
+ // Replace Argv[0] with the full path of the binary we're executing:
+ // If the command line was "foo", the binary might be called "foo.efi".
+ // "The first entry in [Argv] is always the full file path of the
+ // executable" - UEFI Shell Spec section 2.3
+ //
+ ImagePath = EfiShellGetFilePathFromDevicePath (DevicePath);
+ // The image we're executing isn't necessarily in a filesystem - it might
+ // be memory mapped. In this case EfiShellGetFilePathFromDevicePath will
+ // return NULL, and we'll leave Argv[0] as UpdateArgcArgv set it.
+ if (ImagePath != NULL) {
+ if (ShellParamsProtocol.Argv == NULL) {
+ // Command line was empty or null.
+ // (UpdateArgcArgv sets Argv to NULL when CommandLine is "" or NULL)
+ ShellParamsProtocol.Argv = AllocatePool (sizeof (CHAR16 *));
+ if (ShellParamsProtocol.Argv == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Cleanup;
+ }
+ ShellParamsProtocol.Argc = 1;
+ } else {
+ // Free the string UpdateArgcArgv put in Argv[0];
+ FreePool (ShellParamsProtocol.Argv[0]);
+ }
+ ShellParamsProtocol.Argv[0] = ImagePath;
+ }
+
Status = gBS->InstallProtocolInterface(&NewHandle, &gEfiShellParametersProtocolGuid, EFI_NATIVE_INTERFACE, &ShellParamsProtocol);
ASSERT_EFI_ERROR(Status);
@@ -1706,6 +1734,7 @@ EfiShellRemoveDupInFileList(
{
EFI_SHELL_FILE_INFO *ShellFileListItem;
EFI_SHELL_FILE_INFO *ShellFileListItem2;
+ EFI_SHELL_FILE_INFO *TempNode;
if (FileList == NULL || *FileList == NULL) {
return (EFI_INVALID_PARAMETER);
@@ -1723,8 +1752,15 @@ EfiShellRemoveDupInFileList(
(CHAR16*)ShellFileListItem->FullName,
(CHAR16*)ShellFileListItem2->FullName) == 0
){
+ TempNode = (EFI_SHELL_FILE_INFO *)GetPreviousNode(
+ &(*FileList)->Link,
+ &ShellFileListItem2->Link
+ );
RemoveEntryList(&ShellFileListItem2->Link);
InternalFreeShellFileInfoNode(ShellFileListItem2);
+ // Set ShellFileListItem2 to PreviousNode so we don't access Freed
+ // memory in GetNextNode in the loop expression above.
+ ShellFileListItem2 = TempNode;
}
}
}