Looks good to me. Reviewed-by: Ye Ting <ting...@intel.com> -----Original Message----- From: Fu, Siyuan Sent: Friday, March 04, 2016 4:40 PM To: Fu, Siyuan <siyuan...@intel.com>; edk2-devel@lists.01.org Cc: Ye, Ting <ting...@intel.com>; Wu, Jiaxin <jiaxin...@intel.com> Subject: RE: [edk2] [PATCH v3] NetworkPkg: Add URI configuration form to HTTP boot driver.
V3 changes: Update the driver to handle an empty URI device node. > -----Original Message----- > From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Fu > Siyuan > Sent: Friday, March 4, 2016 4:38 PM > To: edk2-devel@lists.01.org > Cc: Ye, Ting <ting...@intel.com>; Wu, Jiaxin <jiaxin...@intel.com> > Subject: [edk2] [PATCH v3] 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...@intel.com> > Cc: Wu Jiaxin <jiaxin...@intel.com> > Cc: Ye Ting <ting...@intel.com> > --- > NetworkPkg/HttpBootDxe/HttpBootClient.c | 99 +-- > NetworkPkg/HttpBootDxe/HttpBootConfig.c | 723 > +++++++++++++++++++++ > NetworkPkg/HttpBootDxe/HttpBootConfig.h | 78 +++ > NetworkPkg/HttpBootDxe/HttpBootConfigNVDataStruc.h | 43 ++ > NetworkPkg/HttpBootDxe/HttpBootConfigStrings.uni | Bin 0 -> 2926 bytes > NetworkPkg/HttpBootDxe/HttpBootConfigVfr.vfr | 53 ++ > NetworkPkg/HttpBootDxe/HttpBootDhcp4.c | 111 +++- > NetworkPkg/HttpBootDxe/HttpBootDhcp4.h | 9 +- > NetworkPkg/HttpBootDxe/HttpBootDhcp6.c | 6 +- > NetworkPkg/HttpBootDxe/HttpBootDxe.c | 44 +- > NetworkPkg/HttpBootDxe/HttpBootDxe.h | 33 +- > NetworkPkg/HttpBootDxe/HttpBootDxe.inf | 17 +- > NetworkPkg/HttpBootDxe/HttpBootImpl.c | 71 +- > NetworkPkg/HttpBootDxe/HttpBootSupport.c | 63 ++ > NetworkPkg/HttpBootDxe/HttpBootSupport.h | 18 + > NetworkPkg/Include/Guid/HttpBootConfigHii.h | 25 + > NetworkPkg/NetworkPkg.dec | 5 +- > 17 files changed, 1288 insertions(+), 110 deletions(-) > create mode 100644 NetworkPkg/HttpBootDxe/HttpBootConfig.c > create mode 100644 NetworkPkg/HttpBootDxe/HttpBootConfig.h > create mode 100644 > NetworkPkg/HttpBootDxe/HttpBootConfigNVDataStruc.h > create mode 100644 NetworkPkg/HttpBootDxe/HttpBootConfigStrings.uni > create mode 100644 NetworkPkg/HttpBootDxe/HttpBootConfigVfr.vfr > create mode 100644 NetworkPkg/Include/Guid/HttpBootConfigHii.h > > diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.c > b/NetworkPkg/HttpBootDxe/HttpBootClient.c > index 2ccac8c..aae4527 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 0000000..db14da0 > --- /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 0000000..a2afd18 > --- /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 0000000..07043e7 > --- /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 > new file mode 100644 > index > 0000000000000000000000000000000000000000..5001220eb3cc71f1bf7e53e > 53b142bea34254043 > GIT binary patch > literal 2926 > zcmb`JT~8B16o${WiT`0!Zq#6_hHznw5v1To>^AKpdexM+lqQ9eZ2|f7>hsRHo! > #=W > zsARJ{U+3dJ@0>ZazkW9C1y5uj?ARtYwUIrwCyXQO+QKsC&TPzR$ciM+co)1gd > UNKF > z>1DK^Eahp_+h%5lOk@KmC9SbtAk|-L)}5E!(?{ga?b>- > 8+lkYChW2x8ys=mI+BR*S > zevHorIHvTalcA+=(Qag0tV=@Jy*1&?(3|sScFA{Wb$bWWj=e7- > N%1~$ah)SMLtoZU > z(eLAXNV`B{<i-OR- > zgZhc8#8A>eS(prwP3&*77*}%t?33%7C626qaCJx?);0m%Q4M > zz8&$^+=as+%K?Y@$UvwVbBvz%A=<^Anz2_wZ=3zyVZ2|$k|VuxJPi2CYB|yg9 > _39; > zc&_AW&R7v2fim}6M=ByKJY&bK_?;2vA4o+oT*Or7B_gUmyhhkm^vX2PfG{nV > tSVm? > z?7~}X@F<f!vy#pn&vj- > q_Oh|U{G6F1kPq$U%1Rw8C%ol6P08{mNZRC0VtahI><i-< > zE+g1fn=%`dSqJo*j^P7q(KeYE7v4f(KPHo#NOYa$gq|{3- > x{s#%4&^v+l@6^U&emO > zs%$3CUu1{KbR4c0^D#DMA#uJtjD%cs@|Yqk8Ts^5yU5D- > ciPXa2)E8%^N$xFL({%3 > z?F8#FOti@+`P?b+rs~pIp0PD}R+f%kmTT{|S1&;?OEq-0raYL#f32XG=a)ZYp6A}O > z>hxeI;YqCrpNeP~Bzuf@8Fj$cbFro%)D9M(fawBkW0z}XRJYYO)t@tR@@8%Gs > MnS! > z;@=S~SN37Gh*te-#H;9Zer}6GwaZty5obu1WX|6GeFQNmd- > fH)9d^>^RL^Be;_@P0 > ziJ>}zyw+#1ENnV;s>lmo)wk)Rp}dRbhw$75n`-mGA<XXv-7sR(-;#NitB&aLnBQ38 > zJ7my9m~Y$0qp`dBpGY<<kc4x8K<>q4p|8%WMypvDSSa_ZISKzX- > pl<b<R+%ObF7Rc > zjH)qh!K}{46>Y$maBJoFZ^WAZAoMrn@6Z8xIdZpW{@<ayUFS- > 7xUW<?Va3}$*!Hnk > zWod|Bw_cZetbNgLRM&+({_5y;n$F$7M);@EpVQpMGbyle|6aAYd- > i#HAoX{5i+dx- > L@vycUt;g^iZoj(& > > literal 0 > HcmV?d00001 > > diff --git a/NetworkPkg/HttpBootDxe/HttpBootConfigVfr.vfr > b/NetworkPkg/HttpBootDxe/HttpBootConfigVfr.vfr > new file mode 100644 > index 0000000..e47c6af > --- /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 9a947a6..b9c8084 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 2bc46de..5ac7f71 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 2538bd1..d2960e4 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 9fb33bb..6a3033d 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 08f88c5..7cb4b2c 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 e24b568..8b4219c 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 9ea0d7f..3adb08d 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 db2af78..f30d9f7 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 8e0fc37..3edea61 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 > diff --git a/NetworkPkg/Include/Guid/HttpBootConfigHii.h > b/NetworkPkg/Include/Guid/HttpBootConfigHii.h > new file mode 100644 > index 0000000..7e44436 > --- /dev/null > +++ b/NetworkPkg/Include/Guid/HttpBootConfigHii.h > @@ -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 > diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec > index 288d1aa..268188a 100644 > --- a/NetworkPkg/NetworkPkg.dec > +++ b/NetworkPkg/NetworkPkg.dec > @@ -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> > -- > 2.7.0.windows.2 > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel