]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
Fixed build failed.
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / GenericBdsLib / BdsBoot.c
index 0005eb38034995c5dfe7fbd81b1a45429b11e1ba..9a8b68752991ad88b2ead7d7dc8d30449eb84956 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   BDS Lib functions which relate with create or process the boot option.\r
 \r
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -18,23 +18,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 BOOLEAN mEnumBootDevice = FALSE;\r
 EFI_HII_HANDLE gBdsLibStringPackHandle = NULL;\r
 \r
-///\r
-/// This GUID is used for an EFI Variable that stores the front device pathes\r
-/// for a partial device path that starts with the HD node.\r
-///\r
-EFI_GUID  mHdBootVariablePrivateGuid = { 0xfab7e9e1, 0x39dd, 0x4f2b, { 0x84, 0x8, 0xe2, 0xe, 0x90, 0x6c, 0xb6, 0xde } };\r
-\r
-///\r
-/// This GUID is used for register UNI string.\r
-///\r
-EFI_GUID mBdsLibStringPackGuid = {  0x3b4d9b23, 0x95ac, 0x44f6, { 0x9f, 0xcd, 0xe, 0x95, 0x94, 0x58, 0x6c, 0x72 } };\r
-\r
-///\r
-/// This GUID is used for Set/Get platform language into/from variable at last time enumeration to ensure the enumeration will\r
-/// only execute once.\r
-///\r
-EFI_GUID mBdsLibLastLangGuid = { 0xe8c545b, 0xa2ee, 0x470d, { 0x8e, 0x26, 0xbd, 0xa1, 0xa1, 0x3c, 0xa, 0xa3 } };\r
-\r
 /**\r
   The constructor function register UNI strings into imageHandle.\r
   \r
@@ -56,7 +39,7 @@ GenericBdsLibConstructor (
 {\r
 \r
   gBdsLibStringPackHandle = HiiAddPackages (\r
-                              &mBdsLibStringPackGuid,\r
+                              &gBdsLibStringPackageGuid,\r
                               &ImageHandle,\r
                               GenericBdsLibStrings,\r
                               NULL\r
@@ -356,15 +339,17 @@ BdsMatchUsbWwid (
 }\r
 \r
 /**\r
-  Find a USB device which match the specified short-form device path start with \r
-  USB Class or USB WWID device path. If ParentDevicePath is NULL, this function\r
-  will search in all USB devices of the platform. If ParentDevicePath is not NULL,\r
-  this function will only search in its child devices.\r
+  Find a USB device path which match the specified short-form device path start\r
+  with USB Class or USB WWID device path and load the boot file then return the \r
+  image handle. If ParentDevicePath is NULL, this function will search in all USB\r
+  devices of the platform. If ParentDevicePath is not NULL,this function will only\r
+  search in its child devices.\r
 \r
   @param ParentDevicePath      The device path of the parent.\r
   @param ShortFormDevicePath   The USB Class or USB WWID device path to match.\r
 \r
-  @return  The handle of matched USB device, or NULL if not found.\r
+  @return  The image Handle if find load file from specified short-form device path\r
+           or NULL if not found.\r
 \r
 **/\r
 EFI_HANDLE *\r
