]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
MdeModulePkg/UefiBootManagerLib: fix LoadImage/StartImage status code rep.
[mirror_edk2.git] / MdeModulePkg / Library / UefiBootManagerLib / BmBoot.c
index 6a23477eb8730dfa94faa4e6447b792d514cd901..4ce83ce22d617620ceb98f90824525da9c2b358c 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Library functions which relates with booting.\r
 \r
-Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.<BR>\r
 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
@@ -1667,6 +1667,51 @@ BmIsBootManagerMenuFilePath (
   return FALSE;\r
 }\r
 \r
+/**\r
+  Report status code with EFI_RETURN_STATUS_EXTENDED_DATA about LoadImage() or\r
+  StartImage() failure.\r
+\r
+  @param[in] ErrorCode      An Error Code in the Software Class, DXE Boot\r
+                            Service Driver Subclass. ErrorCode will be used to\r
+                            compose the Value parameter for status code\r
+                            reporting. Must be one of\r
+                            EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR and\r
+                            EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED.\r
+\r
+  @param[in] FailureStatus  The failure status returned by the boot service\r
+                            that should be reported.\r
+**/\r
+VOID\r
+BmReportLoadFailure (\r
+  IN UINT32     ErrorCode,\r
+  IN EFI_STATUS FailureStatus\r
+  )\r
+{\r
+  EFI_RETURN_STATUS_EXTENDED_DATA ExtendedData;\r
+\r
+  if (!ReportErrorCodeEnabled ()) {\r
+    return;\r
+  }\r
+\r
+  ASSERT (\r
+    (ErrorCode == EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR) ||\r
+    (ErrorCode == EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED)\r
+    );\r
+\r
+  ZeroMem (&ExtendedData, sizeof (ExtendedData));\r
+  ExtendedData.ReturnStatus = FailureStatus;\r
+\r
+  REPORT_STATUS_CODE_EX (\r
+    (EFI_ERROR_CODE | EFI_ERROR_MINOR),\r
+    (EFI_SOFTWARE_DXE_BS_DRIVER | ErrorCode),\r
+    0,\r
+    NULL,\r
+    NULL,\r
+    &ExtendedData.DataHeader + 1,\r
+    sizeof (ExtendedData) - sizeof (ExtendedData.DataHeader)\r
+    );\r
+}\r
+\r
 /**\r
   Attempt to boot the EFI boot option. This routine sets L"BootCurent" and\r
   also signals the EFI ready to boot event. If the device path for the option\r
@@ -1820,12 +1865,9 @@ EfiBootManagerBoot (
 \r
     if (EFI_ERROR (Status)) {\r
       //\r
-      // Report Status Code to indicate that the failure to load boot option\r
+      // Report Status Code with the failure status to indicate that the failure to load boot option\r
       //\r
-      REPORT_STATUS_CODE (\r
-        EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-        (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR)\r
-        );\r
+      BmReportLoadFailure (EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR, Status);\r
       BootOption->Status = Status;\r
       //\r
       // Destroy the RAM disk\r
@@ -1904,12 +1946,9 @@ EfiBootManagerBoot (
   BootOption->Status = Status;\r
   if (EFI_ERROR (Status)) {\r
     //\r
-    // Report Status Code to indicate that boot failure\r
+    // Report Status Code with the failure status to indicate that boot failure\r
     //\r
-    REPORT_STATUS_CODE (\r
-      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-      (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED)\r
-      );\r
+    BmReportLoadFailure (EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED, Status);\r
   }\r
   PERF_END_EX (gImageHandle, "BdsAttempt", NULL, 0, (UINT32) OptionNumber);\r
 \r
@@ -1979,37 +2018,33 @@ BmMatchPartitionDevicePathNode (
   }\r
 \r
   //\r
-  // find the partition device path node\r
+  // Match all the partition device path nodes including the nested partition nodes\r
   //\r
   while (!IsDevicePathEnd (BlockIoDevicePath)) {\r
     if ((DevicePathType (BlockIoDevicePath) == MEDIA_DEVICE_PATH) &&\r
         (DevicePathSubType (BlockIoDevicePath) == MEDIA_HARDDRIVE_DP)\r
         ) {\r
-      break;\r
+      //\r
+      // See if the harddrive device path in blockio matches the orig Hard Drive Node\r
+      //\r
+      Node = (HARDDRIVE_DEVICE_PATH *) BlockIoDevicePath;\r
+\r
+      //\r
+      // Match Signature and PartitionNumber.\r
+      // Unused bytes in Signature are initiaized with zeros.\r
+      //\r
+      if ((Node->PartitionNumber == HardDriveDevicePath->PartitionNumber) &&\r
+          (Node->MBRType == HardDriveDevicePath->MBRType) &&\r
+          (Node->SignatureType == HardDriveDevicePath->SignatureType) &&\r
+          (CompareMem (Node->Signature, HardDriveDevicePath->Signature, sizeof (Node->Signature)) == 0)) {\r
+        return TRUE;\r
+      }\r
     }\r
 \r
     BlockIoDevicePath = NextDevicePathNode (BlockIoDevicePath);\r
   }\r
 \r
-  if (IsDevicePathEnd (BlockIoDevicePath)) {\r
-    return FALSE;\r
-  }\r
-\r
-  //\r
-  // See if the harddrive device path in blockio matches the orig Hard Drive Node\r
-  //\r
-  Node = (HARDDRIVE_DEVICE_PATH *) BlockIoDevicePath;\r
-\r
-  //\r
-  // Match Signature and PartitionNumber.\r
-  // Unused bytes in Signature are initiaized with zeros.\r
-  //\r
-  return (BOOLEAN) (\r
-    (Node->PartitionNumber == HardDriveDevicePath->PartitionNumber) &&\r
-    (Node->MBRType == HardDriveDevicePath->MBRType) &&\r
-    (Node->SignatureType == HardDriveDevicePath->SignatureType) &&\r
-    (CompareMem (Node->Signature, HardDriveDevicePath->Signature, sizeof (Node->Signature)) == 0)\r
-    );\r
+  return FALSE;\r
 }\r
 \r
 /**\r
@@ -2461,3 +2496,26 @@ EfiBootManagerGetBootManagerMenu (
   }\r
 }\r
 \r
+/**\r
+  Get the next possible full path pointing to the load option.\r
+  The routine doesn't guarantee the returned full path points to an existing\r
+  file, and it also doesn't guarantee the existing file is a valid load option.\r
+  BmGetNextLoadOptionBuffer() guarantees.\r
+\r
+  @param FilePath  The device path pointing to a load option.\r
+                   It could be a short-form device path.\r
+  @param FullPath  The full path returned by the routine in last call.\r
+                   Set to NULL in first call.\r
+\r
+  @return The next possible full path pointing to the load option.\r
+          Caller is responsible to free the memory.\r
+**/\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+EFIAPI\r
+EfiBootManagerGetNextLoadOptionDevicePath (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL          *FilePath,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL          *FullPath\r
+  )\r
+{\r
+  return BmGetNextLoadOptionDevicePath(FilePath, FullPath);\r
+}\r