MdeModulePkg/BdsDxe: Avoid overwriting PlatformRecovery####

Current implementation always creates PlatformRecovery0000
pointing to \EFI\BOOT\BOOT$(ARCH).efi but it may overwrite
PlatformRecovery#### created before (maybe by a DXE driver).

The patch only uses the smallest unused option number for
the \EFI\BOOT\BOOT$(ARCH).efi PlatformRecovery#### to avoid
overwriting already-created PlatformRecovery####.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Jie Lin <jie.lin@intel.com>
Reviewed-by: Sunny Wang <sunnywang@hpe.com>
diff --git a/MdeModulePkg/Universal/BdsDxe/BdsEntry.c b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c
index 32bcbf3..98b3931 100644
--- a/MdeModulePkg/Universal/BdsDxe/BdsEntry.c
+++ b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c
@@ -837,7 +837,7 @@
   FilePath = FileDevicePath (NULL, EFI_REMOVABLE_MEDIA_FILE_NAME);

   Status = EfiBootManagerInitializeLoadOption (

              &LoadOption,

-             0,

+             LoadOptionNumberUnassigned,

              LoadOptionTypePlatformRecovery,

              LOAD_OPTION_ACTIVE,

              L"Default PlatformRecovery",

@@ -846,9 +846,24 @@
              0

              );

   ASSERT_EFI_ERROR (Status);

-  EfiBootManagerLoadOptionToVariable (&LoadOption);

+  LoadOptions = EfiBootManagerGetLoadOptions (&LoadOptionCount, LoadOptionTypePlatformRecovery);

+  if (EfiBootManagerFindLoadOption (&LoadOption, LoadOptions, LoadOptionCount) == -1) {

+    for (Index = 0; Index < LoadOptionCount; Index++) {

+      //

+      // The PlatformRecovery#### options are sorted by OptionNumber.

+      // Find the the smallest unused number as the new OptionNumber.

+      //

+      if (LoadOptions[Index].OptionNumber != Index) {

+        break;

+      }

+    }

+    LoadOption.OptionNumber = Index;

+    Status = EfiBootManagerLoadOptionToVariable (&LoadOption);

+    ASSERT_EFI_ERROR (Status);

+  }

   EfiBootManagerFreeLoadOption (&LoadOption);

   FreePool (FilePath);

+  EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);

 

   //

   // Report Status Code to indicate connecting drivers will happen