29 if (!Private->UsingIpv6) {
30 ControllerHandle = Private->Ip4Nic->Controller;
32 ControllerHandle = Private->Ip6Nic->Controller;
38 Status =
gBS->HandleProtocol (
40 &gEfiHttpBootCallbackProtocolGuid,
41 (VOID **)&Private->HttpBootCallback
43 if (Status == EFI_UNSUPPORTED) {
45 &Private->LoadFileCallback,
53 Status =
gBS->InstallProtocolInterface (
55 &gEfiHttpBootCallbackProtocolGuid,
57 &Private->LoadFileCallback
59 if (EFI_ERROR (Status)) {
63 Private->HttpBootCallback = &Private->LoadFileCallback;
82 if (Private->HttpBootCallback == &Private->LoadFileCallback) {
83 if (!Private->UsingIpv6) {
84 ControllerHandle = Private->Ip4Nic->Controller;
86 ControllerHandle = Private->Ip6Nic->Controller;
89 gBS->UninstallProtocolInterface (
91 &gEfiHttpBootCallbackProtocolGuid,
92 Private->HttpBootCallback
94 Private->HttpBootCallback =
NULL;
120 IN BOOLEAN UsingIpv6,
130 if ((Private ==
NULL) || (FilePath ==
NULL)) {
131 return EFI_INVALID_PARAMETER;
139 if (EFI_ERROR (Status)) {
140 return EFI_INVALID_PARAMETER;
146 if (Private->Started) {
153 if ((UsingIpv6 != Private->UsingIpv6) ||
160 if (EFI_ERROR (Status)) {
175 return EFI_ALREADY_STARTED;
182 if (UsingIpv6 && (Private->Ip6Nic !=
NULL)) {
183 Private->UsingIpv6 =
TRUE;
184 }
else if (!UsingIpv6 && (Private->Ip4Nic !=
NULL)) {
185 Private->UsingIpv6 =
FALSE;
191 return EFI_UNSUPPORTED;
197 Private->FilePathUri = Uri;
198 if (Private->FilePathUri !=
NULL) {
200 Private->FilePathUri,
203 &Private->FilePathUriParser
205 if (EFI_ERROR (Status)) {
214 ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer));
215 if (!Private->UsingIpv6) {
216 for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) {
217 Private->OfferBuffer[Index].Dhcp4.Packet.Offer.Size = HTTP_CACHED_DHCP4_PACKET_MAX_SIZE;
220 for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) {
221 Private->OfferBuffer[Index].Dhcp6.Packet.Offer.Size = HTTP_CACHED_DHCP6_PACKET_MAX_SIZE;
225 if (Private->UsingIpv6) {
230 if (EFI_ERROR (Status)) {
235 Private->Started =
TRUE;
236 Print (L
"\n>>Start HTTP Boot over IPv%d", Private->UsingIpv6 ? 6 : 4);
260 if (Private ==
NULL) {
261 return EFI_INVALID_PARAMETER;
264 if (!Private->Started) {
265 return EFI_NOT_STARTED;
268 Status = EFI_DEVICE_ERROR;
270 if (!Private->UsingIpv6) {
309 IN VOID *Buffer OPTIONAL,
310 OUT HTTP_BOOT_IMAGE_TYPE *ImageType
313 HTTP_GET_BOOT_FILE_STATE State;
317 if (Private->BootFileSize == 0) {
318 State = GetBootFileHead;
320 State = LoadBootFile;
325 case GetBootFileHead:
332 &Private->BootFileSize,
336 if ((EFI_ERROR (Status)) && (Status != EFI_BUFFER_TOO_SMALL)) {
337 if ((Private->AuthData !=
NULL) && (Status == EFI_ACCESS_DENIED)) {
341 State = GetBootFileHead;
343 State = GetBootFileGet;
346 State = LoadBootFile;
355 ASSERT (Private->BootFileSize == 0);
359 &Private->BootFileSize,
363 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
364 State = GetBootFileError;
366 State = LoadBootFile;
372 if (*BufferSize < Private->BootFileSize) {
373 *BufferSize = Private->BootFileSize;
374 *ImageType = Private->ImageType;
375 Status = EFI_BUFFER_TOO_SMALL;
382 for (Retries = 1; Retries <=
PcdGet32 (PcdMaxHttpResumeRetries); Retries++) {
390 if (!EFI_ERROR (Status) ||
391 ((Status != EFI_TIMEOUT) && (Status != EFI_DEVICE_ERROR)) ||
392 (Retries >=
PcdGet32 (PcdMaxHttpResumeRetries)))
402 Private->HttpCreated =
FALSE;
405 if (EFI_ERROR (Status)) {
409 DEBUG ((DEBUG_WARN | DEBUG_INFO,
"HttpBootGetBootFileCaller: NBP file download interrupted, will try to resume the operation.\n"));
410 gBS->Stall (1000 * 1000 *
PcdGet32 (PcdHttpDelayBetweenResumeRetries));
413 if (EFI_ERROR (Status) && (Retries >=
PcdGet32 (PcdMaxHttpResumeRetries))) {
414 DEBUG ((DEBUG_ERROR,
"HttpBootGetBootFileCaller: Error downloading NBP file, even after trying to resume %d times.\n", Retries));
419 case GetBootFileError:
421 AsciiPrint (
"\n Error: Could not retrieve NBP file size from HTTP server.\n");
454 IN VOID *Buffer OPTIONAL,
455 OUT HTTP_BOOT_IMAGE_TYPE *ImageType
460 if ((Private ==
NULL) || (ImageType ==
NULL) || (BufferSize ==
NULL)) {
461 return EFI_INVALID_PARAMETER;
464 if ((*BufferSize != 0) && (Buffer ==
NULL)) {
465 return EFI_INVALID_PARAMETER;
468 if (!Private->Started) {
469 return EFI_NOT_STARTED;
473 if (EFI_ERROR (Status)) {
477 if (Private->BootFileUri ==
NULL) {
482 if (EFI_ERROR (Status)) {
483 AsciiPrint (
"\n Error: Could not retrieve NBP file size from HTTP server.\n");
488 if (!Private->HttpCreated) {
493 if (EFI_ERROR (Status)) {
506 if (EFI_ERROR (Status)) {
507 if (Status == EFI_ACCESS_DENIED) {
508 AsciiPrint (
"\n Error: Could not establish connection with HTTP server.\n");
509 }
else if ((Status == EFI_BUFFER_TOO_SMALL) && (Buffer !=
NULL)) {
510 AsciiPrint (
"\n Error: Buffer size is smaller than the requested file.\n");
511 }
else if (Status == EFI_OUT_OF_RESOURCES) {
512 AsciiPrint (
"\n Error: Could not allocate I/O buffers.\n");
513 }
else if (Status == EFI_DEVICE_ERROR) {
514 AsciiPrint (
"\n Error: Network device error.\n");
515 }
else if (Status == EFI_TIMEOUT) {
516 AsciiPrint (
"\n Error: Server response timeout.\n");
517 }
else if (Status == EFI_ABORTED) {
518 AsciiPrint (
"\n Error: Remote boot cancelled.\n");
519 }
else if (Status != EFI_BUFFER_TOO_SMALL) {
520 AsciiPrint (
"\n Error: Unexpected network error.\n");
545 if (Private ==
NULL) {
546 return EFI_INVALID_PARAMETER;
549 if (!Private->Started) {
550 return EFI_NOT_STARTED;
553 if (Private->HttpCreated) {
555 Private->HttpCreated =
FALSE;
558 Private->Started =
FALSE;
563 Private->BootFileUri =
NULL;
564 Private->BootFileUriParser =
NULL;
565 Private->BootFileSize = 0;
566 Private->SelectIndex = 0;
567 Private->SelectProxyType = HttpOfferTypeMax;
568 Private->PartialTransferredSize = 0;
570 if (!Private->UsingIpv6) {
574 Private->Dhcp4->Stop (Private->Dhcp4);
575 Private->Dhcp4->Configure (Private->Dhcp4,
NULL);
577 for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) {
578 if (Private->OfferBuffer[Index].Dhcp4.UriParser) {
586 Private->Dhcp6->Stop (Private->Dhcp6);
587 Private->Dhcp6->Configure (Private->Dhcp6,
NULL);
589 for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) {
590 if (Private->OfferBuffer[Index].Dhcp6.UriParser) {
596 if (Private->AuthData !=
NULL) {
598 Private->AuthData =
NULL;
601 if (Private->AuthScheme !=
NULL) {
603 Private->AuthScheme =
NULL;
606 if (Private->DnsServerIp !=
NULL) {
608 Private->DnsServerIp =
NULL;
611 if (Private->FilePathUri !=
NULL) {
614 Private->FilePathUri =
NULL;
615 Private->FilePathUriParser =
NULL;
618 if (Private->LastModifiedOrEtag !=
NULL) {
619 FreePool (Private->LastModifiedOrEtag);
620 Private->LastModifiedOrEtag =
NULL;
623 ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer));
624 Private->OfferNum = 0;
625 ZeroMem (Private->OfferCount, sizeof (Private->OfferCount));
626 ZeroMem (Private->OfferIndex, sizeof (Private->OfferIndex));
669 IN BOOLEAN BootPolicy,
671 IN VOID *Buffer OPTIONAL
679 HTTP_BOOT_IMAGE_TYPE ImageType;
681 if ((This ==
NULL) || (BufferSize ==
NULL) || (FilePath ==
NULL)) {
682 return EFI_INVALID_PARAMETER;
689 return EFI_UNSUPPORTED;
692 VirtualNic = HTTP_BOOT_VIRTUAL_NIC_FROM_LOADFILE (This);
693 Private = VirtualNic->Private;
701 AsciiPrint (
"\n Error: Could not detect network connection.\n");
709 if (VirtualNic == Private->Ip6Nic) {
717 if ((Status !=
EFI_SUCCESS) && (Status != EFI_ALREADY_STARTED)) {
724 ImageType = ImageTypeMax;
726 if (EFI_ERROR (Status)) {
727 if ((Status == EFI_BUFFER_TOO_SMALL) && ((ImageType == ImageTypeVirtualCd) || (ImageType == ImageTypeVirtualDisk))) {
728 Status = EFI_WARN_FILE_SYSTEM;
729 }
else if (Status != EFI_BUFFER_TOO_SMALL) {
739 if ((ImageType == ImageTypeVirtualCd) || (ImageType == ImageTypeVirtualDisk)) {
741 if (!EFI_ERROR (Status)) {
742 Status = EFI_WARN_FILE_SYSTEM;
744 AsciiPrint (
"\n Error: Could not register RAM disk to the system.\n");
790 IN UINT32 DataLength,
791 IN VOID *Data OPTIONAL
799 Private = HTTP_BOOT_PRIVATE_DATA_FROM_CALLBACK_PROTOCOL (This);
812 (Private->PartialTransferredSize == 0))
836 if (HttpHeader !=
NULL) {
837 Print (L
"\n HTTP ERROR: Resource Redirected.\n New Location: %a\n", HttpHeader->
FieldValue);
859 if (HttpHeader !=
NULL) {
861 Private->ReceivedSize = 0;
862 Private->Percentage = 0;
869 if (DataLength != 0) {
870 if (Private->FileSize != 0) {
874 if (Private->ReceivedSize == 0) {
875 Print (L
" File Size: %lu Bytes\n", Private->FileSize);
878 Private->ReceivedSize += DataLength;
880 if (Private->Percentage != Percentage) {
881 Private->Percentage = Percentage;
882 Print (L
"\r Downloading...%d%%", Percentage);
889 Private->ReceivedSize += DataLength;
890 Print (L
"\r Downloading...%lu Bytes", Private->ReceivedSize);
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
UINTN EFIAPI AsciiStrDecimalToUintn(IN CONST CHAR8 *String)
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
UINT64 EFIAPI DivU64x64Remainder(IN UINT64 Dividend, IN UINT64 Divisor, OUT UINT64 *Remainder OPTIONAL)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define HTTP_HEADER_CONTENT_LENGTH
#define HTTP_HEADER_CONTENT_RANGE
#define HTTP_HEADER_LOCATION
EFI_HTTP_BOOT_CALLBACK_DATA_TYPE
EFI_STATUS HttpBootCreateHttpIo(IN HTTP_BOOT_PRIVATE_DATA *Private)
EFI_STATUS HttpBootDiscoverBootInfo(IN OUT HTTP_BOOT_PRIVATE_DATA *Private)
EFI_STATUS HttpBootGetBootFile(IN HTTP_BOOT_PRIVATE_DATA *Private, IN BOOLEAN HeaderOnly, IN OUT UINTN *BufferSize, OUT UINT8 *Buffer, OUT HTTP_BOOT_IMAGE_TYPE *ImageType)
VOID HttpBootFreeCacheList(IN HTTP_BOOT_PRIVATE_DATA *Private)
EFI_STATUS HttpBootDhcp4Dora(IN HTTP_BOOT_PRIVATE_DATA *Private)
EFI_STATUS HttpBootSetIp6Policy(IN HTTP_BOOT_PRIVATE_DATA *Private)
EFI_STATUS HttpBootDhcp6Sarr(IN HTTP_BOOT_PRIVATE_DATA *Private)
VOID HttpBootUninstallCallback(IN HTTP_BOOT_PRIVATE_DATA *Private)
EFI_STATUS HttpBootLoadFile(IN HTTP_BOOT_PRIVATE_DATA *Private, IN OUT UINTN *BufferSize, IN VOID *Buffer OPTIONAL, OUT HTTP_BOOT_IMAGE_TYPE *ImageType)
GLOBAL_REMOVE_IF_UNREFERENCED EFI_LOAD_FILE_PROTOCOL gHttpBootDxeLoadFile
EFI_STATUS HttpBootGetBootFileCaller(IN HTTP_BOOT_PRIVATE_DATA *Private, IN OUT UINTN *BufferSize, IN VOID *Buffer OPTIONAL, OUT HTTP_BOOT_IMAGE_TYPE *ImageType)
EFI_STATUS HttpBootStart(IN HTTP_BOOT_PRIVATE_DATA *Private, IN BOOLEAN UsingIpv6, IN EFI_DEVICE_PATH_PROTOCOL *FilePath)
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)
EFI_STATUS HttpBootDhcp(IN HTTP_BOOT_PRIVATE_DATA *Private)
GLOBAL_REMOVE_IF_UNREFERENCED EFI_HTTP_BOOT_CALLBACK_PROTOCOL gHttpBootDxeHttpBootCallback
EFI_STATUS HttpBootInstallCallback(IN HTTP_BOOT_PRIVATE_DATA *Private)
EFI_STATUS HttpBootStop(IN HTTP_BOOT_PRIVATE_DATA *Private)
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)
EFI_STATUS HttpBootRegisterRamDisk(IN HTTP_BOOT_PRIVATE_DATA *Private, IN UINTN BufferSize, IN VOID *Buffer, IN HTTP_BOOT_IMAGE_TYPE ImageType)
BOOLEAN HttpBootIsHttpRedirectStatusCode(IN EFI_HTTP_STATUS_CODE StatusCode)
EFI_STATUS HttpBootParseFilePath(IN EFI_DEVICE_PATH_PROTOCOL *FilePath, OUT CHAR8 **UriAddress)
VOID HttpIoDestroyIo(IN HTTP_IO *HttpIo)
EFI_HTTP_HEADER *EFIAPI HttpFindHeader(IN UINTN HeaderCount, IN EFI_HTTP_HEADER *Headers, IN CHAR8 *FieldName)
VOID EFIAPI HttpUrlFreeParser(IN VOID *UrlParser)
EFI_STATUS EFIAPI HttpParseUrl(IN CHAR8 *Url, IN UINT32 Length, IN BOOLEAN IsConnectMethod, OUT VOID **UrlParser)
#define GLOBAL_REMOVE_IF_UNREFERENCED
#define DEBUG(Expression)
EFI_STATUS EFIAPI NetLibDetectMediaWaitTimeout(IN EFI_HANDLE ServiceHandle, IN UINT64 Timeout, OUT EFI_STATUS *MediaState)
#define PcdGet32(TokenName)
UINTN EFIAPI AsciiPrint(IN CONST CHAR8 *Format,...)
UINTN EFIAPI Print(IN CONST CHAR16 *Format,...)
EFI_HTTP_HEADER * Headers
union EFI_HTTP_MESSAGE::@577 Data
EFI_HTTP_RESPONSE_DATA * Response
EFI_HTTP_REQUEST_DATA * Request
EFI_HTTP_STATUS_CODE StatusCode