]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
MdeModulePkg/UefiBootManagerLib: Avoid buggy USB short-form expanding
[mirror_edk2.git] / MdeModulePkg / Library / UefiBootManagerLib / BmBoot.c
index d5818ca0698520ee93e47b3949285fc7bafaf7a4..d6844823aa5519c72a182d033000ebd07fe744d4 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Library functions which relates with booting.\r
 \r
-Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2017, 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
@@ -131,21 +131,16 @@ BmFindBootOptionInVariable (
 }\r
 \r
 /**\r
-  Get the file buffer using a Memory Mapped Device Path.\r
-\r
+  Return the correct FV file path.\r
   FV address may change across reboot. This routine promises the FV file device path is right.\r
 \r
   @param  FilePath     The Memory Mapped Device Path to get the file buffer.\r
-  @param  FullPath     Receive the updated FV Device Path pointint to the file.\r
-  @param  FileSize     Receive the file buffer size.\r
 \r
-  @return  The file buffer.\r
+  @return  The updated FV Device Path pointint to the file.\r
 **/\r
-VOID *\r
-BmGetFileBufferByFvFilePath (\r
-  IN EFI_DEVICE_PATH_PROTOCOL      *FilePath,\r
-  OUT EFI_DEVICE_PATH_PROTOCOL     **FullPath,\r
-  OUT UINTN                        *FileSize\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+BmAdjustFvFilePath (\r
+  IN EFI_DEVICE_PATH_PROTOCOL      *FilePath\r
   )\r
 {\r
   EFI_STATUS                    Status;\r
@@ -153,11 +148,10 @@ BmGetFileBufferByFvFilePath (
   EFI_DEVICE_PATH_PROTOCOL      *FvFileNode;\r
   EFI_HANDLE                    FvHandle;\r
   EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;\r
-  UINT32                        AuthenticationStatus;\r
   UINTN                         FvHandleCount;\r
   EFI_HANDLE                    *FvHandles;\r
   EFI_DEVICE_PATH_PROTOCOL      *NewDevicePath;\r
-  VOID                          *FileBuffer;\r
+  EFI_DEVICE_PATH_PROTOCOL      *FullPath;\r
 \r
   //\r
   // Get the file buffer by using the exactly FilePath.\r
@@ -165,11 +159,7 @@ BmGetFileBufferByFvFilePath (
   FvFileNode = FilePath;\r
   Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &FvFileNode, &FvHandle);\r
   if (!EFI_ERROR (Status)) {\r
-    FileBuffer = GetFileBufferByFilePath (TRUE, FilePath, FileSize, &AuthenticationStatus);\r
-    if (FileBuffer != NULL) {\r
-      *FullPath = DuplicateDevicePath (FilePath);\r
-    }\r
-    return FileBuffer;\r
+    return DuplicateDevicePath (FilePath);\r
   }\r
 \r
   //\r
@@ -190,11 +180,10 @@ BmGetFileBufferByFvFilePath (
          (VOID **) &LoadedImage\r
          );\r
   NewDevicePath = AppendDevicePathNode (DevicePathFromHandle (LoadedImage->DeviceHandle), FvFileNode);\r
-  FileBuffer = BmGetFileBufferByFvFilePath (NewDevicePath, FullPath, FileSize);\r
+  FullPath = BmAdjustFvFilePath (NewDevicePath);\r
   FreePool (NewDevicePath);\r
-\r
-  if (FileBuffer != NULL) {\r
-    return FileBuffer;\r
+  if (FullPath != NULL) {\r
+    return FullPath;\r
   }\r
 \r
   //\r
@@ -207,22 +196,25 @@ BmGetFileBufferByFvFilePath (
          &FvHandleCount,\r
          &FvHandles\r
          );\r
-  for (Index = 0; (Index < FvHandleCount) && (FileBuffer == NULL); Index++) {\r
+  for (Index = 0; Index < FvHandleCount; Index++) {\r
     if (FvHandles[Index] == LoadedImage->DeviceHandle) {\r
       //\r
-      // Skip current FV\r
+      // Skip current FV, it was handed in first step.\r
       //\r
       continue;\r
     }\r
     NewDevicePath = AppendDevicePathNode (DevicePathFromHandle (FvHandles[Index]), FvFileNode);\r
-    FileBuffer = BmGetFileBufferByFvFilePath (NewDevicePath, FullPath, FileSize);\r
+    FullPath = BmAdjustFvFilePath (NewDevicePath);\r
     FreePool (NewDevicePath);\r
+    if (FullPath != NULL) {\r
+      break;\r
+    }\r
   }\r
   \r
   if (FvHandles != NULL) {\r
     FreePool (FvHandles);\r
   }\r
-  return FileBuffer;\r
+  return FullPath;\r
 }\r
 \r
 /**\r
@@ -555,46 +547,64 @@ BmFindUsbDevice (
 \r
   @param FilePath      The device path pointing to a load option.\r
                        It could be a short-form device path.\r
-  @param FullPath      Return the full device path of the load option after\r
-                       short-form device path expanding.\r
-                       Caller is responsible to free it.\r
-  @param FileSize      Return the load option size.\r
+  @param FullPath      The full path returned by the routine in last call.\r
+                       Set to NULL in first call.\r
   @param ShortformNode Pointer to the USB short-form device path node in the FilePath buffer.\r
 \r
-  @return The load option buffer. Caller is responsible to free the memory.\r
+  @return The next possible full path pointing to the load option.\r
+          Caller is responsible to free the memory.\r
 **/\r
-VOID *\r
+EFI_DEVICE_PATH_PROTOCOL *\r
 BmExpandUsbDevicePath (\r
   IN  EFI_DEVICE_PATH_PROTOCOL  *FilePath,\r
-  OUT EFI_DEVICE_PATH_PROTOCOL  **FullPath,\r
-  OUT UINTN                     *FileSize,\r
-  IN EFI_DEVICE_PATH_PROTOCOL   *ShortformNode\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *FullPath,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *ShortformNode\r
   )\r
 {\r
   UINTN                             ParentDevicePathSize;\r
   EFI_DEVICE_PATH_PROTOCOL          *RemainingDevicePath;\r
-  EFI_DEVICE_PATH_PROTOCOL          *FullDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL          *NextFullPath;\r
   EFI_HANDLE                        *Handles;\r
   UINTN                             HandleCount;\r
   UINTN                             Index;\r
-  VOID                              *FileBuffer;\r
+  BOOLEAN                           GetNext;\r
 \r
+  NextFullPath = NULL;\r
+  GetNext = (BOOLEAN)(FullPath == NULL);\r
   ParentDevicePathSize = (UINTN) ShortformNode - (UINTN) FilePath;\r
   RemainingDevicePath = NextDevicePathNode (ShortformNode);\r
-  FileBuffer = NULL;\r
   Handles = BmFindUsbDevice (FilePath, ParentDevicePathSize, &HandleCount);\r
 \r
-  for (Index = 0; (Index < HandleCount) && (FileBuffer == NULL); Index++) {\r
-    FullDevicePath = AppendDevicePath (DevicePathFromHandle (Handles[Index]), RemainingDevicePath);\r
-    FileBuffer = EfiBootManagerGetLoadOptionBuffer (FullDevicePath, FullPath, FileSize);\r
-    FreePool (FullDevicePath);\r
+  for (Index = 0; Index < HandleCount; Index++) {\r
+    FilePath = AppendDevicePath (DevicePathFromHandle (Handles[Index]), RemainingDevicePath);\r
+    if (FilePath == NULL) {\r
+      //\r
+      // Out of memory.\r
+      //\r
+      continue;\r
+    }\r
+    NextFullPath = BmGetNextLoadOptionDevicePath (FilePath, NULL);\r
+    FreePool (FilePath);\r
+    if (NextFullPath == NULL) {\r
+      //\r
+      // No BlockIo or SimpleFileSystem under FilePath.\r
+      //\r
+      continue;\r
+    }\r
+    if (GetNext) {\r
+      break;\r
+    } else {\r
+      GetNext = (BOOLEAN)(CompareMem (NextFullPath, FullPath, GetDevicePathSize (NextFullPath)) == 0);\r
+      FreePool (NextFullPath);\r
+      NextFullPath = NULL;\r
+    }\r
   }\r
 \r
   if (Handles != NULL) {\r
     FreePool (Handles);\r
   }\r
 \r
-  return FileBuffer;\r
+  return NextFullPath;\r
 }\r
 \r
 /**\r
@@ -602,18 +612,16 @@ BmExpandUsbDevicePath (
 \r
   @param FilePath      The device path pointing to a load option.\r
                        It could be a short-form device path.\r
-  @param FullPath      Return the full device path of the load option after\r
-                       short-form device path expanding.\r
-                       Caller is responsible to free it.\r
-  @param FileSize      Return the load option size.\r
+  @param FullPath      The full path returned by the routine in last call.\r
+                       Set to NULL in first call.\r
 \r
-  @return The load option buffer. Caller is responsible to free the memory.\r
+  @return The next possible full path pointing to the load option.\r
+          Caller is responsible to free the memory.\r
 **/\r
-VOID *\r
+EFI_DEVICE_PATH_PROTOCOL *\r
 BmExpandFileDevicePath (\r
   IN  EFI_DEVICE_PATH_PROTOCOL    *FilePath,\r
-  OUT EFI_DEVICE_PATH_PROTOCOL    **FullPath,\r
-  OUT UINTN                       *FileSize\r
+  IN  EFI_DEVICE_PATH_PROTOCOL    *FullPath\r
   )\r
 {\r
   EFI_STATUS                      Status;\r
@@ -622,9 +630,8 @@ BmExpandFileDevicePath (
   EFI_HANDLE                      *Handles;\r
   EFI_BLOCK_IO_PROTOCOL           *BlockIo;\r
   UINTN                           MediaType;\r
-  EFI_DEVICE_PATH_PROTOCOL        *FullDevicePath;\r
-  VOID                            *FileBuffer;\r
-  UINT32                          AuthenticationStatus;\r
+  EFI_DEVICE_PATH_PROTOCOL        *NextFullPath;\r
+  BOOLEAN                         GetNext;\r
   \r
   EfiBootManagerConnectAll ();\r
   Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles);\r
@@ -633,6 +640,8 @@ BmExpandFileDevicePath (
     Handles = NULL;\r
   }\r
 \r
+  GetNext = (BOOLEAN)(FullPath == NULL);\r
+  NextFullPath = NULL;\r
   //\r
   // Enumerate all removable media devices followed by all fixed media devices,\r
   //   followed by media devices which don't layer on block io.\r
@@ -647,24 +656,26 @@ BmExpandFileDevicePath (
           (MediaType == 1 && BlockIo != NULL && !BlockIo->Media->RemovableMedia) ||\r
           (MediaType == 2 && BlockIo == NULL)\r
           ) {\r
-        FullDevicePath = AppendDevicePath (DevicePathFromHandle (Handles[Index]), FilePath);\r
-        FileBuffer = GetFileBufferByFilePath (TRUE, FullDevicePath, FileSize, &AuthenticationStatus);\r
-        if (FileBuffer != NULL) {\r
-          *FullPath = FullDevicePath;\r
-          FreePool (Handles);\r
-          return FileBuffer;\r
+        NextFullPath = AppendDevicePath (DevicePathFromHandle (Handles[Index]), FilePath);\r
+        if (GetNext) {\r
+          break;\r
+        } else {\r
+          GetNext = (BOOLEAN)(CompareMem (NextFullPath, FullPath, GetDevicePathSize (NextFullPath)) == 0);\r
+          FreePool (NextFullPath);\r
+          NextFullPath = NULL;\r
         }\r
-        FreePool (FullDevicePath);\r
       }\r
     }\r
+    if (NextFullPath != NULL) {\r
+      break;\r
+    }\r
   }\r
 \r
   if (Handles != NULL) {\r
     FreePool (Handles);\r
   }\r
 \r
-  *FullPath = NULL;\r
-  return NULL;\r
+  return NextFullPath;\r
 }\r
 \r
 /**\r
@@ -672,25 +683,25 @@ BmExpandFileDevicePath (
 \r
   @param FilePath      The device path pointing to a load option.\r
                        It could be a short-form device path.\r
-  @param FullPath      Return the full device path of the load option after\r
-                       short-form device path expanding.\r
-                       Caller is responsible to free it.\r
-  @param FileSize      Return the load option size.\r
+  @param FullPath      The full path returned by the routine in last call.\r
+                       Set to NULL in first call.\r
 \r
-  @return The load option buffer. Caller is responsible to free the memory.\r
+  @return The next possible full path pointing to the load option.\r
+          Caller is responsible to free the memory.\r
 **/\r
-VOID *\r
+EFI_DEVICE_PATH_PROTOCOL *\r
 BmExpandUriDevicePath (\r
   IN  EFI_DEVICE_PATH_PROTOCOL    *FilePath,\r
-  OUT EFI_DEVICE_PATH_PROTOCOL    **FullPath,\r
-  OUT UINTN                       *FileSize\r
+  IN  EFI_DEVICE_PATH_PROTOCOL    *FullPath\r
   )\r
 {\r
   EFI_STATUS                      Status;\r
   UINTN                           Index;\r
   UINTN                           HandleCount;\r
   EFI_HANDLE                      *Handles;\r
-  VOID                            *FileBuffer;\r
+  EFI_DEVICE_PATH_PROTOCOL        *NextFullPath;\r
+  EFI_DEVICE_PATH_PROTOCOL        *RamDiskDevicePath;\r
+  BOOLEAN                         GetNext;\r
 \r
   EfiBootManagerConnectAll ();\r
   Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiLoadFileProtocolGuid, NULL, &HandleCount, &Handles);\r
@@ -699,11 +710,29 @@ BmExpandUriDevicePath (
     Handles = NULL;\r
   }\r
 \r
-  FileBuffer = NULL;\r
+  NextFullPath = NULL;\r
+  GetNext = (BOOLEAN)(FullPath == NULL);\r
   for (Index = 0; Index < HandleCount; Index++) {\r
-    FileBuffer = BmGetFileBufferFromLoadFile (Handles[Index], FilePath, FullPath, FileSize);\r
-    if (FileBuffer != NULL) {\r
+    NextFullPath = BmExpandLoadFile (Handles[Index], FilePath);\r
+\r
+    if (NextFullPath == NULL) {\r
+      continue;\r
+    }\r
+\r
+    if (GetNext) {\r
       break;\r
+    } else {\r
+      GetNext = (BOOLEAN)(CompareMem (NextFullPath, FullPath, GetDevicePathSize (NextFullPath)) == 0);\r
+      //\r
+      // Free the resource occupied by the RAM disk.\r
+      //\r
+      RamDiskDevicePath = BmGetRamDiskDevicePath (NextFullPath);\r
+      if (RamDiskDevicePath != NULL) {\r
+        BmDestroyRamDisk (RamDiskDevicePath);\r
+        FreePool (RamDiskDevicePath);\r
+      }\r
+      FreePool (NextFullPath);\r
+      NextFullPath = NULL;\r
     }\r
   }\r
 \r
@@ -711,7 +740,7 @@ BmExpandUriDevicePath (
     FreePool (Handles);\r
   }\r
 \r
-  return FileBuffer;\r
+  return NextFullPath;\r
 }\r
 \r
 /**\r
@@ -781,35 +810,28 @@ BmCachePartitionDevicePath (
 \r
   @param FilePath      The device path pointing to a load option.\r
                        It could be a short-form device path.\r
-  @param FullPath      Return the full device path of the load option after\r
-                       short-form device path expanding.\r
-                       Caller is responsible to free it.\r
-  @param FileSize      Return the load option size.\r
 \r
-  @return The load option buffer. Caller is responsible to free the memory.\r
+  @return The full device path pointing to the load option.\r
 **/\r
-VOID *\r
+EFI_DEVICE_PATH_PROTOCOL *\r
 BmExpandPartitionDevicePath (\r
-  IN  EFI_DEVICE_PATH_PROTOCOL  *FilePath,\r
-  OUT EFI_DEVICE_PATH_PROTOCOL  **FullPath,\r
-  OUT UINTN                     *FileSize\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *FilePath\r
   )\r
 {\r
   EFI_STATUS                Status;\r
   UINTN                     BlockIoHandleCount;\r
   EFI_HANDLE                *BlockIoBuffer;\r
-  VOID                      *FileBuffer;\r
   EFI_DEVICE_PATH_PROTOCOL  *BlockIoDevicePath;\r
   UINTN                     Index;\r
   EFI_DEVICE_PATH_PROTOCOL  *CachedDevicePath;\r
   EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;\r
   EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *FullPath;\r
   UINTN                     CachedDevicePathSize;\r
   BOOLEAN                   NeedAdjust;\r
   EFI_DEVICE_PATH_PROTOCOL  *Instance;\r
   UINTN                     Size;\r
 \r
-  FileBuffer = NULL;\r
   //\r
   // Check if there is prestore 'HDDP' variable.\r
   // If exist, search the front path which point to partition node in the variable instants.\r
@@ -833,6 +855,7 @@ BmExpandPartitionDevicePath (
     ASSERT_EFI_ERROR (Status);\r
   }\r
 \r
+  FullPath = NULL;\r
   if (CachedDevicePath != NULL) {\r
     TempNewDevicePath = CachedDevicePath;\r
     NeedAdjust = FALSE;\r
@@ -851,10 +874,20 @@ BmExpandPartitionDevicePath (
         Status = EfiBootManagerConnectDevicePath (Instance, NULL);\r
         if (!EFI_ERROR (Status)) {\r
           TempDevicePath = AppendDevicePath (Instance, NextDevicePathNode (FilePath));\r
-          FileBuffer = EfiBootManagerGetLoadOptionBuffer (TempDevicePath, FullPath, FileSize);\r
+          //\r
+          // TempDevicePath = ACPI()/PCI()/ATA()/Partition()\r
+          // or             = ACPI()/PCI()/ATA()/Partition()/.../A.EFI\r
+          //\r
+          // When TempDevicePath = ACPI()/PCI()/ATA()/Partition(),\r
+          // it may expand to two potienal full paths (nested partition, rarely happen):\r
+          //   1. ACPI()/PCI()/ATA()/Partition()/Partition(A1)/EFI/BootX64.EFI\r
+          //   2. ACPI()/PCI()/ATA()/Partition()/Partition(A2)/EFI/BootX64.EFI\r
+          // For simplicity, only #1 is returned.\r
+          //\r
+          FullPath = BmGetNextLoadOptionDevicePath (TempDevicePath, NULL);\r
           FreePool (TempDevicePath);\r
 \r
-          if (FileBuffer != NULL) {\r
+          if (FullPath != NULL) {\r
             //\r
             // Adjust the 'HDDP' instances sequence if the matched one is not first one.\r
             //\r
@@ -875,7 +908,7 @@ BmExpandPartitionDevicePath (
 \r
             FreePool (Instance);\r
             FreePool (CachedDevicePath);\r
-            return FileBuffer;\r
+            return FullPath;\r
           }\r
         }\r
       }\r
@@ -911,10 +944,10 @@ BmExpandPartitionDevicePath (
       // Find the matched partition device path\r
       //\r
       TempDevicePath = AppendDevicePath (BlockIoDevicePath, NextDevicePathNode (FilePath));\r
-      FileBuffer = EfiBootManagerGetLoadOptionBuffer (TempDevicePath, FullPath, FileSize);\r
+      FullPath = BmGetNextLoadOptionDevicePath (TempDevicePath, NULL);\r
       FreePool (TempDevicePath);\r
 \r
-      if (FileBuffer != NULL) {\r
+      if (FullPath != NULL) {\r
         BmCachePartitionDevicePath (&CachedDevicePath, BlockIoDevicePath);\r
 \r
         //\r
@@ -940,7 +973,7 @@ BmExpandPartitionDevicePath (
   if (BlockIoBuffer != NULL) {\r
     FreePool (BlockIoBuffer);\r
   }\r
-  return FileBuffer;\r
+  return FullPath;\r
 }\r
 \r
 /**\r
@@ -948,16 +981,16 @@ BmExpandPartitionDevicePath (
   by appending EFI_REMOVABLE_MEDIA_FILE_NAME.\r
 \r
   @param DevicePath  The media device path pointing to a BlockIo or SimpleFileSystem instance.\r
-  @param FullPath    Return the full device path pointing to the load option.\r
-  @param FileSize    Return the size of the load option.\r
+  @param FullPath    The full path returned by the routine in last call.\r
+                     Set to NULL in first call.\r
 \r
-  @return  The load option buffer.\r
+  @return The next possible full path pointing to the load option.\r
+          Caller is responsible to free the memory.\r
 **/\r
-VOID *\r
+EFI_DEVICE_PATH_PROTOCOL *\r
 BmExpandMediaDevicePath (\r
   IN  EFI_DEVICE_PATH_PROTOCOL        *DevicePath,\r
-  OUT EFI_DEVICE_PATH_PROTOCOL        **FullPath,\r
-  OUT UINTN                           *FileSize\r
+  IN  EFI_DEVICE_PATH_PROTOCOL        *FullPath\r
   )\r
 {\r
   EFI_STATUS                          Status;\r
@@ -965,14 +998,15 @@ BmExpandMediaDevicePath (
   EFI_BLOCK_IO_PROTOCOL               *BlockIo;\r
   VOID                                *Buffer;\r
   EFI_DEVICE_PATH_PROTOCOL            *TempDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL            *NextFullPath;\r
   UINTN                               Size;\r
   UINTN                               TempSize;\r
   EFI_HANDLE                          *SimpleFileSystemHandles;\r
   UINTN                               NumberSimpleFileSystemHandles;\r
   UINTN                               Index;\r
-  VOID                                *FileBuffer;\r
-  UINT32                              AuthenticationStatus;\r
+  BOOLEAN                             GetNext;\r
 \r
+  GetNext = (BOOLEAN)(FullPath == NULL);\r
   //\r
   // Check whether the device is connected\r
   //\r
@@ -981,19 +1015,25 @@ BmExpandMediaDevicePath (
   if (!EFI_ERROR (Status)) {\r
     ASSERT (IsDevicePathEnd (TempDevicePath));\r
 \r
-    TempDevicePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);\r
-    FileBuffer = GetFileBufferByFilePath (TRUE, TempDevicePath, FileSize, &AuthenticationStatus);\r
-    if (FileBuffer == NULL) {\r
-      FreePool (TempDevicePath);\r
-      TempDevicePath = NULL;\r
+    NextFullPath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);\r
+    //\r
+    // For device path pointing to simple file system, it only expands to one full path.\r
+    //\r
+    if (GetNext) {\r
+      return NextFullPath;\r
+    } else {\r
+      FreePool (NextFullPath);\r
+      return NULL;\r
     }\r
-    *FullPath = TempDevicePath;\r
-    return FileBuffer;\r
   }\r
 \r
+  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   //\r
-  // For device boot option only pointing to the removable device handle, \r
-  // should make sure all its children handles (its child partion or media handles) are created and connected. \r
+  // For device boot option only pointing to the removable device handle,\r
+  // should make sure all its children handles (its child partion or media handles)\r
+  // are created and connected.\r
   //\r
   gBS->ConnectController (Handle, NULL, NULL, TRUE);\r
 \r
@@ -1004,8 +1044,6 @@ BmExpandMediaDevicePath (
   // returned. After the Block IO protocol is reinstalled, subsequent\r
   // Block IO read/write will success.\r
   //\r
-  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle);\r
-  ASSERT_EFI_ERROR (Status);\r
   Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);\r
   ASSERT_EFI_ERROR (Status);\r
   Buffer = AllocatePool (BlockIo->Media->BlockSize);\r
@@ -1023,8 +1061,7 @@ BmExpandMediaDevicePath (
   //\r
   // Detect the the default boot file from removable Media\r
   //\r
-  FileBuffer = NULL;\r
-  *FullPath = NULL;\r
+  NextFullPath = NULL;\r
   Size = GetDevicePathSize (DevicePath) - END_DEVICE_PATH_LENGTH;\r
   gBS->LocateHandleBuffer (\r
          ByProtocol,\r
@@ -1043,13 +1080,14 @@ BmExpandMediaDevicePath (
     // Check whether the device path of boot option is part of the SimpleFileSystem handle's device path\r
     //\r
     if ((Size <= TempSize) && (CompareMem (TempDevicePath, DevicePath, Size) == 0)) {\r
-      TempDevicePath = FileDevicePath (SimpleFileSystemHandles[Index], EFI_REMOVABLE_MEDIA_FILE_NAME);\r
-      FileBuffer = GetFileBufferByFilePath (TRUE, TempDevicePath, FileSize, &AuthenticationStatus);\r
-      if (FileBuffer != NULL) {\r
-        *FullPath = TempDevicePath;\r
+      NextFullPath = FileDevicePath (SimpleFileSystemHandles[Index], EFI_REMOVABLE_MEDIA_FILE_NAME);\r
+      if (GetNext) {\r
         break;\r
+      } else {\r
+        GetNext = (BOOLEAN)(CompareMem (NextFullPath, FullPath, GetDevicePathSize (NextFullPath)) == 0);\r
+        FreePool (NextFullPath);\r
+        NextFullPath = NULL;\r
       }\r
-      FreePool (TempDevicePath);\r
     }\r
   }\r
 \r
@@ -1057,7 +1095,7 @@ BmExpandMediaDevicePath (
     FreePool (SimpleFileSystemHandles);\r
   }\r
 \r
-  return FileBuffer;\r
+  return NextFullPath;\r
 }\r
 \r
 /**\r
@@ -1096,17 +1134,14 @@ BmMatchHttpBootDevicePath (
   Get the file buffer from the file system produced by Load File instance.\r
 \r
   @param LoadFileHandle The handle of LoadFile instance.\r
-  @param FullPath       Return the full device path pointing to the load option.\r
-  @param FileSize       Return the size of the load option.\r
   @param RamDiskHandle  Return the RAM Disk handle.\r
 \r
-  @return  The load option buffer.\r
+  @return The next possible full path pointing to the load option.\r
+          Caller is responsible to free the memory.\r
 **/\r
-VOID *\r
-BmGetFileBufferFromLoadFileSystem (\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+BmExpandNetworkFileSystem (\r
   IN  EFI_HANDLE                      LoadFileHandle,\r
-  OUT EFI_DEVICE_PATH_PROTOCOL        **FullPath,\r
-  OUT UINTN                           *FileSize,\r
   OUT EFI_HANDLE                      *RamDiskHandle\r
   )\r
 {\r
@@ -1136,6 +1171,9 @@ BmGetFileBufferFromLoadFileSystem (
     if (!EFI_ERROR (Status) &&\r
         (Handle == LoadFileHandle) &&\r
         (DevicePathType (Node) == MEDIA_DEVICE_PATH) && (DevicePathSubType (Node) == MEDIA_RAM_DISK_DP)) {\r
+      //\r
+      // Find the BlockIo instance populated from the LoadFile.\r
+      //\r
       Handle = Handles[Index];\r
       break;\r
     }\r
@@ -1152,13 +1190,16 @@ BmGetFileBufferFromLoadFileSystem (
   *RamDiskHandle = Handle;\r
 \r
   if (Handle != NULL) {\r
-    return BmExpandMediaDevicePath (DevicePathFromHandle (Handle), FullPath, FileSize);\r
+    //\r
+    // Re-use BmExpandMediaDevicePath() to get the full device path of load option.\r
+    // But assume only one SimpleFileSystem can be found under the BlockIo.\r
+    //\r
+    return BmExpandMediaDevicePath (DevicePathFromHandle (Handle), NULL);\r
   } else {\r
     return NULL;\r
   }\r
 }\r
 \r
-\r
 /**\r
   Return the RAM Disk device path created by LoadFile.\r
 \r
@@ -1272,27 +1313,21 @@ BmDestroyRamDisk (
 \r
   @param LoadFileHandle The specified Load File instance.\r
   @param FilePath       The file path which will pass to LoadFile().\r
-  @param FullPath       Return the full device path pointing to the load option.\r
-  @param FileSize       Return the size of the load option.\r
 \r
-  @return  The load option buffer or NULL if fails.\r
+  @return  The full device path pointing to the load option buffer.\r
 **/\r
-VOID *\r
-BmGetFileBufferFromLoadFile (\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+BmExpandLoadFile (\r
   IN  EFI_HANDLE                      LoadFileHandle,\r
-  IN  EFI_DEVICE_PATH_PROTOCOL        *FilePath,\r
-  OUT EFI_DEVICE_PATH_PROTOCOL        **FullPath,\r
-  OUT UINTN                           *FileSize\r
+  IN  EFI_DEVICE_PATH_PROTOCOL        *FilePath\r
   )\r
 {\r
   EFI_STATUS                          Status;\r
   EFI_LOAD_FILE_PROTOCOL              *LoadFile;\r
   VOID                                *FileBuffer;\r
-  BOOLEAN                             LoadFileSystem;\r
   EFI_HANDLE                          RamDiskHandle;\r
   UINTN                               BufferSize;\r
-\r
-  *FileSize = 0;\r
+  EFI_DEVICE_PATH_PROTOCOL            *FullPath;\r
 \r
   Status = gBS->OpenProtocol (\r
                   LoadFileHandle,\r
@@ -1311,52 +1346,60 @@ BmGetFileBufferFromLoadFile (
     return NULL;\r
   }\r
 \r
-  LoadFileSystem = (BOOLEAN) (Status == EFI_WARN_FILE_SYSTEM);\r
-  FileBuffer = LoadFileSystem ? AllocateReservedPages (EFI_SIZE_TO_PAGES (BufferSize)) : AllocatePool (BufferSize);\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    //\r
+    // The load option buffer is directly returned by LoadFile.\r
+    //\r
+    return DuplicateDevicePath (DevicePathFromHandle (LoadFileHandle));\r
+  }\r
+\r
+  //\r
+  // The load option resides in a RAM disk.\r
+  //\r
+  FileBuffer = AllocateReservedPages (EFI_SIZE_TO_PAGES (BufferSize));\r
   if (FileBuffer == NULL) {\r
     return NULL;\r
   }\r
 \r
   Status = LoadFile->LoadFile (LoadFile, FilePath, TRUE, &BufferSize, FileBuffer);\r
   if (EFI_ERROR (Status)) {\r
-    if (LoadFileSystem) {\r
-      FreePages (FileBuffer, EFI_SIZE_TO_PAGES (BufferSize));\r
-    } else {\r
-      FreePool (FileBuffer);\r
-    }\r
+    FreePages (FileBuffer, EFI_SIZE_TO_PAGES (BufferSize));\r
     return NULL;\r
   }\r
 \r
-  if (LoadFileSystem) {\r
-    FileBuffer = BmGetFileBufferFromLoadFileSystem (LoadFileHandle, FullPath, FileSize, &RamDiskHandle);\r
-    if (FileBuffer == NULL) {\r
-      //\r
-      // If there is no bootable executable in the populated\r
-      //\r
-      BmDestroyRamDisk (DevicePathFromHandle (RamDiskHandle));\r
-    }\r
-  } else {\r
-    *FileSize = BufferSize;\r
-    *FullPath = DuplicateDevicePath (DevicePathFromHandle (LoadFileHandle));\r
+  FullPath = BmExpandNetworkFileSystem (LoadFileHandle, &RamDiskHandle);\r
+  if (FullPath == NULL) {\r
+    //\r
+    // Free the memory occupied by the RAM disk if there is no BlockIo or SimpleFileSystem instance.\r
+    //\r
+    BmDestroyRamDisk (DevicePathFromHandle (RamDiskHandle));\r
   }\r
 \r
-  return FileBuffer;\r
+  return FullPath;\r
 }\r
 \r
 /**\r
-  Get the file buffer from all the Load File instances.\r
+  Return the full device path pointing to the load option.\r
+\r
+  FilePath may:\r
+  1. Exactly matches to a LoadFile instance.\r
+  2. Cannot match to any LoadFile instance. Wide match is required.\r
+  In either case, the routine may return:\r
+  1. A copy of FilePath when FilePath matches to a LoadFile instance and\r
+     the LoadFile returns a load option buffer.\r
+  2. A new device path with IP and URI information updated when wide match\r
+     happens.\r
+  3. A new device path pointing to a load option in RAM disk.\r
+  In either case, only one full device path is returned for a specified\r
+  FilePath.\r
 \r
   @param FilePath    The media device path pointing to a LoadFile instance.\r
-  @param FullPath    Return the full device path pointing to the load option.\r
-  @param FileSize    Return the size of the load option.\r
 \r
   @return  The load option buffer.\r
 **/\r
-VOID *\r
-BmGetFileBufferFromLoadFiles (\r
-  IN  EFI_DEVICE_PATH_PROTOCOL        *FilePath,\r
-  OUT EFI_DEVICE_PATH_PROTOCOL        **FullPath,\r
-  OUT UINTN                           *FileSize\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+BmExpandLoadFiles (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL        *FilePath\r
   )\r
 {\r
   EFI_STATUS                      Status;\r
@@ -1409,7 +1452,7 @@ BmGetFileBufferFromLoadFiles (
     return NULL;\r
   }\r
 \r
-  return BmGetFileBufferFromLoadFile (Handle, FilePath, FullPath, FileSize);\r
+  return BmExpandLoadFile (Handle, FilePath);\r
 }\r
 \r
 /**\r
@@ -1431,20 +1474,38 @@ EfiBootManagerGetLoadOptionBuffer (
   OUT EFI_DEVICE_PATH_PROTOCOL          **FullPath,\r
   OUT UINTN                             *FileSize\r
   )\r
+{\r
+  *FullPath = NULL;\r
+\r
+  EfiBootManagerConnectDevicePath (FilePath, NULL);\r
+  return BmGetNextLoadOptionBuffer (LoadOptionTypeMax, FilePath, FullPath, FileSize);\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
+BmGetNextLoadOptionDevicePath (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL          *FilePath,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL          *FullPath\r
+  )\r
 {\r
   EFI_HANDLE                      Handle;\r
-  VOID                            *FileBuffer;\r
-  UINT32                          AuthenticationStatus;\r
   EFI_DEVICE_PATH_PROTOCOL        *Node;\r
   EFI_STATUS                      Status;\r
 \r
-  ASSERT ((FilePath != NULL) && (FullPath != NULL) && (FileSize != NULL));\r
-\r
-  EfiBootManagerConnectDevicePath (FilePath, NULL);\r
-\r
-  *FullPath  = NULL;\r
-  *FileSize  = 0;\r
-  FileBuffer = NULL;\r
+  ASSERT (FilePath != NULL);\r
 \r
   //\r
   // Boot from media device by adding a default file name \EFI\BOOT\BOOT{machine type short-name}.EFI\r
@@ -1456,7 +1517,7 @@ EfiBootManagerGetLoadOptionBuffer (
   }\r
 \r
   if (!EFI_ERROR (Status) && IsDevicePathEnd (Node)) {\r
-    return BmExpandMediaDevicePath (FilePath, FullPath, FileSize);\r
+    return BmExpandMediaDevicePath (FilePath, FullPath);\r
   }\r
 \r
   //\r
@@ -1467,78 +1528,96 @@ EfiBootManagerGetLoadOptionBuffer (
     //\r
     // Expand the Harddrive device path\r
     //\r
-    return BmExpandPartitionDevicePath (FilePath, FullPath, FileSize);\r
+    if (FullPath == NULL) {\r
+      return BmExpandPartitionDevicePath (FilePath);\r
+    } else {\r
+      return NULL;\r
+    }\r
   } else if ((DevicePathType (FilePath) == MEDIA_DEVICE_PATH) &&\r
              (DevicePathSubType (FilePath) == MEDIA_FILEPATH_DP)) {\r
     //\r
     // Expand the File-path device path\r
     //\r
-    return BmExpandFileDevicePath (FilePath, FullPath, FileSize);\r
+    return BmExpandFileDevicePath (FilePath, FullPath);\r
   } else if ((DevicePathType (FilePath) == MESSAGING_DEVICE_PATH) &&\r
              (DevicePathSubType (FilePath) == MSG_URI_DP)) {\r
     //\r
     // Expand the URI device path\r
     //\r
-    return BmExpandUriDevicePath (FilePath, FullPath, FileSize);\r
+    return BmExpandUriDevicePath (FilePath, FullPath);\r
   } else {\r
-    for (Node = FilePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {\r
-      if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) &&\r
-          ((DevicePathSubType (Node) == MSG_USB_CLASS_DP) || (DevicePathSubType (Node) == MSG_USB_WWID_DP))) {\r
-        break;\r
+    Node = FilePath;\r
+    Status = gBS->LocateDevicePath (&gEfiUsbIoProtocolGuid, &Node, &Handle);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Only expand the USB WWID/Class device path\r
+      // when FilePath doesn't point to a physical UsbIo controller.\r
+      // Otherwise, infinite recursion will happen.\r
+      //\r
+      for (Node = FilePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {\r
+        if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) &&\r
+            ((DevicePathSubType (Node) == MSG_USB_CLASS_DP) || (DevicePathSubType (Node) == MSG_USB_WWID_DP))) {\r
+          break;\r
+        }\r
       }\r
-    }\r
 \r
-    if (!IsDevicePathEnd (Node)) {\r
       //\r
       // Expand the USB WWID/Class device path\r
       //\r
-      FileBuffer = BmExpandUsbDevicePath (FilePath, FullPath, FileSize, Node);\r
-      if ((FileBuffer == NULL) && (FilePath == Node)) {\r
-        //\r
-        // Boot Option device path starts with USB Class or USB WWID device path.\r
-        // For Boot Option device path which doesn't begin with the USB Class or\r
-        // USB WWID device path, it's not needed to connect again here.\r
-        //\r
-        BmConnectUsbShortFormDevicePath (FilePath);\r
-        FileBuffer = BmExpandUsbDevicePath (FilePath, FullPath, FileSize, Node);\r
+      if (!IsDevicePathEnd (Node)) {\r
+        if (FilePath == Node) {\r
+          //\r
+          // Boot Option device path starts with USB Class or USB WWID device path.\r
+          // For Boot Option device path which doesn't begin with the USB Class or\r
+          // USB WWID device path, it's not needed to connect again here.\r
+          //\r
+          BmConnectUsbShortFormDevicePath (FilePath);\r
+        }\r
+        return BmExpandUsbDevicePath (FilePath, FullPath, Node);\r
       }\r
-      return FileBuffer;\r
     }\r
   }\r
 \r
   //\r
-  // Get file buffer from FV file path.\r
+  // For the below cases, FilePath only expands to one Full path.\r
+  // So just handle the case when FullPath == NULL.\r
+  //\r
+  if (FullPath != NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Load option resides in FV.\r
   //\r
   if (BmIsFvFilePath (FilePath)) {\r
-    return BmGetFileBufferByFvFilePath (FilePath, FullPath, FileSize);\r
+    return BmAdjustFvFilePath (FilePath);\r
   }\r
 \r
   //\r
-  // Get file buffer from simple file system.\r
+  // Load option resides in Simple File System.\r
   //\r
   Node   = FilePath;\r
   Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &Node, &Handle);\r
   if (!EFI_ERROR (Status)) {\r
-    FileBuffer = GetFileBufferByFilePath (TRUE, FilePath, FileSize, &AuthenticationStatus);\r
-    if (FileBuffer != NULL) {\r
-      *FullPath = DuplicateDevicePath (FilePath);\r
-    }\r
-    return FileBuffer;\r
+    return DuplicateDevicePath (FilePath);\r
   }\r
 \r
-  return BmGetFileBufferFromLoadFiles (FilePath, FullPath, FileSize);\r
+  //\r
+  // Last chance to try: Load option may be loaded through LoadFile.\r
+  //\r
+  return BmExpandLoadFiles (FilePath);\r
 }\r
 \r
 /**\r
-  Check if it's a Device Path pointing to BootMenuApp.\r
+  Check if it's a Device Path pointing to BootManagerMenu.\r
 \r
   @param  DevicePath     Input device path.\r
 \r
-  @retval TRUE   The device path is BootMenuApp File Device Path.\r
-  @retval FALSE  The device path is NOT BootMenuApp File Device Path.\r
+  @retval TRUE   The device path is BootManagerMenu File Device Path.\r
+  @retval FALSE  The device path is NOT BootManagerMenu File Device Path.\r
 **/\r
 BOOLEAN\r
-BmIsBootMenuAppFilePath (\r
+BmIsBootManagerMenuFilePath (\r
   EFI_DEVICE_PATH_PROTOCOL     *DevicePath\r
 )\r
 {\r
@@ -1645,7 +1724,7 @@ EfiBootManagerBoot (
   // 3. Signal the EVT_SIGNAL_READY_TO_BOOT event when we are about to load and execute\r
   //    the boot option.\r
   //\r
-  if (BmIsBootMenuAppFilePath (BootOption->FilePath)) {\r
+  if (BmIsBootManagerMenuFilePath (BootOption->FilePath)) {\r
     DEBUG ((EFI_D_INFO, "[Bds] Booting Boot Manager Menu.\n"));\r
     BmStopHotkeyService (NULL, NULL);\r
   } else {\r
@@ -1684,21 +1763,13 @@ EfiBootManagerBoot (
   ImageHandle       = NULL;\r
   RamDiskDevicePath = NULL;\r
   if (DevicePathType (BootOption->FilePath) != BBS_DEVICE_PATH) {\r
-    Status     = EFI_NOT_FOUND;\r
-    FileBuffer = EfiBootManagerGetLoadOptionBuffer (BootOption->FilePath, &FilePath, &FileSize);\r
+    Status   = EFI_NOT_FOUND;\r
+    FilePath = NULL;\r
+    EfiBootManagerConnectDevicePath (BootOption->FilePath, NULL);\r
+    FileBuffer = BmGetNextLoadOptionBuffer (LoadOptionTypeBoot, BootOption->FilePath, &FilePath, &FileSize);\r
     if (FileBuffer != NULL) {\r
       RamDiskDevicePath = BmGetRamDiskDevicePath (FilePath);\r
-    }\r
-    DEBUG_CODE (\r
-      if (FileBuffer != NULL && CompareMem (BootOption->FilePath, FilePath, GetDevicePathSize (FilePath)) != 0) {\r
-        DEBUG ((EFI_D_INFO, "[Bds] DevicePath expand: "));\r
-        BmPrintDp (BootOption->FilePath);\r
-        DEBUG ((EFI_D_INFO, " -> "));\r
-        BmPrintDp (FilePath);\r
-        DEBUG ((EFI_D_INFO, "\n"));\r
-      }\r
-    );\r
-    if (BmIsLoadOptionPeHeaderValid (BootOption->OptionType, FileBuffer, FileSize)) {\r
+\r
       REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad));\r
       Status = gBS->LoadImage (\r
                       TRUE,\r
@@ -1940,7 +2011,6 @@ BmEnumerateBootOptions (
   UINTN                                 Removable;\r
   UINTN                                 Index;\r
   CHAR16                                *Description;\r
-  UINT32                                BootAttributes;\r
 \r
   ASSERT (BootOptionCount != NULL);\r
 \r
@@ -2070,6 +2140,12 @@ BmEnumerateBootOptions (
          &Handles\r
          );\r
   for (Index = 0; Index < HandleCount; Index++) {\r
+    //\r
+    // Ignore BootManagerMenu. its boot option will be created by EfiBootManagerGetBootManagerMenu().\r
+    //\r
+    if (BmIsBootManagerMenuFilePath (DevicePathFromHandle (Handles[Index]))) {\r
+      continue;\r
+    }\r
 \r
     Description = BmGetBootDescription (Handles[Index]);\r
     BootOptions = ReallocatePool (\r
@@ -2079,19 +2155,11 @@ BmEnumerateBootOptions (
                     );\r
     ASSERT (BootOptions != NULL);\r
 \r
-    //\r
-    // If LoadFile includes BootMenuApp, its boot attribue will be set to APP and HIDDEN.\r
-    //\r
-    BootAttributes = LOAD_OPTION_ACTIVE;\r
-    if (BmIsBootMenuAppFilePath (DevicePathFromHandle (Handles[Index]))) {\r
-      BootAttributes = LOAD_OPTION_CATEGORY_APP | LOAD_OPTION_ACTIVE | LOAD_OPTION_HIDDEN;\r
-    }\r
-\r
     Status = EfiBootManagerInitializeLoadOption (\r
                &BootOptions[(*BootOptionCount)++],\r
                LoadOptionNumberUnassigned,\r
                LoadOptionTypeBoot,\r
-               BootAttributes,\r
+               LOAD_OPTION_ACTIVE,\r
                Description,\r
                DevicePathFromHandle (Handles[Index]),\r
                NULL,\r
@@ -2155,7 +2223,7 @@ EfiBootManagerRefreshAllBootOption (
       // Only check those added by BDS\r
       // so that the boot options added by end-user or OS installer won't be deleted\r
       //\r
-      if (EfiBootManagerFindLoadOption (&NvBootOptions[Index], BootOptions, BootOptionCount) == (UINTN) -1) {\r
+      if (EfiBootManagerFindLoadOption (&NvBootOptions[Index], BootOptions, BootOptionCount) == -1) {\r
         Status = EfiBootManagerDeleteLoadOptionVariable (NvBootOptions[Index].OptionNumber, LoadOptionTypeBoot);\r
         //\r
         // Deleting variable with current variable implementation shouldn't fail.\r
@@ -2169,7 +2237,7 @@ EfiBootManagerRefreshAllBootOption (
   // Add new EFI boot options to NV\r
   //\r
   for (Index = 0; Index < BootOptionCount; Index++) {\r
-    if (EfiBootManagerFindLoadOption (&BootOptions[Index], NvBootOptions, NvBootOptionCount) == (UINTN) -1) {\r
+    if (EfiBootManagerFindLoadOption (&BootOptions[Index], NvBootOptions, NvBootOptionCount) == -1) {\r
       EfiBootManagerAddLoadOptionVariable (&BootOptions[Index], (UINTN) -1);\r
       //\r
       // Try best to add the boot options so continue upon failure.\r
@@ -2213,8 +2281,9 @@ BmRegisterBootManagerMenu (
   UINTN                              DataSize;\r
 \r
   DevicePath = NULL;\r
+  Description = NULL;\r
   //\r
-  // Try to find BootMenuApp from LoadFile protocol\r
+  // Try to find BootManagerMenu from LoadFile protocol\r
   //\r
   gBS->LocateHandleBuffer (\r
          ByProtocol,\r
@@ -2224,7 +2293,7 @@ BmRegisterBootManagerMenu (
          &Handles\r
          );\r
   for (Index = 0; Index < HandleCount; Index++) {\r
-    if (BmIsBootMenuAppFilePath (DevicePathFromHandle (Handles[Index]))) {\r
+    if (BmIsBootManagerMenuFilePath (DevicePathFromHandle (Handles[Index]))) {\r
       DevicePath  = DuplicateDevicePath (DevicePathFromHandle (Handles[Index]));\r
       Description = BmGetBootDescription (Handles[Index]);\r
       break;\r
@@ -2333,7 +2402,7 @@ EfiBootManagerGetBootManagerMenu (
   BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
 \r
   for (Index = 0; Index < BootOptionCount; Index++) {\r
-    if (BmIsBootMenuAppFilePath (BootOptions[Index].FilePath)) {\r
+    if (BmIsBootManagerMenuFilePath (BootOptions[Index].FilePath)) {\r
         Status = EfiBootManagerInitializeLoadOption (\r
                    BootOption,\r
                    BootOptions[Index].OptionNumber,\r