+/**\r
+ Return the description for network boot device.\r
+\r
+ @param Handle Controller handle.\r
+\r
+ @return The description string.\r
+**/\r
+CHAR16 *\r
+BmGetNetworkDescription (\r
+ IN EFI_HANDLE Handle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ MAC_ADDR_DEVICE_PATH *Mac;\r
+ VLAN_DEVICE_PATH *Vlan;\r
+ EFI_DEVICE_PATH_PROTOCOL *Ip;\r
+ EFI_DEVICE_PATH_PROTOCOL *Uri;\r
+ CHAR16 *Description;\r
+ UINTN DescriptionSize;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Handle,\r
+ &gEfiLoadFileProtocolGuid,\r
+ NULL,\r
+ gImageHandle,\r
+ Handle,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Handle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &DevicePath,\r
+ gImageHandle,\r
+ Handle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status) || (DevicePath == NULL)) {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // The PXE device path is like:\r
+ // ....../Mac(...)[/Vlan(...)]\r
+ // ....../Mac(...)[/Vlan(...)]/IPv4(...)\r
+ // ....../Mac(...)[/Vlan(...)]/IPv6(...)\r
+ //\r
+ // The HTTP device path is like:\r
+ // ....../Mac(...)[/Vlan(...)]/IPv4(...)/Uri(...)\r
+ // ....../Mac(...)[/Vlan(...)]/IPv6(...)/Uri(...)\r
+ //\r
+ while (!IsDevicePathEnd (DevicePath) &&\r
+ ((DevicePathType (DevicePath) != MESSAGING_DEVICE_PATH) ||\r
+ (DevicePathSubType (DevicePath) != MSG_MAC_ADDR_DP))\r
+ ) {\r
+ DevicePath = NextDevicePathNode (DevicePath);\r
+ }\r
+\r
+ if (IsDevicePathEnd (DevicePath)) {\r
+ return NULL;\r
+ }\r
+\r
+ Mac = (MAC_ADDR_DEVICE_PATH *) DevicePath;\r
+ DevicePath = NextDevicePathNode (DevicePath);\r
+\r
+ if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&\r
+ (DevicePathSubType (DevicePath) == MSG_VLAN_DP)\r
+ ) {\r
+ Vlan = (VLAN_DEVICE_PATH *) DevicePath;\r
+ DevicePath = NextDevicePathNode (DevicePath);\r
+ } else {\r
+ Vlan = NULL;\r
+ }\r
+\r
+ if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&\r
+ ((DevicePathSubType (DevicePath) == MSG_IPv4_DP) ||\r
+ (DevicePathSubType (DevicePath) == MSG_IPv6_DP))\r
+ ) {\r
+ Ip = DevicePath;\r
+ DevicePath = NextDevicePathNode (DevicePath);\r
+ } else {\r
+ Ip = NULL;\r
+ }\r
+\r
+ if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&\r
+ (DevicePathSubType (DevicePath) == MSG_URI_DP)\r
+ ) {\r
+ Uri = DevicePath;\r
+ DevicePath = NextDevicePathNode (DevicePath);\r
+ } else {\r
+ Uri = NULL;\r
+ }\r
+\r
+ //\r
+ // Build description like below:\r
+ // "PXEv6 (MAC:112233445566 VLAN1)"\r
+ // "HTTPv4 (MAC:112233445566)"\r
+ //\r
+ DescriptionSize = sizeof (L"HTTPv6 (MAC:112233445566 VLAN65535)");\r
+ Description = AllocatePool (DescriptionSize);\r
+ ASSERT (Description != NULL);\r
+ UnicodeSPrint (\r
+ Description, DescriptionSize,\r
+ (Vlan == NULL) ?\r
+ L"%sv%d (MAC:%02x%02x%02x%02x%02x%02x)" :\r
+ L"%sv%d (MAC:%02x%02x%02x%02x%02x%02x VLAN%d)",\r
+ (Uri == NULL) ? L"PXE" : L"HTTP",\r
+ ((Ip == NULL) || (DevicePathSubType (Ip) == MSG_IPv4_DP)) ? 4 : 6,\r
+ Mac->MacAddress.Addr[0], Mac->MacAddress.Addr[1], Mac->MacAddress.Addr[2],\r
+ Mac->MacAddress.Addr[3], Mac->MacAddress.Addr[4], Mac->MacAddress.Addr[5],\r
+ (Vlan == NULL) ? 0 : Vlan->VlanId\r
+ );\r
+ return Description;\r
+}\r
+\r