4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Boot functions implementation for UefiPxeBc Driver.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync http://opensource.org/licenses/bsd-license.php.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "PxeBcImpl.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Display the string of the boot item.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If the length of the boot item string beyond 70 Char, just display 70 Char.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Str The pointer to the string.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Len The length of the string.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPxeBcDisplayBootItem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 *Str,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 Len
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Tmp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Cut off the chars behind 70th.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Len = (UINT8) MIN (PXEBC_DISPLAY_MAX_LINE, Len);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Tmp = Str[Len];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Str[Len] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("%a \n", Str);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Restore the original 70th char.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Str[Len] = Tmp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Select and maintain the boot prompt if needed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Private Pointer to PxeBc private data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Selected boot prompt done.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_TIMEOUT Selected boot prompt timed out.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The proxy offer is not Pxe10.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED User cancelled the operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY Reading the input key from the keyboard has not finish.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPxeBcSelectBootPrompt (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN PXEBC_PRIVATE_DATA *Private
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PXEBC_DHCP_PACKET_CACHE *Cache;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PXEBC_VENDOR_OPTION *VendorOpt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_MODE *Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EVENT TimeoutEvent;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_EVENT DescendEvent;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INPUT_KEY InputKey;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 OfferType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Timeout;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *Prompt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 PromptLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync INT32 SecCol;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync INT32 SecRow;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutEvent = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DescendEvent = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mode = Private->PxeBc.Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cache = Mode->ProxyOfferReceived ? &Private->ProxyOffer : &Private->DhcpAck;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OfferType = Mode->UsingIpv6 ? Cache->Dhcp6.OfferType : Cache->Dhcp4.OfferType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Only ProxyPxe10 offer needs boot prompt.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (OfferType != PxeOfferTypeProxyPxe10) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // There is no specified ProxyPxe10 for IPv6 in PXE and UEFI spec.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (!Mode->UsingIpv6);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VendorOpt = &Cache->Dhcp4.VendorOpt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IS_VALID_BOOT_PROMPT (VendorOpt->BitMap)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Timeout = VendorOpt->MenuPrompt->Timeout;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Prompt = VendorOpt->MenuPrompt->Prompt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PromptLen = (UINT8) (VendorOpt->MenuPromptLen - 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The valid scope of Timeout refers to PXE2.1 spec.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Timeout == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Timeout == 255) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create and start a timer as timeout event.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CreateEvent (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EVT_TIMER,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TPL_CALLBACK,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &TimeoutEvent
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->SetTimer (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimeoutEvent,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimerRelative,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Timeout * TICKS_PER_SECOND
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create and start a periodic timer as descend event by second.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CreateEvent (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EVT_TIMER,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TPL_CALLBACK,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &DescendEvent
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->SetTimer (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DescendEvent,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TimerPeriodic,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TICKS_PER_SECOND
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Display the boot item and cursor on the screen.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SecCol = gST->ConOut->Mode->CursorColumn;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SecRow = gST->ConOut->Mode->CursorRow;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBcDisplayBootItem (Prompt, PromptLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gST->ConOut->SetCursorPosition (gST->ConOut, SecCol + PromptLen, SecRow);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("(%d) ", Timeout--);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (gBS->CheckEvent (DescendEvent))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gST->ConOut->SetCursorPosition (gST->ConOut, SecCol + PromptLen, SecRow);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("(%d) ", Timeout--);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (gST->ConIn->ReadKeyStroke (gST->ConIn, &InputKey) == EFI_NOT_READY) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (10 * TICKS_PER_MS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Parse the input key by user.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (InputKey.ScanCode == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (InputKey.UnicodeChar) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case CTRL ('c'):
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case CTRL ('m'):
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'm':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'M':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (InputKey.ScanCode) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SCAN_F8:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_TIMEOUT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SCAN_ESC:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync continue;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Reset the cursor on the screen.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gST->ConOut->SetCursorPosition (gST->ConOut, 0 , SecRow + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncON_EXIT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DescendEvent != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseEvent (DescendEvent);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TimeoutEvent != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseEvent (TimeoutEvent);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Select the boot menu by user's input.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Private Pointer to PxeBc private data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Type The type of the menu.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] UseDefaultItem Use default item or not.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED User cancel operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Select the boot menu success.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY Read the input key from the keybroad has not finish.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPxeBcSelectBootMenu (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN PXEBC_PRIVATE_DATA *Private,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT16 *Type,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN UseDefaultItem
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_MODE *Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PXEBC_DHCP_PACKET_CACHE *Cache;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PXEBC_VENDOR_OPTION *VendorOpt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INPUT_KEY InputKey;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 OfferType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 MenuSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 MenuNum;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync INT32 TopRow;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Select;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 LastSelect;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Finish;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR8 Blank[PXEBC_DISPLAY_MAX_LINE];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PXEBC_BOOT_MENU_ENTRY *MenuItem;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PXEBC_BOOT_MENU_ENTRY *MenuArray[PXEBC_MENU_MAX_NUM];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Finish = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Select = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Type = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mode = Private->PxeBc.Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cache = Mode->ProxyOfferReceived ? &Private->ProxyOffer : &Private->DhcpAck;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OfferType = Mode->UsingIpv6 ? Cache->Dhcp6.OfferType : Cache->Dhcp4.OfferType;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // There is no specified ProxyPxe10 for IPv6 in PXE and UEFI spec.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (!Mode->UsingIpv6);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (OfferType == PxeOfferTypeProxyPxe10);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VendorOpt = &Cache->Dhcp4.VendorOpt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IS_VALID_BOOT_MENU (VendorOpt->BitMap)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Display the boot menu on the screen.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetMem (Blank, sizeof(Blank), ' ');
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MenuSize = VendorOpt->BootMenuLen;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MenuItem = VendorOpt->BootMenu;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (MenuSize == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (MenuSize > 0 && Index < PXEBC_MENU_MAX_NUM) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (MenuItem != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MenuArray[Index] = MenuItem;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MenuSize = (UINT8) (MenuSize - (MenuItem->DescLen + 3));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MenuItem = (PXEBC_BOOT_MENU_ENTRY *) ((UINT8 *) MenuItem + MenuItem->DescLen + 3);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Index++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (UseDefaultItem) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (MenuArray[0] != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (Type, &MenuArray[0]->Type, sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Type = NTOHS (*Type);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MenuNum = Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < MenuNum; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (MenuArray[Index] != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBcDisplayBootItem (MenuArray[Index]->DescStr, MenuArray[Index]->DescLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TopRow = gST->ConOut->Mode->CursorRow - MenuNum;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Select the boot item by user in the boot menu.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync do {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Highlight selected row.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gST->ConOut->SetCursorPosition (gST->ConOut, 0, TopRow + Select);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Select < PXEBC_MENU_MAX_NUM);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (MenuArray[Select] != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Blank[MenuArray[Select]->DescLen] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("%a\r", Blank);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBcDisplayBootItem (MenuArray[Select]->DescStr, MenuArray[Select]->DescLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gST->ConOut->SetCursorPosition (gST->ConOut, 0, TopRow + MenuNum);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LastSelect = Select;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (gST->ConIn->ReadKeyStroke (gST->ConIn, &InputKey) == EFI_NOT_READY) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->Stall (10 * TICKS_PER_MS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (InputKey.ScanCode != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (InputKey.UnicodeChar) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case CTRL ('c'):
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InputKey.ScanCode = SCAN_ESC;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case CTRL ('j'): /* linefeed */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case CTRL ('m'): /* return */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Finish = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case CTRL ('i'): /* tab */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case ' ':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'd':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'D':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InputKey.ScanCode = SCAN_DOWN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case CTRL ('h'): /* backspace */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'u':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case 'U':
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InputKey.ScanCode = SCAN_UP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InputKey.ScanCode = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (InputKey.ScanCode) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SCAN_LEFT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SCAN_UP:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Select != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Select--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SCAN_DOWN:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SCAN_RIGHT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (++Select == MenuNum) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Select--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SCAN_PAGE_UP:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SCAN_HOME:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Select = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SCAN_PAGE_DOWN:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SCAN_END:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Select = (UINT16) (MenuNum - 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case SCAN_ESC:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Unhighlight the last selected row.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gST->ConOut->SetCursorPosition (gST->ConOut, 0, TopRow + LastSelect);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (LastSelect < PXEBC_MENU_MAX_NUM);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (MenuArray[LastSelect] != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Blank[MenuArray[LastSelect]->DescLen] = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("%a\r", Blank);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBcDisplayBootItem (MenuArray[LastSelect]->DescStr, MenuArray[LastSelect]->DescLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gST->ConOut->SetCursorPosition (gST->ConOut, 0, TopRow + MenuNum);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (!Finish);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Swap the byte order.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Select < PXEBC_MENU_MAX_NUM);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (MenuArray[Select] != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (Type, &MenuArray[Select]->Type, sizeof (UINT16));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Type = NTOHS (*Type);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Parse out the boot information from the last Dhcp4 reply packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Private Pointer to PxeBc private data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] BufferSize Size of the boot file to be downloaded.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Successfully parsed out all the boot information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to parse out the boot information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPxeBcDhcp4BootInfo (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT PXEBC_PRIVATE_DATA *Private,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT64 *BufferSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_MODE *Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PXEBC_DHCP4_PACKET_CACHE *Cache4;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBc = &Private->PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mode = PxeBc->Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *BufferSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the last received Dhcp4 reply packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Mode->PxeReplyReceived) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cache4 = &Private->PxeReply.Dhcp4;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Mode->ProxyOfferReceived) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cache4 = &Private->ProxyOffer.Dhcp4;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cache4 = &Private->DhcpAck.Dhcp4;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Parse the boot server Ipv4 address by next server address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If this field isn't available, use option 54 instead.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->ServerIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Cache4->Packet.Offer.Dhcp4.Header.ServerAddr,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_IPv4_ADDRESS)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Private->ServerIp.Addr[0] == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->ServerIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_SERVER_ID]->Data,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_IPv4_ADDRESS)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Parse the boot file name by option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->BootFileName = Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN] != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Parse the boot file size by option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&Value, Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN]->Data, sizeof (Value));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = NTOHS (Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The field of boot file size is 512 bytes in unit.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *BufferSize = 512 * Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the bootfile size by tftp command if no option available.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBc->Mtftp (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBc,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BufferSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->BlockSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->ServerIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->BootFileName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save the value of boot file size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->BootFileSize = (UINTN) *BufferSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Display all the information: boot server address, boot file name and boot file size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n Server IP address is ");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBcShowIp4Addr (&Private->ServerIp.v4);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n NBP filename is %a", Private->BootFileName);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n NBP filesize is %d Bytes", Private->BootFileSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Parse out the boot information from the last Dhcp6 reply packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Private Pointer to PxeBc private data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] BufferSize Size of the boot file to be downloaded.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Successfully parsed out all the boot information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to parse out the boot information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPxeBcDhcp6BootInfo (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT PXEBC_PRIVATE_DATA *Private,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT64 *BufferSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_MODE *Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PXEBC_DHCP6_PACKET_CACHE *Cache6;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBc = &Private->PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mode = PxeBc->Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *BufferSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the last received Dhcp6 reply packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Mode->PxeReplyReceived) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cache6 = &Private->PxeReply.Dhcp6;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Mode->ProxyOfferReceived) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cache6 = &Private->ProxyOffer.Dhcp6;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cache6 = &Private->DhcpAck.Dhcp6;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Cache6->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Parse (m)tftp server ip address and bootfile name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBcExtractBootFileUrl (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->BootFileName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->ServerIp.v6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (CHAR8 *) (Cache6->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->Data),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->OpLen)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Parse the value of boot file size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Cache6->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_PARAM] != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Parse it out if have the boot file parameter option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBcExtractBootFileParam ((CHAR8 *) Cache6->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_PARAM]->Data, &Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The field of boot file size is 512 bytes in unit.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *BufferSize = 512 * Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send get file size command by tftp if option unavailable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBc->Mtftp (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBc,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BufferSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->BlockSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->ServerIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->BootFileName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save the value of boot file size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->BootFileSize = (UINTN) *BufferSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Display all the information: boot server address, boot file name and boot file size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n Server IP address is ");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBcShowIp6Addr (&Private->ServerIp.v6);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n NBP filename is %a", Private->BootFileName);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n NBP filesize is %d Bytes", Private->BootFileSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Extract the discover information and boot server entry from the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync cached packets if unspecified.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Private Pointer to PxeBc private data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Type The type of bootstrap to perform.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Info Pointer to EFI_PXE_BASE_CODE_DISCOVER_INFO.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] BootEntry Pointer to PXEBC_BOOT_SVR_ENTRY.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] SrvList Pointer to EFI_PXE_BASE_CODE_SRVLIST.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Successfully extracted the information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Failed to extract the information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPxeBcExtractDiscoverInfo (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN PXEBC_PRIVATE_DATA *Private,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 Type,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_PXE_BASE_CODE_DISCOVER_INFO *Info,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT PXEBC_BOOT_SVR_ENTRY **BootEntry,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT EFI_PXE_BASE_CODE_SRVLIST **SrvList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_MODE *Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PXEBC_DHCP4_PACKET_CACHE *Cache4;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PXEBC_VENDOR_OPTION *VendorOpt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PXEBC_BOOT_SVR_ENTRY *Entry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN IsFound;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mode = Private->PxeBc.Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Mode->UsingIpv6) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Info->IpCnt = 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Info->UseUCast = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Info->SrvList[0].Type = Type;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Info->SrvList[0].AcceptAnyResponse = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // There is no vendor options specified in DHCPv6, so take BootFileUrl in the last cached packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&Info->SrvList[0].IpAddr, &Private->ServerIp, sizeof (EFI_IP_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *SrvList = Info->SrvList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Entry = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsFound = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cache4 = (Mode->ProxyOfferReceived) ? &Private->ProxyOffer.Dhcp4 : &Private->DhcpAck.Dhcp4;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VendorOpt = &Cache4->VendorOpt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Mode->DhcpAckReceived || !IS_VALID_DISCOVER_VENDOR_OPTION (VendorOpt->BitMap)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Address is not acquired or no discovery options.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Parse the boot server entry from the vendor option in the last cached packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Info->UseMCast = (BOOLEAN) !IS_DISABLE_MCAST_DISCOVER (VendorOpt->DiscoverCtrl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Info->UseBCast = (BOOLEAN) !IS_DISABLE_BCAST_DISCOVER (VendorOpt->DiscoverCtrl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Info->MustUseList = (BOOLEAN) IS_ENABLE_USE_SERVER_LIST (VendorOpt->DiscoverCtrl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Info->UseUCast = Info->MustUseList;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Info->UseMCast) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the multicast discover ip address from vendor option if has.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&Info->ServerMCastIp.v4, &VendorOpt->DiscoverMcastIp, sizeof (EFI_IPv4_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Info->IpCnt = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Info->MustUseList) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Entry = VendorOpt->BootSvr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (((UINT8) (Entry - VendorOpt->BootSvr)) < VendorOpt->BootSvrLen) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Entry->Type == HTONS (Type)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsFound = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync break;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Entry = GET_NEXT_BOOT_SVR_ENTRY (Entry);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IsFound) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Info->IpCnt = Entry->IpCnt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *BootEntry = Entry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Build the discover packet and send out for boot server.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Private Pointer to PxeBc private data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Type PxeBc option boot item type.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Layer Pointer to option boot item layer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] UseBis Use BIS or not.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DestIp Pointer to the destination address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpCount The count of the server address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] SrvList Pointer to the server address list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Successfully discovered boot file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate resource.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND Can't get the PXE reply packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to discover boot file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPxeBcDiscoverBootServer (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN PXEBC_PRIVATE_DATA *Private,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 Type,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 *Layer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN UseBis,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP_ADDRESS *DestIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT16 IpCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_PXE_BASE_CODE_SRVLIST *SrvList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Private->PxeBc.Mode->UsingIpv6) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return PxeBcDhcp6Discover (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Layer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UseBis,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DestIp
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return PxeBcDhcp4Discover (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Layer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UseBis,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DestIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SrvList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Discover all the boot information for boot file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Private Pointer to PxeBc private data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] BufferSize Size of the boot file to be downloaded.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Successfully obtained all the boot information .
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL The buffer size is not enough for boot file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED User cancel current operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to parse out the boot information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPxeBcDiscoverBootFile (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT PXEBC_PRIVATE_DATA *Private,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT64 *BufferSize
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_MODE *Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Type;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT16 Layer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN UseBis;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBc = &Private->PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mode = PxeBc->Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Type = EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Layer = EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Start D.O.R.A/S.A.R.R exchange to acquire station ip address and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // other pxe boot information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBc->Dhcp (PxeBc, TRUE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Select a boot server from boot server list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBcSelectBootPrompt (Private);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Status == EFI_SUCCESS) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Choose by user's input.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBcSelectBootMenu (Private, &Type, TRUE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Status == EFI_TIMEOUT) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Choose by default item.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBcSelectBootMenu (Private, &Type, FALSE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Type == EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Local boot(PXE bootstrap server) need abort
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Start to discover the boot server to get (m)tftp server ip address, bootfile
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // name and bootfile size.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UseBis = (BOOLEAN) (Mode->BisSupported && Mode->BisDetected);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBc->Discover (PxeBc, Type, &Layer, UseBis, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Parse the boot information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Mode->UsingIpv6) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBcDhcp6BootInfo (Private, BufferSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBcDhcp4BootInfo (Private, BufferSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Install PxeBaseCodeCallbackProtocol if not installed before.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Private Pointer to PxeBc private data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] NewMakeCallback If TRUE, it is a new callback.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Otherwise, it is not new callback.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS PxeBaseCodeCallbackProtocol installed succesfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to install PxeBaseCodeCallbackProtocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPxeBcInstallCallback (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT PXEBC_PRIVATE_DATA *Private,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT BOOLEAN *NewMakeCallback
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether PxeBaseCodeCallbackProtocol already installed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBc = &Private->PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->HandleProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiPxeBaseCodeCallbackProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID **) &Private->PxeBcCallback
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Status == EFI_UNSUPPORTED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->LoadFileCallback,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gPxeBcCallBackTemplate,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install a default callback if user didn't offer one.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->InstallProtocolInterface (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiPxeBaseCodeCallbackProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_NATIVE_INTERFACE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->LoadFileCallback
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (*NewMakeCallback) = (BOOLEAN) (Status == EFI_SUCCESS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBc->SetParameters (PxeBc, NULL, NULL, NULL, NULL, NewMakeCallback);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBc->Stop (PxeBc);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Uninstall PxeBaseCodeCallbackProtocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Private Pointer to PxeBc private data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] NewMakeCallback If TRUE, it is a new callback.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Otherwise, it is not new callback.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPxeBcUninstallCallback (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN PXEBC_PRIVATE_DATA *Private,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN NewMakeCallback
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBc = &Private->PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NewMakeCallback) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewMakeCallback = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBc->SetParameters (PxeBc, NULL, NULL, NULL, NULL, &NewMakeCallback);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->UninstallProtocolInterface (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiPxeBaseCodeCallbackProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->LoadFileCallback
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Download one of boot file in the list, and it's special for IPv6.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Private Pointer to PxeBc private data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] BufferSize Size of user buffer for input;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync required buffer size for output.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Buffer Pointer to user buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Read one of boot file in the list successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL The buffer size is not enough for boot file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND There is no proper boot file available.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to download boot file in the list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPxeBcReadBootFileList (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN PXEBC_PRIVATE_DATA *Private,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINT64 *BufferSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Buffer OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBc = &Private->PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Try to download the boot file if everything is ready.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Buffer != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBc->Mtftp (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBc,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_TFTP_READ_FILE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Buffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BufferSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->BlockSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->ServerIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->BootFileName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_BUFFER_TOO_SMALL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Load boot file into user buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Private Pointer to PxeBc private data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] BufferSize Size of user buffer for input;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync required buffer size for output.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Buffer Pointer to user buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Get all the boot information successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL The buffer size is not enough for boot file.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED User cancelled the current operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to parse out the boot information.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncPxeBcLoadBootFile (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN PXEBC_PRIVATE_DATA *Private,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINTN *BufferSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Buffer OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN NewMakeCallback;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 RequiredSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT64 CurrentSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_MODE *PxeBcMode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewMakeCallback = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBc = &Private->PxeBc;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBcMode = &Private->Mode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentSize = *BufferSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RequiredSize = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install pxebc callback protocol if hasn't been installed yet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBcInstallCallback (Private, &NewMakeCallback);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR(Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Private->BootFileSize == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Discover the boot information about the bootfile if hasn't.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBcDiscoverBootFile (Private, &RequiredSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PXEBC_IS_SIZE_OVERFLOWED (RequiredSize)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // It's error if the required buffer size is beyond the system scope.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (RequiredSize > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the right buffer size of the bootfile required.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CurrentSize < RequiredSize || Buffer == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // It's buffer too small if the size of user buffer is smaller than the required.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentSize = RequiredSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_BUFFER_TOO_SMALL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentSize = RequiredSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (RequiredSize == 0 && PxeBcMode->UsingIpv6) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Try to download another bootfile in list if failed to get the filesize of the last one.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // It's special for the case of IPv6.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBcReadBootFileList (Private, &CurrentSize, Buffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (CurrentSize < Private->BootFileSize || Buffer == NULL ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // It's buffer too small if the size of user buffer is smaller than the required.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CurrentSize = Private->BootFileSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_BUFFER_TOO_SMALL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Begin to download the bootfile if everything is ready.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n Downloading NBP file...\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PxeBcMode->UsingIpv6) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBcReadBootFileList (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &CurrentSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = PxeBc->Mtftp (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBc,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_PXE_BASE_CODE_TFTP_READ_FILE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Buffer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &CurrentSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->BlockSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Private->ServerIp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private->BootFileName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncON_EXIT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *BufferSize = (UINTN) CurrentSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PxeBcUninstallCallback(Private, NewMakeCallback);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Status == EFI_SUCCESS) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n Succeed to download NBP file.\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Status == EFI_BUFFER_TOO_SMALL && Buffer != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n PXE-E05: Buffer size is smaller than the requested file.\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Status == EFI_DEVICE_ERROR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n PXE-E07: Network device error.\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Status == EFI_OUT_OF_RESOURCES) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n PXE-E09: Could not allocate I/O buffers.\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Status == EFI_NO_MEDIA) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n PXE-E12: Could not detect network connection.\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Status == EFI_NO_RESPONSE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n PXE-E16: No offer received.\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Status == EFI_TIMEOUT) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n PXE-E18: Server response timeout.\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Status == EFI_ABORTED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n PXE-E21: Remote boot cancelled.\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Status == EFI_ICMP_ERROR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n PXE-E22: Client received ICMP error from server.\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Status == EFI_TFTP_ERROR) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n PXE-E23: Client received TFTP error from server.\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Status == EFI_NOT_FOUND) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n PXE-E53: No boot filename received.\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Status != EFI_BUFFER_TOO_SMALL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiPrint ("\n PXE-E99: Unexpected network error.\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync