diff options
author | Fu Siyuan <siyuan.fu@intel.com> | 2016-02-15 13:55:11 +0800 |
---|---|---|
committer | Fu Siyuan <siyuan.fu@intel.com> | 2016-03-07 09:12:14 +0800 |
commit | fa848a4048943251fc057fe8d6c5a82e01d2ffb6 (patch) | |
tree | 0ffe9aa44385b2bd9e49c974f3ed52345579e61e /NetworkPkg/HttpBootDxe | |
parent | 9353c60cea6eeedbbe4b336aea02646e2bf25f47 (diff) | |
download | edk2-platforms-fa848a4048943251fc057fe8d6c5a82e01d2ffb6.tar.xz |
NetworkPkg: Add URI configuration form to HTTP boot driver.
This patch updates the HTTP boot driver to produce a setup page for the boot
file URI configuration. A new boot option will be created for the manual
configured URI address. This change is made to support the HTTP boot usage
in home environment.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Fu Siyuan <siyuan.fu@intel.com>
Reviewed-by: Wu Jiaxin <jiaxin.wu@intel.com>
Reviewed-by: Ye Ting <ting.ye@intel.com>
Diffstat (limited to 'NetworkPkg/HttpBootDxe')
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootClient.c | 99 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootConfig.c | 723 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootConfig.h | 78 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootConfigNVDataStruc.h | 43 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootConfigStrings.uni | bin | 0 -> 2926 bytes | |||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootConfigVfr.vfr | 53 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootDhcp4.c | 111 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootDhcp4.h | 9 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootDhcp6.c | 6 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootDxe.c | 44 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootDxe.h | 33 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootDxe.inf | 17 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootImpl.c | 71 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootSupport.c | 63 | ||||
-rw-r--r-- | NetworkPkg/HttpBootDxe/HttpBootSupport.h | 18 |
15 files changed, 1259 insertions, 109 deletions
diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.c b/NetworkPkg/HttpBootDxe/HttpBootClient.c index 2ccac8c842..aae452729c 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootClient.c +++ b/NetworkPkg/HttpBootDxe/HttpBootClient.c @@ -168,18 +168,35 @@ HttpBootDhcp4ExtractUriInfo ( // HttpOffer contains the boot file URL.
//
SelectOffer = &Private->OfferBuffer[SelectIndex].Dhcp4;
- if ((SelectOffer->OfferType == HttpOfferTypeDhcpIpUri) || (SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns)) {
- HttpOffer = SelectOffer;
+ if (Private->FilePathUri == NULL) {
+ //
+ // In Corporate environment, we need a HttpOffer.
+ //
+ if ((SelectOffer->OfferType == HttpOfferTypeDhcpIpUri) ||
+ (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns) ||
+ (SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns)) {
+ HttpOffer = SelectOffer;
+ } else {
+ ASSERT (Private->SelectProxyType != HttpOfferTypeMax);
+ ProxyIndex = Private->OfferIndex[Private->SelectProxyType][0];
+ HttpOffer = &Private->OfferBuffer[ProxyIndex].Dhcp4;
+ }
+ Private->BootFileUriParser = HttpOffer->UriParser;
+ Private->BootFileUri = (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Data;
} else {
- ASSERT (Private->SelectProxyType != HttpOfferTypeMax);
- ProxyIndex = Private->OfferIndex[Private->SelectProxyType][0];
- HttpOffer = &Private->OfferBuffer[ProxyIndex].Dhcp4;
+ //
+ // In Home environment the BootFileUri comes from the FilePath.
+ //
+ Private->BootFileUriParser = Private->FilePathUriParser;
+ Private->BootFileUri = Private->FilePathUri;
}
//
// Configure the default DNS server if server assigned.
//
- if ((SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns) || (SelectOffer->OfferType == HttpOfferTypeDhcpDns)) {
+ if ((SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns) ||
+ (SelectOffer->OfferType == HttpOfferTypeDhcpDns) ||
+ (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns)) {
Option = SelectOffer->OptList[HTTP_BOOT_DHCP4_TAG_INDEX_DNS_SERVER];
ASSERT (Option != NULL);
Status = HttpBootRegisterIp4Dns (
@@ -196,8 +213,8 @@ HttpBootDhcp4ExtractUriInfo ( // Extract the port from URL, and use default HTTP port 80 if not provided.
//
Status = HttpUrlGetPort (
- (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Data,
- HttpOffer->UriParser,
+ Private->BootFileUri,
+ Private->BootFileUriParser,
&Private->Port
);
if (EFI_ERROR (Status) || Private->Port == 0) {
@@ -205,13 +222,6 @@ HttpBootDhcp4ExtractUriInfo ( }
//
- // Record the URI of boot file from the selected HTTP offer.
- //
- Private->BootFileUriParser = HttpOffer->UriParser;
- Private->BootFileUri = (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Data;
-
-
- //
// All boot informations are valid here.
//
AsciiPrint ("\n URI: %a", Private->BootFileUri);
@@ -260,12 +270,27 @@ HttpBootDhcp6ExtractUriInfo ( // HttpOffer contains the boot file URL.
//
SelectOffer = &Private->OfferBuffer[SelectIndex].Dhcp6;
- if ((SelectOffer->OfferType == HttpOfferTypeDhcpIpUri) || (SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns)) {
- HttpOffer = SelectOffer;
+ if (Private->FilePathUri == NULL) {
+ //
+ // In Corporate environment, we need a HttpOffer.
+ //
+ if ((SelectOffer->OfferType == HttpOfferTypeDhcpIpUri) ||
+ (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns) ||
+ (SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns)) {
+ HttpOffer = SelectOffer;
+ } else {
+ ASSERT (Private->SelectProxyType != HttpOfferTypeMax);
+ ProxyIndex = Private->OfferIndex[Private->SelectProxyType][0];
+ HttpOffer = &Private->OfferBuffer[ProxyIndex].Dhcp6;
+ }
+ Private->BootFileUriParser = HttpOffer->UriParser;
+ Private->BootFileUri = (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data;
} else {
- ASSERT (Private->SelectProxyType != HttpOfferTypeMax);
- ProxyIndex = Private->OfferIndex[Private->SelectProxyType][0];
- HttpOffer = &Private->OfferBuffer[ProxyIndex].Dhcp6;
+ //
+ // In Home environment the BootFileUri comes from the FilePath.
+ //
+ Private->BootFileUriParser = Private->FilePathUriParser;
+ Private->BootFileUri = Private->FilePathUri;
}
//
@@ -279,7 +304,9 @@ HttpBootDhcp6ExtractUriInfo ( //
// Configure the default DNS server if server assigned.
//
- if ((SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns) || (SelectOffer->OfferType == HttpOfferTypeDhcpDns)) {
+ if ((SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns) ||
+ (SelectOffer->OfferType == HttpOfferTypeDhcpDns) ||
+ (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns)) {
Option = SelectOffer->OptList[HTTP_BOOT_DHCP6_IDX_DNS_SERVER];
ASSERT (Option != NULL);
Status = HttpBootSetIp6Dns (
@@ -297,8 +324,8 @@ HttpBootDhcp6ExtractUriInfo ( // whether can send message to HTTP Server Ip through the GateWay.
//
Status = HttpUrlGetIp6 (
- (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data,
- HttpOffer->UriParser,
+ Private->BootFileUri,
+ Private->BootFileUriParser,
&IpAddr
);
@@ -307,8 +334,8 @@ HttpBootDhcp6ExtractUriInfo ( // The Http server address is expressed by Name Ip, so perform DNS resolution
//
Status = HttpUrlGetHostName (
- (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data,
- HttpOffer->UriParser,
+ Private->BootFileUri,
+ Private->BootFileUriParser,
&HostName
);
if (EFI_ERROR (Status)) {
@@ -343,8 +370,8 @@ HttpBootDhcp6ExtractUriInfo ( // Extract the port from URL, and use default HTTP port 80 if not provided.
//
Status = HttpUrlGetPort (
- (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data,
- HttpOffer->UriParser,
+ Private->BootFileUri,
+ Private->BootFileUriParser,
&Private->Port
);
if (EFI_ERROR (Status) || Private->Port == 0) {
@@ -352,13 +379,6 @@ HttpBootDhcp6ExtractUriInfo ( }
//
- // Record the URI of boot file from the selected HTTP offer.
- //
- Private->BootFileUriParser = HttpOffer->UriParser;
- Private->BootFileUri = (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data;
-
-
- //
// All boot informations are valid here.
//
AsciiPrint ("\n URI: %a", Private->BootFileUri);
@@ -570,10 +590,6 @@ HttpBootGetFileFromCache ( return EFI_INVALID_PARAMETER;
}
- //
- // Search file in the cache list, the cache entry will be released upon a successful
- // match.
- //
NET_LIST_FOR_EACH (Entry, &Private->CacheList) {
Cache = NET_LIST_USER_STRUCT (Entry, HTTP_BOOT_CACHE_CONTENT, Link);
//
@@ -607,12 +623,6 @@ HttpBootGetFileFromCache ( }
}
*BufferSize = CopyedSize;
-
- //
- // On success, free the cached data to release the memory resource.
- //
- RemoveEntryList (&Cache->Link);
- HttpBootFreeCache (Cache);
return EFI_SUCCESS;
}
}
@@ -1083,3 +1093,4 @@ ERROR_1: return Status;
}
+
diff --git a/NetworkPkg/HttpBootDxe/HttpBootConfig.c b/NetworkPkg/HttpBootDxe/HttpBootConfig.c new file mode 100644 index 0000000000..db14da06d5 --- /dev/null +++ b/NetworkPkg/HttpBootDxe/HttpBootConfig.c @@ -0,0 +1,723 @@ +/** @file
+ Helper functions for configuring or getting the parameters relating to HTTP Boot.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "HttpBootDxe.h"
+
+CHAR16 mHttpBootConfigStorageName[] = L"HTTP_BOOT_CONFIG_IFR_NVDATA";
+
+/**
+ Add new boot option for HTTP boot.
+
+ @param[in] Private Pointer to the driver private data.
+ @param[in] UsingIpv6 Set to TRUE if creating boot option for IPv6.
+ @param[in] Description The description text of the boot option.
+ @param[in] Uri The URI string of the boot file.
+
+ @retval EFI_SUCCESS The boot option is created successfully.
+ @retval Others Failed to create new boot option.
+
+**/
+EFI_STATUS
+HttpBootAddBootOption (
+ IN HTTP_BOOT_PRIVATE_DATA *Private,
+ IN BOOLEAN UsingIpv6,
+ IN CHAR16 *Description,
+ IN CHAR16 *Uri
+ )
+{
+ EFI_DEV_PATH *Node;
+ EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ UINTN Length;
+ CHAR8 AsciiUri[URI_STR_MAX_SIZE];
+ CHAR16 *CurrentOrder;
+ EFI_STATUS Status;
+ UINTN OrderCount;
+ UINTN TargetLocation;
+ BOOLEAN Found;
+ UINT8 *TempByteBuffer;
+ UINT8 *TempByteStart;
+ UINTN DescSize;
+ UINTN FilePathSize;
+ CHAR16 OptionStr[10];
+ UINT16 *NewOrder;
+ UINTN Index;
+
+ NewOrder = NULL;
+ TempByteStart = NULL;
+ NewDevicePath = NULL;
+ NewOrder = NULL;
+ Node = NULL;
+ TmpDevicePath = NULL;
+ CurrentOrder = NULL;
+
+ if (StrLen (Description) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Convert the scheme to all lower case.
+ //
+ for (Index = 0; Index < StrLen (Uri); Index++) {
+ if (Uri[Index] == L':') {
+ break;
+ }
+ if (Uri[Index] >= L'A' && Uri[Index] <= L'Z') {
+ Uri[Index] -= (CHAR16)(L'A' - L'a');
+ }
+ }
+
+ //
+ // Only accept http and https URI.
+ //
+ if ((StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 7) != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Create a new device path by appending the IP node and URI node to
+ // the driver's parent device path
+ //
+ if (!UsingIpv6) {
+ Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH));
+ if (Node == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+ Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH;
+ Node->Ipv4.Header.SubType = MSG_IPv4_DP;
+ SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
+ } else {
+ Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
+ if (Node == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+ Node->Ipv6.Header.Type = MESSAGING_DEVICE_PATH;
+ Node->Ipv6.Header.SubType = MSG_IPv6_DP;
+ SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH));
+ }
+ TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
+ FreePool (Node);
+ if (TmpDevicePath == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Update the URI node with the input boot file URI.
+ //
+ UnicodeStrToAsciiStr (Uri, AsciiUri);
+ Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri);
+ Node = AllocatePool (Length);
+ if (Node == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ FreePool (TmpDevicePath);
+ goto ON_EXIT;
+ }
+ Node->DevPath.Type = MESSAGING_DEVICE_PATH;
+ Node->DevPath.SubType = MSG_URI_DP;
+ SetDevicePathNodeLength (Node, Length);
+ CopyMem ((UINT8*) Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), AsciiUri, AsciiStrSize (AsciiUri));
+ NewDevicePath = AppendDevicePathNode (TmpDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
+ FreePool (Node);
+ FreePool (TmpDevicePath);
+ if (NewDevicePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Get current "BootOrder" variable and find a free target.
+ //
+ Length = 0;
+ Status = GetVariable2 (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ &CurrentOrder,
+ &Length
+ );
+ if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {
+ goto ON_EXIT;
+ }
+ OrderCount = Length / sizeof (UINT16);
+ Found = FALSE;
+ for (TargetLocation=0; TargetLocation < 0xFFFF; TargetLocation++) {
+ Found = TRUE;
+ for (Index = 0; Index < OrderCount; Index++) {
+ if (CurrentOrder[Index] == TargetLocation) {
+ Found = FALSE;
+ break;
+ }
+ }
+ if (Found) {
+ break;
+ }
+ }
+
+ if (TargetLocation == 0xFFFF) {
+ DEBUG ((EFI_D_ERROR, "Could not find unused target index.\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ } else {
+ DEBUG ((EFI_D_INFO, "TargetIndex = %04x.\n", TargetLocation));
+ }
+
+ //
+ // Construct and set the "Boot####" variable
+ //
+ DescSize = StrSize(Description);
+ FilePathSize = GetDevicePathSize (NewDevicePath);
+ TempByteBuffer = AllocateZeroPool(sizeof(EFI_LOAD_OPTION) + DescSize + FilePathSize);
+ if (TempByteBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ TempByteStart = TempByteBuffer;
+ *((UINT32 *) TempByteBuffer) = LOAD_OPTION_ACTIVE; // Attributes
+ TempByteBuffer += sizeof (UINT32);
+
+ *((UINT16 *) TempByteBuffer) = (UINT16)FilePathSize; // FilePathListLength
+ TempByteBuffer += sizeof (UINT16);
+
+ CopyMem (TempByteBuffer, Description, DescSize);
+ TempByteBuffer += DescSize;
+ CopyMem (TempByteBuffer, NewDevicePath, FilePathSize);
+
+ UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", L"Boot", TargetLocation);
+ Status = gRT->SetVariable (
+ OptionStr,
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,
+ TempByteStart
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Insert into the order list and set "BootOrder" variable
+ //
+ NewOrder = AllocateZeroPool ((OrderCount + 1) * sizeof (UINT16));
+ if (NewOrder == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+ CopyMem(NewOrder, CurrentOrder, OrderCount * sizeof(UINT16));
+ NewOrder[OrderCount] = (UINT16) TargetLocation;
+ Status = gRT->SetVariable (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ ((OrderCount + 1) * sizeof (UINT16)),
+ NewOrder
+ );
+
+
+ON_EXIT:
+
+ if (CurrentOrder != NULL) {
+ FreePool (CurrentOrder);
+ }
+ if (NewOrder != NULL) {
+ FreePool (NewOrder);
+ }
+ if (TempByteStart != NULL) {
+ FreePool (TempByteStart);
+ }
+ if (NewDevicePath != NULL) {
+ FreePool (NewDevicePath);
+ }
+
+ return Status;
+}
+
+/**
+
+ This function allows the caller to request the current
+ configuration for one or more named elements. The resulting
+ string is in <ConfigAltResp> format. Also, any and all alternative
+ configuration strings shall be appended to the end of the
+ current configuration string. If they are, they must appear
+ after the current configuration. They must contain the same
+ routing (GUID, NAME, PATH) as the current configuration string.
+ They must have an additional description indicating the type of
+ alternative configuration the string represents,
+ "ALTCFG=<StringToken>". That <StringToken> (when
+ converted from Hex UNICODE to binary) is a reference to a
+ string in the associated string pack.
+
+ @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param[in] Request A null-terminated Unicode string in
+ <ConfigRequest> format. Note that this
+ includes the routing information as well as
+ the configurable name / value pairs. It is
+ invalid for this string to be in
+ <MultiConfigRequest> format.
+
+ @param[out] Progress On return, points to a character in the
+ Request string. Points to the string's null
+ terminator if request was successful. Points
+ to the most recent "&" before the first
+ failing name / value pair (or the beginning
+ of the string if the failure is in the first
+ name / value pair) if the request was not successful.
+
+ @param[out] Results A null-terminated Unicode string in
+ <ConfigAltResp> format which has all values
+ filled in for the names in the Request string.
+ String to be allocated by the called function.
+
+ @retval EFI_SUCCESS The Results string is filled with the
+ values corresponding to all requested
+ names.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_INVALID_PARAMETER For example, passing in a NULL
+ for the Request parameter
+ would result in this type of
+ error. In this case, the
+ Progress parameter would be
+ set to NULL.
+
+ @retval EFI_NOT_FOUND Routing data doesn't match any
+ known driver. Progress set to the
+ first character in the routing header.
+ Note: There is no requirement that the
+ driver validate the routing data. It
+ must skip the <ConfigHdr> in order to
+ process the names.
+
+ @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
+ to most recent "&" before the
+ error or the beginning of the
+ string.
+
+ @retval EFI_INVALID_PARAMETER Unknown name. Progress points
+ to the & before the name in
+ question.
+
+**/
+EFI_STATUS
+EFIAPI
+HttpBootFormExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
+ EFI_STRING ConfigRequestHdr;
+ EFI_STRING ConfigRequest;
+ BOOLEAN AllocatedRequest;
+ UINTN Size;
+
+ if (Progress == NULL || Results == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Progress = Request;
+ if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gHttpBootConfigGuid, mHttpBootConfigStorageName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ ConfigRequestHdr = NULL;
+ ConfigRequest = NULL;
+ AllocatedRequest = FALSE;
+ Size = 0;
+
+ CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
+ //
+ // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+ //
+ BufferSize = sizeof (HTTP_BOOT_CONFIG_IFR_NVDATA);
+ ZeroMem (&CallbackInfo->HttpBootNvData, BufferSize);
+
+ ConfigRequest = Request;
+ if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
+ //
+ // Request has no request element, construct full request string.
+ // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+ // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
+ //
+ ConfigRequestHdr = HiiConstructConfigHdr (&gHttpBootConfigGuid, mHttpBootConfigStorageName, CallbackInfo->ChildHandle);
+ Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+ ConfigRequest = AllocateZeroPool (Size);
+ ASSERT (ConfigRequest != NULL);
+ AllocatedRequest = TRUE;
+ UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+ FreePool (ConfigRequestHdr);
+ }
+
+ Status = gHiiConfigRouting->BlockToConfig (
+ gHiiConfigRouting,
+ ConfigRequest,
+ (UINT8 *) &CallbackInfo->HttpBootNvData,
+ BufferSize,
+ Results,
+ Progress
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Free the allocated config request string.
+ //
+ if (AllocatedRequest) {
+ FreePool (ConfigRequest);
+ ConfigRequest = NULL;
+ }
+ //
+ // Set Progress string to the original request string.
+ //
+ if (Request == NULL) {
+ *Progress = NULL;
+ } else if (StrStr (Request, L"OFFSET") == NULL) {
+ *Progress = Request + StrLen (Request);
+ }
+
+ return Status;
+}
+
+/**
+
+ This function applies changes in a driver's configuration.
+ Input is a Configuration, which has the routing data for this
+ driver followed by name / value configuration pairs. The driver
+ must apply those pairs to its configurable storage. If the
+ driver's configuration is stored in a linear block of data
+ and the driver's name / value pairs are in <BlockConfig>
+ format, it may use the ConfigToBlock helper function (above) to
+ simplify the job.
+
+ @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param[in] Configuration A null-terminated Unicode string in
+ <ConfigString> format.
+
+ @param[out] Progress A pointer to a string filled in with the
+ offset of the most recent '&' before the
+ first failing name / value pair (or the
+ beginning of the string if the failure
+ is in the first name / value pair) or
+ the terminating NULL if all was
+ successful.
+
+ @retval EFI_SUCCESS The results have been distributed or are
+ awaiting distribution.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
+ Results parameter would result
+ in this type of error.
+
+ @retval EFI_NOT_FOUND Target for the specified routing data
+ was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+HttpBootFormRouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
+ HTTP_BOOT_PRIVATE_DATA *Private;
+
+ if (Progress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *Progress = Configuration;
+
+ if (Configuration == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check routing data in <ConfigHdr>.
+ // Note: there is no name for Name/Value storage, only GUID will be checked
+ //
+ if (!HiiIsConfigHdrMatch (Configuration, &gHttpBootConfigGuid, mHttpBootConfigStorageName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
+ Private = HTTP_BOOT_PRIVATE_DATA_FROM_CALLBACK_INFO (CallbackInfo);
+
+ BufferSize = sizeof (HTTP_BOOT_CONFIG_IFR_NVDATA);
+ ZeroMem (&CallbackInfo->HttpBootNvData, BufferSize);
+
+ Status = gHiiConfigRouting->ConfigToBlock (
+ gHiiConfigRouting,
+ Configuration,
+ (UINT8 *) &CallbackInfo->HttpBootNvData,
+ &BufferSize,
+ Progress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Create a new boot option according to the configuration data.
+ //
+ Status = HttpBootAddBootOption (
+ Private,
+ (CallbackInfo->HttpBootNvData.IpVersion == HTTP_BOOT_IP_VERSION_6) ? TRUE : FALSE,
+ CallbackInfo->HttpBootNvData.Description,
+ CallbackInfo->HttpBootNvData.Uri
+ );
+
+ return Status;
+}
+
+/**
+
+ This function is called to provide results data to the driver.
+ This data consists of a unique key that is used to identify
+ which data is either being passed back or being asked for.
+
+ @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param[in] Action Specifies the type of action taken by the browser.
+ @param[in] QuestionId A unique value which is sent to the original
+ exporting driver so that it can identify the type
+ of data to expect. The format of the data tends to
+ vary based on the opcode that generated the callback.
+ @param[in] Type The type of value for the question.
+ @param[in, out] Value A pointer to the data being sent to the original
+ exporting driver.
+ @param[out] ActionRequest On return, points to the action requested by the
+ callback function.
+
+ @retval EFI_SUCCESS The callback successfully handled the action.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
+ variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be saved.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the
+ callback.
+**/
+EFI_STATUS
+EFIAPI
+HttpBootFormCallback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN OUT EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Initialize the configuration form.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is initialized.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+
+**/
+EFI_STATUS
+HttpBootConfigFormInit (
+ IN HTTP_BOOT_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
+ VENDOR_DEVICE_PATH VendorDeviceNode;
+ EFI_SERVICE_BINDING_PROTOCOL *HttpSb;
+ CHAR16 *MacString;
+ CHAR16 *OldMenuString;
+ CHAR16 MenuString[128];
+
+ CallbackInfo = &Private->CallbackInfo;
+
+ if (CallbackInfo->Initilized) {
+ return EFI_SUCCESS;
+ }
+
+ CallbackInfo->Signature = HTTP_BOOT_FORM_CALLBACK_INFO_SIGNATURE;
+
+ //
+ // Construct device path node for EFI HII Config Access protocol,
+ // which consists of controller physical device path and one hardware
+ // vendor guid node.
+ //
+ ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));
+ VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;
+ VendorDeviceNode.Header.SubType = HW_VENDOR_DP;
+ CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid);
+ SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));
+ CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (
+ Private->ParentDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode
+ );
+ if (CallbackInfo->HiiVendorDevicePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ CallbackInfo->ConfigAccess.ExtractConfig = HttpBootFormExtractConfig;
+ CallbackInfo->ConfigAccess.RouteConfig = HttpBootFormRouteConfig;
+ CallbackInfo->ConfigAccess.Callback = HttpBootFormCallback;
+
+ //
+ // Install Device Path Protocol and Config Access protocol to driver handle.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &CallbackInfo->ChildHandle,
+ &gEfiDevicePathProtocolGuid,
+ CallbackInfo->HiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &CallbackInfo->ConfigAccess,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Open the Parent Handle for the child
+ //
+ Status = gBS->OpenProtocol (
+ Private->Controller,
+ &gEfiHttpServiceBindingProtocolGuid,
+ (VOID **) &HttpSb,
+ Private->Image,
+ CallbackInfo->ChildHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ //
+ // Publish our HII data.
+ //
+ CallbackInfo->RegisteredHandle = HiiAddPackages (
+ &gHttpBootConfigGuid,
+ CallbackInfo->ChildHandle,
+ HttpBootDxeStrings,
+ HttpBootConfigVfrBin,
+ NULL
+ );
+ if (CallbackInfo->RegisteredHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ //
+ // Append MAC string in the menu help string
+ //
+ Status = NetLibGetMacString (Private->Controller, Private->Image, &MacString);
+ if (!EFI_ERROR (Status)) {
+ OldMenuString = HiiGetString (
+ CallbackInfo->RegisteredHandle,
+ STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP),
+ NULL
+ );
+ UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);
+ HiiSetString (
+ CallbackInfo->RegisteredHandle,
+ STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP),
+ MenuString,
+ NULL
+ );
+
+ FreePool (MacString);
+ FreePool (OldMenuString);
+
+ return EFI_SUCCESS;
+ }
+
+Error:
+
+ HttpBootConfigFormUnload (Private);
+ return Status;
+}
+
+/**
+ Unload the configuration form, this includes: delete all the configuration
+ entries, uninstall the form callback protocol, and free the resources used.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is unloaded.
+ @retval Others Failed to unload the form.
+
+**/
+EFI_STATUS
+HttpBootConfigFormUnload (
+ IN HTTP_BOOT_PRIVATE_DATA *Private
+ )
+{
+ HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
+
+ CallbackInfo = &Private->CallbackInfo;
+ if (CallbackInfo->ChildHandle != NULL) {
+ //
+ // Close the child handle
+ //
+ gBS->CloseProtocol (
+ Private->Controller,
+ &gEfiHttpServiceBindingProtocolGuid,
+ Private->Image,
+ CallbackInfo->ChildHandle
+ );
+
+ //
+ // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
+ //
+ gBS->UninstallMultipleProtocolInterfaces (
+ CallbackInfo->ChildHandle,
+ &gEfiDevicePathProtocolGuid,
+ CallbackInfo->HiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &CallbackInfo->ConfigAccess,
+ NULL
+ );
+ CallbackInfo->ChildHandle = NULL;
+ }
+
+ if (CallbackInfo->HiiVendorDevicePath != NULL) {
+ FreePool (CallbackInfo->HiiVendorDevicePath);
+ CallbackInfo->HiiVendorDevicePath = NULL;
+ }
+
+ if (CallbackInfo->RegisteredHandle != NULL) {
+ //
+ // Remove HII package list
+ //
+ HiiRemovePackages (CallbackInfo->RegisteredHandle);
+ CallbackInfo->RegisteredHandle = NULL;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/NetworkPkg/HttpBootDxe/HttpBootConfig.h b/NetworkPkg/HttpBootDxe/HttpBootConfig.h new file mode 100644 index 0000000000..a2afd18a88 --- /dev/null +++ b/NetworkPkg/HttpBootDxe/HttpBootConfig.h @@ -0,0 +1,78 @@ +/** @file
+ The header file of functions for configuring or getting the parameters
+ relating to HTTP Boot.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _HTTP_BOOT_CONFIG_H_
+#define _HTTP_BOOT_CONFIG_H_
+
+
+#include "HttpBootConfigNVDataStruc.h"
+
+typedef struct _HTTP_BOOT_FORM_CALLBACK_INFO HTTP_BOOT_FORM_CALLBACK_INFO;
+
+extern UINT8 HttpBootDxeStrings[];
+extern UINT8 HttpBootConfigVfrBin[];
+
+#pragma pack()
+
+#define HTTP_BOOT_FORM_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('H', 'B', 'f', 'c')
+
+#define HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(Callback) \
+ CR ( \
+ Callback, \
+ HTTP_BOOT_FORM_CALLBACK_INFO, \
+ ConfigAccess, \
+ HTTP_BOOT_FORM_CALLBACK_INFO_SIGNATURE \
+ )
+
+struct _HTTP_BOOT_FORM_CALLBACK_INFO {
+ UINT32 Signature;
+ BOOLEAN Initilized;
+ EFI_HANDLE ChildHandle;
+ EFI_DEVICE_PATH_PROTOCOL *HiiVendorDevicePath;
+ EFI_HII_HANDLE RegisteredHandle;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+ HTTP_BOOT_CONFIG_IFR_NVDATA HttpBootNvData;
+};
+
+/**
+ Initialize the configuration form.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is initialized.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+
+**/
+EFI_STATUS
+HttpBootConfigFormInit (
+ IN HTTP_BOOT_PRIVATE_DATA *Private
+ );
+
+/**
+ Unload the configuration form, this includes: delete all the configuration
+ entries, uninstall the form callback protocol, and free the resources used.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is unloaded.
+ @retval Others Failed to unload the form.
+
+**/
+EFI_STATUS
+HttpBootConfigFormUnload (
+ IN HTTP_BOOT_PRIVATE_DATA *Private
+ );
+
+#endif
diff --git a/NetworkPkg/HttpBootDxe/HttpBootConfigNVDataStruc.h b/NetworkPkg/HttpBootDxe/HttpBootConfigNVDataStruc.h new file mode 100644 index 0000000000..07043e7ee8 --- /dev/null +++ b/NetworkPkg/HttpBootDxe/HttpBootConfigNVDataStruc.h @@ -0,0 +1,43 @@ +/** @file
+ Define NVData structures used by the HTTP Boot configuration component.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _HTTP_BOOT_NVDATA_STRUC_H_
+#define _HTTP_BOOT_NVDATA_STRUC_H_
+
+#include <Guid/HttpBootConfigHii.h>
+
+#define HTTP_BOOT_IP_VERSION_4 0
+#define HTTP_BOOT_IP_VERSION_6 1
+
+//
+// Macros used for an IPv4 or an IPv6 address.
+//
+#define URI_STR_MIN_SIZE 8
+#define URI_STR_MAX_SIZE 255
+
+#define CONFIGURATION_VARSTORE_ID 0x1234
+
+#define FORMID_MAIN_FORM 1
+
+#pragma pack(1)
+typedef struct _HTTP_BOOT_CONFIG_IFR_NVDATA {
+ UINT8 IpVersion;
+ UINT8 Padding;
+ CHAR16 Description[URI_STR_MAX_SIZE];
+ CHAR16 Uri[URI_STR_MAX_SIZE];
+} HTTP_BOOT_CONFIG_IFR_NVDATA;
+#pragma pack()
+
+
+#endif
diff --git a/NetworkPkg/HttpBootDxe/HttpBootConfigStrings.uni b/NetworkPkg/HttpBootDxe/HttpBootConfigStrings.uni Binary files differnew file mode 100644 index 0000000000..5001220eb3 --- /dev/null +++ b/NetworkPkg/HttpBootDxe/HttpBootConfigStrings.uni diff --git a/NetworkPkg/HttpBootDxe/HttpBootConfigVfr.vfr b/NetworkPkg/HttpBootDxe/HttpBootConfigVfr.vfr new file mode 100644 index 0000000000..e47c6af3ad --- /dev/null +++ b/NetworkPkg/HttpBootDxe/HttpBootConfigVfr.vfr @@ -0,0 +1,53 @@ +/** @file
+ VFR file used by the HTTP Boot configuration component.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "HttpBootConfigNVDataStruc.h"
+
+
+formset
+ guid = HTTP_BOOT_CONFIG_GUID,
+ title = STRING_TOKEN(STR_HTTP_BOOT_CONFIG_FORM_TITLE),
+ help = STRING_TOKEN(STR_HTTP_BOOT_CONFIG_FORM_HELP),
+
+ varstore HTTP_BOOT_CONFIG_IFR_NVDATA,
+ name = HTTP_BOOT_CONFIG_IFR_NVDATA,
+ guid = HTTP_BOOT_CONFIG_GUID;
+
+ form formid = FORMID_MAIN_FORM,
+ title = STRING_TOKEN(STR_HTTP_BOOT_CONFIG_FORM_TITLE);
+
+ string varid = HTTP_BOOT_CONFIG_IFR_NVDATA.Description,
+ prompt = STRING_TOKEN(STR_BOOT_DESCRIPTION_PROMPT),
+ help = STRING_TOKEN(STR_NULL_STRING),
+ minsize = 6,
+ maxsize = 75,
+ endstring;
+
+ oneof varid = HTTP_BOOT_CONFIG_IFR_NVDATA.IpVersion,
+ prompt = STRING_TOKEN(STR_HTTP_BOOT_IP_VERSION_PROMPT),
+ help = STRING_TOKEN(STR_HTTP_BOOT_IP_VERSION_HELP),
+ option text = STRING_TOKEN(STR_HTTP_BOOT_IP_VERSION_4), value = HTTP_BOOT_IP_VERSION_4, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_HTTP_BOOT_IP_VERSION_6), value = HTTP_BOOT_IP_VERSION_6, flags = 0;
+ endoneof;
+
+ string varid = HTTP_BOOT_CONFIG_IFR_NVDATA.Uri,
+ prompt = STRING_TOKEN(STR_BOOT_URI_PROMPT),
+ help = STRING_TOKEN(STR_BOOT_URI_HELP),
+ minsize = URI_STR_MIN_SIZE,
+ maxsize = URI_STR_MAX_SIZE,
+ endstring;
+ endform;
+
+endformset;
diff --git a/NetworkPkg/HttpBootDxe/HttpBootDhcp4.c b/NetworkPkg/HttpBootDxe/HttpBootDhcp4.c index 9a947a6ea6..b9c8084e11 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDhcp4.c +++ b/NetworkPkg/HttpBootDxe/HttpBootDhcp4.c @@ -1,7 +1,7 @@ /** @file
Functions implementation related with DHCPv4 for HTTP boot driver.
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
@@ -395,7 +395,11 @@ HttpBootParseDhcp4Packet ( //
if (IsHttpOffer) {
if (IpExpressedUri) {
- OfferType = IsProxyOffer ? HttpOfferTypeProxyIpUri : HttpOfferTypeDhcpIpUri;
+ if (IsProxyOffer) {
+ OfferType = HttpOfferTypeProxyIpUri;
+ } else {
+ OfferType = IsDnsOffer ? HttpOfferTypeDhcpIpUriDns : HttpOfferTypeDhcpIpUri;
+ }
} else {
if (!IsProxyOffer) {
OfferType = IsDnsOffer ? HttpOfferTypeDhcpNameUriDns : HttpOfferTypeDhcpNameUri;
@@ -473,46 +477,81 @@ HttpBootSelectDhcpOffer ( {
Private->SelectIndex = 0;
Private->SelectProxyType = HttpOfferTypeMax;
-
- //
- // Priority1: HttpOfferTypeDhcpIpUri
- // Priority2: HttpOfferTypeDhcpNameUriDns
- // Priority3: HttpOfferTypeDhcpOnly + HttpOfferTypeProxyIpUri
- // Priority4: HttpOfferTypeDhcpDns + HttpOfferTypeProxyIpUri
- // Priority5: HttpOfferTypeDhcpDns + HttpOfferTypeProxyNameUri
- // Priority6: HttpOfferTypeDhcpDns + HttpOfferTypeDhcpNameUri
- //
- if (Private->OfferCount[HttpOfferTypeDhcpIpUri] > 0) {
+
+ if (Private->FilePathUri != NULL) {
+ //
+ // We are in home environment, the URI is already specified.
+ // Just need to choose a DHCP offer.
+ // The offer with DNS server address takes priority here.
+ //
+ if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0) {
+
+ Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
+
+ } else if (Private->OfferCount[HttpOfferTypeDhcpIpUriDns] > 0) {
- Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUri][0] + 1;
+ Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUriDns][0] + 1;
+
+ } else if (Private->OfferCount[HttpOfferTypeDhcpNameUriDns] > 0) {
- } else if (Private->OfferCount[HttpOfferTypeDhcpNameUriDns] > 0) {
-
- Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpNameUriDns][0] + 1;
+ Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpNameUriDns][0] + 1;
+
+ } else if (Private->OfferCount[HttpOfferTypeDhcpOnly] > 0) {
- } else if (Private->OfferCount[HttpOfferTypeDhcpOnly] > 0 &&
- Private->OfferCount[HttpOfferTypeProxyIpUri] > 0) {
-
- Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpOnly][0] + 1;
- Private->SelectProxyType = HttpOfferTypeProxyIpUri;
+ Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpOnly][0] + 1;
+
+ } else if (Private->OfferCount[HttpOfferTypeDhcpIpUri] > 0) {
- } else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
- Private->OfferCount[HttpOfferTypeProxyIpUri] > 0) {
-
- Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
- Private->SelectProxyType = HttpOfferTypeProxyIpUri;
+ Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUri][0] + 1;
+ }
- } else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
- Private->OfferCount[HttpOfferTypeProxyNameUri] > 0) {
-
- Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
- Private->SelectProxyType = HttpOfferTypeProxyNameUri;
+ } else {
+ //
+ // We are in corporate environment.
+ //
+ // Priority1: HttpOfferTypeDhcpIpUri or HttpOfferTypeDhcpIpUriDns
+ // Priority2: HttpOfferTypeDhcpNameUriDns
+ // Priority3: HttpOfferTypeDhcpOnly + HttpOfferTypeProxyIpUri
+ // Priority4: HttpOfferTypeDhcpDns + HttpOfferTypeProxyIpUri
+ // Priority5: HttpOfferTypeDhcpDns + HttpOfferTypeProxyNameUri
+ // Priority6: HttpOfferTypeDhcpDns + HttpOfferTypeDhcpNameUri
+ //
+ if (Private->OfferCount[HttpOfferTypeDhcpIpUri] > 0) {
+
+ Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUri][0] + 1;
+
+ } else if (Private->OfferCount[HttpOfferTypeDhcpIpUriDns] > 0) {
+
+ Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUriDns][0] + 1;
+
+ }else if (Private->OfferCount[HttpOfferTypeDhcpNameUriDns] > 0) {
- } else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
- Private->OfferCount[HttpOfferTypeDhcpNameUri] > 0) {
-
- Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
- Private->SelectProxyType = HttpOfferTypeDhcpNameUri;
+ Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpNameUriDns][0] + 1;
+
+ } else if (Private->OfferCount[HttpOfferTypeDhcpOnly] > 0 &&
+ Private->OfferCount[HttpOfferTypeProxyIpUri] > 0) {
+
+ Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpOnly][0] + 1;
+ Private->SelectProxyType = HttpOfferTypeProxyIpUri;
+
+ } else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
+ Private->OfferCount[HttpOfferTypeProxyIpUri] > 0) {
+
+ Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
+ Private->SelectProxyType = HttpOfferTypeProxyIpUri;
+
+ } else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
+ Private->OfferCount[HttpOfferTypeProxyNameUri] > 0) {
+
+ Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
+ Private->SelectProxyType = HttpOfferTypeProxyNameUri;
+
+ } else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
+ Private->OfferCount[HttpOfferTypeDhcpNameUri] > 0) {
+
+ Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
+ Private->SelectProxyType = HttpOfferTypeDhcpNameUri;
+ }
}
}
diff --git a/NetworkPkg/HttpBootDxe/HttpBootDhcp4.h b/NetworkPkg/HttpBootDxe/HttpBootDhcp4.h index 2bc46deafd..5ac7f71165 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDhcp4.h +++ b/NetworkPkg/HttpBootDxe/HttpBootDhcp4.h @@ -1,7 +1,7 @@ /** @file
Functions declaration related with DHCPv4 for HTTP boot driver.
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
@@ -96,11 +96,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. ///
typedef enum {
//
- // <IP address, IP expressed URI> or
- // <IP address, IP expressed URI, Name-server (will be ignored)>
+ // <IP address, IP expressed URI>
//
HttpOfferTypeDhcpIpUri,
//
+ // <IP address, IP expressed URI, Name-server>
+ //
+ HttpOfferTypeDhcpIpUriDns,
+ //
// <IP address, Domain-name expressed URI, Name-server>
//
HttpOfferTypeDhcpNameUriDns,
diff --git a/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c b/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c index 2538bd116c..d2960e4f6c 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c +++ b/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c @@ -298,7 +298,11 @@ HttpBootParseDhcp6Packet ( //
if (IsHttpOffer) {
if (IpExpressedUri) {
- OfferType = IsProxyOffer ? HttpOfferTypeProxyIpUri : HttpOfferTypeDhcpIpUri;
+ if (IsProxyOffer) {
+ OfferType = HttpOfferTypeProxyIpUri;
+ } else {
+ OfferType = IsDnsOffer ? HttpOfferTypeDhcpIpUriDns : HttpOfferTypeDhcpIpUri;
+ }
} else {
if (!IsProxyOffer) {
OfferType = IsDnsOffer ? HttpOfferTypeDhcpNameUriDns : HttpOfferTypeDhcpNameUri;
diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.c b/NetworkPkg/HttpBootDxe/HttpBootDxe.c index 9fb33bbb53..6a3033db11 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDxe.c +++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.c @@ -1,7 +1,7 @@ /** @file
Driver Binding functions implementation for UEFI HTTP boot.
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
@@ -365,6 +365,14 @@ HttpBootIp4DxeDriverBindingStart ( }
//
+ // Initialize the HII configuration form.
+ //
+ Status = HttpBootConfigFormInit (Private);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ //
// Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
// NIC handle and the private data.
//
@@ -508,8 +516,9 @@ HttpBootIp4DxeDriverBindingStart ( ON_ERROR:
-
+
HttpBootDestroyIp4Children (This, Private);
+ HttpBootConfigFormUnload (Private);
FreePool (Private);
return Status;
@@ -615,6 +624,11 @@ HttpBootIp4DxeDriverBindingStop ( // Release the cached data.
//
HttpBootFreeCacheList (Private);
+
+ //
+ // Unload the config form.
+ //
+ HttpBootConfigFormUnload (Private);
gBS->UninstallProtocolInterface (
NicHandle,
@@ -823,6 +837,14 @@ HttpBootIp6DxeDriverBindingStart ( }
//
+ // Initialize the HII configuration form.
+ //
+ Status = HttpBootConfigFormInit (Private);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ //
// Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
// NIC handle and the private data.
//
@@ -989,12 +1011,12 @@ HttpBootIp6DxeDriverBindingStart ( return EFI_SUCCESS;
ON_ERROR:
-
- HttpBootDestroyIp6Children(This, Private);
- FreePool (Private);
- return Status;
-
+ HttpBootDestroyIp6Children(This, Private);
+ HttpBootConfigFormUnload (Private);
+ FreePool (Private);
+
+ return Status;
}
/**
@@ -1096,7 +1118,12 @@ HttpBootIp6DxeDriverBindingStop ( // Release the cached data.
//
HttpBootFreeCacheList (Private);
-
+
+ //
+ // Unload the config form.
+ //
+ HttpBootConfigFormUnload (Private);
+
gBS->UninstallProtocolInterface (
NicHandle,
&gEfiCallerIdGuid,
@@ -1128,6 +1155,7 @@ HttpBootDxeDriverEntryPoint ( )
{
EFI_STATUS Status;
+
//
// Install UEFI Driver Model protocol(s).
//
diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.h b/NetworkPkg/HttpBootDxe/HttpBootDxe.h index 08f88c5606..7cb4b2c55a 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDxe.h +++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.h @@ -1,7 +1,7 @@ /** @file
UEFI HTTP boot driver's private data structure and interfaces declaration.
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
@@ -24,6 +24,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // Libraries
//
#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiHiiServicesLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
@@ -31,6 +33,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include <Library/DebugLib.h>
#include <Library/NetLib.h>
#include <Library/HttpLib.h>
+#include <Library/HiiLib.h>
+#include <Library/PrintLib.h>
//
// UEFI Driver Model Protocols
@@ -42,6 +46,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. //
// Consumed Protocols
//
+#include <Protocol/ServiceBinding.h>
+#include <Protocol/HiiConfigAccess.h>
#include <Protocol/NetworkInterfaceIdentifier.h>
#include <Protocol/Dhcp4.h>
#include <Protocol/Dhcp6.h>
@@ -55,6 +61,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include <Protocol/LoadFile.h>
//
+// Consumed Guids
+//
+#include <Guid/HttpBootConfigHii.h>
+
+//
// Driver Version
//
#define HTTP_BOOT_DXE_VERSION 0xa
@@ -81,6 +92,7 @@ typedef struct _HTTP_BOOT_VIRTUAL_NIC HTTP_BOOT_VIRTUAL_NIC; #include "HttpBootImpl.h"
#include "HttpBootSupport.h"
#include "HttpBootClient.h"
+#include "HttpBootConfig.h"
typedef union {
HTTP_BOOT_DHCP4_PACKET_CACHE Dhcp4;
@@ -95,6 +107,14 @@ struct _HTTP_BOOT_VIRTUAL_NIC { HTTP_BOOT_PRIVATE_DATA *Private;
};
+#define HTTP_BOOT_PRIVATE_DATA_FROM_CALLBACK_INFO(Callback) \
+ CR ( \
+ Callback, \
+ HTTP_BOOT_PRIVATE_DATA, \
+ CallbackInfo, \
+ HTTP_BOOT_PRIVATE_DATA_SIGNATURE \
+ )
+
struct _HTTP_BOOT_PRIVATE_DATA {
UINT32 Signature;
EFI_HANDLE Controller;
@@ -132,6 +152,11 @@ struct _HTTP_BOOT_PRIVATE_DATA { UINT32 Id;
//
+ // HII callback info block
+ //
+ HTTP_BOOT_FORM_CALLBACK_INFO CallbackInfo;
+
+ //
// Mode data
//
BOOLEAN UsingIpv6;
@@ -147,6 +172,12 @@ struct _HTTP_BOOT_PRIVATE_DATA { BOOLEAN NoGateway;
//
+ // URI string extracted from the input FilePath parameter.
+ //
+ CHAR8 *FilePathUri;
+ VOID *FilePathUriParser;
+
+ //
// Cached HTTP data
//
LIST_ENTRY CacheList;
diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.inf b/NetworkPkg/HttpBootDxe/HttpBootDxe.inf index e24b568ddc..8b4219cb17 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDxe.inf +++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.inf @@ -1,7 +1,7 @@ ## @file
# This modules produce the Load File Protocol for UEFI HTTP boot.
#
-# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
@@ -25,10 +25,12 @@ [Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
+ NetworkPkg/NetworkPkg.dec
[Sources]
HttpBootDxe.h
HttpBootDxe.c
+ HttpBootConfig.c
HttpBootComponentName.h
HttpBootComponentName.c
HttpBootImpl.h
@@ -41,6 +43,8 @@ HttpBootSupport.c
HttpBootClient.h
HttpBootClient.c
+ HttpBootConfigVfr.vfr
+ HttpBootConfigStrings.uni
[LibraryClasses]
UefiDriverEntryPoint
@@ -52,6 +56,9 @@ DebugLib
NetLib
HttpLib
+ HiiLib
+ PrintLib
+ UefiHiiServicesLib
[Protocols]
## TO_START
@@ -72,6 +79,14 @@ gEfiIp6ProtocolGuid ## TO_START
gEfiIp6ConfigProtocolGuid ## TO_START
gEfiNetworkInterfaceIdentifierProtocolGuid_31 ## SOMETIMES_CONSUMES
+ gEfiHiiConfigAccessProtocolGuid ## BY_START
+
+[Guids]
+ ## SOMETIMES_CONSUMES ## GUID # HiiIsConfigHdrMatch mHttpBootConfigStorageName
+ ## SOMETIMES_PRODUCES ## GUID # HiiConstructConfigHdr mHttpBootConfigStorageName
+ ## SOMETIMES_PRODUCES ## GUID # HiiGetBrowserData mHttpBootConfigStorageName
+ ## SOMETIMES_CONSUMES ## HII
+ gHttpBootConfigGuid
[UserExtensions.TianoCore."ExtraFiles"]
HttpBootDxeExtra.uni
diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c index 9ea0d7f95f..3adb08d9f6 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c @@ -1,7 +1,7 @@ /** @file
The implementation of EFI_LOAD_FILE_PROTOCOL for UEFI HTTP boot.
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
@@ -21,22 +21,25 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. @param[in] UsingIpv6 Specifies the type of IP addresses that are to be
used during the session that is being started.
Set to TRUE for IPv6, and FALSE for IPv4.
+ @param[in] FilePath The device specific path of the file to load.
@retval EFI_SUCCESS HTTP boot was successfully enabled.
@retval EFI_INVALID_PARAMETER Private is NULL.
@retval EFI_ALREADY_STARTED The driver is already in started state.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources.
**/
EFI_STATUS
HttpBootStart (
IN HTTP_BOOT_PRIVATE_DATA *Private,
- IN BOOLEAN UsingIpv6
+ IN BOOLEAN UsingIpv6,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath
)
{
UINTN Index;
EFI_STATUS Status;
- if (Private == NULL) {
+ if (Private == NULL || FilePath == NULL) {
return EFI_INVALID_PARAMETER;
}
@@ -54,6 +57,26 @@ HttpBootStart ( } else {
return EFI_UNSUPPORTED;
}
+
+ //
+ // Check whether the URI address is specified.
+ //
+ Status = HttpBootParseFilePath (FilePath, &Private->FilePathUri);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Private->FilePathUri != NULL) {
+ Status = HttpParseUrl (
+ Private->FilePathUri,
+ (UINT32) AsciiStrLen (Private->FilePathUri),
+ FALSE,
+ &Private->FilePathUriParser
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
//
// Init the content of cached DHCP offer list.
@@ -301,12 +324,21 @@ HttpBootStop ( }
}
}
+
+ if (Private->FilePathUri!= NULL) {
+ FreePool (Private->FilePathUri);
+ HttpUrlFreeParser (Private->FilePathUriParser);
+ Private->FilePathUri = NULL;
+ Private->FilePathUriParser = NULL;
+ }
ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer));
Private->OfferNum = 0;
ZeroMem (Private->OfferCount, sizeof (Private->OfferCount));
ZeroMem (Private->OfferIndex, sizeof (Private->OfferIndex));
-
+
+ HttpBootFreeCacheList (Private);
+
return EFI_SUCCESS;
}
@@ -357,7 +389,7 @@ HttpBootDxeLoadFile ( BOOLEAN UsingIpv6;
EFI_STATUS Status;
- if (This == NULL || BufferSize == NULL) {
+ if (This == NULL || BufferSize == NULL || FilePath == NULL) {
return EFI_INVALID_PARAMETER;
}
@@ -370,7 +402,6 @@ HttpBootDxeLoadFile ( VirtualNic = HTTP_BOOT_VIRTUAL_NIC_FROM_LOADFILE (This);
Private = VirtualNic->Private;
- UsingIpv6 = FALSE;
//
// Check media status before HTTP boot start
@@ -380,27 +411,37 @@ HttpBootDxeLoadFile ( if (!MediaPresent) {
return EFI_NO_MEDIA;
}
-
+
//
// Check whether the virtual nic is using IPv6 or not.
//
+ UsingIpv6 = FALSE;
if (VirtualNic == Private->Ip6Nic) {
UsingIpv6 = TRUE;
}
-
+
//
- // Initialize HTTP boot and load the boot file.
+ // Initialize HTTP boot.
//
- Status = HttpBootStart (Private, UsingIpv6);
- if (Status == EFI_ALREADY_STARTED && UsingIpv6 != Private->UsingIpv6) {
+ Status = HttpBootStart (Private, UsingIpv6, FilePath);
+ if (Status == EFI_ALREADY_STARTED) {
//
- // Http boot Driver has already been started but not on the required IP version, restart it.
+ // Restart the HTTP boot driver in 2 cases:
+ // 1. Http boot Driver has already been started but not on the required IP version.
+ // 2. The required boot FilePath is different with the one we produced in the device path
+ // protocol.
//
- Status = HttpBootStop (Private);
- if (!EFI_ERROR (Status)) {
- Status = HttpBootStart (Private, UsingIpv6);
+ if ((UsingIpv6 != Private->UsingIpv6) || !IsDevicePathEnd(FilePath)) {
+ Status = HttpBootStop (Private);
+ if (!EFI_ERROR (Status)) {
+ Status = HttpBootStart (Private, UsingIpv6, FilePath);
+ }
}
}
+
+ //
+ // Load the boot file.
+ //
if (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED) {
Status = HttpBootLoadFile (Private, BufferSize, Buffer);
}
diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.c b/NetworkPkg/HttpBootDxe/HttpBootSupport.c index db2af780a1..f30d9f7fb0 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootSupport.c +++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.c @@ -977,3 +977,66 @@ HttpIoRecvResponse ( return Status;
}
+
+/**
+ Get the URI address string from the input device path.
+
+ Caller need to free the buffer in the UriAddress pointer.
+
+ @param[in] FilePath Pointer to the device path which contains a URI device path node.
+ @param[in] UriAddress The URI address string extract from the device path.
+
+ @retval EFI_SUCCESS The URI string is returned.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+
+**/
+EFI_STATUS
+HttpBootParseFilePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ OUT CHAR8 **UriAddress
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ URI_DEVICE_PATH *UriDevicePath;
+ CHAR8 *Uri;
+ UINTN UriStrLength;
+
+ if (FilePath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *UriAddress = NULL;
+
+ //
+ // Extract the URI address from the FilePath
+ //
+ TempDevicePath = FilePath;
+ while (!IsDevicePathEnd (TempDevicePath)) {
+ if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) &&
+ (DevicePathSubType (TempDevicePath) == MSG_URI_DP)) {
+ UriDevicePath = (URI_DEVICE_PATH*) TempDevicePath;
+ //
+ // UEFI Spec doesn't require the URI to be a NULL-terminated string
+ // So we allocate a new buffer and always append a '\0' to it.
+ //
+ UriStrLength = DevicePathNodeLength (UriDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);
+ if (UriStrLength == 0) {
+ //
+ // return a NULL UriAddress if it's a empty URI device path node.
+ //
+ break;
+ }
+ Uri = AllocatePool (UriStrLength + 1);
+ if (Uri == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (Uri, UriDevicePath->Uri, DevicePathNodeLength (UriDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL));
+ Uri[DevicePathNodeLength (UriDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL)] = '\0';
+
+ *UriAddress = Uri;
+ }
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.h b/NetworkPkg/HttpBootDxe/HttpBootSupport.h index 8e0fc37fdd..3edea615af 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootSupport.h +++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.h @@ -329,4 +329,22 @@ HttpIoRecvResponse ( OUT HTTP_IO_RESPONSE_DATA *ResponseData
);
+/**
+ Get the URI address string from the input device path.
+
+ Caller need to free the buffer in the UriAddress pointer.
+
+ @param[in] FilePath Pointer to the device path which contains a URI device path node.
+ @param[in] UriAddress The URI address string extract from the device path.
+
+ @retval EFI_SUCCESS The URI string is returned.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+
+**/
+EFI_STATUS
+HttpBootParseFilePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ OUT CHAR8 **UriAddress
+ );
+
#endif
|