]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
MdeModulePkg: Fix a performance data buffer overrun issue
[mirror_edk2.git] / MdeModulePkg / Library / UefiBootManagerLib / BmBoot.c
index 028edc35d53963f9c309b7bd0bdfd291f7d09888..8f14cf6d3f8116a6c7b44206757b4363e7a33231 100644 (file)
@@ -1,6 +1,7 @@
 /** @file\r
   Library functions which relates with booting.\r
 \r
+(C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
 Copyright (c) 2011 - 2015, 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
@@ -69,6 +70,8 @@ EfiBootManagerRegisterLegacyBootSupport (
   @retval MessageNetworkBoot           If given device path contains MESSAGING_DEVICE_PATH type device path node\r
                                        and its last device path node's subtype is MSG_MAC_ADDR_DP, MSG_VLAN_DP,\r
                                        MSG_IPv4_DP or MSG_IPv6_DP.\r
+  @retval MessageHttpBoot              If given device path contains MESSAGING_DEVICE_PATH type device path node\r
+                                       and its last device path node's subtype is MSG_URI_DP.\r
   @retval UnsupportedBoot              If tiven device path doesn't match the above condition, it's not supported.\r
 \r
 **/\r
@@ -113,7 +116,7 @@ BmDevicePathType (
         // If the device path not only point to driver device, it is not a messaging device path,\r
         //\r
         if (!IsDevicePathEndType (NextNode)) {\r
-          break;\r
+          continue;\r
         }\r
 \r
         switch (DevicePathSubType (Node)) {\r
@@ -139,6 +142,10 @@ BmDevicePathType (
         case MSG_IPv6_DP:\r
           return BmMessageNetworkBoot;\r
           break;\r
+\r
+        case MSG_URI_DP:\r
+          return BmMessageHttpBoot;\r
+          break;\r
         }\r
     }\r
   }\r
@@ -686,6 +693,10 @@ BmGetMiscDescription (
     Description = L"Network";\r
     break;\r
 \r
+  case BmMessageHttpBoot:\r
+    Description = L"Http";\r
+    break;\r
+\r
   default:\r
     Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **) &Fs);\r
     if (!EFI_ERROR (Status)) {\r
@@ -946,7 +957,6 @@ BmFindUsbDevice (
   EFI_DEVICE_PATH_PROTOCOL  *UsbIoDevicePath;\r
   EFI_USB_IO_PROTOCOL       *UsbIo;\r
   UINTN                     Index;\r
-  UINTN                     UsbIoDevicePathSize;\r
   BOOLEAN                   Matched;\r
 \r
   ASSERT (UsbIoHandleCount != NULL);  \r
@@ -978,7 +988,6 @@ BmFindUsbDevice (
     UsbIoDevicePath = DevicePathFromHandle (UsbIoHandles[Index]);\r
     Matched         = FALSE;\r
     if (!EFI_ERROR (Status) && (UsbIoDevicePath != NULL)) {\r
-      UsbIoDevicePathSize = GetDevicePathSize (UsbIoDevicePath) - END_DEVICE_PATH_LENGTH;\r
 \r
       //\r
       // Compare starting part of UsbIoHandle's device path with ParentDevicePath.\r
@@ -1501,9 +1510,18 @@ BmGetLoadOptionBuffer (
   // Directly reads the load option when it doesn't reside in simple file system instance (LoadFile/LoadFile2),\r
   //   or it directly points to a file in simple file system instance.\r
   //\r
+  Node   = FilePath;\r
+  Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &Node, &Handle);\r
   FileBuffer = GetFileBufferByFilePath (TRUE, FilePath, FileSize, &AuthenticationStatus);\r
   if (FileBuffer != NULL) {\r
-    *FullPath = DuplicateDevicePath (FilePath);\r
+    if (EFI_ERROR (Status)) {\r
+      *FullPath = DuplicateDevicePath (FilePath);\r
+    } else {\r
+      //\r
+      // LoadFile () may cause the device path of the Handle be updated.\r
+      //\r
+      *FullPath = AppendDevicePath (DevicePathFromHandle (Handle), Node);\r
+    }\r
   }\r
 \r
   return FileBuffer;\r
@@ -1849,6 +1867,66 @@ BmMatchPartitionDevicePathNode (
     );\r
 }\r
 \r
+/**\r
+  Enumerate all boot option descriptions and append " 2"/" 3"/... to make\r
+  unique description.\r
+\r
+  @param BootOptions            Array of boot options.\r
+  @param BootOptionCount        Count of boot options.\r
+**/\r
+VOID\r
+BmMakeBootOptionDescriptionUnique (\r
+  EFI_BOOT_MANAGER_LOAD_OPTION         *BootOptions,\r
+  UINTN                                BootOptionCount\r
+  )\r
+{\r
+  UINTN                                Base;\r
+  UINTN                                Index;\r
+  UINTN                                DescriptionSize;\r
+  UINTN                                MaxSuffixSize;\r
+  BOOLEAN                              *Visited;\r
+  UINTN                                MatchCount;\r
+\r
+  if (BootOptionCount == 0) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Calculate the maximum buffer size for the number suffix.\r
+  // The initial sizeof (CHAR16) is for the blank space before the number.\r
+  //\r
+  MaxSuffixSize = sizeof (CHAR16);\r
+  for (Index = BootOptionCount; Index != 0; Index = Index / 10) {\r
+    MaxSuffixSize += sizeof (CHAR16);\r
+  }\r
+\r
+  Visited = AllocateZeroPool (sizeof (BOOLEAN) * BootOptionCount);\r
+  ASSERT (Visited != NULL);\r
+\r
+  for (Base = 0; Base < BootOptionCount; Base++) {\r
+    if (!Visited[Base]) {\r
+      MatchCount      = 1;\r
+      Visited[Base]   = TRUE;\r
+      DescriptionSize = StrSize (BootOptions[Base].Description);\r
+      for (Index = Base + 1; Index < BootOptionCount; Index++) {\r
+        if (!Visited[Index] && StrCmp (BootOptions[Base].Description, BootOptions[Index].Description) == 0) {\r
+          Visited[Index] = TRUE;\r
+          MatchCount++;\r
+          FreePool (BootOptions[Index].Description);\r
+          BootOptions[Index].Description = AllocatePool (DescriptionSize + MaxSuffixSize);\r
+          UnicodeSPrint (\r
+            BootOptions[Index].Description, DescriptionSize + MaxSuffixSize,\r
+            L"%s %d",\r
+            BootOptions[Base].Description, MatchCount\r
+            );\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  FreePool (Visited);\r
+}\r
+\r
 /**\r
   Emuerate all possible bootable medias in the following order:\r
   1. Removable BlockIo            - The boot option only points to the removable media\r
@@ -2035,6 +2113,7 @@ BmEnumerateBootOptions (
     FreePool (Handles);\r
   }\r
 \r
+  BmMakeBootOptionDescriptionUnique (BootOptions, *BootOptionCount);\r
   return BootOptions;\r
 }\r
 \r