/** @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
@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
// 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
case MSG_IPv6_DP:\r
return BmMessageNetworkBoot;\r
break;\r
+\r
+ case MSG_URI_DP:\r
+ return BmMessageHttpBoot;\r
+ break;\r
}\r
}\r
}\r
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
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
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
// 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
);\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
FreePool (Handles);\r
}\r
\r
+ BmMakeBootOptionDescriptionUnique (BootOptions, *BootOptionCount);\r
return BootOptions;\r
}\r
\r