@@ -381,7 +366,13 @@ BdsFindUsbDevice (
   UINTN                     Index;\r
   UINTN                     ParentSize;\r
   UINTN                     Size;\r
-  EFI_HANDLE                ReturnHandle;\r
+  EFI_HANDLE                ImageHandle;\r
+  EFI_HANDLE                Handle;\r
+  EFI_DEVICE_PATH_PROTOCOL  *FullDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *NextDevicePath;\r
+\r
+  FullDevicePath = NULL;\r
+  ImageHandle    = NULL;\r
 \r
   //\r
   // Get all UsbIo Handles.\r
@@ -399,7 +390,6 @@ BdsFindUsbDevice (
     return NULL;\r
   }\r
 \r
-  ReturnHandle = NULL;\r
   ParentSize = (ParentDevicePath == NULL) ? 0 : GetDevicePathSize (ParentDevicePath);\r
   for (Index = 0; Index < UsbIoHandleCount; Index++) {\r
     //\r
@@ -414,13 +404,15 @@ BdsFindUsbDevice (
       continue;\r
     }\r
 \r
+    UsbIoDevicePath = DevicePathFromHandle (UsbIoHandleBuffer[Index]);\r
+    if (UsbIoDevicePath == NULL) {\r
+      continue;\r
+    }\r
+\r
     if (ParentDevicePath != NULL) {\r
       //\r
       // Compare starting part of UsbIoHandle's device path with ParentDevicePath.\r
       //\r
-      UsbIoDevicePath = DevicePathFromHandle (UsbIoHandleBuffer[Index]);\r
-      ASSERT (UsbIoDevicePath != NULL);\r
-\r
       Size = GetDevicePathSize (UsbIoDevicePath);\r
       if ((Size < ParentSize) ||\r
           (CompareMem (UsbIoDevicePath, ParentDevicePath, ParentSize - END_DEVICE_PATH_LENGTH) != 0)) {\r
@@ -430,18 +422,83 @@ BdsFindUsbDevice (
 \r
     if (BdsMatchUsbClass (UsbIo, (USB_CLASS_DEVICE_PATH *) ShortFormDevicePath) ||\r
         BdsMatchUsbWwid (UsbIo, (USB_WWID_DEVICE_PATH *) ShortFormDevicePath)) {\r
-      ReturnHandle = UsbIoHandleBuffer[Index];\r
+      //\r
+      // Try to find if there is the boot file in this DevicePath\r
+      //\r
+      NextDevicePath = NextDevicePathNode (ShortFormDevicePath);\r
+      if (!IsDevicePathEnd (NextDevicePath)) {\r
+        FullDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePath);\r
+        //\r
+        // Connect the full device path, so that Simple File System protocol\r
+        // could be installed for this USB device.\r
+        //\r
+        BdsLibConnectDevicePath (FullDevicePath);\r
+        REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad));\r
+        Status = gBS->LoadImage (\r
+                       TRUE,\r
+                       gImageHandle,\r
+                       FullDevicePath,\r
+                       NULL,\r
+                       0,\r
+                       &ImageHandle\r
+                       );\r
+        FreePool (FullDevicePath);\r
+      } else {\r
+        FullDevicePath = UsbIoDevicePath;\r
+        Status = EFI_NOT_FOUND;\r
+      }\r
+\r
+      //\r
+      // If we didn't find an image directly, we need to try as if it is a removable device boot option\r
+      // and load the image according to the default boot behavior for removable device.\r
+      //\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // check if there is a bootable removable media could be found in this device path ,\r
+        // and get the bootable media handle\r
+        //\r
+        Handle = BdsLibGetBootableHandle(UsbIoDevicePath);\r
+        if (Handle == NULL) {\r
+          continue;\r
+        }\r
+        //\r
+        // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media\r
+        //  machinename is ia32, ia64, x64, ...\r
+        //\r
+        FullDevicePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);\r
+        if (FullDevicePath != NULL) {\r
+          REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad));\r
+          Status = gBS->LoadImage (\r
+                          TRUE,\r
+                          gImageHandle,\r
+                          FullDevicePath,\r
+                          NULL,\r
+                          0,\r
+                          &ImageHandle\r
+                          );\r
+          if (EFI_ERROR (Status)) {\r
+            //\r
+            // The DevicePath failed, and it's not a valid\r
+            // removable media device.\r
+            //\r
+            continue;\r
+          }\r
+        } else {\r
+          continue;\r
+        }\r
+      }\r
       break;\r
     }\r
   }\r
 \r
   FreePool (UsbIoHandleBuffer);\r
-  return ReturnHandle;\r
+  return ImageHandle;\r
 }\r
 \r
 /**\r
   Expand USB Class or USB WWID device path node to be full device path of a USB\r
-  device in platform.\r
+  device in platform then load the boot file on this full device path and return the \r
+  image handle.\r
 \r
   This function support following 4 cases:\r
   1) Boot Option device path starts with a USB Class or USB WWID device path,\r
@@ -458,28 +515,25 @@ BdsFindUsbDevice (
 \r
   @param  DevicePath    The Boot Option device path.\r
 \r
-  @return  The full device path after expanding, or NULL if there is no USB Class\r
-           or USB WWID device path found, or USB Class or USB WWID device path\r
-           was found but failed to expand it.\r
+  @return  The image handle of boot file, or NULL if there is no boot file found in\r
+           the specified USB Class or USB WWID device path.\r
 \r
 **/\r
