X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FHttpBootDxe%2FHttpBootImpl.c;h=3da585a29164c8c05f1c7c904730c63ae571cd4b;hb=f0064ac3afa28e1aa3b6b9c22c6cf422a4bb8771;hp=dfd0e23db02d2f41fad348c53a86a8b08117690f;hpb=bb4831c03dd15ff8528dcdbc7d2ad1835f55563e;p=mirror_edk2.git diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c index dfd0e23db0..3da585a291 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c @@ -1,15 +1,9 @@ /** @file The implementation of EFI_LOAD_FILE_PROTOCOL for UEFI HTTP boot. -Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
-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. +SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -20,17 +14,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. @param[in] Private Pointer to HTTP Boot private data. - @retval EFI_SUCCESS HTTP Boot Callback Protocol installed succesfully. + @retval EFI_SUCCESS HTTP Boot Callback Protocol installed successfully. @retval Others Failed to install HTTP Boot Callback Protocol. **/ EFI_STATUS HttpBootInstallCallback ( - IN HTTP_BOOT_PRIVATE_DATA *Private + IN HTTP_BOOT_PRIVATE_DATA *Private ) { - EFI_STATUS Status; - EFI_HANDLE ControllerHandle; + EFI_STATUS Status; + EFI_HANDLE ControllerHandle; if (!Private->UsingIpv6) { ControllerHandle = Private->Ip4Nic->Controller; @@ -44,10 +38,9 @@ HttpBootInstallCallback ( Status = gBS->HandleProtocol ( ControllerHandle, &gEfiHttpBootCallbackProtocolGuid, - (VOID **) &Private->HttpBootCallback + (VOID **)&Private->HttpBootCallback ); if (Status == EFI_UNSUPPORTED) { - CopyMem ( &Private->LoadFileCallback, &gHttpBootDxeHttpBootCallback, @@ -66,6 +59,7 @@ HttpBootInstallCallback ( if (EFI_ERROR (Status)) { return Status; } + Private->HttpBootCallback = &Private->LoadFileCallback; } @@ -80,15 +74,15 @@ HttpBootInstallCallback ( **/ VOID HttpBootUninstallCallback ( - IN HTTP_BOOT_PRIVATE_DATA *Private + IN HTTP_BOOT_PRIVATE_DATA *Private ) { if (Private->HttpBootCallback == &Private->LoadFileCallback) { gBS->UninstallProtocolInterface ( - Private->Controller, - &gEfiHttpBootCallbackProtocolGuid, - &Private->HttpBootCallback - ); + Private->Controller, + &gEfiHttpBootCallbackProtocolGuid, + &Private->HttpBootCallback + ); Private->HttpBootCallback = NULL; } } @@ -96,7 +90,7 @@ HttpBootUninstallCallback ( /** Enable the use of UEFI HTTP boot function. - If the driver has already been started but not satisfy the requirement (IP stack and + If the driver has already been started but not satisfy the requirement (IP stack and specified boot file path), this function will stop the driver and start it again. @param[in] Private The pointer to the driver's private data. @@ -110,33 +104,34 @@ HttpBootUninstallCallback ( @retval EFI_INVALID_PARAMETER The FilePath doesn't contain a valid URI device path node. @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 EFI_DEVICE_PATH_PROTOCOL *FilePath + IN HTTP_BOOT_PRIVATE_DATA *Private, + IN BOOLEAN UsingIpv6, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath ) { - UINTN Index; - EFI_STATUS Status; - CHAR8 *Uri; - + UINTN Index; + EFI_STATUS Status; + CHAR8 *Uri; - if (Private == NULL || FilePath == NULL) { + Uri = NULL; + + if ((Private == NULL) || (FilePath == NULL)) { return EFI_INVALID_PARAMETER; } - + // // Check the URI in the input FilePath, in order to see whether it is - // required to boot from a new specified boot file. + // required to boot from a new specified boot file. // Status = HttpBootParseFilePath (FilePath, &Uri); if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } - + // // Check whether we need to stop and restart the HTTP boot driver. // @@ -147,13 +142,18 @@ HttpBootStart ( // 2. The specified boot file URI in FilePath is different with the one we have // recorded before. // - if ((UsingIpv6 != Private->UsingIpv6) || - ((Uri != NULL) && (AsciiStrCmp (Private->BootFileUri, Uri) != 0))) { + if ((UsingIpv6 != Private->UsingIpv6) || + ((Uri != NULL) && (AsciiStrCmp (Private->BootFileUri, Uri) != 0))) + { // // Restart is required, first stop then continue this start function. // Status = HttpBootStop (Private); if (EFI_ERROR (Status)) { + if (Uri != NULL) { + FreePool (Uri); + } + return Status; } } else { @@ -163,6 +163,7 @@ HttpBootStart ( if (Uri != NULL) { FreePool (Uri); } + return EFI_ALREADY_STARTED; } } @@ -170,14 +171,15 @@ HttpBootStart ( // // Detect whether using ipv6 or not, and set it to the private data. // - if (UsingIpv6 && Private->Ip6Nic != NULL) { + if (UsingIpv6 && (Private->Ip6Nic != NULL)) { Private->UsingIpv6 = TRUE; - } else if (!UsingIpv6 && Private->Ip4Nic != NULL) { + } else if (!UsingIpv6 && (Private->Ip4Nic != NULL)) { Private->UsingIpv6 = FALSE; } else { if (Uri != NULL) { FreePool (Uri); } + return EFI_UNSUPPORTED; } @@ -188,7 +190,7 @@ HttpBootStart ( if (Private->FilePathUri != NULL) { Status = HttpParseUrl ( Private->FilePathUri, - (UINT32) AsciiStrLen (Private->FilePathUri), + (UINT32)AsciiStrLen (Private->FilePathUri), FALSE, &Private->FilePathUriParser ); @@ -197,7 +199,7 @@ HttpBootStart ( return Status; } } - + // // Init the content of cached DHCP offer list. // @@ -221,7 +223,8 @@ HttpBootStart ( return Status; } } - Private->Started = TRUE; + + Private->Started = TRUE; Print (L"\n>>Start HTTP Boot over IPv%d", Private->UsingIpv6 ? 6 : 4); return EFI_SUCCESS; @@ -237,19 +240,19 @@ HttpBootStart ( @retval EFI_NOT_STARTED The driver is in stopped state. @retval EFI_DEVICE_ERROR An unexpected network error occurred. @retval Others Other errors as indicated. - + **/ EFI_STATUS HttpBootDhcp ( - IN HTTP_BOOT_PRIVATE_DATA *Private + IN HTTP_BOOT_PRIVATE_DATA *Private ) { - EFI_STATUS Status; + EFI_STATUS Status; if (Private == NULL) { return EFI_INVALID_PARAMETER; } - + if (!Private->Started) { return EFI_NOT_STARTED; } @@ -262,7 +265,7 @@ HttpBootDhcp ( // Status = HttpBootDhcp4Dora (Private); } else { - // + // // Start S.A.R.R process to get a IPv6 address and other boot information. // Status = HttpBootDhcp6Sarr (Private); @@ -288,36 +291,36 @@ HttpBootDhcp ( @retval EFI_INVALID_PARAMETER Private is NULL, or ImageType is NULL, or BufferSize is NULL. @retval EFI_INVALID_PARAMETER *BufferSize is not zero, and Buffer is NULL. @retval EFI_NOT_STARTED The driver is in stopped state. - @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the boot file. BufferSize has + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the boot file. BufferSize has been updated with the size needed to complete the request. @retval EFI_DEVICE_ERROR An unexpected network error occurred. @retval Others Other errors as indicated. - + **/ EFI_STATUS HttpBootLoadFile ( - IN HTTP_BOOT_PRIVATE_DATA *Private, - IN OUT UINTN *BufferSize, - IN VOID *Buffer, OPTIONAL - OUT HTTP_BOOT_IMAGE_TYPE *ImageType + IN HTTP_BOOT_PRIVATE_DATA *Private, + IN OUT UINTN *BufferSize, + IN VOID *Buffer OPTIONAL, + OUT HTTP_BOOT_IMAGE_TYPE *ImageType ) { - EFI_STATUS Status; + EFI_STATUS Status; - if (Private == NULL || ImageType == NULL || BufferSize == NULL ) { + if ((Private == NULL) || (ImageType == NULL) || (BufferSize == NULL)) { return EFI_INVALID_PARAMETER; } - if (*BufferSize != 0 && Buffer == NULL) { + if ((*BufferSize != 0) && (Buffer == NULL)) { return EFI_INVALID_PARAMETER; } - + if (!Private->Started) { return EFI_NOT_STARTED; } Status = HttpBootInstallCallback (Private); - if (EFI_ERROR(Status)) { + if (EFI_ERROR (Status)) { goto ON_EXIT; } @@ -327,6 +330,7 @@ HttpBootLoadFile ( // Status = HttpBootDiscoverBootInfo (Private); if (EFI_ERROR (Status)) { + AsciiPrint ("\n Error: Could not retrieve NBP file size from HTTP server.\n"); goto ON_EXIT; } } @@ -356,7 +360,7 @@ HttpBootLoadFile ( NULL, &Private->ImageType ); - if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { + if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) { // // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method. // @@ -368,7 +372,8 @@ HttpBootLoadFile ( NULL, &Private->ImageType ); - if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { + if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) { + AsciiPrint ("\n Error: Could not retrieve NBP file size from HTTP server.\n"); goto ON_EXIT; } } @@ -376,8 +381,8 @@ HttpBootLoadFile ( if (*BufferSize < Private->BootFileSize) { *BufferSize = Private->BootFileSize; - *ImageType = Private->ImageType; - Status = EFI_BUFFER_TOO_SMALL; + *ImageType = Private->ImageType; + Status = EFI_BUFFER_TOO_SMALL; goto ON_EXIT; } @@ -391,9 +396,28 @@ HttpBootLoadFile ( Buffer, ImageType ); - + ON_EXIT: HttpBootUninstallCallback (Private); + + if (EFI_ERROR (Status)) { + if (Status == EFI_ACCESS_DENIED) { + AsciiPrint ("\n Error: Could not establish connection with HTTP server.\n"); + } else if ((Status == EFI_BUFFER_TOO_SMALL) && (Buffer != NULL)) { + AsciiPrint ("\n Error: Buffer size is smaller than the requested file.\n"); + } else if (Status == EFI_OUT_OF_RESOURCES) { + AsciiPrint ("\n Error: Could not allocate I/O buffers.\n"); + } else if (Status == EFI_DEVICE_ERROR) { + AsciiPrint ("\n Error: Network device error.\n"); + } else if (Status == EFI_TIMEOUT) { + AsciiPrint ("\n Error: Server response timeout.\n"); + } else if (Status == EFI_ABORTED) { + AsciiPrint ("\n Error: Remote boot cancelled.\n"); + } else if (Status != EFI_BUFFER_TOO_SMALL) { + AsciiPrint ("\n Error: Unexpected network error.\n"); + } + } + return Status; } @@ -406,38 +430,38 @@ ON_EXIT: @retval EFI_NOT_STARTED The driver is already in stopped state. @retval EFI_INVALID_PARAMETER Private is NULL. @retval Others Unexpected error when stop the function. - + **/ EFI_STATUS HttpBootStop ( - IN HTTP_BOOT_PRIVATE_DATA *Private + IN HTTP_BOOT_PRIVATE_DATA *Private ) { - UINTN Index; + UINTN Index; if (Private == NULL) { return EFI_INVALID_PARAMETER; } - + if (!Private->Started) { return EFI_NOT_STARTED; } - + if (Private->HttpCreated) { HttpIoDestroyIo (&Private->HttpIo); Private->HttpCreated = FALSE; } - + Private->Started = FALSE; ZeroMem (&Private->StationIp, sizeof (EFI_IP_ADDRESS)); ZeroMem (&Private->SubnetMask, sizeof (EFI_IP_ADDRESS)); ZeroMem (&Private->GatewayIp, sizeof (EFI_IP_ADDRESS)); - Private->Port = 0; - Private->BootFileUri = NULL; + Private->Port = 0; + Private->BootFileUri = NULL; Private->BootFileUriParser = NULL; - Private->BootFileSize = 0; - Private->SelectIndex = 0; - Private->SelectProxyType = HttpOfferTypeMax; + Private->BootFileSize = 0; + Private->SelectIndex = 0; + Private->SelectProxyType = HttpOfferTypeMax; if (!Private->UsingIpv6) { // @@ -457,7 +481,7 @@ HttpBootStop ( // Private->Dhcp6->Stop (Private->Dhcp6); Private->Dhcp6->Configure (Private->Dhcp6, NULL); - + for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) { if (Private->OfferBuffer[Index].Dhcp6.UriParser) { HttpUrlFreeParser (Private->OfferBuffer[Index].Dhcp6.UriParser); @@ -465,20 +489,25 @@ HttpBootStop ( } } - if (Private->FilePathUri!= NULL) { + if (Private->DnsServerIp != NULL) { + FreePool (Private->DnsServerIp); + Private->DnsServerIp = NULL; + } + + if (Private->FilePathUri != NULL) { FreePool (Private->FilePathUri); HttpUrlFreeParser (Private->FilePathUriParser); - Private->FilePathUri = NULL; + 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; } @@ -516,21 +545,21 @@ HttpBootStop ( EFI_STATUS EFIAPI HttpBootDxeLoadFile ( - IN EFI_LOAD_FILE_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN BOOLEAN BootPolicy, - IN OUT UINTN *BufferSize, - IN VOID *Buffer OPTIONAL + IN EFI_LOAD_FILE_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN BOOLEAN BootPolicy, + IN OUT UINTN *BufferSize, + IN VOID *Buffer OPTIONAL ) { - HTTP_BOOT_PRIVATE_DATA *Private; - HTTP_BOOT_VIRTUAL_NIC *VirtualNic; - BOOLEAN MediaPresent; - BOOLEAN UsingIpv6; - EFI_STATUS Status; - HTTP_BOOT_IMAGE_TYPE ImageType; - - if (This == NULL || BufferSize == NULL || FilePath == NULL) { + HTTP_BOOT_PRIVATE_DATA *Private; + HTTP_BOOT_VIRTUAL_NIC *VirtualNic; + EFI_STATUS MediaStatus; + BOOLEAN UsingIpv6; + EFI_STATUS Status; + HTTP_BOOT_IMAGE_TYPE ImageType; + + if ((This == NULL) || (BufferSize == NULL) || (FilePath == NULL)) { return EFI_INVALID_PARAMETER; } @@ -542,17 +571,18 @@ HttpBootDxeLoadFile ( } VirtualNic = HTTP_BOOT_VIRTUAL_NIC_FROM_LOADFILE (This); - Private = VirtualNic->Private; - + Private = VirtualNic->Private; + // // Check media status before HTTP boot start // - MediaPresent = TRUE; - NetLibDetectMedia (Private->Controller, &MediaPresent); - if (!MediaPresent) { + MediaStatus = EFI_SUCCESS; + NetLibDetectMediaWaitTimeout (Private->Controller, HTTP_BOOT_CHECK_MEDIA_WAITING_TIME, &MediaStatus); + if (MediaStatus != EFI_SUCCESS) { + AsciiPrint ("\n Error: Could not detect network connection.\n"); return EFI_NO_MEDIA; } - + // // Check whether the virtual nic is using IPv6 or not. // @@ -565,31 +595,34 @@ HttpBootDxeLoadFile ( // Initialize HTTP boot. // Status = HttpBootStart (Private, UsingIpv6, FilePath); - if (Status != EFI_SUCCESS && Status != EFI_ALREADY_STARTED) { + if ((Status != EFI_SUCCESS) && (Status != EFI_ALREADY_STARTED)) { return Status; } - + // // Load the boot file. // ImageType = ImageTypeMax; - Status = HttpBootLoadFile (Private, BufferSize, Buffer, &ImageType); + Status = HttpBootLoadFile (Private, BufferSize, Buffer, &ImageType); if (EFI_ERROR (Status)) { - if (Status == EFI_BUFFER_TOO_SMALL && (ImageType == ImageTypeVirtualCd || ImageType == ImageTypeVirtualDisk)) { + if ((Status == EFI_BUFFER_TOO_SMALL) && ((ImageType == ImageTypeVirtualCd) || (ImageType == ImageTypeVirtualDisk))) { Status = EFI_WARN_FILE_SYSTEM; } else if (Status != EFI_BUFFER_TOO_SMALL) { HttpBootStop (Private); } + return Status; } // // Register the RAM Disk to the system if needed. // - if (ImageType == ImageTypeVirtualCd || ImageType == ImageTypeVirtualDisk) { + if ((ImageType == ImageTypeVirtualCd) || (ImageType == ImageTypeVirtualDisk)) { Status = HttpBootRegisterRamDisk (Private, *BufferSize, Buffer, ImageType); if (!EFI_ERROR (Status)) { Status = EFI_WARN_FILE_SYSTEM; + } else { + AsciiPrint ("\n Error: Could not register RAM disk to the system.\n"); } } @@ -603,7 +636,7 @@ HttpBootDxeLoadFile ( /// /// Load File Protocol instance /// -GLOBAL_REMOVE_IF_UNREFERENCED +GLOBAL_REMOVE_IF_UNREFERENCED EFI_LOAD_FILE_PROTOCOL gHttpBootDxeLoadFile = { HttpBootDxeLoadFile }; @@ -625,18 +658,18 @@ EFI_LOAD_FILE_PROTOCOL gHttpBootDxeLoadFile = { @param[in] DataLength The length in bytes of the buffer pointed to by Data. @param[in] Data A pointer to the buffer of data, the data type is specified by DataType. - + @retval EFI_SUCCESS Tells the HTTP Boot driver to continue the HTTP Boot process. @retval EFI_ABORTED Tells the HTTP Boot driver to abort the current HTTP Boot process. **/ EFI_STATUS EFIAPI HttpBootCallback ( - IN EFI_HTTP_BOOT_CALLBACK_PROTOCOL *This, - IN EFI_HTTP_BOOT_CALLBACK_DATA_TYPE DataType, - IN BOOLEAN Received, - IN UINT32 DataLength, - IN VOID *Data OPTIONAL + IN EFI_HTTP_BOOT_CALLBACK_PROTOCOL *This, + IN EFI_HTTP_BOOT_CALLBACK_DATA_TYPE DataType, + IN BOOLEAN Received, + IN UINT32 DataLength, + IN VOID *Data OPTIONAL ) { EFI_HTTP_MESSAGE *HttpMessage; @@ -644,88 +677,95 @@ HttpBootCallback ( HTTP_BOOT_PRIVATE_DATA *Private; UINT32 Percentage; - Private = HTTP_BOOT_PRIVATE_DATA_FROM_CALLBACK_PROTOCOL(This); + Private = HTTP_BOOT_PRIVATE_DATA_FROM_CALLBACK_PROTOCOL (This); switch (DataType) { - case HttpBootDhcp4: - case HttpBootDhcp6: - Print (L"."); - break; - - case HttpBootHttpRequest: - if (Data != NULL) { - HttpMessage = (EFI_HTTP_MESSAGE *) Data; - if (HttpMessage->Data.Request->Method == HttpMethodGet && - HttpMessage->Data.Request->Url != NULL) { - Print (L"\n URI: %s\n", HttpMessage->Data.Request->Url); + case HttpBootDhcp4: + case HttpBootDhcp6: + Print (L"."); + break; + + case HttpBootHttpRequest: + if (Data != NULL) { + HttpMessage = (EFI_HTTP_MESSAGE *)Data; + if ((HttpMessage->Data.Request->Method == HttpMethodGet) && + (HttpMessage->Data.Request->Url != NULL)) + { + Print (L"\n URI: %s\n", HttpMessage->Data.Request->Url); + } } - } - break; - - case HttpBootHttpResponse: - if (Data != NULL) { - HttpMessage = (EFI_HTTP_MESSAGE *) Data; - - if (HttpMessage->Data.Response != NULL) { - if (HttpBootIsHttpRedirectStatusCode (HttpMessage->Data.Response->StatusCode)) { - // - // Server indicates the resource has been redirected to a different URL - // according to the section 6.4 of RFC7231 and the RFC 7538. - // Display the redirect information on the screen. - // - HttpHeader = HttpFindHeader ( - HttpMessage->HeaderCount, - HttpMessage->Headers, - HTTP_HEADER_LOCATION - ); - if (HttpHeader != NULL) { - Print (L"\n HTTP ERROR: Resource Redirected.\n New Location: %a\n", HttpHeader->FieldValue); + + break; + + case HttpBootHttpResponse: + if (Data != NULL) { + HttpMessage = (EFI_HTTP_MESSAGE *)Data; + + if (HttpMessage->Data.Response != NULL) { + if (HttpBootIsHttpRedirectStatusCode (HttpMessage->Data.Response->StatusCode)) { + // + // Server indicates the resource has been redirected to a different URL + // according to the section 6.4 of RFC7231 and the RFC 7538. + // Display the redirect information on the screen. + // + HttpHeader = HttpFindHeader ( + HttpMessage->HeaderCount, + HttpMessage->Headers, + HTTP_HEADER_LOCATION + ); + if (HttpHeader != NULL) { + Print (L"\n HTTP ERROR: Resource Redirected.\n New Location: %a\n", HttpHeader->FieldValue); + } + + break; } } - } - - HttpHeader = HttpFindHeader ( - HttpMessage->HeaderCount, - HttpMessage->Headers, - HTTP_HEADER_CONTENT_LENGTH - ); - if (HttpHeader != NULL) { - Private->FileSize = AsciiStrDecimalToUintn (HttpHeader->FieldValue); - Private->ReceivedSize = 0; - Private->Percentage = 0; - } - } - break; - - case HttpBootHttpEntityBody: - if (DataLength != 0) { - if (Private->FileSize != 0) { - // - // We already know the file size, print in percentage format. - // - if (Private->ReceivedSize == 0) { - Print (L" File Size: %lu Bytes\n", Private->FileSize); + + HttpHeader = HttpFindHeader ( + HttpMessage->HeaderCount, + HttpMessage->Headers, + HTTP_HEADER_CONTENT_LENGTH + ); + if (HttpHeader != NULL) { + Private->FileSize = AsciiStrDecimalToUintn (HttpHeader->FieldValue); + Private->ReceivedSize = 0; + Private->Percentage = 0; } - Private->ReceivedSize += DataLength; - Percentage = (UINT32) DivU64x64Remainder (MultU64x32 (Private->ReceivedSize, 100), Private->FileSize, NULL); - if (Private->Percentage != Percentage) { - Private->Percentage = Percentage; - Print (L"\r Downloading...%d%%", Percentage); + } + + break; + + case HttpBootHttpEntityBody: + if (DataLength != 0) { + if (Private->FileSize != 0) { + // + // We already know the file size, print in percentage format. + // + if (Private->ReceivedSize == 0) { + Print (L" File Size: %lu Bytes\n", Private->FileSize); + } + + Private->ReceivedSize += DataLength; + Percentage = (UINT32)DivU64x64Remainder (MultU64x32 (Private->ReceivedSize, 100), Private->FileSize, NULL); + if (Private->Percentage != Percentage) { + Private->Percentage = Percentage; + Print (L"\r Downloading...%d%%", Percentage); + } + } else { + // + // In some case we couldn't get the file size from the HTTP header, so we + // just print the downloaded file size. + // + Private->ReceivedSize += DataLength; + Print (L"\r Downloading...%lu Bytes", Private->ReceivedSize); } - } else { - // - // In some case we couldn't get the file size from the HTTP header, so we - // just print the downloaded file size. - // - Private->ReceivedSize += DataLength; - Print (L"\r Downloading...%lu Bytes", Private->ReceivedSize); } - } - break; - default: - break; - }; + break; + + default: + break; + } return EFI_SUCCESS; } @@ -733,7 +773,7 @@ HttpBootCallback ( /// /// HTTP Boot Callback Protocol instance /// -GLOBAL_REMOVE_IF_UNREFERENCED +GLOBAL_REMOVE_IF_UNREFERENCED EFI_HTTP_BOOT_CALLBACK_PROTOCOL gHttpBootDxeHttpBootCallback = { HttpBootCallback };