]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ShellPkg: Make Argv[0] the full file path of the command
authorBrendan Jackman <Brendan.Jackman@arm.com>
Tue, 11 Feb 2014 22:45:18 +0000 (22:45 +0000)
committerjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 11 Feb 2014 22:45:18 +0000 (22:45 +0000)
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

ShellPkg/Application/Shell/ShellProtocol.c

index 9260d9b021e6beb620ee7734210c9f942e90a34a..502713770501158cf80c12e596f6a5bc2b4eef38 100644 (file)
@@ -1396,6 +1396,7 @@ InternalShellExecuteDevicePath(
   EFI_SHELL_PARAMETERS_PROTOCOL ShellParamsProtocol;\r
   UINTN                         InternalExitDataSize;\r
   UINTN                         *ExitDataSizePtr;\r
   EFI_SHELL_PARAMETERS_PROTOCOL ShellParamsProtocol;\r
   UINTN                         InternalExitDataSize;\r
   UINTN                         *ExitDataSizePtr;\r
+  CHAR16                        *ImagePath;\r
 \r
   // ExitDataSize is not OPTIONAL for gBS->BootServices, provide somewhere for\r
   // it to be dumped if the caller doesn't want it.\r
 \r
   // ExitDataSize is not OPTIONAL for gBS->BootServices, provide somewhere for\r
   // it to be dumped if the caller doesn't want it.\r
@@ -1464,6 +1465,33 @@ InternalShellExecuteDevicePath(
     ShellParamsProtocol.StdErr  = ShellInfoObject.NewShellParametersProtocol->StdErr;\r
     Status = UpdateArgcArgv(&ShellParamsProtocol, CommandLine, NULL, NULL);\r
     ASSERT_EFI_ERROR(Status);\r
     ShellParamsProtocol.StdErr  = ShellInfoObject.NewShellParametersProtocol->StdErr;\r
     Status = UpdateArgcArgv(&ShellParamsProtocol, CommandLine, NULL, NULL);\r
     ASSERT_EFI_ERROR(Status);\r
+    //\r
+    // Replace Argv[0] with the full path of the binary we're executing:\r
+    // If the command line was "foo", the binary might be called "foo.efi".\r
+    // "The first entry in [Argv] is always the full file path of the\r
+    //  executable" - UEFI Shell Spec section 2.3\r
+    //\r
+    ImagePath = EfiShellGetFilePathFromDevicePath (DevicePath);\r
+    // The image we're executing isn't necessarily in a filesystem - it might\r
+    // be memory mapped. In this case EfiShellGetFilePathFromDevicePath will\r
+    // return NULL, and we'll leave Argv[0] as UpdateArgcArgv set it.\r
+    if (ImagePath != NULL) {\r
+      if (ShellParamsProtocol.Argv == NULL) {\r
+        // Command line was empty or null.\r
+        // (UpdateArgcArgv sets Argv to NULL when CommandLine is "" or NULL)\r
+        ShellParamsProtocol.Argv = AllocatePool (sizeof (CHAR16 *));\r
+        if (ShellParamsProtocol.Argv == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto Cleanup;\r
+        }\r
+        ShellParamsProtocol.Argc = 1;\r
+      } else {\r
+        // Free the string UpdateArgcArgv put in Argv[0];\r
+        FreePool (ShellParamsProtocol.Argv[0]);\r
+      }\r
+      ShellParamsProtocol.Argv[0] = ImagePath;\r
+    }\r
+\r
     Status = gBS->InstallProtocolInterface(&NewHandle, &gEfiShellParametersProtocolGuid, EFI_NATIVE_INTERFACE, &ShellParamsProtocol);\r
     ASSERT_EFI_ERROR(Status);\r
 \r
     Status = gBS->InstallProtocolInterface(&NewHandle, &gEfiShellParametersProtocolGuid, EFI_NATIVE_INTERFACE, &ShellParamsProtocol);\r
     ASSERT_EFI_ERROR(Status);\r
 \r
@@ -1706,6 +1734,7 @@ EfiShellRemoveDupInFileList(
 {\r
   EFI_SHELL_FILE_INFO *ShellFileListItem;\r
   EFI_SHELL_FILE_INFO *ShellFileListItem2;\r
 {\r
   EFI_SHELL_FILE_INFO *ShellFileListItem;\r
   EFI_SHELL_FILE_INFO *ShellFileListItem2;\r
+  EFI_SHELL_FILE_INFO *TempNode;\r
 \r
   if (FileList == NULL || *FileList == NULL) {\r
     return (EFI_INVALID_PARAMETER);\r
 \r
   if (FileList == NULL || *FileList == NULL) {\r
     return (EFI_INVALID_PARAMETER);\r
@@ -1723,8 +1752,15 @@ EfiShellRemoveDupInFileList(
             (CHAR16*)ShellFileListItem->FullName,\r
             (CHAR16*)ShellFileListItem2->FullName) == 0\r
          ){\r
             (CHAR16*)ShellFileListItem->FullName,\r
             (CHAR16*)ShellFileListItem2->FullName) == 0\r
          ){\r
+        TempNode = (EFI_SHELL_FILE_INFO *)GetPreviousNode(\r
+                                            &(*FileList)->Link,\r
+                                            &ShellFileListItem2->Link\r
+                                            );\r
         RemoveEntryList(&ShellFileListItem2->Link);\r
         InternalFreeShellFileInfoNode(ShellFileListItem2);\r
         RemoveEntryList(&ShellFileListItem2->Link);\r
         InternalFreeShellFileInfoNode(ShellFileListItem2);\r
+        // Set ShellFileListItem2 to PreviousNode so we don't access Freed\r
+        // memory in GetNextNode in the loop expression above.\r
+        ShellFileListItem2 = TempNode;\r
       }\r
     }\r
   }\r
       }\r
     }\r
   }\r