]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_loadfile.c
Retiring the ANT/JAVA build and removing the older EDK II packages that required...
[mirror_edk2.git] / EdkModulePkg / Universal / Network / PxeBc / Dxe / pxe_loadfile.c
diff --git a/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_loadfile.c b/EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_loadfile.c
deleted file mode 100644 (file)
index 20ae95d..0000000
+++ /dev/null
@@ -1,1657 +0,0 @@
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-  pxe_loadfile.c\r
-\r
-Abstract:\r
-  An implementation of the load file protocol for network devices.\r
-\r
---*/\r
-\r
-\r
-#include "Bc.h"\r
-\r
-#define DO_MENU     (EFI_SUCCESS)\r
-#define NO_MENU     (DO_MENU + 1)\r
-#define LOCAL_BOOT  (EFI_ABORTED)\r
-#define AUTO_SELECT (NO_MENU)\r
-\r
-#define NUMBER_ROWS   25  // we set to mode 0\r
-#define MAX_MENULIST  23\r
-\r
-#define Ctl(x)  (0x1F & (x))\r
-\r
-typedef union {\r
-  DHCPV4_OP_STRUCT          *OpPtr;\r
-  PXE_BOOT_MENU_ENTRY       *CurrentMenuItemPtr;\r
-  PXE_OP_DISCOVERY_CONTROL  *DiscCtlOpStr;\r
-  PXE_OP_BOOT_MENU          *MenuPtr;\r
-  UINT8                     *BytePtr;\r
-} UNION_PTR;\r
-\r
-\r
-STATIC\r
-EFI_PXE_BASE_CODE_CALLBACK_STATUS\r
-EFIAPI\r
-bc_callback (\r
-  IN EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL  * This,\r
-  IN EFI_PXE_BASE_CODE_FUNCTION           Function,\r
-  IN BOOLEAN                              Received,\r
-  IN UINT32                               PacketLength,\r
-  IN EFI_PXE_BASE_CODE_PACKET             * PacketPtr OPTIONAL\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  PxeBc callback routine for status updates and aborts.\r
-\r
-Arguments:\r
-\r
-  This - Pointer to PxeBcCallback interface\r
-  Function - PxeBc function ID#\r
-  Received - Receive/transmit flag\r
-  PacketLength - Length of received packet (0 == idle callback)\r
-  PacketPtr - Pointer to received packet (NULL == idle callback)\r
-\r
-Returns:\r
-\r
-  EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE -\r
-  EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT -\r
-\r
---*/\r
-{\r
-  STATIC UINTN  Propeller;\r
-\r
-  EFI_INPUT_KEY Key;\r
-  UINTN         Row;\r
-  UINTN         Col;\r
-\r
-  Propeller = 0;\r
-  //\r
-  // Resolve Warning 4 unreferenced parameter problem\r
-  //\r
-  This = This;\r
-\r
-  //\r
-  // Check for user abort.\r
-  //\r
-  if (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key) == EFI_SUCCESS) {\r
-    if (!Key.ScanCode) {\r
-      if (Key.UnicodeChar == Ctl ('c')) {\r
-        return EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT;\r
-      }\r
-    } else if (Key.ScanCode == SCAN_ESC) {\r
-      return EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT;\r
-    }\r
-  }\r
-  //\r
-  // Do nothing if this is a receive.\r
-  //\r
-  if (Received) {\r
-    return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;\r
-  }\r
-  //\r
-  // The display code is only for these functions.\r
-  //\r
-  switch (Function) {\r
-  case EFI_PXE_BASE_CODE_FUNCTION_MTFTP:\r
-    //\r
-    // If this is a transmit and not a M/TFTP open request,\r
-    // return now.  Do not print a dot for each M/TFTP packet\r
-    // that is sent, only for the open packets.\r
-    //\r
-    if (PacketLength != 0 && PacketPtr != NULL) {\r
-      if (PacketPtr->Raw[0x1C] != 0x00 || PacketPtr->Raw[0x1D] != 0x01) {\r
-        return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;\r
-      }\r
-    }\r
-\r
-    break;\r
-\r
-  case EFI_PXE_BASE_CODE_FUNCTION_DHCP:\r
-  case EFI_PXE_BASE_CODE_FUNCTION_DISCOVER:\r
-    break;\r
-\r
-  default:\r
-    return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;\r
-  }\r
-  //\r
-  // Display routines\r
-  //\r
-  if (PacketLength != 0 && PacketPtr != NULL) {\r
-    //\r
-    // Display a '.' when a packet is transmitted.\r
-    //\r
-    AsciiPrint (".");\r
-  } else if (PacketLength == 0 && PacketPtr == NULL) {\r
-    //\r
-    // Display a propeller when waiting for packets if at\r
-    // least 200 ms have passed.\r
-    //\r
-    Row = gST->ConOut->Mode->CursorRow;\r
-    Col = gST->ConOut->Mode->CursorColumn;\r
-\r
-    AsciiPrint ("%c", "/-\\|"[Propeller]);\r
-    gST->ConOut->SetCursorPosition (gST->ConOut, Col, Row);\r
-\r
-    Propeller = (Propeller + 1) & 3;\r
-  }\r
-\r
-  return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;\r
-}\r
-\r
-STATIC EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL  _bc_callback = {\r
-  EFI_PXE_BASE_CODE_CALLBACK_INTERFACE_REVISION,\r
-  &bc_callback\r
-};\r
-\r
-STATIC\r
-VOID\r
-PrintIpv4 (\r
-  UINT8 *Ptr\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Display an IPv4 address in dot notation.\r
-\r
-Arguments:\r
-\r
-  Ptr - Pointer to IPv4 address.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-{\r
-  if (Ptr != NULL) {\r
-    AsciiPrint ("%d.%d.%d.%d", Ptr[0], Ptr[1], Ptr[2], Ptr[3]);\r
-  }\r
-}\r
-\r
-STATIC\r
-VOID\r
-ShowMyInfo (\r
-  IN PXE_BASECODE_DEVICE *Private\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Display client and server IP information.\r
-\r
-Arguments:\r
-\r
-  Private - Pointer to PxeBc interface\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-{\r
-  EFI_PXE_BASE_CODE_MODE  *PxeBcMode;\r
-  UINTN                   Index;\r
-\r
-  //\r
-  // Do nothing if a NULL pointer is passed in.\r
-  //\r
-  if (Private == NULL) {\r
-    return ;\r
-  }\r
-  //\r
-  // Get pointer to PXE BaseCode mode structure\r
-  //\r
-  PxeBcMode = Private->EfiBc.Mode;\r
-\r
-  //\r
-  // Display client IP address\r
-  //\r
-  AsciiPrint ("\rCLIENT IP: ");\r
-  PrintIpv4 (PxeBcMode->StationIp.v4.Addr);\r
-\r
-  //\r
-  // Display subnet mask\r
-  //\r
-  AsciiPrint ("  MASK: ");\r
-  PrintIpv4 (PxeBcMode->SubnetMask.v4.Addr);\r
-\r
-  //\r
-  // Display DHCP and proxyDHCP IP addresses\r
-  //\r
-  if (PxeBcMode->ProxyOfferReceived) {\r
-    AsciiPrint ("\nDHCP IP: ");\r
-    PrintIpv4 (((DHCPV4_OP_SERVER_IP *) DHCPV4_ACK_BUFFER.OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip.Addr);\r
-\r
-    AsciiPrint ("  PROXY IP: ");\r
-    PrintIpv4 (((DHCPV4_OP_SERVER_IP *) PXE_OFFER_BUFFER.OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip.Addr);\r
-  } else {\r
-    AsciiPrint ("  DHCP IP: ");\r
-    PrintIpv4 (((DHCPV4_OP_SERVER_IP *) DHCPV4_ACK_BUFFER.OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1])->Ip.Addr);\r
-  }\r
-  //\r
-  // Display gateway IP addresses\r
-  //\r
-  for (Index = 0; Index < PxeBcMode->RouteTableEntries; ++Index) {\r
-    if ((Index % 3) == 0) {\r
-      AsciiPrint ("\r\nGATEWAY IP:");\r
-    }\r
-\r
-    AsciiPrint (" ");\r
-    PrintIpv4 (PxeBcMode->RouteTable[Index].GwAddr.v4.Addr);\r
-    AsciiPrint (" ");\r
-  }\r
-\r
-  AsciiPrint ("\n");\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-DoPrompt (\r
-  PXE_BASECODE_DEVICE *Private,\r
-  PXE_OP_BOOT_PROMPT  *BootPromptPtr\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Display prompt and wait for input.\r
-\r
-Arguments:\r
-\r
-  Private - Pointer to PxeBc interface\r
-  BootPromptPtr - Pointer to PXE boot prompt option\r
-\r
-Returns:\r
-\r
-  AUTO_SELECT -\r
-  DO_MENU -\r
-  NO_MENU -\r
-  LOCAL_BOOT -\r
-\r
---*/\r
-{\r
-  EFI_STATUS  Status;\r
-  EFI_EVENT   TimeoutEvent;\r
-  EFI_EVENT   SecondsEvent;\r
-  INT32       SecColumn;\r
-  INT32       SecRow;\r
-  UINT8       SaveChar;\r
-  UINT8       SecsLeft;\r
-\r
-  //\r
-  // if auto select, just get right to it\r
-  //\r
-  if (BootPromptPtr->Timeout == PXE_BOOT_PROMPT_AUTO_SELECT) {\r
-    return AUTO_SELECT;\r
-  }\r
-  //\r
-  // if no timeout, go directly to display of menu\r
-  //\r
-  if (BootPromptPtr->Timeout == PXE_BOOT_PROMPT_NO_TIMEOUT) {\r
-    return DO_MENU;\r
-  }\r
-  //\r
-  //\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER,\r
-                  TPL_CALLBACK,\r
-                  NULL,\r
-                  NULL,\r
-                  &TimeoutEvent\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return DO_MENU;\r
-  }\r
-\r
-  Status = gBS->SetTimer (\r
-                  TimeoutEvent,\r
-                  TimerRelative,\r
-                  BootPromptPtr->Timeout * 10000000 + 100000\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->CloseEvent (TimeoutEvent);\r
-    return DO_MENU;\r
-  }\r
-  //\r
-  //\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER,\r
-                  TPL_CALLBACK,\r
-                  NULL,\r
-                  NULL,\r
-                  &SecondsEvent\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->CloseEvent (TimeoutEvent);\r
-    return DO_MENU;\r
-  }\r
-\r
-  Status = gBS->SetTimer (\r
-                  SecondsEvent,\r
-                  TimerPeriodic,\r
-                  10000000\r
-                  );  /* 1 second */\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->CloseEvent (SecondsEvent);\r
-    gBS->CloseEvent (TimeoutEvent);\r
-    return DO_MENU;\r
-  }\r
-  //\r
-  // display the prompt\r
-  // IMPORTANT!  This prompt is an ASCII character string that may\r
-  // not be terminated with a NULL byte.\r
-  //\r
-  SaveChar  = BootPromptPtr->Prompt[BootPromptPtr->Header.Length - 1];\r
-  BootPromptPtr->Prompt[BootPromptPtr->Header.Length - 1] = 0;\r
-\r
-  AsciiPrint ("%a ", BootPromptPtr->Prompt);\r
-  BootPromptPtr->Prompt[BootPromptPtr->Header.Length - 1] = SaveChar;\r
-\r
-  //\r
-  // wait until time expires or selection made - menu or local\r
-  //\r
-  SecColumn = gST->ConOut->Mode->CursorColumn;\r
-  SecRow    = gST->ConOut->Mode->CursorRow;\r
-  SecsLeft  = BootPromptPtr->Timeout;\r
-\r
-  gST->ConOut->SetCursorPosition (gST->ConOut, SecColumn, SecRow);\r
-  AsciiPrint ("(%d) ", SecsLeft);\r
-\r
-  //\r
-  // set the default action to be AUTO_SELECT\r
-  //\r
-  Status = AUTO_SELECT;\r
-\r
-  while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {\r
-    EFI_INPUT_KEY Key;\r
-\r
-    if (!EFI_ERROR (gBS->CheckEvent (SecondsEvent))) {\r
-      --SecsLeft;\r
-      gST->ConOut->SetCursorPosition (gST->ConOut, SecColumn, SecRow);\r
-      AsciiPrint ("(%d) ", SecsLeft);\r
-    }\r
-\r
-    if (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key) == EFI_NOT_READY) {\r
-      UINT8       Buffer[512];\r
-      UINTN       BufferSize;\r
-\r
-      BufferSize = sizeof Buffer;\r
-\r
-      Private->EfiBc.UdpRead (\r
-                       &Private->EfiBc,\r
-                       EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP |\r
-                       EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT |\r
-                       EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT,\r
-                       NULL, /* dest ip */\r
-                       NULL, /* dest port */\r
-                       NULL, /* src ip */\r
-                       NULL, /* src port */\r
-                       NULL, /* hdr size */\r
-                       NULL, /* hdr ptr */\r
-                       &BufferSize,\r
-                       Buffer\r
-                       );\r
-\r
-      continue;\r
-    }\r
-\r
-    if (Key.ScanCode == 0) {\r
-      switch (Key.UnicodeChar) {\r
-      case Ctl ('c'):\r
-        Status = LOCAL_BOOT;\r
-        break;\r
-\r
-      case Ctl ('m'):\r
-      case 'm':\r
-      case 'M':\r
-        Status = DO_MENU;\r
-        break;\r
-\r
-      default:\r
-        continue;\r
-      }\r
-    } else {\r
-      switch (Key.ScanCode) {\r
-      case SCAN_F8:\r
-        Status = DO_MENU;\r
-        break;\r
-\r
-      case SCAN_ESC:\r
-        Status = LOCAL_BOOT;\r
-        break;\r
-\r
-      default:\r
-        continue;\r
-      }\r
-    }\r
-\r
-    break;\r
-  }\r
-\r
-  gBS->CloseEvent (SecondsEvent);\r
-  gBS->CloseEvent (TimeoutEvent);\r
-\r
-  gST->ConOut->SetCursorPosition (gST->ConOut, SecColumn, SecRow);\r
-  AsciiPrint ("     ");\r
-\r
-  return Status;\r
-}\r
-\r
-STATIC\r
-VOID\r
-PrintMenuItem (\r
-  PXE_BOOT_MENU_ENTRY *MenuItemPtr\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Display one menu item.\r
-\r
-Arguments:\r
-\r
-  MenuItemPtr - Pointer to PXE menu item option.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-{\r
-  UINT8 Length;\r
-  UINT8 SaveChar;\r
-\r
-  Length                    = (UINT8) EFI_MIN (70, MenuItemPtr->DataLen);\r
-  SaveChar                  = MenuItemPtr->Data[Length];\r
-\r
-  MenuItemPtr->Data[Length] = 0;\r
-  AsciiPrint ("     %a\n", MenuItemPtr->Data);\r
-  MenuItemPtr->Data[Length] = SaveChar;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-DoMenu (\r
-  PXE_BASECODE_DEVICE *Private,\r
-  DHCP_RECEIVE_BUFFER *RxBufferPtr\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Display and process menu.\r
-\r
-Arguments:\r
-\r
-  Private - Pointer to PxeBc interface\r
-  RxBufferPtr - Pointer to receive buffer\r
-\r
-Returns:\r
-\r
-  NO_MENU -\r
-  LOCAL_BOOT -\r
-\r
---*/\r
-{\r
-  PXE_OP_DISCOVERY_CONTROL  *DiscoveryControlPtr;\r
-  PXE_BOOT_MENU_ENTRY       *MenuItemPtrs[MAX_MENULIST];\r
-  EFI_STATUS                Status;\r
-  UNION_PTR                 Ptr;\r
-  UINTN                     SaveNumRte;\r
-  UINTN                     TopRow;\r
-  UINTN                     MenuLth;\r
-  UINTN                     NumMenuItems;\r
-  UINTN                     Index;\r
-  UINTN                     Longest;\r
-  UINTN                     Selected;\r
-  UINT16                    Type;\r
-  UINT16                    Layer;\r
-  BOOLEAN                   Done;\r
-\r
-  Selected  = 0;\r
-  Layer     = 0;\r
-\r
-  DEBUG ((EFI_D_WARN, "\nDoMenu()  Enter."));\r
-\r
-  /* see if we have a menu/prompt */\r
-  if (!(RxBufferPtr->OpAdds.Status & DISCOVER_TYPE)) {\r
-    DEBUG (\r
-      (EFI_D_WARN,\r
-      "\nDoMenu()  No menu/prompt info.  OpAdds.Status == %xh  ",\r
-      RxBufferPtr->OpAdds.Status)\r
-      );\r
-\r
-    return NO_MENU;\r
-  }\r
-\r
-  DiscoveryControlPtr = (PXE_OP_DISCOVERY_CONTROL *) RxBufferPtr->OpAdds.PxeOptAdds[VEND_PXE_DISCOVERY_CONTROL_IX - 1];\r
-\r
-  //\r
-  // if not USE_BOOTFILE or no bootfile given, must have menu stuff\r
-  //\r
-  if ((DiscoveryControlPtr->ControlBits & USE_BOOTFILE) && RxBufferPtr->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]) {\r
-    DEBUG ((EFI_D_WARN, "\nDoMenu()  DHCP w/ bootfile.  "));\r
-    return NO_MENU;\r
-  }\r
-  //\r
-  // do prompt & menu if necessary\r
-  //\r
-  Status = DoPrompt (Private, (PXE_OP_BOOT_PROMPT *) RxBufferPtr->OpAdds.PxeOptAdds[VEND_PXE_BOOT_PROMPT_IX - 1]);\r
-\r
-  if (Status == LOCAL_BOOT) {\r
-    DEBUG ((EFI_D_WARN, "\nDoMenu()  DoPrompt() returned LOCAL_BOOT.  "));\r
-\r
-    return Status;\r
-  }\r
-\r
-  Ptr.BytePtr             = (UINT8 *) RxBufferPtr->OpAdds.PxeOptAdds[VEND_PXE_BOOT_MENU_IX - 1];\r
-\r
-  MenuLth                 = Ptr.MenuPtr->Header.Length;\r
-  Ptr.CurrentMenuItemPtr  = Ptr.MenuPtr->MenuItem;\r
-\r
-  //\r
-  // build menu items array\r
-  //\r
-  for (Longest = NumMenuItems = Index = 0; Index < MenuLth && NumMenuItems < MAX_MENULIST;) {\r
-    UINTN lth;\r
-\r
-    lth = Ptr.CurrentMenuItemPtr->DataLen + sizeof (*Ptr.CurrentMenuItemPtr) - sizeof (Ptr.CurrentMenuItemPtr->Data);\r
-\r
-    MenuItemPtrs[NumMenuItems++] = Ptr.CurrentMenuItemPtr;\r
-\r
-    if (lth > Longest) {\r
-      //\r
-      // check if too long\r
-      //\r
-      if ((Longest = lth) > 70 + (sizeof (*Ptr.CurrentMenuItemPtr) - sizeof (Ptr.CurrentMenuItemPtr->Data))) {\r
-        Longest = 70 + (sizeof (*Ptr.CurrentMenuItemPtr) - sizeof (Ptr.CurrentMenuItemPtr->Data));\r
-      }\r
-    }\r
-\r
-    Index += lth;\r
-    Ptr.BytePtr += lth;\r
-  }\r
-\r
-  if (Status != AUTO_SELECT) {\r
-    UINT8 BlankBuf[75];\r
-\r
-    SetMem (BlankBuf, sizeof BlankBuf, ' ');\r
-    BlankBuf[Longest + 5 - (sizeof (*Ptr.CurrentMenuItemPtr) - sizeof (Ptr.CurrentMenuItemPtr->Data))] = 0;\r
-    AsciiPrint ("\n");\r
-\r
-    //\r
-    // now put up menu\r
-    //\r
-    for (Index = 0; Index < NumMenuItems; ++Index) {\r
-      PrintMenuItem (MenuItemPtrs[Index]);\r
-    }\r
-\r
-    TopRow = gST->ConOut->Mode->CursorRow - NumMenuItems;\r
-\r
-    //\r
-    // now wait for a selection\r
-    //\r
-    Done = FALSE;\r
-    do {\r
-      //\r
-      // highlight selection\r
-      //\r
-      EFI_INPUT_KEY Key;\r
-      UINTN         NewSelected;\r
-\r
-      NewSelected = Selected;\r
-\r
-      //\r
-      // highlight selected row\r
-      //\r
-      gST->ConOut->SetAttribute (\r
-                    gST->ConOut,\r
-                    EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)\r
-                    );\r
-      gST->ConOut->SetCursorPosition (gST->ConOut, 0, TopRow + Selected);\r
-\r
-      AsciiPrint (" --->%a\r", BlankBuf);\r
-\r
-      PrintMenuItem (MenuItemPtrs[Selected]);\r
-      gST->ConOut->SetAttribute (\r
-                    gST->ConOut,\r
-                    EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)\r
-                    );\r
-      gST->ConOut->SetCursorPosition (gST->ConOut, 0, TopRow + NumMenuItems);\r
-\r
-      //\r
-      // wait for a keystroke\r
-      //\r
-      while (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key) == EFI_NOT_READY) {\r
-        UINT8 TmpBuf[512];\r
-        UINTN TmpBufLen;\r
-\r
-        TmpBufLen = sizeof TmpBuf;\r
-\r
-        Private->EfiBc.UdpRead (\r
-                        &Private->EfiBc,\r
-                        EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP |\r
-                        EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT |\r
-                        EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT,\r
-                        NULL, /* dest ip */\r
-                        NULL, /* dest port */\r
-                        NULL, /* src ip */\r
-                        NULL, /* src port */\r
-                        NULL, /* hdr size */\r
-                        NULL, /* hdr ptr */\r
-                        &TmpBufLen,\r
-                        TmpBuf\r
-                        );\r
-      }\r
-\r
-      if (!Key.ScanCode) {\r
-        switch (Key.UnicodeChar) {\r
-        case Ctl ('c'):\r
-          Key.ScanCode = SCAN_ESC;\r
-          break;\r
-\r
-        case Ctl ('j'): /* linefeed */\r
-        case Ctl ('m'): /* return */\r
-          Done = TRUE;\r
-          break;\r
-\r
-        case Ctl ('i'): /* tab */\r
-        case ' ':\r
-        case 'd':\r
-        case 'D':\r
-          Key.ScanCode = SCAN_DOWN;\r
-          break;\r
-\r
-        case Ctl ('h'): /* backspace */\r
-        case 'u':\r
-        case 'U':\r
-          Key.ScanCode = SCAN_UP;\r
-          break;\r
-\r
-        default:\r
-          Key.ScanCode = 0;\r
-        }\r
-      }\r
-\r
-      switch (Key.ScanCode) {\r
-      case SCAN_LEFT:\r
-      case SCAN_UP:\r
-        if (NewSelected) {\r
-          --NewSelected;\r
-        }\r
-\r
-        break;\r
-\r
-      case SCAN_DOWN:\r
-      case SCAN_RIGHT:\r
-        if (++NewSelected == NumMenuItems) {\r
-          --NewSelected;\r
-        }\r
-\r
-        break;\r
-\r
-      case SCAN_PAGE_UP:\r
-      case SCAN_HOME:\r
-        NewSelected = 0;\r
-        break;\r
-\r
-      case SCAN_PAGE_DOWN:\r
-      case SCAN_END:\r
-        NewSelected = NumMenuItems - 1;\r
-        break;\r
-\r
-      case SCAN_ESC:\r
-        return LOCAL_BOOT;\r
-      }\r
-\r
-      /* unhighlight last selected row */\r
-      gST->ConOut->SetCursorPosition (gST->ConOut, 5, TopRow + Selected);\r
-\r
-      AsciiPrint ("%a\r", BlankBuf);\r
-\r
-      PrintMenuItem (MenuItemPtrs[Selected]);\r
-\r
-      Selected = NewSelected;\r
-    } while (!Done);\r
-  }\r
-\r
-  SaveNumRte  = Private->EfiBc.Mode->RouteTableEntries;\r
-\r
-  Type        = NTOHS (MenuItemPtrs[Selected]->Type);\r
-\r
-  if (Type == 0) {\r
-    DEBUG ((EFI_D_WARN, "\nDoMenu()  Local boot selected.  "));\r
-    return LOCAL_BOOT;\r
-  }\r
-\r
-  AsciiPrint ("Discover");\r
-\r
-  Status = Private->EfiBc.Discover (\r
-                            &Private->EfiBc,\r
-                            Type,\r
-                            &Layer,\r
-                            (BOOLEAN) (Private->EfiBc.Mode->BisSupported && Private->EfiBc.Mode->BisDetected),\r
-                            0\r
-                            );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    AsciiPrint ("\r                    \r");\r
-\r
-    DEBUG (\r
-      (EFI_D_WARN,\r
-      "\nDoMenu()  Return w/ %xh (%r).",\r
-      Status,\r
-      Status)\r
-      );\r
-\r
-    return Status;\r
-  }\r
-\r
-  AsciiPrint ("\rBOOT_SERVER_IP: ");\r
-  PrintIpv4 ((UINT8 *) &Private->ServerIp);\r
-\r
-  for (Index = SaveNumRte; Index < Private->EfiBc.Mode->RouteTableEntries; ++Index) {\r
-    if ((Index % 3) == 0) {\r
-      AsciiPrint ("\r\nGATEWAY IP:");\r
-    }\r
-\r
-    AsciiPrint (" ");\r
-    PrintIpv4 ((UINT8 *) &Private->EfiBc.Mode->RouteTable[Index].GwAddr);\r
-    AsciiPrint (" ");\r
-  }\r
-\r
-  AsciiPrint ("\n");\r
-\r
-  DEBUG ((EFI_D_WARN, "\nDoMenu()  Return w/ EFI_SUCCESS.  "));\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-UINT16\r
-GetValue (\r
-  DHCPV4_OP_STRUCT *OpPtr\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Get value 8- or 16-bit value from DHCP option.\r
-\r
-Arguments:\r
-\r
-  OpPtr - Pointer to DHCP option\r
-\r
-Returns:\r
-\r
-  Value from DHCP option\r
-\r
---*/\r
-{\r
-  if (OpPtr->Header.Length == 1) {\r
-    return OpPtr->Data[0];\r
-  } else {\r
-    return NTOHS (OpPtr->Data);\r
-  }\r
-}\r
-\r
-STATIC\r
-UINT8 *\r
-_PxeBcFindOpt (\r
-  UINT8 *BufferPtr,\r
-  UINTN BufferLen,\r
-  UINT8 OpCode\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Locate opcode in buffer.\r
-\r
-Arguments:\r
-\r
-  BufferPtr - Pointer to buffer\r
-  BufferLen - Length of buffer\r
-  OpCode - Option number\r
-\r
-Returns:\r
-\r
-  Pointer to opcode, may be NULL\r
-\r
---*/\r
-{\r
-  if (BufferPtr == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  while (BufferLen != 0) {\r
-    if (*BufferPtr == OpCode) {\r
-      return BufferPtr;\r
-    }\r
-\r
-    switch (*BufferPtr) {\r
-    case OP_END:\r
-      return NULL;\r
-\r
-    case OP_PAD:\r
-      ++BufferPtr;\r
-      --BufferLen;\r
-      continue;\r
-    }\r
-\r
-    if ((UINTN) BufferLen <= (UINTN) 2 + BufferPtr[1]) {\r
-      return NULL;\r
-    }\r
-\r
-    BufferLen -= 2 + BufferPtr[1];\r
-    BufferPtr += 2 + BufferPtr[1];\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-STATIC\r
-UINT8 *\r
-PxeBcFindDhcpOpt (\r
-  EFI_PXE_BASE_CODE_PACKET  *PacketPtr,\r
-  UINT8                     OpCode\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Find option in packet\r
-\r
-Arguments:\r
-\r
-  PacketPtr - Pointer to packet\r
-  OpCode - option number\r
-\r
-Returns:\r
-\r
-  Pointer to option in packet\r
-\r
---*/\r
-{\r
-  UINTN PacketLen;\r
-  UINT8 Overload;\r
-  UINT8 *OptionBufferPtr;\r
-\r
-  //\r
-  //\r
-  //\r
-  PacketLen = 380;\r
-  Overload  = 0;\r
-\r
-  //\r
-  // Figure size of DHCP option space.\r
-  //\r
-  OptionBufferPtr = _PxeBcFindOpt (\r
-                      PacketPtr->Dhcpv4.DhcpOptions,\r
-                      380,\r
-                      OP_DHCP_MAX_MESSAGE_SZ\r
-                      );\r
-\r
-  if (OptionBufferPtr != NULL) {\r
-    if (OptionBufferPtr[1] == 2) {\r
-      UINT16  n;\r
-\r
-      CopyMem (&n, &OptionBufferPtr[2], 2);\r
-      PacketLen = HTONS (n);\r
-\r
-      if (PacketLen < sizeof (EFI_PXE_BASE_CODE_DHCPV4_PACKET)) {\r
-        PacketLen = 380;\r
-      } else {\r
-        PacketLen -= (PacketPtr->Dhcpv4.DhcpOptions - &PacketPtr->Dhcpv4.BootpOpcode) + 28;\r
-      }\r
-    }\r
-  }\r
-  //\r
-  // Look for option overloading.\r
-  //\r
-  OptionBufferPtr = _PxeBcFindOpt (\r
-                      PacketPtr->Dhcpv4.DhcpOptions,\r
-                      PacketLen,\r
-                      OP_DHCP_OPTION_OVERLOAD\r
-                      );\r
-\r
-  if (OptionBufferPtr != NULL) {\r
-    if (OptionBufferPtr[1] == 1) {\r
-      Overload = OptionBufferPtr[2];\r
-    }\r
-  }\r
-  //\r
-  // Look for caller's option.\r
-  //\r
-  OptionBufferPtr = _PxeBcFindOpt (\r
-                      PacketPtr->Dhcpv4.DhcpOptions,\r
-                      PacketLen,\r
-                      OpCode\r
-                      );\r
-\r
-  if (OptionBufferPtr != NULL) {\r
-    return OptionBufferPtr;\r
-  }\r
-\r
-  if (Overload & OVLD_FILE) {\r
-    OptionBufferPtr = _PxeBcFindOpt (PacketPtr->Dhcpv4.BootpBootFile, 128, OpCode);\r
-\r
-    if (OptionBufferPtr != NULL) {\r
-      return OptionBufferPtr;\r
-    }\r
-  }\r
-\r
-  if (Overload & OVLD_SRVR_NAME) {\r
-    OptionBufferPtr = _PxeBcFindOpt (PacketPtr->Dhcpv4.BootpSrvName, 64, OpCode);\r
-\r
-    if (OptionBufferPtr != NULL) {\r
-      return OptionBufferPtr;\r
-    }\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-DownloadFile (\r
-  IN PXE_BASECODE_DEVICE  *Private,\r
-  IN OUT UINT64           *BufferSize,\r
-  IN VOID                 *Buffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Download file into buffer\r
-\r
-Arguments:\r
-\r
-  Private - Pointer to PxeBc interface\r
-  BufferSize - pointer to size of download buffer\r
-  Buffer - Pointer to buffer\r
-\r
-Returns:\r
-\r
-  EFI_BUFFER_TOO_SMALL -\r
-  EFI_NOT_FOUND -\r
-  EFI_PROTOCOL_ERROR -\r
-\r
---*/\r
-{\r
-  EFI_PXE_BASE_CODE_MTFTP_INFO  MtftpInfo;\r
-  EFI_PXE_BASE_CODE_TFTP_OPCODE OpCode;\r
-  DHCP_RECEIVE_BUFFER           *RxBuf;\r
-  EFI_STATUS                    Status;\r
-  UINTN                         BlockSize;\r
-\r
-  RxBuf     = (DHCP_RECEIVE_BUFFER *) Private->BootServerReceiveBuffer;\r
-  BlockSize = 0x8000;\r
-\r
-  DEBUG ((EFI_D_WARN, "\nDownloadFile()  Enter."));\r
-\r
-  if (Buffer == NULL || *BufferSize == 0 || *BufferSize < Private->FileSize) {\r
-    if (Private->FileSize != 0) {\r
-      *BufferSize = Private->FileSize;\r
-      return EFI_BUFFER_TOO_SMALL;\r
-    }\r
-\r
-    AsciiPrint ("\nTSize");\r
-\r
-    OpCode = EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE;\r
-  } else if (RxBuf->OpAdds.Status & WfM11a_TYPE) {\r
-    OpCode = EFI_PXE_BASE_CODE_MTFTP_READ_FILE;\r
-\r
-    ZeroMem (&MtftpInfo, sizeof MtftpInfo);\r
-\r
-    *(IPV4_ADDR *) &MtftpInfo.MCastIp = *(IPV4_ADDR *) RxBuf->OpAdds.PxeOptAdds[VEND_PXE_MTFTP_IP - 1]->Data;\r
-\r
-    CopyMem (\r
-      &MtftpInfo.CPort,\r
-      RxBuf->OpAdds.PxeOptAdds[VEND_PXE_MTFTP_CPORT - 1]->Data,\r
-      sizeof MtftpInfo.CPort\r
-      );\r
-\r
-    CopyMem (\r
-      &MtftpInfo.SPort,\r
-      RxBuf->OpAdds.PxeOptAdds[VEND_PXE_MTFTP_SPORT - 1]->Data,\r
-      sizeof MtftpInfo.SPort\r
-      );\r
-\r
-    MtftpInfo.ListenTimeout   = GetValue (RxBuf->OpAdds.PxeOptAdds[VEND_PXE_MTFTP_TMOUT - 1]);\r
-\r
-    MtftpInfo.TransmitTimeout = GetValue (RxBuf->OpAdds.PxeOptAdds[VEND_PXE_MTFTP_DELAY - 1]);\r
-\r
-    AsciiPrint ("\nMTFTP");\r
-  } else {\r
-    AsciiPrint ("\nTFTP");\r
-\r
-    OpCode = EFI_PXE_BASE_CODE_TFTP_READ_FILE;\r
-  }\r
-\r
-  Private->FileSize = 0;\r
-\r
-  RxBuf->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]->Data[RxBuf->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]->Header.Length] = 0;\r
-\r
-  Status = Private->EfiBc.Mtftp (\r
-                            &Private->EfiBc,\r
-                            OpCode,\r
-                            Buffer,\r
-                            FALSE,\r
-                            BufferSize,\r
-                            &BlockSize,\r
-                            &Private->ServerIp,\r
-                            (UINT8 *) RxBuf->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]->Data,\r
-                            &MtftpInfo,\r
-                            FALSE\r
-                            );\r
-\r
-  if (Status != EFI_SUCCESS && Status != EFI_BUFFER_TOO_SMALL) {\r
-    DEBUG ((EFI_D_WARN, "\nDownloadFile()  Exit #1 %Xh", Status));\r
-    return Status;\r
-  }\r
-\r
-  if (sizeof (UINTN) < sizeof (UINT64) && *BufferSize > 0xFFFFFFFF) {\r
-    Private->FileSize = 0xFFFFFFFF;\r
-  } else {\r
-    Private->FileSize = (UINTN) *BufferSize;\r
-  }\r
-\r
-  if (OpCode == EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE) {\r
-    DEBUG ((EFI_D_WARN, "\nDownloadFile()  Exit #2"));\r
-    return EFI_BUFFER_TOO_SMALL;\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_WARN, "\nDownloadFile()  Exit #3 %Xh", Status));\r
-    return Status;\r
-  }\r
-\r
-  if (Private->EfiBc.Mode->BisSupported && Private->EfiBc.Mode->BisDetected && Private->EfiBc.Mode->PxeBisReplyReceived) {\r
-    UINT64  CredentialLen;\r
-    UINT8   CredentialFilename[256];\r
-    UINT8   *op;\r
-    VOID    *CredentialBuffer;\r
-\r
-    //\r
-    // Get name of credential file.  It may be in the BOOTP\r
-    // bootfile field or a DHCP option.\r
-    //\r
-    ZeroMem (CredentialFilename, sizeof CredentialFilename);\r
-\r
-    op = PxeBcFindDhcpOpt (&Private->EfiBc.Mode->PxeBisReply, OP_DHCP_BOOTFILE);\r
-\r
-    if (op != NULL) {\r
-      if (op[1] == 0) {\r
-        /* No credential filename */\r
-        return EFI_NOT_FOUND;\r
-      }\r
-\r
-      CopyMem (CredentialFilename, &op[2], op[1]);\r
-    } else {\r
-      if (Private->EfiBc.Mode->PxeBisReply.Dhcpv4.BootpBootFile[0] == 0) {\r
-        /* No credential filename */\r
-        return EFI_NOT_FOUND;\r
-      }\r
-\r
-      CopyMem (CredentialFilename, &op[2], 128);\r
-    }\r
-    //\r
-    // Get size of credential file.  It may be available as a\r
-    // DHCP option.  If not, use the TFTP get file size.\r
-    //\r
-    CredentialLen = 0;\r
-\r
-    op            = PxeBcFindDhcpOpt (&Private->EfiBc.Mode->PxeBisReply, OP_BOOT_FILE_SZ);\r
-\r
-    if (op != NULL) {\r
-      /*\r
-       * This is actually the size of the credential file\r
-       * buffer.  The actual credential file size will be\r
-       * returned when we download the file.\r
-       */\r
-      if (op[1] == 2) {\r
-        UINT16  n;\r
-\r
-        CopyMem (&n, &op[2], 2);\r
-        CredentialLen = HTONS (n) * 512;\r
-      }\r
-    }\r
-\r
-    if (CredentialLen == 0) {\r
-      BlockSize = 8192;\r
-\r
-      Status = Private->EfiBc.Mtftp (\r
-                                &Private->EfiBc,\r
-                                EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,\r
-                                NULL,\r
-                                FALSE,\r
-                                &CredentialLen,\r
-                                &BlockSize,\r
-                                &Private->ServerIp,\r
-                                CredentialFilename,\r
-                                NULL,\r
-                                FALSE\r
-                                );\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-\r
-      if (CredentialLen == 0) {\r
-        //\r
-        // %%TBD -- EFI error for invalid credential\r
-        // file.\r
-        //\r
-        return EFI_PROTOCOL_ERROR;\r
-      }\r
-    }\r
-    //\r
-    // Allocate credential file buffer.\r
-    //\r
-    CredentialBuffer = AllocatePool ((UINTN) CredentialLen);\r
-    if (CredentialBuffer == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    //\r
-    // Download credential file.\r
-    //\r
-    BlockSize = 8192;\r
-\r
-    Status = Private->EfiBc.Mtftp (\r
-                              &Private->EfiBc,\r
-                              EFI_PXE_BASE_CODE_TFTP_READ_FILE,\r
-                              CredentialBuffer,\r
-                              FALSE,\r
-                              &CredentialLen,\r
-                              &BlockSize,\r
-                              &Private->ServerIp,\r
-                              CredentialFilename,\r
-                              NULL,\r
-                              FALSE\r
-                              );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      FreePool (CredentialBuffer);\r
-      return Status;\r
-    }\r
-    //\r
-    // Verify credentials.\r
-    //\r
-    if (PxebcBisVerify (Private, Buffer, Private->FileSize, CredentialBuffer, (UINTN) CredentialLen)) {\r
-      Status = EFI_SUCCESS;\r
-    } else {\r
-      //\r
-      // %%TBD -- An EFI error code for failing credential verification.\r
-      //\r
-      Status = EFI_PROTOCOL_ERROR;\r
-    }\r
-\r
-    FreePool (CredentialBuffer);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-LoadfileStart (\r
-  IN PXE_BASECODE_DEVICE  *Private,\r
-  IN OUT UINT64           *BufferSize,\r
-  IN VOID                 *Buffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Start PXE DHCP.  Get DHCP and proxyDHCP information.\r
-  Display remote boot menu and prompt.  Select item from menu.\r
-\r
-Arguments:\r
-\r
-  Private - Pointer to PxeBc interface\r
-  BufferSize - Pointer to download buffer size\r
-  Buffer - Pointer to download buffer\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS -\r
-  EFI_NOT_READY -\r
-\r
---*/\r
-{\r
-  EFI_PXE_BASE_CODE_MODE      *PxeBcMode;\r
-  EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
-  EFI_SIMPLE_NETWORK_MODE     *SnpMode;\r
-  EFI_STATUS                  Status;\r
-  VOID                        *RxBuf;\r
-\r
-  DEBUG ((EFI_D_WARN, "\nLoadfileStart()  Enter."));\r
-\r
-  //\r
-  // Try to start BaseCode, for now only IPv4 is supported\r
-  // so don't try to start using IPv6.\r
-  //\r
-  Status = Private->EfiBc.Start (&Private->EfiBc, FALSE);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    if (Status != EFI_ALREADY_STARTED) {\r
-      DEBUG ((EFI_D_NET, "\nLoadfileStart()  Exit  BC.Start() == %xh", Status));\r
-      return Status;\r
-    }\r
-  }\r
-  //\r
-  // Get pointers to PXE mode structure, SNP protocol structure\r
-  // and SNP mode structure.\r
-  //\r
-  PxeBcMode = Private->EfiBc.Mode;\r
-  Snp       = Private->SimpleNetwork;\r
-  SnpMode   = Snp->Mode;\r
-\r
-  //\r
-  // Display client MAC address, like 16-bit PXE ROMs\r
-  //\r
-  AsciiPrint ("\nCLIENT MAC ADDR: ");\r
-\r
-  {\r
-    UINTN Index;\r
-    UINTN hlen;\r
-\r
-    hlen = SnpMode->HwAddressSize;\r
-\r
-    for (Index = 0; Index < hlen; ++Index) {\r
-      AsciiPrint ("%02x ", SnpMode->CurrentAddress.Addr[Index]);\r
-    }\r
-  }\r
-\r
-  AsciiPrint ("\nDHCP");\r
-\r
-  Status = Private->EfiBc.Dhcp (&Private->EfiBc, TRUE);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_WARN, "\nLoadfileStart()  Exit  BC.Dhcp() == %Xh", Status));\r
-    AsciiPrint ("\r               \r");\r
-    return Status;\r
-  }\r
-\r
-  ShowMyInfo (Private);\r
-\r
-  RxBuf = PxeBcMode->ProxyOfferReceived ? &PXE_OFFER_BUFFER : &DHCPV4_ACK_BUFFER;\r
-#define RxBufferPtr ((DHCP_RECEIVE_BUFFER *) RxBuf)\r
-\r
-  Status = DoMenu (Private, RxBufferPtr);\r
-\r
-  if (Status == EFI_SUCCESS) {\r
-    //\r
-    // did a discovery - take info from discovery packet\r
-    //\r
-    RxBuf = &PXE_ACK_BUFFER;\r
-  } else if (Status == NO_MENU) {\r
-    //\r
-    // did not do a discovery - take info from rxbuf\r
-    //\r
-    Private->ServerIp.Addr[0] = RxBufferPtr->u.Dhcpv4.siaddr;\r
-\r
-    if (!(Private->ServerIp.Addr[0])) {\r
-      *(IPV4_ADDR *) &Private->ServerIp = *(IPV4_ADDR *) RxBufferPtr->OpAdds.PktOptAdds[OP_DHCP_SERVER_IP_IX - 1]->Data;\r
-    }\r
-  } else {\r
-    DEBUG ((EFI_D_WARN, "\nLoadfileStart()  Exit  DoMenu() == %Xh", Status));\r
-    return Status;\r
-  }\r
-\r
-  if (!RxBufferPtr->OpAdds.PktOptAdds[OP_DHCP_BOOTFILE_IX - 1]) {\r
-    DEBUG ((EFI_D_WARN, "\nLoadfileStart()  Exit  Not ready?"));\r
-    return EFI_NOT_READY;\r
-  }\r
-  //\r
-  // check for file size option sent\r
-  //\r
-  if (RxBufferPtr->OpAdds.PktOptAdds[OP_BOOT_FILE_SZ_IX - 1]) {\r
-    Private->FileSize = 512 * NTOHS (RxBufferPtr->OpAdds.PktOptAdds[OP_BOOT_FILE_SZ_IX - 1]->Data);\r
-  }\r
-\r
-  Private->BootServerReceiveBuffer  = RxBufferPtr;\r
-\r
-  Status = DownloadFile (Private, BufferSize, Buffer);\r
-\r
-  DEBUG (\r
-    (EFI_D_WARN,\r
-    "\nLoadfileStart()  Exit.  DownloadFile() = %Xh",\r
-    Status)\r
-    );\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-LoadFile (\r
-  IN EFI_LOAD_FILE_PROTOCOL           *This,\r
-  IN EFI_DEVICE_PATH_PROTOCOL         *FilePath,\r
-  IN BOOLEAN                          BootPolicy,\r
-  IN OUT UINTN                        *BufferSize,\r
-  IN OUT VOID                         *Buffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Loadfile interface for PxeBc interface\r
-\r
-Arguments:\r
-\r
-  This -  Pointer to Loadfile interface\r
-  FilePath - Not used and not checked\r
-  BootPolicy - Must be TRUE\r
-  BufferSize - Pointer to buffer size\r
-  Buffer - Pointer to download buffer or NULL\r
-\r
-Returns:\r
-\r
-  EFI_INVALID_PARAMETER -\r
-  EFI_UNSUPPORTED -\r
-  EFI_SUCCESS -\r
-  EFI_BUFFER_TOO_SMALL -\r
-\r
---*/\r
-{\r
-  LOADFILE_DEVICE *LoadfilePtr;\r
-  UINT64          TmpBufSz;\r
-  INT32           OrigMode;\r
-  INT32           OrigAttribute;\r
-  BOOLEAN         RemoveCallback;\r
-  BOOLEAN         NewMakeCallback;\r
-  EFI_STATUS      Status;\r
-  EFI_STATUS      TempStatus;\r
-  //\r
-  //\r
-  //\r
-  OrigMode        = gST->ConOut->Mode->Mode;\r
-  OrigAttribute   = gST->ConOut->Mode->Attribute;\r
-  RemoveCallback  = FALSE;\r
-\r
-  AsciiPrint ("Running LoadFile()\n");\r
-\r
-  //\r
-  // If either if these parameters are NULL, we cannot continue.\r
-  //\r
-  if (This == NULL || BufferSize == NULL) {\r
-    DEBUG ((EFI_D_WARN, "\nLoadFile()  This or BufferSize == NULL"));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // We only support BootPolicy == TRUE\r
-  //\r
-  if (!BootPolicy) {\r
-    DEBUG ((EFI_D_WARN, "\nLoadFile()  BootPolicy == FALSE"));\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-  //\r
-  // Get pointer to LoadFile protocol structure.\r
-  //\r
-  LoadfilePtr = CR (This, LOADFILE_DEVICE, LoadFile, LOADFILE_DEVICE_SIGNATURE);\r
-\r
-  if (LoadfilePtr == NULL) {\r
-    DEBUG (\r
-      (EFI_D_NET,\r
-      "\nLoadFile()  Could not get pointer to LoadFile structure")\r
-      );\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Lock interface\r
-  //\r
-  EfiAcquireLock (&LoadfilePtr->Lock);\r
-\r
-  //\r
-  // Set console output mode and display attribute\r
-  //\r
-  if (OrigMode != 0) {\r
-    gST->ConOut->SetMode (gST->ConOut, 0);\r
-  }\r
-\r
-  gST->ConOut->SetAttribute (\r
-                gST->ConOut,\r
-                EFI_TEXT_ATTR (EFI_LIGHTGRAY,EFI_BLACK)\r
-                );\r
-\r
-  //\r
-  // See if BaseCode already has a Callback protocol attached.\r
-  // If there is none, attach our own Callback protocol.\r
-  //\r
-  Status = gBS->HandleProtocol (\r
-                  LoadfilePtr->Private->Handle,\r
-                  &gEfiPxeBaseCodeCallbackProtocolGuid,\r
-                  (VOID *) &LoadfilePtr->Private->CallbackProtocolPtr\r
-                  );\r
-\r
-  if (Status == EFI_SUCCESS) {\r
-    //\r
-    // There is already a callback routine.  Do nothing.\r
-    //\r
-    DEBUG ((EFI_D_WARN, "\nLoadFile()  BC callback exists."));\r
-  } else if (Status == EFI_UNSUPPORTED) {\r
-    //\r
-    // No BaseCode Callback protocol found.  Add our own.\r
-    //\r
-    Status = gBS->InstallProtocolInterface (\r
-                    &LoadfilePtr->Private->Handle,\r
-                    &gEfiPxeBaseCodeCallbackProtocolGuid,\r
-                    EFI_NATIVE_INTERFACE,\r
-                    &_bc_callback\r
-                    );\r
-\r
-    DEBUG ((EFI_D_WARN, "\nLoadFile()  Callback install status == %xh", Status));\r
-\r
-    RemoveCallback = (BOOLEAN) (Status == EFI_SUCCESS);\r
-\r
-    if (LoadfilePtr->Private->EfiBc.Mode != NULL && LoadfilePtr->Private->EfiBc.Mode->Started) {\r
-      NewMakeCallback = TRUE;\r
-      LoadfilePtr->Private->EfiBc.SetParameters (\r
-                                    &LoadfilePtr->Private->EfiBc,\r
-                                    NULL,\r
-                                    NULL,\r
-                                    NULL,\r
-                                    NULL,\r
-                                    &NewMakeCallback\r
-                                    );\r
-    }\r
-  } else {\r
-    DEBUG ((EFI_D_WARN, "\nLoadFile()  Callback check status == %xh", Status));\r
-  }\r
-  //\r
-  // Check for starting or for continuing after already getting\r
-  // the file size.\r
-  //\r
-  if (LoadfilePtr->Private->FileSize == 0) {\r
-    TmpBufSz  = 0;\r
-    Status    = LoadfileStart (LoadfilePtr->Private, &TmpBufSz, Buffer);\r
-\r
-    if (sizeof (UINTN) < sizeof (UINT64) && TmpBufSz > 0xFFFFFFFF) {\r
-      *BufferSize = 0xFFFFFFFF;\r
-    } else {\r
-      *BufferSize = (UINTN) TmpBufSz;\r
-    }\r
-\r
-    if (Status == EFI_BUFFER_TOO_SMALL) {\r
-      //\r
-      // This is done so loadfile will work even if the boot manager\r
-      // did not make the first call with Buffer == NULL.\r
-      //\r
-      Buffer = NULL;\r
-    }\r
-  } else if (Buffer == NULL) {\r
-    DEBUG ((EFI_D_WARN, "\nLoadfile()  Get buffer size"));\r
-\r
-    //\r
-    // Continuing from previous LoadFile request.  Make sure there\r
-    // is a buffer and that it is big enough.\r
-    //\r
-    *BufferSize = LoadfilePtr->Private->FileSize;\r
-    Status      = EFI_BUFFER_TOO_SMALL;\r
-  } else {\r
-    DEBUG ((EFI_D_WARN, "\nLoadFile()  Download file"));\r
-\r
-    //\r
-    // Everything looks good, try to download the file.\r
-    //\r
-    TmpBufSz  = *BufferSize;\r
-    Status    = DownloadFile (LoadfilePtr->Private, &TmpBufSz, Buffer);\r
-\r
-    //\r
-    // Next call to loadfile will start DHCP process again.\r
-    //\r
-    LoadfilePtr->Private->FileSize = 0;\r
-  }\r
-  //\r
-  // If we added a callback protocol, now is the time to remove it.\r
-  //\r
-  if (RemoveCallback) {\r
-    NewMakeCallback = FALSE;\r
-    TempStatus = LoadfilePtr->Private->EfiBc.SetParameters (\r
-                                          &LoadfilePtr->Private->EfiBc,\r
-                                          NULL,\r
-                                          NULL,\r
-                                          NULL,\r
-                                          NULL,\r
-                                          &NewMakeCallback\r
-                                          );\r
-\r
-    if (TempStatus == EFI_SUCCESS) {\r
-      gBS->UninstallProtocolInterface (\r
-            LoadfilePtr->Private->Handle,\r
-            &gEfiPxeBaseCodeCallbackProtocolGuid,\r
-            &_bc_callback\r
-            );\r
-    }\r
-  }\r
-  //\r
-  // Restore display mode and attribute\r
-  //\r
-  if (OrigMode != 0) {\r
-    gST->ConOut->SetMode (gST->ConOut, OrigMode);\r
-  }\r
-\r
-  gST->ConOut->SetAttribute (gST->ConOut, OrigAttribute);\r
-\r
-  //\r
-  // Unlock interface\r
-  //\r
-  EfiReleaseLock (&LoadfilePtr->Lock);\r
-\r
-  DEBUG ((EFI_D_WARN, "\nBC.Loadfile()  Status == %xh\n", Status));\r
-\r
-  if (Status == EFI_SUCCESS) {\r
-    /* 0 */\r
-    return EFI_SUCCESS;\r
-  } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    /* 5 */\r
-    //\r
-    // Error is only displayed when we are actually trying to\r
-    // download the boot image.\r
-    //\r
-    if (Buffer == NULL) {\r
-      return EFI_BUFFER_TOO_SMALL;\r
-    }\r
-    AsciiPrint ("\nPXE-E05: Download buffer is smaller than requested file.\n");\r
-  } else if (Status == EFI_DEVICE_ERROR) {\r
-    /* 7 */\r
-    AsciiPrint ("\nPXE-E07: Network device error.  Check network connection.\n");\r
-  } else if (Status == EFI_OUT_OF_RESOURCES) {\r
-    /* 9 */\r
-    AsciiPrint ("\nPXE-E09: Could not allocate I/O buffers.\n");\r
-  } else if (Status == EFI_NO_MEDIA) {\r
-    /* 12 */\r
-    AsciiPrint ("\nPXE-E12: Could not detect network connection.  Check cable.\n");\r
-  } else if (Status == EFI_NO_RESPONSE) {\r
-    /* 16 */\r
-    AsciiPrint ("\nPXE-E16: Valid PXE offer not received.\n");\r
-  } else if (Status == EFI_TIMEOUT) {\r
-    /* 18 */\r
-    AsciiPrint ("\nPXE-E18: Timeout.  Server did not respond.\n");\r
-  } else if (Status == EFI_ABORTED) {\r
-    /* 21 */\r
-    AsciiPrint ("\nPXE-E21: Remote boot cancelled.\n");\r
-  } else if (Status == EFI_ICMP_ERROR) {\r
-    /* 22 */\r
-    AsciiPrint ("\nPXE-E22: Client received ICMP error from server.\n");\r
-\r
-    if ((LoadfilePtr->Private->EfiBc.Mode != NULL) && LoadfilePtr->Private->EfiBc.Mode->IcmpErrorReceived) {\r
-      AsciiPrint (\r
-        "PXE-E98: Type: %xh  Code: %xh  ",\r
-        LoadfilePtr->Private->EfiBc.Mode->IcmpError.Type,\r
-        LoadfilePtr->Private->EfiBc.Mode->IcmpError.Code\r
-        );\r
-\r
-      switch (LoadfilePtr->Private->EfiBc.Mode->IcmpError.Type) {\r
-      case 0x03:\r
-        switch (LoadfilePtr->Private->EfiBc.Mode->IcmpError.Code) {\r
-        case 0x00:              /* net unreachable */\r
-          AsciiPrint ("Net unreachable");\r
-          break;\r
-\r
-        case 0x01:              /* host unreachable */\r
-          AsciiPrint ("Host unreachable");\r
-          break;\r
-\r
-        case 0x02:              /* protocol unreachable */\r
-          AsciiPrint ("Protocol unreachable");\r
-          break;\r
-\r
-        case 0x03:              /* port unreachable */\r
-          AsciiPrint ("Port unreachable");\r
-          break;\r
-\r
-        case 0x04:              /* Fragmentation needed */\r
-          AsciiPrint ("Fragmentation needed");\r
-          break;\r
-\r
-        case 0x05:              /* Source route failed */\r
-          AsciiPrint ("Source route failed");\r
-          break;\r
-        }\r
-\r
-        break;\r
-      }\r
-\r
-      AsciiPrint ("\n");\r
-    }\r
-  } else if (Status == EFI_TFTP_ERROR) {\r
-    /* 23 */\r
-    AsciiPrint ("\nPXE-E23: Client received TFTP error from server.\n");\r
-\r
-    if ((LoadfilePtr->Private->EfiBc.Mode != NULL) && (LoadfilePtr->Private->EfiBc.Mode->TftpErrorReceived)) {\r
-      AsciiPrint (\r
-        "PXE-E98: Code: %xh  %a\n",\r
-        LoadfilePtr->Private->EfiBc.Mode->TftpError.ErrorCode,\r
-        LoadfilePtr->Private->EfiBc.Mode->TftpError.ErrorString\r
-        );\r
-    }\r
-  } else {\r
-    AsciiPrint ("\nPXE-E99: Unexpected network error: %xh\n", Status);\r
-  }\r
-\r
-  LoadfilePtr->Private->EfiBc.Stop (&LoadfilePtr->Private->EfiBc);\r
-\r
-  return Status;\r
-}\r