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>
This commit is contained in:
Fu Siyuan 2016-02-15 13:55:11 +08:00
parent 9353c60cea
commit fa848a4048
17 changed files with 1288 additions and 110 deletions

View File

@ -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,21 +213,14 @@ 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) {
Private->Port = 80;
}
//
// 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.
//
@ -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,21 +370,14 @@ 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) {
Private->Port = 80;
}
//
// 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.
//
@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

Binary file not shown.

View File

@ -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;

View File

@ -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;
@ -474,45 +478,80 @@ 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[HttpOfferTypeDhcpIpUri][0] + 1;
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
} else if (Private->OfferCount[HttpOfferTypeDhcpNameUriDns] > 0) {
} else if (Private->OfferCount[HttpOfferTypeDhcpIpUriDns] > 0) {
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpNameUriDns][0] + 1;
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUriDns][0] + 1;
} else if (Private->OfferCount[HttpOfferTypeDhcpOnly] > 0 &&
Private->OfferCount[HttpOfferTypeProxyIpUri] > 0) {
} else if (Private->OfferCount[HttpOfferTypeDhcpNameUriDns] > 0) {
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpOnly][0] + 1;
Private->SelectProxyType = HttpOfferTypeProxyIpUri;
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpNameUriDns][0] + 1;
} else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
Private->OfferCount[HttpOfferTypeProxyIpUri] > 0) {
} else if (Private->OfferCount[HttpOfferTypeDhcpOnly] > 0) {
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
Private->SelectProxyType = HttpOfferTypeProxyIpUri;
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpOnly][0] + 1;
} else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
Private->OfferCount[HttpOfferTypeProxyNameUri] > 0) {
} else if (Private->OfferCount[HttpOfferTypeDhcpIpUri] > 0) {
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
Private->SelectProxyType = HttpOfferTypeProxyNameUri;
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUri][0] + 1;
}
} else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
Private->OfferCount[HttpOfferTypeDhcpNameUri] > 0) {
} 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[HttpOfferTypeDhcpDns][0] + 1;
Private->SelectProxyType = HttpOfferTypeDhcpNameUri;
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) {
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;
}
}
}

View File

@ -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,

View File

@ -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;

View File

@ -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
@ -364,6 +364,14 @@ HttpBootIp4DxeDriverBindingStart (
goto ON_ERROR;
}
//
// 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.
@ -510,6 +518,7 @@ HttpBootIp4DxeDriverBindingStart (
ON_ERROR:
HttpBootDestroyIp4Children (This, Private);
HttpBootConfigFormUnload (Private);
FreePool (Private);
return Status;
@ -616,6 +625,11 @@ HttpBootIp4DxeDriverBindingStop (
//
HttpBootFreeCacheList (Private);
//
// Unload the config form.
//
HttpBootConfigFormUnload (Private);
gBS->UninstallProtocolInterface (
NicHandle,
&gEfiCallerIdGuid,
@ -822,6 +836,14 @@ HttpBootIp6DxeDriverBindingStart (
goto ON_ERROR;
}
//
// 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.
@ -990,11 +1012,11 @@ HttpBootIp6DxeDriverBindingStart (
ON_ERROR:
HttpBootDestroyIp6Children(This, Private);
FreePool (Private);
return Status;
HttpBootDestroyIp6Children(This, Private);
HttpBootConfigFormUnload (Private);
FreePool (Private);
return Status;
}
/**
@ -1097,6 +1119,11 @@ HttpBootIp6DxeDriverBindingStop (
//
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).
//

View File

@ -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>
@ -54,6 +60,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
#include <Protocol/LoadFile.h>
//
// Consumed Guids
//
#include <Guid/HttpBootConfigHii.h>
//
// Driver Version
//
@ -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;
@ -131,6 +151,11 @@ struct _HTTP_BOOT_PRIVATE_DATA {
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINT32 Id;
//
// HII callback info block
//
HTTP_BOOT_FORM_CALLBACK_INFO CallbackInfo;
//
// Mode data
//
@ -146,6 +171,12 @@ struct _HTTP_BOOT_PRIVATE_DATA {
UINTN BootFileSize;
BOOLEAN NoGateway;
//
// URI string extracted from the input FilePath parameter.
//
CHAR8 *FilePathUri;
VOID *FilePathUriParser;
//
// Cached HTTP data
//

View File

@ -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

View File

@ -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;
}
@ -55,6 +58,26 @@ HttpBootStart (
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.
//
@ -302,11 +325,20 @@ 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
@ -384,23 +415,33 @@ HttpBootDxeLoadFile (
//
// 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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -0,0 +1,25 @@
/** @file
GUIDs used as HII FormSet and HII Package list GUID in HTTP boot driver.
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 that 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_HII_GUID_H__
#define __HTTP_BOOT_HII_GUID_H__
#define HTTP_BOOT_CONFIG_GUID \
{ \
0x4d20583a, 0x7765, 0x4e7a, { 0x8a, 0x67, 0xdc, 0xde, 0x74, 0xee, 0x3e, 0xc5 } \
}
extern EFI_GUID gHttpBootConfigGuid;
#endif

View File

@ -4,7 +4,7 @@
# This package provides network modules that conform to UEFI 2.4 specification.
#
# (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2009 - 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.
@ -37,6 +37,9 @@
# Include/Guid/IscsiConfigHii.h
gIScsiConfigGuid = { 0x4b47d616, 0xa8d6, 0x4552, { 0x9d, 0x44, 0xcc, 0xad, 0x2e, 0xf, 0x4c, 0xf9}}
# Include/Guid/HttpBootConfigHii.h
gHttpBootConfigGuid = { 0x4d20583a, 0x7765, 0x4e7a, { 0x8a, 0x67, 0xdc, 0xde, 0x74, 0xee, 0x3e, 0xc5 }}
[PcdsFeatureFlag]
## Indicates if the IPsec IKEv2 Certificate Authentication feature is enabled or not.<BR><BR>
# TRUE - Certificate Authentication feature is enabled.<BR>