-EFI_DEVICE_PATH_PROTOCOL *\r
+EFI_HANDLE *\r
 BdsExpandUsbShortFormDevicePath (\r
   IN EFI_DEVICE_PATH_PROTOCOL       *DevicePath\r
   )\r
 {\r
-  EFI_DEVICE_PATH_PROTOCOL  *FullDevicePath;\r
-  EFI_HANDLE                *UsbIoHandle;\r
-  EFI_DEVICE_PATH_PROTOCOL  *UsbIoDevicePath;\r
+  EFI_HANDLE                *ImageHandle;\r
   EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;\r
-  EFI_DEVICE_PATH_PROTOCOL  *NextDevicePath;\r
   EFI_DEVICE_PATH_PROTOCOL  *ShortFormDevicePath;\r
 \r
   //\r
   // Search for USB Class or USB WWID device path node.\r
   //\r
   ShortFormDevicePath = NULL;\r
-  TempDevicePath = DevicePath;\r
+  ImageHandle         = NULL;\r
+  TempDevicePath      = DevicePath;\r
   while (!IsDevicePathEnd (TempDevicePath)) {\r
     if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) &&\r
         ((DevicePathSubType (TempDevicePath) == MSG_USB_CLASS_DP) ||\r
@@ -487,7 +541,6 @@ BdsExpandUsbShortFormDevicePath (
       ShortFormDevicePath = TempDevicePath;\r
       break;\r
     }\r
-\r
     TempDevicePath = NextDevicePathNode (TempDevicePath);\r
   }\r
 \r
@@ -502,14 +555,14 @@ BdsExpandUsbShortFormDevicePath (
     //\r
     // Boot Option device path starts with USB Class or USB WWID device path.\r
     //\r
-    UsbIoHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath);\r
-    if (UsbIoHandle == NULL) {\r
+    ImageHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath);\r
+    if (ImageHandle == NULL) {\r
       //\r
       // Failed to find a match in existing devices, connect the short form USB\r
       // device path and try again.\r
       //\r
       BdsLibConnectUsbDevByShortFormDP (0xff, ShortFormDevicePath);\r
-      UsbIoHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath);\r
+      ImageHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath);\r
     }\r
   } else {\r
     //\r
@@ -524,53 +577,16 @@ BdsExpandUsbShortFormDevicePath (
     SetDevicePathEndNode (((UINT8 *) TempDevicePath) + ((UINTN) ShortFormDevicePath - (UINTN) DevicePath));\r
 \r
     //\r
-    // The USB Host Controller device path is in already in Boot Option device path\r
+    // The USB Host Controller device path is already in Boot Option device path\r
     // and USB Bus driver already support RemainingDevicePath starts with USB\r
     // Class or USB WWID device path, so just search in existing USB devices and\r
     // doesn't perform ConnectController here.\r
     //\r
-    UsbIoHandle = BdsFindUsbDevice (TempDevicePath, ShortFormDevicePath);\r
+    ImageHandle = BdsFindUsbDevice (TempDevicePath, ShortFormDevicePath);\r
     FreePool (TempDevicePath);\r
   }\r
 \r
-  if (UsbIoHandle == NULL) {\r
-    //\r
-    // Failed to expand USB Class or USB WWID device path.\r
-    //\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Get device path of the matched USB device.\r
-  //\r
-  UsbIoDevicePath = DevicePathFromHandle (UsbIoHandle);\r
-  ASSERT (UsbIoDevicePath != NULL);\r
-\r
-  FullDevicePath = NULL;\r
-  //\r
-  // Advance to next device path node to skip the USB Class or USB WWID device path.\r
-  //\r
-  NextDevicePath = NextDevicePathNode (ShortFormDevicePath);\r
-  if (!IsDevicePathEnd (NextDevicePath)) {\r
-    //\r
-    // There is remaining device path after USB Class or USB WWID device path\r
-    // node, append it to the USB device path.\r
-    //\r
-    FullDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePath);\r
-\r
-    //\r
-    // Connect the full device path, so that Simple File System protocol\r
-    // could be installed for this USB device.\r
-    //\r
-    BdsLibConnectDevicePath (FullDevicePath);\r
-  } else {\r
-    //\r
-    // USB Class or WWID device path is in the end.\r
-    //\r
-    FullDevicePath = UsbIoDevicePath;\r
-  }\r
-\r
-  return FullDevicePath;\r
+  return ImageHandle;\r
 }\r
 \r
 /**\r
@@ -598,6 +614,7 @@ BdsLibBootViaBootOption (
   )\r
 {\r
   EFI_STATUS                Status;\r
+  EFI_STATUS                StatusLogo;\r
   EFI_HANDLE                Handle;\r
   EFI_HANDLE                ImageHandle;\r
   EFI_DEVICE_PATH_PROTOCOL  *FilePath;\r
@@ -605,6 +622,7 @@ BdsLibBootViaBootOption (
   EFI_DEVICE_PATH_PROTOCOL  *WorkingDevicePath;\r
   EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;\r
   LIST_ENTRY                TempBootLists;\r
+  EFI_BOOT_LOGO_PROTOCOL    *BootLogo;\r
 \r
   //\r
   // Record the performance data for End of BDS\r
@@ -638,26 +656,6 @@ BdsLibBootViaBootOption (
     }\r
   }\r
 \r
-  //\r
-  // Expand USB Class or USB WWID drive path node to full device path.\r
-  //\r
-  WorkingDevicePath = BdsExpandUsbShortFormDevicePath (DevicePath);\r
-  if (WorkingDevicePath != NULL) {\r
-    DevicePath = WorkingDevicePath;\r
-  }\r
-\r
-  //\r
-  // Signal the EVT_SIGNAL_READY_TO_BOOT event\r
-  //\r
-  EfiSignalEventReadyToBoot();\r
-\r
-  //\r
-  // Adjust the different type memory page number just before booting\r
-  // and save the updated info into the variable for next boot to use\r
-  //\r
-  BdsSetMemoryTypeInformationVariable ();\r
-\r
-\r
   //\r
   // Set Boot Current\r
   //\r
@@ -676,41 +674,64 @@ BdsLibBootViaBootOption (
           );\r
   }\r
 \r
-  ASSERT (Option->DevicePath != NULL);\r
-  if ((DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&\r
-      (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)\r
-    ) {\r
-    //\r
-    // Check to see if we should legacy BOOT. If yes then do the legacy boot\r
-    //\r
-    return BdsLibDoLegacyBoot (Option);\r
-  }\r
+  //\r
+  // Signal the EVT_SIGNAL_READY_TO_BOOT event\r
+  //\r
+  EfiSignalEventReadyToBoot();\r
+\r
+  //\r
+  // Expand USB Class or USB WWID device path node to be full device path of a USB\r
+  // device in platform then load the boot file on this full device path and get the\r
+  // image handle.\r
+  //\r
+  ImageHandle = BdsExpandUsbShortFormDevicePath (DevicePath);\r
+\r
+  //\r
+  // Adjust the different type memory page number just before booting\r
+  // and save the updated info into the variable for next boot to use\r
+  //\r
+  BdsSetMemoryTypeInformationVariable ();\r
 \r
   //\r
-  // If the boot option point to Internal FV shell, make sure it is valid\r
+  // By expanding the USB Class or WWID device path, the ImageHandle has returnned.\r
+  // Here get the ImageHandle for the non USB class or WWID device path.\r
   //\r
-  Status = BdsLibUpdateFvFileDevicePath (&DevicePath, PcdGetPtr(PcdShellFile));\r
-  if (!EFI_ERROR(Status)) {\r
-    if (Option->DevicePath != NULL) {\r
-      FreePool(Option->DevicePath);\r
+  if (ImageHandle == NULL) {\r
+    ASSERT (Option->DevicePath != NULL);\r
+    if ((DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&\r
+        (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)\r
+       ) {\r
+      //\r
+      // Check to see if we should legacy BOOT. If yes then do the legacy boot\r
+      //\r
+      return BdsLibDoLegacyBoot (Option);\r
     }\r
-    Option->DevicePath  = AllocateZeroPool (GetDevicePathSize (DevicePath));\r
-    ASSERT(Option->DevicePath != NULL);\r
-    CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));\r
-    //\r
-    // Update the shell boot option\r
-    //\r
-    InitializeListHead (&TempBootLists);\r
-    BdsLibRegisterNewOption (&TempBootLists, DevicePath, L"EFI Internal Shell", L"BootOrder");\r
 \r
     //\r
-    // free the temporary device path created by BdsLibUpdateFvFileDevicePath()\r
+    // If the boot option point to Internal FV shell, make sure it is valid\r
     //\r
-    FreePool (DevicePath);\r
-    DevicePath = Option->DevicePath;\r
-  }\r
+    Status = BdsLibUpdateFvFileDevicePath (&DevicePath, PcdGetPtr(PcdShellFile));\r
+    if (!EFI_ERROR(Status)) {\r
+      if (Option->DevicePath != NULL) {\r
+        FreePool(Option->DevicePath);\r
+      }\r
+      Option->DevicePath  = AllocateZeroPool (GetDevicePathSize (DevicePath));\r
+      ASSERT(Option->DevicePath != NULL);\r
+      CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));\r
+      //\r
+      // Update the shell boot option\r
+      //\r
+      InitializeListHead (&TempBootLists);\r
+      BdsLibRegisterNewOption (&TempBootLists, DevicePath, L"EFI Internal Shell", L"BootOrder");\r
+\r
+      //\r
+      // free the temporary device path created by BdsLibUpdateFvFileDevicePath()\r
+      //\r
+      FreePool (DevicePath);\r
+      DevicePath = Option->DevicePath;\r
+    }\r
 \r
-  DEBUG_CODE_BEGIN();\r
+    DEBUG_CODE_BEGIN();\r
 \r
     if (Option->Description == NULL) {\r
       DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting from unknown device path\n"));\r
@@ -718,63 +739,72 @@ BdsLibBootViaBootOption (
       DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting %S\n", Option->Description));\r
     }\r
         \r
-  DEBUG_CODE_END();\r
+    DEBUG_CODE_END();\r
   \r
-  Status = gBS->LoadImage (\r
-                  TRUE,\r
-                  gImageHandle,\r
-                  DevicePath,\r
-                  NULL,\r
-                  0,\r
-                  &ImageHandle\r
-                  );\r
-\r
-  //\r
-  // If we didn't find an image directly, we need to try as if it is a removable device boot option\r
-  // and load the image according to the default boot behavior for removable device.\r
-  //\r
-  if (EFI_ERROR (Status)) {\r
     //\r
-    // check if there is a bootable removable media could be found in this device path ,\r
-    // and get the bootable media handle\r
+    // Report status code for OS Loader LoadImage.\r
     //\r
-    Handle = BdsLibGetBootableHandle(DevicePath);\r
-    if (Handle == NULL) {\r
-       goto Done;\r
-    }\r
+    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad));\r
+    Status = gBS->LoadImage (\r
+                    TRUE,\r
+                    gImageHandle,\r
+                    DevicePath,\r
+                    NULL,\r
+                    0,\r
+                    &ImageHandle\r
+                    );\r
+\r
     //\r
-    // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media\r
-    //  machinename is ia32, ia64, x64, ...\r
+    // If we didn't find an image directly, we need to try as if it is a removable device boot option\r
+    // and load the image according to the default boot behavior for removable device.\r
     //\r
-    FilePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);\r
-    if (FilePath != NULL) {\r
-      Status = gBS->LoadImage (\r
-                      TRUE,\r
-                      gImageHandle,\r
-                      FilePath,\r
-                      NULL,\r
-                      0,\r
-                      &ImageHandle\r
-                      );\r
-      if (EFI_ERROR (Status)) {\r
-        //\r
-        // The DevicePath failed, and it's not a valid\r
-        // removable media device.\r
-        //\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // check if there is a bootable removable media could be found in this device path ,\r
+      // and get the bootable media handle\r
+      //\r
+      Handle = BdsLibGetBootableHandle(DevicePath);\r
+      if (Handle == NULL) {\r
         goto Done;\r
       }\r
+      //\r
+      // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media\r
+      //  machinename is ia32, ia64, x64, ...\r
+      //\r
+      FilePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);\r
+      if (FilePath != NULL) {\r
+        REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad));\r
+        Status = gBS->LoadImage (\r
+                        TRUE,\r
+                        gImageHandle,\r
+                        FilePath,\r
+                        NULL,\r
+                        0,\r
+                        &ImageHandle\r
+                        );\r
+       if (EFI_ERROR (Status)) {\r
+          //\r
+          // The DevicePath failed, and it's not a valid\r
+          // removable media device.\r
+          //\r
+          goto Done;\r
+        }\r
+      }\r
     }\r
-  }\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    // It there is any error from the Boot attempt exit now.\r
-    //\r
-    goto Done;\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // It there is any error from the Boot attempt exit now.\r
+      //\r
+      goto Done;\r
+    }\r
   }\r
   //\r
   // Provide the image with it's load options\r
   //\r
+  if (ImageHandle == NULL) {\r
+    goto Done;\r
+  }\r
   Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
@@ -782,6 +812,12 @@ BdsLibBootViaBootOption (
     ImageInfo->LoadOptionsSize  = Option->LoadOptionsSize;\r
     ImageInfo->LoadOptions      = Option->LoadOptions;\r
   }\r
+\r
+  //\r
+  // Clean to NULL because the image is loaded directly from the firmwares boot manager.\r
+  //\r
+  ImageInfo->ParentHandle = NULL;\r
+\r
   //\r
   // Before calling the image, enable the Watchdog Timer for\r
   // the 5 Minute period\r
@@ -795,6 +831,11 @@ BdsLibBootViaBootOption (
     WriteBootToOsPerformanceData ();\r
   );\r
 \r
+  //\r
+  // Report status code for OS Loader StartImage.\r
+  //\r
+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderStart));\r
+\r
   Status = gBS->StartImage (ImageHandle, ExitDataSize, ExitData);\r
   DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Image Return Status = %r\n", Status));\r
 \r
@@ -804,6 +845,15 @@ BdsLibBootViaBootOption (
   gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);\r
 \r
 Done:\r
+  //\r
+  // Set Logo status invalid after trying one boot option\r
+  //\r
+  BootLogo = NULL;\r
+  StatusLogo = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);\r
+  if (!EFI_ERROR (StatusLogo) && (BootLogo != NULL)) {\r
+    BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);\r
+  }\r
+\r
   //\r
   // Clear Boot Current\r
   //\r
@@ -857,13 +907,13 @@ BdsExpandPartitionPartialDevicePathToFull (
 \r
   FullDevicePath = NULL;\r
   //\r
-  // Check if there is prestore 'HDDP' variable.\r
+  // Check if there is prestore HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable.\r
   // If exist, search the front path which point to partition node in the variable instants.\r
-  // If fail to find or 'HDDP' not exist, reconnect all and search in all system\r
+  // If fail to find or HD_BOOT_DEVICE_PATH_VARIABLE_NAME not exist, reconnect all and search in all system\r
   //\r
   CachedDevicePath = BdsLibGetVariableAndSize (\r
-                      L"HDDP",\r
-                      &mHdBootVariablePrivateGuid,\r
+                      HD_BOOT_DEVICE_PATH_VARIABLE_NAME,\r
+                      &gHdBootDevicePathVariablGuid,\r
                       &CachedDevicePathSize\r
                       );\r
 \r
@@ -905,7 +955,7 @@ BdsExpandPartitionPartialDevicePathToFull (
       FullDevicePath = AppendDevicePath (Instance, DevicePath);\r
 \r
       //\r
-      // Adjust the 'HDDP' instances sequence if the matched one is not first one.\r
+      // Adjust the HD_BOOT_DEVICE_PATH_VARIABLE_NAME instances sequence if the matched one is not first one.\r
       //\r
       if (NeedAdjust) {\r
         //\r
@@ -925,8 +975,8 @@ BdsExpandPartitionPartialDevicePathToFull (
         // Save the matching Device Path so we don't need to do a connect all next time\r
         //\r
         Status = gRT->SetVariable (\r
-                        L"HDDP",\r
-                        &mHdBootVariablePrivateGuid,\r
+                        HD_BOOT_DEVICE_PATH_VARIABLE_NAME,\r
+                        &gHdBootDevicePathVariablGuid,\r
                         EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                         GetDevicePathSize (CachedDevicePath),\r
                         CachedDevicePath\r
@@ -940,7 +990,7 @@ BdsExpandPartitionPartialDevicePathToFull (
   }\r
 \r
   //\r
-  // If we get here we fail to find or 'HDDP' not exist, and now we need\r
+  // If we get here we fail to find or HD_BOOT_DEVICE_PATH_VARIABLE_NAME not exist, and now we need\r
   // to search all devices in the system for a matched partition\r
   //\r
   BdsLibConnectAllDriversToAllControllers ();\r
@@ -970,11 +1020,11 @@ BdsExpandPartitionPartialDevicePathToFull (
       FullDevicePath = AppendDevicePath (BlockIoDevicePath, DevicePath);\r
 \r
       //\r
-      // Save the matched partition device path in 'HDDP' variable\r
+      // Save the matched partition device path in HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable\r
       //\r
       if (CachedDevicePath != NULL) {\r
         //\r
-        // Save the matched partition device path as first instance of 'HDDP' variable\r
+        // Save the matched partition device path as first instance of HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable\r
         //\r
         if (BdsLibMatchDevicePaths (CachedDevicePath, BlockIoDevicePath)) {\r
           TempNewDevicePath = CachedDevicePath;\r
@@ -993,7 +1043,8 @@ BdsExpandPartitionPartialDevicePathToFull (
         }\r
         //\r
         // Here limit the device path instance number to 12, which is max number for a system support 3 IDE controller\r
-        // If the user try to boot many OS in different HDs or partitions, in theory, the 'HDDP' variable maybe become larger and larger.\r
+        // If the user try to boot many OS in different HDs or partitions, in theory, \r
+        // the HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable maybe become larger and larger.\r
         //\r
         InstanceNum = 0;\r
         ASSERT (CachedDevicePath != NULL);\r
@@ -1023,8 +1074,8 @@ BdsExpandPartitionPartialDevicePathToFull (
       // Save the matching Device Path so we don't need to do a connect all next time\r
       //\r
       Status = gRT->SetVariable (\r
-                      L"HDDP",\r
-                      &mHdBootVariablePrivateGuid,\r
+                      HD_BOOT_DEVICE_PATH_VARIABLE_NAME,\r
+                      &gHdBootDevicePathVariablGuid,\r
                       EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
                       GetDevicePathSize (CachedDevicePath),\r
                       CachedDevicePath\r
@@ -1193,6 +1244,13 @@ BdsLibDeleteOptionFromHandle (
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
+    if (!ValidateOption(BootOptionVar, BootOptionSize)) {\r
+      BdsDeleteBootOption (BootOrder[Index], BootOrder, &BootOrderSize);\r
+      FreePool (BootOptionVar);\r
+      Index++;\r
+      continue;\r
+    }\r
+\r
     TempPtr = BootOptionVar;\r
     TempPtr += sizeof (UINT32) + sizeof (UINT16);\r
     TempPtr += StrSize ((CHAR16 *) TempPtr);\r
@@ -1255,10 +1313,14 @@ BdsDeleteAllInvalidEfiBootOption (
   EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;\r
   UINT8                     *TempPtr;\r
   CHAR16                    *Description;\r
+  BOOLEAN                   Corrupted;\r
 \r
-  Status        = EFI_SUCCESS;\r
-  BootOrder     = NULL;\r
-  BootOrderSize = 0;\r
+  Status           = EFI_SUCCESS;\r
+  BootOrder        = NULL;\r
+  Description      = NULL;\r
+  OptionDevicePath = NULL;\r
+  BootOrderSize    = 0;\r
+  Corrupted        = FALSE;\r
 \r
   //\r
   // Check "BootOrder" variable firstly, this variable hold the number of boot options\r
@@ -1285,23 +1347,27 @@ BdsDeleteAllInvalidEfiBootOption (
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
-    TempPtr = BootOptionVar;\r
-    TempPtr += sizeof (UINT32) + sizeof (UINT16);\r
-    Description = (CHAR16 *) TempPtr;\r
-    TempPtr += StrSize ((CHAR16 *) TempPtr);\r
-    OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;\r
+    if (!ValidateOption(BootOptionVar, BootOptionSize)) {\r
+      Corrupted = TRUE;\r
+    } else {\r
+      TempPtr = BootOptionVar;\r
+      TempPtr += sizeof (UINT32) + sizeof (UINT16);\r
+      Description = (CHAR16 *) TempPtr;\r
+      TempPtr += StrSize ((CHAR16 *) TempPtr);\r
+      OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;\r
 \r
-    //\r
-    // Skip legacy boot option (BBS boot device)\r
-    //\r
-    if ((DevicePathType (OptionDevicePath) == BBS_DEVICE_PATH) &&\r
-        (DevicePathSubType (OptionDevicePath) == BBS_BBS_DP)) {\r
-      FreePool (BootOptionVar);\r
-      Index++;\r
-      continue;\r
+      //\r
+      // Skip legacy boot option (BBS boot device)\r
+      //\r
+      if ((DevicePathType (OptionDevicePath) == BBS_DEVICE_PATH) &&\r
+          (DevicePathSubType (OptionDevicePath) == BBS_BBS_DP)) {\r
+        FreePool (BootOptionVar);\r
+        Index++;\r
+        continue;\r
+      }\r
     }\r
 \r
-    if (!BdsLibIsValidEFIBootOptDevicePathExt (OptionDevicePath, FALSE, Description)) {\r
+    if (Corrupted || !BdsLibIsValidEFIBootOptDevicePathExt (OptionDevicePath, FALSE, Description)) {\r
       //\r
       // Delete this invalid boot option "Boot####"\r
       //\r
@@ -1316,6 +1382,7 @@ BdsDeleteAllInvalidEfiBootOption (
       // Mark this boot option in boot order as deleted\r
       //\r
       BootOrder[Index] = 0xffff;\r
+      Corrupted        = FALSE;\r
     }\r
 \r
     FreePool (BootOptionVar);\r
@@ -1398,6 +1465,7 @@ BdsLibEnumerateAllBootOption (
 {\r
   EFI_STATUS                    Status;\r
   UINT16                        FloppyNumber;\r
+  UINT16                        HarddriveNumber;\r
   UINT16                        CdromNumber;\r
   UINT16                        UsbNumber;\r
   UINT16                        MiscNumber;\r
@@ -1406,6 +1474,8 @@ BdsLibEnumerateAllBootOption (
   UINTN                         NumberBlockIoHandles;\r
   EFI_HANDLE                    *BlockIoHandles;\r
   EFI_BLOCK_IO_PROTOCOL         *BlkIo;\r
+  BOOLEAN                       Removable[2];\r
+  UINTN                         RemovableIndex;\r
   UINTN                         Index;\r
   UINTN                         NumOfLoadFileHandles;\r
   EFI_HANDLE                    *LoadFileHandles;\r
@@ -1428,13 +1498,14 @@ BdsLibEnumerateAllBootOption (
   EFI_IMAGE_OPTIONAL_HEADER_UNION       HdrData;\r
   EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;\r
 \r
-  FloppyNumber  = 0;\r
-  CdromNumber   = 0;\r
-  UsbNumber     = 0;\r
-  MiscNumber    = 0;\r
-  ScsiNumber    = 0;\r
-  PlatLang      = NULL;\r
-  LastLang      = NULL;\r
+  FloppyNumber    = 0;\r
+  HarddriveNumber = 0;\r
+  CdromNumber     = 0;\r
+  UsbNumber       = 0;\r
+  MiscNumber      = 0;\r
+  ScsiNumber      = 0;\r
+  PlatLang        = NULL;\r
+  LastLang        = NULL;\r
   ZeroMem (Buffer, sizeof (Buffer));\r
 \r
   //\r
@@ -1442,8 +1513,8 @@ BdsLibEnumerateAllBootOption (
   // device from the boot order variable\r
   //\r
   if (mEnumBootDevice) {\r
-    LastLang = GetVariable (L"LastEnumLang", &mBdsLibLastLangGuid);\r
-    PlatLang = GetEfiGlobalVariable (L"PlatformLang");\r
+    GetVariable2 (LAST_ENUM_LANGUAGE_VARIABLE_NAME, &gLastEnumLangGuid, (VOID**)&LastLang, NULL);\r
+    GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatLang, NULL);\r
     ASSERT (PlatLang != NULL);\r
     if ((LastLang != NULL) && (AsciiStrCmp (LastLang, PlatLang) == 0)) {\r
       Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");\r
@@ -1452,8 +1523,8 @@ BdsLibEnumerateAllBootOption (
       return Status;\r
     } else {\r
       Status = gRT->SetVariable (\r
-        L"LastEnumLang",\r
-        &mBdsLibLastLangGuid,\r
+        LAST_ENUM_LANGUAGE_VARIABLE_NAME,\r
+        &gLastEnumLangGuid,\r
         EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
         AsciiStrSize (PlatLang),\r
         PlatLang\r
@@ -1480,8 +1551,13 @@ BdsLibEnumerateAllBootOption (
   BdsDeleteAllInvalidEfiBootOption ();\r
 \r
   //\r
-  // Parse removable media\r
+  // Parse removable media followed by fixed media.\r
+  // The Removable[] array is used by the for-loop below to create removable media boot options \r
+  // at first, and then to create fixed media boot options.\r
   //\r
+  Removable[0]  = FALSE;\r
+  Removable[1]  = TRUE;\r
+\r
   gBS->LocateHandleBuffer (\r
         ByProtocol,\r
         &gEfiBlockIoProtocolGuid,\r
@@ -1490,81 +1566,90 @@ BdsLibEnumerateAllBootOption (
         &BlockIoHandles\r
         );\r
 \r
-  for (Index = 0; Index < NumberBlockIoHandles; Index++) {\r
-    Status = gBS->HandleProtocol (\r
-                    BlockIoHandles[Index],\r
-                    &gEfiBlockIoProtocolGuid,\r
-                    (VOID **) &BlkIo\r
-                    );\r
-    if (!EFI_ERROR (Status)) {\r
-      if (!BlkIo->Media->RemovableMedia) {\r
-        //\r
-        // skip the non-removable block devices\r
-        //\r
+  for (RemovableIndex = 0; RemovableIndex < 2; RemovableIndex++) {\r
+    for (Index = 0; Index < NumberBlockIoHandles; Index++) {\r
+      Status = gBS->HandleProtocol (\r
+                      BlockIoHandles[Index],\r
+                      &gEfiBlockIoProtocolGuid,\r
+                      (VOID **) &BlkIo\r
+                      );\r
+      //\r
+      // skip the fixed block io then the removable block io\r
+      //\r
+      if (EFI_ERROR (Status) || (BlkIo->Media->RemovableMedia == Removable[RemovableIndex])) {\r
         continue;\r
       }\r
-    }\r
-    DevicePath  = DevicePathFromHandle (BlockIoHandles[Index]);\r
-    DevicePathType = BdsGetBootTypeFromDevicePath (DevicePath);\r
+      DevicePath  = DevicePathFromHandle (BlockIoHandles[Index]);\r
+      DevicePathType = BdsGetBootTypeFromDevicePath (DevicePath);\r
 \r
-    switch (DevicePathType) {\r
-    case BDS_EFI_ACPI_FLOPPY_BOOT:\r
-      if (FloppyNumber != 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)), FloppyNumber);\r
-      } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)));\r
-      }\r
-      BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
-      FloppyNumber++;\r
-      break;\r
+      switch (DevicePathType) {\r
+      case BDS_EFI_ACPI_FLOPPY_BOOT:\r
+        if (FloppyNumber != 0) {\r
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)), FloppyNumber);\r
+        } else {\r
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)));\r
+        }\r
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
+        FloppyNumber++;\r
+        break;\r
 \r
-    //\r
-    // Assume a removable SATA device should be the DVD/CD device\r
-    //\r
-    case BDS_EFI_MESSAGE_ATAPI_BOOT:\r
-    case BDS_EFI_MESSAGE_SATA_BOOT:\r
-      if (CdromNumber != 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)), CdromNumber);\r
-      } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)));\r
-      }\r
-      DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Buffer: %S\n", Buffer));\r
-      BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
-      CdromNumber++;\r
-      break;\r
+      //\r
+      // Assume a removable SATA device should be the DVD/CD device, a fixed SATA device should be the Hard Drive device.\r
+      //\r
+      case BDS_EFI_MESSAGE_ATAPI_BOOT:\r
+      case BDS_EFI_MESSAGE_SATA_BOOT:\r
+        if (BlkIo->Media->RemovableMedia) {\r
+          if (CdromNumber != 0) {\r
+            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)), CdromNumber);\r
+          } else {\r
+            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)));\r
+          }\r
+          CdromNumber++;\r
+        } else {\r
+          if (HarddriveNumber != 0) {\r
+            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)), HarddriveNumber);\r
+          } else {\r
+            UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)));\r
+          }\r
+          HarddriveNumber++;\r
+        }\r
+        DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Buffer: %S\n", Buffer));\r
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
+        break;\r
 \r
-    case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:\r
-      if (UsbNumber != 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)), UsbNumber);\r
-      } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)));\r
-      }\r
-      BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
-      UsbNumber++;\r
-      break;\r
+      case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:\r
+        if (UsbNumber != 0) {\r
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)), UsbNumber);\r
+        } else {\r
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)));\r
+        }\r
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
+        UsbNumber++;\r
+        break;\r
 \r
-    case BDS_EFI_MESSAGE_SCSI_BOOT:\r
-      if (ScsiNumber != 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)), ScsiNumber);\r
-      } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)));\r
-      }\r
-      BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
-      ScsiNumber++;\r
-      break;\r
+      case BDS_EFI_MESSAGE_SCSI_BOOT:\r
+        if (ScsiNumber != 0) {\r
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)), ScsiNumber);\r
+        } else {\r
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)));\r
+        }\r
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
+        ScsiNumber++;\r
+        break;\r
 \r
-    case BDS_EFI_MESSAGE_MISC_BOOT:\r
-      if (MiscNumber != 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)), MiscNumber);\r
-      } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)));\r
-      }\r
-      BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
-      MiscNumber++;\r
-      break;\r
+      case BDS_EFI_MESSAGE_MISC_BOOT:\r
+        if (MiscNumber != 0) {\r
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)), MiscNumber);\r
+        } else {\r
+          UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)));\r
+        }\r
+        BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
+        MiscNumber++;\r
+        break;\r
 \r
-    default:\r
-      break;\r
+      default:\r
+        break;\r
+      }\r
     }\r
   }\r
 \r
@@ -1600,7 +1685,7 @@ BdsLibEnumerateAllBootOption (
     // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI\r
     //  machinename is ia32, ia64, x64, ...\r
     //\r
-    Hdr.Union = &HdrData;\r
+    Hdr.Union  = &HdrData;\r
     NeedDelete = TRUE;\r
     Status     = BdsLibGetImageHeader (\r
                    FileSystemHandles[Index],\r
@@ -1849,6 +1934,7 @@ BdsLibGetBootableHandle (
   )\r
 {\r
   EFI_STATUS                      Status;\r
+  EFI_TPL                         OldTpl;\r
   EFI_DEVICE_PATH_PROTOCOL        *UpdatedDevicePath;\r
   EFI_DEVICE_PATH_PROTOCOL        *DupDevicePath;\r
   EFI_HANDLE                      Handle;\r
@@ -1868,6 +1954,12 @@ BdsLibGetBootableHandle (
 \r
   UpdatedDevicePath = DevicePath;\r
 \r
+  //\r
+  // Enter to critical section to protect the acquired BlockIo instance \r
+  // from getting released due to the USB mass storage hotplug event\r
+  //\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
   //\r
   // Check whether the device is connected\r
   //\r
@@ -1895,6 +1987,8 @@ BdsLibGetBootableHandle (
     // Get BlockIo protocol and check removable attribute\r
     //\r
     Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
     //\r
     // Issue a dummy read to the device to check for media change.\r
     // When the removable media is changed, any Block IO read/write will\r
@@ -1991,6 +2085,8 @@ BdsLibGetBootableHandle (
     FreePool(SimpleFileSystemHandles);\r
   }\r
 \r
+  gBS->RestoreTPL (OldTpl);\r
+\r
   return ReturnHandle;\r
 }\r
 \r
@@ -2326,14 +2422,17 @@ BdsLibIsValidEFIBootOptDevicePathExt (
   }\r
 \r
   //\r
-  // Check if it's a valid boot option for internal Shell\r
+  // Check if it's a valid boot option for internal FV application\r
   //\r
   if (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode) != NULL) {\r
     //\r
-    // If the boot option point to Internal FV shell, make sure it is valid\r
+    // If the boot option point to internal FV application, make sure it is valid\r
     //\r
     TempDevicePath = DevPath;\r
-    Status = BdsLibUpdateFvFileDevicePath (&TempDevicePath, PcdGetPtr(PcdShellFile));\r
+    Status = BdsLibUpdateFvFileDevicePath (\r
+               &TempDevicePath,\r
+               EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode)\r
+               );\r
     if (Status == EFI_ALREADY_STARTED) {\r
       return TRUE;\r
     } else {\r