]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootOption.c
Remove IntelFrameworkModulePkg
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / BootOption.c
diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootOption.c b/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootOption.c
deleted file mode 100644 (file)
index 96fe935..0000000
+++ /dev/null
@@ -1,1755 +0,0 @@
-/** @file\r
-  Provide boot option support for Application "BootMaint"\r
-\r
-  Include file system navigation, system handle selection\r
-\r
-  Boot option manipulation\r
-\r
-Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "BootMaint.h"\r
-#include "BBSsupport.h"\r
-\r
-/**\r
-  Create a menu entry by given menu type.\r
-\r
-  @param MenuType        The Menu type to be created.\r
-\r
-  @retval NULL           If failed to create the menu.\r
-  @return the new menu entry.\r
-\r
-**/\r
-BM_MENU_ENTRY *\r
-BOpt_CreateMenuEntry (\r
-  UINTN           MenuType\r
-  )\r
-{\r
-  BM_MENU_ENTRY *MenuEntry;\r
-  UINTN         ContextSize;\r
-\r
-  //\r
-  // Get context size according to menu type\r
-  //\r
-  switch (MenuType) {\r
-  case BM_LOAD_CONTEXT_SELECT:\r
-    ContextSize = sizeof (BM_LOAD_CONTEXT);\r
-    break;\r
-\r
-  case BM_FILE_CONTEXT_SELECT:\r
-    ContextSize = sizeof (BM_FILE_CONTEXT);\r
-    break;\r
-\r
-  case BM_CONSOLE_CONTEXT_SELECT:\r
-    ContextSize = sizeof (BM_CONSOLE_CONTEXT);\r
-    break;\r
-\r
-  case BM_TERMINAL_CONTEXT_SELECT:\r
-    ContextSize = sizeof (BM_TERMINAL_CONTEXT);\r
-    break;\r
-\r
-  case BM_HANDLE_CONTEXT_SELECT:\r
-    ContextSize = sizeof (BM_HANDLE_CONTEXT);\r
-    break;\r
-\r
-  case BM_LEGACY_DEV_CONTEXT_SELECT:\r
-    ContextSize = sizeof (BM_LEGACY_DEVICE_CONTEXT);\r
-    break;\r
-\r
-  default:\r
-    ContextSize = 0;\r
-    break;\r
-  }\r
-\r
-  if (ContextSize == 0) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Create new menu entry\r
-  //\r
-  MenuEntry = AllocateZeroPool (sizeof (BM_MENU_ENTRY));\r
-  if (MenuEntry == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  MenuEntry->VariableContext = AllocateZeroPool (ContextSize);\r
-  if (MenuEntry->VariableContext == NULL) {\r
-    FreePool (MenuEntry);\r
-    return NULL;\r
-  }\r
-\r
-  MenuEntry->Signature        = BM_MENU_ENTRY_SIGNATURE;\r
-  MenuEntry->ContextSelection = MenuType;\r
-  return MenuEntry;\r
-}\r
-\r
-/**\r
-  Free up all resource allocated for a BM_MENU_ENTRY.\r
-\r
-  @param MenuEntry   A pointer to BM_MENU_ENTRY.\r
-\r
-**/\r
-VOID\r
-BOpt_DestroyMenuEntry (\r
-  BM_MENU_ENTRY         *MenuEntry\r
-  )\r
-{\r
-  BM_LOAD_CONTEXT           *LoadContext;\r
-  BM_FILE_CONTEXT           *FileContext;\r
-  BM_CONSOLE_CONTEXT        *ConsoleContext;\r
-  BM_TERMINAL_CONTEXT       *TerminalContext;\r
-  BM_HANDLE_CONTEXT         *HandleContext;\r
-  BM_LEGACY_DEVICE_CONTEXT  *LegacyDevContext;\r
-\r
-  //\r
-  //  Select by the type in Menu entry for current context type\r
-  //\r
-  switch (MenuEntry->ContextSelection) {\r
-  case BM_LOAD_CONTEXT_SELECT:\r
-    LoadContext = (BM_LOAD_CONTEXT *) MenuEntry->VariableContext;\r
-    FreePool (LoadContext->FilePathList);\r
-    FreePool (LoadContext->LoadOption);\r
-    if (LoadContext->OptionalData != NULL) {\r
-      FreePool (LoadContext->OptionalData);\r
-    }\r
-    FreePool (LoadContext);\r
-    break;\r
-\r
-  case BM_FILE_CONTEXT_SELECT:\r
-    FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;\r
-\r
-    if (!FileContext->IsRoot) {\r
-      FreePool (FileContext->DevicePath);\r
-    } else {\r
-      if (FileContext->FHandle != NULL) {\r
-        FileContext->FHandle->Close (FileContext->FHandle);\r
-      }\r
-    }\r
-\r
-    if (FileContext->FileName != NULL) {\r
-      FreePool (FileContext->FileName);\r
-    }\r
-    if (FileContext->Info != NULL) {\r
-      FreePool (FileContext->Info);\r
-    }\r
-    FreePool (FileContext);\r
-    break;\r
-\r
-  case BM_CONSOLE_CONTEXT_SELECT:\r
-    ConsoleContext = (BM_CONSOLE_CONTEXT *) MenuEntry->VariableContext;\r
-    FreePool (ConsoleContext->DevicePath);\r
-    FreePool (ConsoleContext);\r
-    break;\r
-\r
-  case BM_TERMINAL_CONTEXT_SELECT:\r
-    TerminalContext = (BM_TERMINAL_CONTEXT *) MenuEntry->VariableContext;\r
-    FreePool (TerminalContext->DevicePath);\r
-    FreePool (TerminalContext);\r
-    break;\r
-\r
-  case BM_HANDLE_CONTEXT_SELECT:\r
-    HandleContext = (BM_HANDLE_CONTEXT *) MenuEntry->VariableContext;\r
-    FreePool (HandleContext);\r
-    break;\r
-\r
-  case BM_LEGACY_DEV_CONTEXT_SELECT:\r
-    LegacyDevContext = (BM_LEGACY_DEVICE_CONTEXT *) MenuEntry->VariableContext;\r
-    FreePool (LegacyDevContext);\r
-\r
-  default:\r
-    break;\r
-  }\r
-\r
-  FreePool (MenuEntry->DisplayString);\r
-  if (MenuEntry->HelpString != NULL) {\r
-    FreePool (MenuEntry->HelpString);\r
-  }\r
-\r
-  FreePool (MenuEntry);\r
-}\r
-\r
-/**\r
-  Get the Menu Entry from the list in Menu Entry List.\r
-\r
-  If MenuNumber is great or equal to the number of Menu\r
-  Entry in the list, then ASSERT.\r
-\r
-  @param MenuOption      The Menu Entry List to read the menu entry.\r
-  @param MenuNumber      The index of Menu Entry.\r
-\r
-  @return The Menu Entry.\r
-\r
-**/\r
-BM_MENU_ENTRY *\r
-BOpt_GetMenuEntry (\r
-  BM_MENU_OPTION      *MenuOption,\r
-  UINTN               MenuNumber\r
-  )\r
-{\r
-  BM_MENU_ENTRY   *NewMenuEntry;\r
-  UINTN           Index;\r
-  LIST_ENTRY      *List;\r
-\r
-  ASSERT (MenuNumber < MenuOption->MenuNumber);\r
-\r
-  List = MenuOption->Head.ForwardLink;\r
-  for (Index = 0; Index < MenuNumber; Index++) {\r
-    List = List->ForwardLink;\r
-  }\r
-\r
-  NewMenuEntry = CR (List, BM_MENU_ENTRY, Link, BM_MENU_ENTRY_SIGNATURE);\r
-\r
-  return NewMenuEntry;\r
-}\r
-\r
-/**\r
-  This function build the FsOptionMenu list which records all\r
-  available file system in the system. They includes all instances\r
-  of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, all instances of EFI_LOAD_FILE_SYSTEM\r
-  and all type of legacy boot device.\r
-\r
-  @param CallbackData    BMM context data\r
-\r
-  @retval  EFI_SUCCESS             Success find the file system\r
-  @retval  EFI_OUT_OF_RESOURCES    Can not create menu entry\r
-\r
-**/\r
-EFI_STATUS\r
-BOpt_FindFileSystem (\r
-  IN BMM_CALLBACK_DATA          *CallbackData\r
-  )\r
-{\r
-  UINTN                     NoBlkIoHandles;\r
-  UINTN                     NoSimpleFsHandles;\r
-  UINTN                     NoLoadFileHandles;\r
-  EFI_HANDLE                *BlkIoHandle;\r
-  EFI_HANDLE                *SimpleFsHandle;\r
-  EFI_HANDLE                *LoadFileHandle;\r
-  UINT16                    *VolumeLabel;\r
-  EFI_BLOCK_IO_PROTOCOL     *BlkIo;\r
-  UINTN                     Index;\r
-  EFI_STATUS                Status;\r
-  BM_MENU_ENTRY             *MenuEntry;\r
-  BM_FILE_CONTEXT           *FileContext;\r
-  UINT16                    *TempStr;\r
-  UINTN                     OptionNumber;\r
-  VOID                      *Buffer;\r
-  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;\r
-  UINT16                    DeviceType;\r
-  BBS_BBS_DEVICE_PATH       BbsDevicePathNode;\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
-  BOOLEAN                   RemovableMedia;\r
-\r
-\r
-  NoSimpleFsHandles = 0;\r
-  NoLoadFileHandles = 0;\r
-  OptionNumber      = 0;\r
-  InitializeListHead (&FsOptionMenu.Head);\r
-\r
-  //\r
-  // Locate Handles that support BlockIo protocol\r
-  //\r
-  Status = gBS->LocateHandleBuffer (\r
-                  ByProtocol,\r
-                  &gEfiBlockIoProtocolGuid,\r
-                  NULL,\r
-                  &NoBlkIoHandles,\r
-                  &BlkIoHandle\r
-                  );\r
-  if (!EFI_ERROR (Status)) {\r
-\r
-    for (Index = 0; Index < NoBlkIoHandles; Index++) {\r
-      Status = gBS->HandleProtocol (\r
-                      BlkIoHandle[Index],\r
-                      &gEfiBlockIoProtocolGuid,\r
-                      (VOID **) &BlkIo\r
-                      );\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        continue;\r
-      }\r
-\r
-      //\r
-      // Issue a dummy read to trigger reinstall of BlockIo protocol for removable media\r
-      //\r
-      if (BlkIo->Media->RemovableMedia) {\r
-        Buffer = AllocateZeroPool (BlkIo->Media->BlockSize);\r
-        if (NULL == Buffer) {\r
-          FreePool (BlkIoHandle);\r
-          return EFI_OUT_OF_RESOURCES;\r
-        }\r
-\r
-        BlkIo->ReadBlocks (\r
-                BlkIo,\r
-                BlkIo->Media->MediaId,\r
-                0,\r
-                BlkIo->Media->BlockSize,\r
-                Buffer\r
-                );\r
-        FreePool (Buffer);\r
-      }\r
-    }\r
-    FreePool (BlkIoHandle);\r
-  }\r
-\r
-  //\r
-  // Locate Handles that support Simple File System protocol\r
-  //\r
-  Status = gBS->LocateHandleBuffer (\r
-                  ByProtocol,\r
-                  &gEfiSimpleFileSystemProtocolGuid,\r
-                  NULL,\r
-                  &NoSimpleFsHandles,\r
-                  &SimpleFsHandle\r
-                  );\r
-  if (!EFI_ERROR (Status)) {\r
-    //\r
-    // Find all the instances of the File System prototocol\r
-    //\r
-    for (Index = 0; Index < NoSimpleFsHandles; Index++) {\r
-      Status = gBS->HandleProtocol (\r
-                      SimpleFsHandle[Index],\r
-                      &gEfiBlockIoProtocolGuid,\r
-                      (VOID **) &BlkIo\r
-                      );\r
-      if (EFI_ERROR (Status)) {\r
-        //\r
-        // If no block IO exists assume it's NOT a removable media\r
-        //\r
-        RemovableMedia = FALSE;\r
-      } else {\r
-        //\r
-        // If block IO exists check to see if it's remobable media\r
-        //\r
-        RemovableMedia = BlkIo->Media->RemovableMedia;\r
-      }\r
-\r
-      //\r
-      // Allocate pool for this load option\r
-      //\r
-      MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);\r
-      if (NULL == MenuEntry) {\r
-        FreePool (SimpleFsHandle);\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-\r
-      FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;\r
-\r
-      FileContext->Handle     = SimpleFsHandle[Index];\r
-      MenuEntry->OptionNumber = Index;\r
-      FileContext->FHandle    = EfiLibOpenRoot (FileContext->Handle);\r
-      if (FileContext->FHandle == NULL) {\r
-        BOpt_DestroyMenuEntry (MenuEntry);\r
-        continue;\r
-      }\r
-\r
-      MenuEntry->HelpString = DevicePathToStr (DevicePathFromHandle (FileContext->Handle));\r
-      FileContext->Info = EfiLibFileSystemVolumeLabelInfo (FileContext->FHandle);\r
-      FileContext->FileName = EfiStrDuplicate (L"\\");\r
-      FileContext->DevicePath = FileDevicePath (\r
-                                  FileContext->Handle,\r
-                                  FileContext->FileName\r
-                                  );\r
-      FileContext->IsDir            = TRUE;\r
-      FileContext->IsRoot           = TRUE;\r
-      FileContext->IsRemovableMedia = RemovableMedia;\r
-      FileContext->IsLoadFile       = FALSE;\r
-\r
-      //\r
-      // Get current file system's Volume Label\r
-      //\r
-      if (FileContext->Info == NULL) {\r
-        VolumeLabel = L"NO FILE SYSTEM INFO";\r
-      } else {\r
-        VolumeLabel = FileContext->Info->VolumeLabel;\r
-        if (*VolumeLabel == 0x0000) {\r
-          VolumeLabel = L"NO VOLUME LABEL";\r
-        }\r
-      }\r
-\r
-      TempStr                   = MenuEntry->HelpString;\r
-      MenuEntry->DisplayString  = AllocateZeroPool (MAX_CHAR);\r
-      ASSERT (MenuEntry->DisplayString != NULL);\r
-      UnicodeSPrint (\r
-        MenuEntry->DisplayString,\r
-        MAX_CHAR,\r
-        L"%s, [%s]",\r
-        VolumeLabel,\r
-        TempStr\r
-        );\r
-      OptionNumber++;\r
-      InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link);\r
-    }\r
-  }\r
-\r
-  if (NoSimpleFsHandles != 0) {\r
-    FreePool (SimpleFsHandle);\r
-  }\r
-  //\r
-  // Searching for handles that support Load File protocol\r
-  //\r
-  Status = gBS->LocateHandleBuffer (\r
-                  ByProtocol,\r
-                  &gEfiLoadFileProtocolGuid,\r
-                  NULL,\r
-                  &NoLoadFileHandles,\r
-                  &LoadFileHandle\r
-                  );\r
-\r
-  if (!EFI_ERROR (Status)) {\r
-    for (Index = 0; Index < NoLoadFileHandles; Index++) {\r
-      MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);\r
-      if (NULL == MenuEntry) {\r
-        FreePool (LoadFileHandle);\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-\r
-      FileContext                   = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;\r
-      FileContext->IsRemovableMedia = FALSE;\r
-      FileContext->IsLoadFile       = TRUE;\r
-      FileContext->Handle           = LoadFileHandle[Index];\r
-      FileContext->IsRoot           = TRUE;\r
-\r
-      FileContext->DevicePath       = DevicePathFromHandle (FileContext->Handle);\r
-      FileContext->FileName         = DevicePathToStr (FileContext->DevicePath);\r
-\r
-      MenuEntry->HelpString     = DevicePathToStr (FileContext->DevicePath);\r
-\r
-      TempStr                   = MenuEntry->HelpString;\r
-      MenuEntry->DisplayString  = AllocateZeroPool (MAX_CHAR);\r
-      ASSERT (MenuEntry->DisplayString != NULL);\r
-      UnicodeSPrint (\r
-        MenuEntry->DisplayString,\r
-        MAX_CHAR,\r
-        L"Load File [%s]",\r
-        TempStr\r
-        );\r
-\r
-      MenuEntry->OptionNumber = OptionNumber;\r
-      OptionNumber++;\r
-      InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link);\r
-    }\r
-  }\r
-\r
-  if (NoLoadFileHandles != 0) {\r
-    FreePool (LoadFileHandle);\r
-  }\r
-\r
-  //\r
-  // Add Legacy Boot Option Support Here\r
-  //\r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiLegacyBiosProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) &LegacyBios\r
-                  );\r
-  if (!EFI_ERROR (Status)) {\r
-\r
-    for (Index = BBS_TYPE_FLOPPY; Index <= BBS_TYPE_EMBEDDED_NETWORK; Index++) {\r
-      MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);\r
-      if (NULL == MenuEntry) {\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-\r
-      FileContext                       = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;\r
-\r
-      FileContext->IsRemovableMedia     = FALSE;\r
-      FileContext->IsLoadFile           = TRUE;\r
-      FileContext->IsBootLegacy         = TRUE;\r
-      DeviceType                        = (UINT16) Index;\r
-      BbsDevicePathNode.Header.Type     = BBS_DEVICE_PATH;\r
-      BbsDevicePathNode.Header.SubType  = BBS_BBS_DP;\r
-      SetDevicePathNodeLength (\r
-        &BbsDevicePathNode.Header,\r
-        sizeof (BBS_BBS_DEVICE_PATH)\r
-        );\r
-      BbsDevicePathNode.DeviceType  = DeviceType;\r
-      BbsDevicePathNode.StatusFlag  = 0;\r
-      BbsDevicePathNode.String[0]   = 0;\r
-      DevicePath = AppendDevicePathNode (\r
-                    EndDevicePath,\r
-                    (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevicePathNode\r
-                    );\r
-\r
-      FileContext->DevicePath   = DevicePath;\r
-      MenuEntry->HelpString     = DevicePathToStr (FileContext->DevicePath);\r
-\r
-      TempStr                   = MenuEntry->HelpString;\r
-      MenuEntry->DisplayString  = AllocateZeroPool (MAX_CHAR);\r
-      ASSERT (MenuEntry->DisplayString != NULL);\r
-      UnicodeSPrint (\r
-        MenuEntry->DisplayString,\r
-        MAX_CHAR,\r
-        L"Boot Legacy [%s]",\r
-        TempStr\r
-        );\r
-      MenuEntry->OptionNumber = OptionNumber;\r
-      OptionNumber++;\r
-      InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link);\r
-    }\r
-  }\r
-  //\r
-  // Remember how many file system options are here\r
-  //\r
-  FsOptionMenu.MenuNumber = OptionNumber;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Free resources allocated in Allocate Rountine.\r
-\r
-  @param FreeMenu        Menu to be freed\r
-**/\r
-VOID\r
-BOpt_FreeMenu (\r
-  BM_MENU_OPTION        *FreeMenu\r
-  )\r
-{\r
-  BM_MENU_ENTRY *MenuEntry;\r
-  while (!IsListEmpty (&FreeMenu->Head)) {\r
-    MenuEntry = CR (\r
-                  FreeMenu->Head.ForwardLink,\r
-                  BM_MENU_ENTRY,\r
-                  Link,\r
-                  BM_MENU_ENTRY_SIGNATURE\r
-                  );\r
-    RemoveEntryList (&MenuEntry->Link);\r
-    BOpt_DestroyMenuEntry (MenuEntry);\r
-  }\r
-  FreeMenu->MenuNumber = 0;\r
-}\r
-\r
-/**\r
-  Find files under current directory\r
-  All files and sub-directories in current directory\r
-  will be stored in DirectoryMenu for future use.\r
-\r
-  @param CallbackData  The BMM context data.\r
-  @param MenuEntry     The Menu Entry.\r
-\r
-  @retval EFI_SUCCESS         Get files from current dir successfully.\r
-  @return Other value if can't get files from current dir.\r
-\r
-**/\r
-EFI_STATUS\r
-BOpt_FindFiles (\r
-  IN BMM_CALLBACK_DATA          *CallbackData,\r
-  IN BM_MENU_ENTRY              *MenuEntry\r
-  )\r
-{\r
-  EFI_FILE_HANDLE NewDir;\r
-  EFI_FILE_HANDLE Dir;\r
-  EFI_FILE_INFO   *DirInfo;\r
-  UINTN           BufferSize;\r
-  UINTN           DirBufferSize;\r
-  BM_MENU_ENTRY   *NewMenuEntry;\r
-  BM_FILE_CONTEXT *FileContext;\r
-  BM_FILE_CONTEXT *NewFileContext;\r
-  UINTN           Pass;\r
-  EFI_STATUS      Status;\r
-  UINTN           OptionNumber;\r
-\r
-  FileContext   = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;\r
-  Dir           = FileContext->FHandle;\r
-  OptionNumber  = 0;\r
-  //\r
-  // Open current directory to get files from it\r
-  //\r
-  Status = Dir->Open (\r
-                  Dir,\r
-                  &NewDir,\r
-                  FileContext->FileName,\r
-                  EFI_FILE_READ_ONLY,\r
-                  0\r
-                  );\r
-  if (!FileContext->IsRoot) {\r
-    Dir->Close (Dir);\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  DirInfo = EfiLibFileInfo (NewDir);\r
-  if (DirInfo == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  if ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  FileContext->DevicePath = FileDevicePath (\r
-                              FileContext->Handle,\r
-                              FileContext->FileName\r
-                              );\r
-\r
-  DirBufferSize = sizeof (EFI_FILE_INFO) + 1024;\r
-  DirInfo       = AllocateZeroPool (DirBufferSize);\r
-  if (DirInfo == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  //\r
-  // Get all files in current directory\r
-  // Pass 1 to get Directories\r
-  // Pass 2 to get files that are EFI images\r
-  //\r
-  for (Pass = 1; Pass <= 2; Pass++) {\r
-    NewDir->SetPosition (NewDir, 0);\r
-    for (;;) {\r
-      BufferSize  = DirBufferSize;\r
-      Status      = NewDir->Read (NewDir, &BufferSize, DirInfo);\r
-      if (EFI_ERROR (Status) || BufferSize == 0) {\r
-        break;\r
-      }\r
-\r
-      if (((DirInfo->Attribute & EFI_FILE_DIRECTORY) != 0 && Pass == 2) ||\r
-          ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0 && Pass == 1)\r
-          ) {\r
-        //\r
-        // Pass 1 is for Directories\r
-        // Pass 2 is for file names\r
-        //\r
-        continue;\r
-      }\r
-\r
-      if (!(BOpt_IsEfiImageName (DirInfo->FileName) || (DirInfo->Attribute & EFI_FILE_DIRECTORY) != 0)) {\r
-        //\r
-        // Slip file unless it is a directory entry or a .EFI file\r
-        //\r
-        continue;\r
-      }\r
-\r
-      NewMenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);\r
-      if (NULL == NewMenuEntry) {\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-\r
-      NewFileContext          = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
-      NewFileContext->Handle  = FileContext->Handle;\r
-      NewFileContext->FileName = BOpt_AppendFileName (\r
-                                  FileContext->FileName,\r
-                                  DirInfo->FileName\r
-                                  );\r
-      NewFileContext->FHandle = NewDir;\r
-      NewFileContext->DevicePath = FileDevicePath (\r
-                                    NewFileContext->Handle,\r
-                                    NewFileContext->FileName\r
-                                    );\r
-      NewMenuEntry->HelpString = NULL;\r
-\r
-      MenuEntry->DisplayStringToken = GetStringTokenFromDepository (\r
-                                        CallbackData,\r
-                                        FileOptionStrDepository\r
-                                        );\r
-\r
-      NewFileContext->IsDir = (BOOLEAN) ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY);\r
-\r
-      if (NewFileContext->IsDir) {\r
-        BufferSize                  = StrLen (DirInfo->FileName) * 2 + 6;\r
-        NewMenuEntry->DisplayString = AllocateZeroPool (BufferSize);\r
-\r
-        UnicodeSPrint (\r
-          NewMenuEntry->DisplayString,\r
-          BufferSize,\r
-          L"<%s>",\r
-          DirInfo->FileName\r
-          );\r
-\r
-      } else {\r
-        NewMenuEntry->DisplayString = EfiStrDuplicate (DirInfo->FileName);\r
-      }\r
-\r
-      NewFileContext->IsRoot            = FALSE;\r
-      NewFileContext->IsLoadFile        = FALSE;\r
-      NewFileContext->IsRemovableMedia  = FALSE;\r
-\r
-      NewMenuEntry->OptionNumber        = OptionNumber;\r
-      OptionNumber++;\r
-      InsertTailList (&DirectoryMenu.Head, &NewMenuEntry->Link);\r
-    }\r
-  }\r
-\r
-  DirectoryMenu.MenuNumber = OptionNumber;\r
-  FreePool (DirInfo);\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Build the LegacyFDMenu LegacyHDMenu LegacyCDMenu according to LegacyBios.GetBbsInfo().\r
-\r
-  @retval EFI_SUCCESS The function complete successfully.\r
-  @retval EFI_OUT_OF_RESOURCES No enough memory to complete this function.\r
-\r
-**/\r
-EFI_STATUS\r
-BOpt_GetLegacyOptions (\r
-  VOID\r
-  )\r
-{\r
-  BM_MENU_ENTRY             *NewMenuEntry;\r
-  BM_LEGACY_DEVICE_CONTEXT  *NewLegacyDevContext;\r
-  EFI_STATUS                Status;\r
-  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;\r
-  UINT16                    HddCount;\r
-  HDD_INFO                  *HddInfo;\r
-  UINT16                    BbsCount;\r
-  BBS_TABLE                 *BbsTable;\r
-  UINT16                    Index;\r
-  CHAR16                    DescString[100];\r
-  UINTN                     FDNum;\r
-  UINTN                     HDNum;\r
-  UINTN                     CDNum;\r
-  UINTN                     NETNum;\r
-  UINTN                     BEVNum;\r
-\r
-  NewMenuEntry  = NULL;\r
-  HddInfo       = NULL;\r
-  BbsTable      = NULL;\r
-  BbsCount      = 0;\r
-\r
-  //\r
-  // Initialize Bbs Table Context from BBS info data\r
-  //\r
-  InitializeListHead (&LegacyFDMenu.Head);\r
-  InitializeListHead (&LegacyHDMenu.Head);\r
-  InitializeListHead (&LegacyCDMenu.Head);\r
-  InitializeListHead (&LegacyNETMenu.Head);\r
-  InitializeListHead (&LegacyBEVMenu.Head);\r
-\r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiLegacyBiosProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) &LegacyBios\r
-                  );\r
-  if (!EFI_ERROR (Status)) {\r
-    Status = LegacyBios->GetBbsInfo (\r
-                          LegacyBios,\r
-                          &HddCount,\r
-                          &HddInfo,\r
-                          &BbsCount,\r
-                          &BbsTable\r
-                          );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  FDNum   = 0;\r
-  HDNum   = 0;\r
-  CDNum   = 0;\r
-  NETNum  = 0;\r
-  BEVNum  = 0;\r
-\r
-  for (Index = 0; Index < BbsCount; Index++) {\r
-    if ((BBS_IGNORE_ENTRY == BbsTable[Index].BootPriority) ||\r
-        (BBS_DO_NOT_BOOT_FROM == BbsTable[Index].BootPriority)\r
-        ) {\r
-      continue;\r
-    }\r
-\r
-    NewMenuEntry = BOpt_CreateMenuEntry (BM_LEGACY_DEV_CONTEXT_SELECT);\r
-    if (NULL == NewMenuEntry) {\r
-      break;\r
-    }\r
-\r
-    NewLegacyDevContext           = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;\r
-    NewLegacyDevContext->BbsEntry = &BbsTable[Index];\r
-    NewLegacyDevContext->BbsIndex = Index;\r
-    NewLegacyDevContext->BbsCount = BbsCount;\r
-    BdsBuildLegacyDevNameString (\r
-      &BbsTable[Index],\r
-      Index,\r
-      sizeof (DescString),\r
-      DescString\r
-      );\r
-    NewLegacyDevContext->Description = AllocateCopyPool (StrSize (DescString), DescString);\r
-    if (NULL == NewLegacyDevContext->Description) {\r
-      break;\r
-    }\r
-\r
-    NewMenuEntry->DisplayString = NewLegacyDevContext->Description;\r
-    NewMenuEntry->HelpString    = NULL;\r
-\r
-    switch (BbsTable[Index].DeviceType) {\r
-    case BBS_FLOPPY:\r
-      InsertTailList (&LegacyFDMenu.Head, &NewMenuEntry->Link);\r
-      FDNum++;\r
-      break;\r
-\r
-    case BBS_HARDDISK:\r
-      InsertTailList (&LegacyHDMenu.Head, &NewMenuEntry->Link);\r
-      HDNum++;\r
-      break;\r
-\r
-    case BBS_CDROM:\r
-      InsertTailList (&LegacyCDMenu.Head, &NewMenuEntry->Link);\r
-      CDNum++;\r
-      break;\r
-\r
-    case BBS_EMBED_NETWORK:\r
-      InsertTailList (&LegacyNETMenu.Head, &NewMenuEntry->Link);\r
-      NETNum++;\r
-      break;\r
-\r
-    case BBS_BEV_DEVICE:\r
-      InsertTailList (&LegacyBEVMenu.Head, &NewMenuEntry->Link);\r
-      BEVNum++;\r
-      break;\r
-    }\r
-  }\r
-\r
-  if (Index != BbsCount) {\r
-    BOpt_FreeLegacyOptions ();\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  LegacyFDMenu.MenuNumber   = FDNum;\r
-  LegacyHDMenu.MenuNumber   = HDNum;\r
-  LegacyCDMenu.MenuNumber   = CDNum;\r
-  LegacyNETMenu.MenuNumber  = NETNum;\r
-  LegacyBEVMenu.MenuNumber  = BEVNum;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Free out resouce allocated from Legacy Boot Options.\r
-\r
-**/\r
-VOID\r
-BOpt_FreeLegacyOptions (\r
-  VOID\r
-  )\r
-{\r
-  BOpt_FreeMenu (&LegacyFDMenu);\r
-  BOpt_FreeMenu (&LegacyHDMenu);\r
-  BOpt_FreeMenu (&LegacyCDMenu);\r
-  BOpt_FreeMenu (&LegacyNETMenu);\r
-  BOpt_FreeMenu (&LegacyBEVMenu);\r
-}\r
-\r
-/**\r
-\r
-  Build the BootOptionMenu according to BootOrder Variable.\r
-  This Routine will access the Boot#### to get EFI_LOAD_OPTION.\r
-\r
-  @param CallbackData The BMM context data.\r
-\r
-  @return EFI_NOT_FOUND Fail to find "BootOrder" variable.\r
-  @return EFI_SUCESS    Success build boot option menu.\r
-\r
-**/\r
-EFI_STATUS\r
-BOpt_GetBootOptions (\r
-  IN  BMM_CALLBACK_DATA         *CallbackData\r
-  )\r
-{\r
-  UINTN                     Index;\r
-  UINT16                    BootString[10];\r
-  UINT8                     *LoadOptionFromVar;\r
-  UINT8                     *LoadOption;\r
-  UINTN                     BootOptionSize;\r
-  BOOLEAN                   BootNextFlag;\r
-  UINT16                    *BootOrderList;\r
-  UINTN                     BootOrderListSize;\r
-  UINT16                    *BootNext;\r
-  UINTN                     BootNextSize;\r
-  BM_MENU_ENTRY             *NewMenuEntry;\r
-  BM_LOAD_CONTEXT           *NewLoadContext;\r
-  UINT8                     *LoadOptionPtr;\r
-  UINTN                     StringSize;\r
-  UINTN                     OptionalDataSize;\r
-  UINT8                     *LoadOptionEnd;\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
-  UINTN                     MenuCount;\r
-  UINT8                     *Ptr;\r
-\r
-  MenuCount         = 0;\r
-  BootOrderListSize = 0;\r
-  BootNextSize      = 0;\r
-  BootOrderList     = NULL;\r
-  BootNext          = NULL;\r
-  LoadOptionFromVar = NULL;\r
-  BOpt_FreeMenu (&BootOptionMenu);\r
-  InitializeListHead (&BootOptionMenu.Head);\r
-\r
-  //\r
-  // Get the BootOrder from the Var\r
-  //\r
-  BootOrderList = BdsLibGetVariableAndSize (\r
-                    L"BootOrder",\r
-                    &gEfiGlobalVariableGuid,\r
-                    &BootOrderListSize\r
-                    );\r
-  if (BootOrderList == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // Get the BootNext from the Var\r
-  //\r
-  BootNext = BdsLibGetVariableAndSize (\r
-              L"BootNext",\r
-              &gEfiGlobalVariableGuid,\r
-              &BootNextSize\r
-              );\r
-\r
-  if (BootNext != NULL) {\r
-    if (BootNextSize != sizeof (UINT16)) {\r
-      FreePool (BootNext);\r
-      BootNext = NULL;\r
-    }\r
-  }\r
-\r
-  for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) {\r
-    UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", BootOrderList[Index]);\r
-    //\r
-    //  Get all loadoptions from the VAR\r
-    //\r
-    LoadOptionFromVar = BdsLibGetVariableAndSize (\r
-                          BootString,\r
-                          &gEfiGlobalVariableGuid,\r
-                          &BootOptionSize\r
-                          );\r
-    if (LoadOptionFromVar == NULL) {\r
-      continue;\r
-    }\r
-\r
-    LoadOption = AllocateZeroPool (BootOptionSize);\r
-    if (LoadOption == NULL) {\r
-      continue;\r
-    }\r
-\r
-    CopyMem (LoadOption, LoadOptionFromVar, BootOptionSize);\r
-    FreePool (LoadOptionFromVar);\r
-\r
-    if (BootNext != NULL) {\r
-      BootNextFlag = (BOOLEAN) (*BootNext == BootOrderList[Index]);\r
-    } else {\r
-      BootNextFlag = FALSE;\r
-    }\r
-\r
-    if (0 == (*((UINT32 *) LoadOption) & LOAD_OPTION_ACTIVE)) {\r
-      FreePool (LoadOption);\r
-      continue;\r
-    }\r
-    //\r
-    // BUGBUG: could not return EFI_OUT_OF_RESOURCES here directly.\r
-    // the buffer allocated already should be freed before returning.\r
-    //\r
-    NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);\r
-    if (NULL == NewMenuEntry) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-\r
-    NewLoadContext                      = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
-\r
-    LoadOptionPtr                       = LoadOption;\r
-    LoadOptionEnd                       = LoadOption + BootOptionSize;\r
-\r
-    NewMenuEntry->OptionNumber          = BootOrderList[Index];\r
-    NewLoadContext->LoadOptionModified  = FALSE;\r
-    NewLoadContext->Deleted             = FALSE;\r
-    NewLoadContext->IsBootNext          = BootNextFlag;\r
-\r
-    //\r
-    // Is a Legacy Device?\r
-    //\r
-    Ptr = (UINT8 *) LoadOption;\r
-\r
-    //\r
-    // Attribute = *(UINT32 *)Ptr;\r
-    //\r
-    Ptr += sizeof (UINT32);\r
-\r
-    //\r
-    // FilePathSize = *(UINT16 *)Ptr;\r
-    //\r
-    Ptr += sizeof (UINT16);\r
-\r
-    //\r
-    // Description = (CHAR16 *)Ptr;\r
-    //\r
-    Ptr += StrSize ((CHAR16 *) Ptr);\r
-\r
-    //\r
-    // Now Ptr point to Device Path\r
-    //\r
-    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;\r
-    if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) {\r
-      NewLoadContext->IsLegacy = TRUE;\r
-    } else {\r
-      NewLoadContext->IsLegacy = FALSE;\r
-    }\r
-    //\r
-    // LoadOption is a pointer type of UINT8\r
-    // for easy use with following LOAD_OPTION\r
-    // embedded in this struct\r
-    //\r
-    NewLoadContext->LoadOption      = LoadOption;\r
-    NewLoadContext->LoadOptionSize  = BootOptionSize;\r
-\r
-    NewLoadContext->Attributes      = *(UINT32 *) LoadOptionPtr;\r
-    NewLoadContext->IsActive        = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_ACTIVE);\r
-\r
-    NewLoadContext->ForceReconnect  = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);\r
-\r
-    LoadOptionPtr += sizeof (UINT32);\r
-\r
-    NewLoadContext->FilePathListLength = *(UINT16 *) LoadOptionPtr;\r
-    LoadOptionPtr += sizeof (UINT16);\r
-\r
-    StringSize = StrSize((UINT16*)LoadOptionPtr);\r
-\r
-    NewLoadContext->Description = AllocateCopyPool (StrSize((UINT16*)LoadOptionPtr), LoadOptionPtr);\r
-    ASSERT (NewLoadContext->Description != NULL);\r
-\r
-    NewMenuEntry->DisplayString = NewLoadContext->Description;\r
-\r
-    LoadOptionPtr += StringSize;\r
-\r
-    NewLoadContext->FilePathList = AllocateZeroPool (NewLoadContext->FilePathListLength);\r
-    ASSERT (NewLoadContext->FilePathList != NULL);\r
-    CopyMem (\r
-      NewLoadContext->FilePathList,\r
-      (EFI_DEVICE_PATH_PROTOCOL *) LoadOptionPtr,\r
-      NewLoadContext->FilePathListLength\r
-      );\r
-\r
-    NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);\r
-    NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (\r
-                                        CallbackData,\r
-                                        BootOptionStrDepository\r
-                                        );\r
-    NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (\r
-                                      CallbackData,\r
-                                      BootOptionHelpStrDepository\r
-                                      );\r
-    LoadOptionPtr += NewLoadContext->FilePathListLength;\r
-\r
-    if (LoadOptionPtr < LoadOptionEnd) {\r
-      OptionalDataSize = BootOptionSize -\r
-        sizeof (UINT32) -\r
-        sizeof (UINT16) -\r
-        StringSize -\r
-        NewLoadContext->FilePathListLength;\r
-\r
-      NewLoadContext->OptionalData = AllocateZeroPool (OptionalDataSize);\r
-      ASSERT (NewLoadContext->OptionalData != NULL);\r
-      CopyMem (\r
-        NewLoadContext->OptionalData,\r
-        LoadOptionPtr,\r
-        OptionalDataSize\r
-        );\r
-\r
-      NewLoadContext->OptionalDataSize = OptionalDataSize;\r
-    }\r
-\r
-    InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);\r
-    MenuCount++;\r
-  }\r
-\r
-  if (BootNext != NULL) {\r
-    FreePool (BootNext);\r
-  }\r
-  if (BootOrderList != NULL) {\r
-    FreePool (BootOrderList);\r
-  }\r
-  BootOptionMenu.MenuNumber = MenuCount;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-\r
-  Append file name to existing file name.\r
-\r
-  @param Str1  The existing file name\r
-  @param Str2  The file name to be appended\r
-\r
-  @return Allocate a new string to hold the appended result.\r
-          Caller is responsible to free the returned string.\r
-\r
-**/\r
-CHAR16 *\r
-BOpt_AppendFileName (\r
-  IN  CHAR16  *Str1,\r
-  IN  CHAR16  *Str2\r
-  )\r
-{\r
-  UINTN   Size1;\r
-  UINTN   Size2;\r
-  UINTN   MaxLen;\r
-  CHAR16  *Str;\r
-  CHAR16  *TmpStr;\r
-  CHAR16  *Ptr;\r
-  CHAR16  *LastSlash;\r
-\r
-  Size1 = StrSize (Str1);\r
-  Size2 = StrSize (Str2);\r
-  MaxLen = (Size1 + Size2 + sizeof (CHAR16)) / sizeof (CHAR16);\r
-  Str   = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
-  ASSERT (Str != NULL);\r
-\r
-  TmpStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
-  ASSERT (TmpStr != NULL);\r
-\r
-  StrCatS (Str, MaxLen, Str1);\r
-  if (!((*Str == '\\') && (*(Str + 1) == 0))) {\r
-    StrCatS (Str, MaxLen, L"\\");\r
-  }\r
-\r
-  StrCatS (Str, MaxLen, Str2);\r
-\r
-  Ptr       = Str;\r
-  LastSlash = Str;\r
-  while (*Ptr != 0) {\r
-    if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '.' && *(Ptr + 3) == L'\\') {\r
-      //\r
-      // Convert "\Name\..\" to "\"\r
-      // DO NOT convert the .. if it is at the end of the string. This will\r
-      // break the .. behavior in changing directories.\r
-      //\r
-\r
-      //\r
-      // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings\r
-      // that overlap.\r
-      //\r
-      StrCpyS (TmpStr, MaxLen, Ptr + 3);\r
-      StrCpyS (LastSlash, MaxLen - ((UINTN) LastSlash - (UINTN) Str) / sizeof (CHAR16), TmpStr);\r
-      Ptr = LastSlash;\r
-    } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') {\r
-      //\r
-      // Convert a "\.\" to a "\"\r
-      //\r
-\r
-      //\r
-      // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings\r
-      // that overlap.\r
-      //\r
-      StrCpyS (TmpStr, MaxLen, Ptr + 2);\r
-      StrCpyS (Ptr, MaxLen - ((UINTN) Ptr - (UINTN) Str) / sizeof (CHAR16), TmpStr);\r
-      Ptr = LastSlash;\r
-    } else if (*Ptr == '\\') {\r
-      LastSlash = Ptr;\r
-    }\r
-\r
-    Ptr++;\r
-  }\r
-\r
-  FreePool (TmpStr);\r
-\r
-  return Str;\r
-}\r
-\r
-/**\r
-\r
-  Check whether current FileName point to a valid\r
-  Efi Image File.\r
-\r
-  @param FileName  File need to be checked.\r
-\r
-  @retval TRUE  Is Efi Image\r
-  @retval FALSE Not a valid Efi Image\r
-\r
-**/\r
-BOOLEAN\r
-BOpt_IsEfiImageName (\r
-  IN UINT16  *FileName\r
-  )\r
-{\r
-  //\r
-  // Search for ".efi" extension\r
-  //\r
-  while (*FileName != L'\0') {\r
-    if (FileName[0] == '.') {\r
-      if (FileName[1] == 'e' || FileName[1] == 'E') {\r
-        if (FileName[2] == 'f' || FileName[2] == 'F') {\r
-          if (FileName[3] == 'i' || FileName[3] == 'I') {\r
-            return TRUE;\r
-          } else if (FileName[3] == 0x0000) {\r
-            return FALSE;\r
-          }\r
-        } else if (FileName[2] == 0x0000) {\r
-          return FALSE;\r
-        }\r
-      } else if (FileName[1] == 0x0000) {\r
-        return FALSE;\r
-      }\r
-    }\r
-\r
-    FileName += 1;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-\r
-\r
-/**\r
-\r
-  Find drivers that will be added as Driver#### variables from handles\r
-  in current system environment\r
-  All valid handles in the system except those consume SimpleFs, LoadFile\r
-  are stored in DriverMenu for future use.\r
-\r
-  @retval EFI_SUCCESS The function complets successfully.\r
-  @return Other value if failed to build the DriverMenu.\r
-\r
-**/\r
-EFI_STATUS\r
-BOpt_FindDrivers (\r
-  VOID\r
-  )\r
-{\r
-  UINTN                           NoDevicePathHandles;\r
-  EFI_HANDLE                      *DevicePathHandle;\r
-  UINTN                           Index;\r
-  EFI_STATUS                      Status;\r
-  BM_MENU_ENTRY                   *NewMenuEntry;\r
-  BM_HANDLE_CONTEXT               *NewHandleContext;\r
-  EFI_HANDLE                      CurHandle;\r
-  UINTN                           OptionNumber;\r
-  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs;\r
-  EFI_LOAD_FILE_PROTOCOL          *LoadFile;\r
-\r
-  SimpleFs  = NULL;\r
-  LoadFile  = NULL;\r
-\r
-  InitializeListHead (&DriverMenu.Head);\r
-\r
-  //\r
-  // At first, get all handles that support Device Path\r
-  // protocol which is the basic requirement for\r
-  // Driver####\r
-  //\r
-  Status = gBS->LocateHandleBuffer (\r
-                  ByProtocol,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  NULL,\r
-                  &NoDevicePathHandles,\r
-                  &DevicePathHandle\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  OptionNumber = 0;\r
-  for (Index = 0; Index < NoDevicePathHandles; Index++) {\r
-    CurHandle = DevicePathHandle[Index];\r
-\r
-    Status = gBS->HandleProtocol (\r
-                    CurHandle,\r
-                    &gEfiSimpleFileSystemProtocolGuid,\r
-                    (VOID **) &SimpleFs\r
-                    );\r
-    if (Status == EFI_SUCCESS) {\r
-      continue;\r
-    }\r
-\r
-    Status = gBS->HandleProtocol (\r
-                    CurHandle,\r
-                    &gEfiLoadFileProtocolGuid,\r
-                    (VOID **) &LoadFile\r
-                    );\r
-    if (Status == EFI_SUCCESS) {\r
-      continue;\r
-    }\r
-\r
-    NewMenuEntry = BOpt_CreateMenuEntry (BM_HANDLE_CONTEXT_SELECT);\r
-    if (NULL == NewMenuEntry) {\r
-      FreePool (DevicePathHandle);\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-\r
-    NewHandleContext              = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;\r
-    NewHandleContext->Handle      = CurHandle;\r
-    NewHandleContext->DevicePath  = DevicePathFromHandle (CurHandle);\r
-    NewMenuEntry->DisplayString = DevicePathToStr (NewHandleContext->DevicePath);\r
-    NewMenuEntry->HelpString    = NULL;\r
-    NewMenuEntry->OptionNumber  = OptionNumber;\r
-    OptionNumber++;\r
-    InsertTailList (&DriverMenu.Head, &NewMenuEntry->Link);\r
-\r
-  }\r
-\r
-  if (DevicePathHandle != NULL) {\r
-    FreePool (DevicePathHandle);\r
-  }\r
-\r
-  DriverMenu.MenuNumber = OptionNumber;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-\r
-  Get the Option Number that has not been allocated for use.\r
-\r
-  @param Type  The type of Option.\r
-\r
-  @return The available Option Number.\r
-\r
-**/\r
-UINT16\r
-BOpt_GetOptionNumber (\r
-  CHAR16        *Type\r
-  )\r
-{\r
-  UINT16        *OrderList;\r
-  UINTN         OrderListSize;\r
-  UINTN         Index;\r
-  CHAR16        StrTemp[20];\r
-  UINT16        *OptionBuffer;\r
-  UINT16        OptionNumber;\r
-  UINTN         OptionSize;\r
-\r
-  OrderListSize = 0;\r
-  OrderList     = NULL;\r
-  OptionNumber  = 0;\r
-  Index         = 0;\r
-\r
-  UnicodeSPrint (StrTemp, sizeof (StrTemp), L"%sOrder", Type);\r
-\r
-  OrderList = BdsLibGetVariableAndSize (\r
-                          StrTemp,\r
-                          &gEfiGlobalVariableGuid,\r
-                          &OrderListSize\r
-                          );\r
-\r
-  for (OptionNumber = 0; ; OptionNumber++) {\r
-    if (OrderList != NULL) {\r
-      for (Index = 0; Index < OrderListSize / sizeof (UINT16); Index++) {\r
-        if (OptionNumber == OrderList[Index]) {\r
-          break;\r
-        }\r
-      }\r
-    }\r
-\r
-    if (Index < OrderListSize / sizeof (UINT16)) {\r
-      //\r
-      // The OptionNumber occurs in the OrderList, continue to use next one\r
-      //\r
-      continue;\r
-    }\r
-    UnicodeSPrint (StrTemp, sizeof (StrTemp), L"%s%04x", Type, (UINTN) OptionNumber);\r
-    DEBUG((EFI_D_ERROR,"Option = %s\n", StrTemp));\r
-    OptionBuffer = BdsLibGetVariableAndSize (\r
-                       StrTemp,\r
-                       &gEfiGlobalVariableGuid,\r
-                       &OptionSize\r
-                       );\r
-    if (NULL == OptionBuffer) {\r
-      //\r
-      // The Boot[OptionNumber] / Driver[OptionNumber] NOT occurs, we found it\r
-      //\r
-      break;\r
-    }\r
-  }\r
-\r
-  return OptionNumber;\r
-}\r
-\r
-/**\r
-\r
-  Get the Option Number for Boot#### that does not used.\r
-\r
-  @return The available Option Number.\r
-\r
-**/\r
-UINT16\r
-BOpt_GetBootOptionNumber (\r
-  VOID\r
-  )\r
-{\r
-  return BOpt_GetOptionNumber (L"Boot");\r
-}\r
-\r
-/**\r
-\r
-  Get the Option Number for Driver#### that does not used.\r
-\r
-  @return The unused Option Number.\r
-\r
-**/\r
-UINT16\r
-BOpt_GetDriverOptionNumber (\r
-  VOID\r
-  )\r
-{\r
-  return BOpt_GetOptionNumber (L"Driver");\r
-}\r
-\r
-/**\r
-\r
-  Build up all DriverOptionMenu\r
-\r
-  @param CallbackData The BMM context data.\r
-\r
-  @retval EFI_SUCESS           The functin completes successfully.\r
-  @retval EFI_OUT_OF_RESOURCES Not enough memory to compete the operation.\r
-  @retval EFI_NOT_FOUND        Fail to get "DriverOrder" variable.\r
-\r
-**/\r
-EFI_STATUS\r
-BOpt_GetDriverOptions (\r
-  IN  BMM_CALLBACK_DATA         *CallbackData\r
-  )\r
-{\r
-  UINTN           Index;\r
-  UINT16          DriverString[12];\r
-  UINT8           *LoadOptionFromVar;\r
-  UINT8           *LoadOption;\r
-  UINTN           DriverOptionSize;\r
-\r
-  UINT16          *DriverOrderList;\r
-  UINTN           DriverOrderListSize;\r
-  BM_MENU_ENTRY   *NewMenuEntry;\r
-  BM_LOAD_CONTEXT *NewLoadContext;\r
-  UINT8           *LoadOptionPtr;\r
-  UINTN           StringSize;\r
-  UINTN           OptionalDataSize;\r
-  UINT8           *LoadOptionEnd;\r
-\r
-  DriverOrderListSize = 0;\r
-  DriverOrderList     = NULL;\r
-  DriverOptionSize    = 0;\r
-  LoadOptionFromVar   = NULL;\r
-  BOpt_FreeMenu (&DriverOptionMenu);\r
-  InitializeListHead (&DriverOptionMenu.Head);\r
-  //\r
-  // Get the DriverOrder from the Var\r
-  //\r
-  DriverOrderList = BdsLibGetVariableAndSize (\r
-                      L"DriverOrder",\r
-                      &gEfiGlobalVariableGuid,\r
-                      &DriverOrderListSize\r
-                      );\r
-  if (DriverOrderList == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  for (Index = 0; Index < DriverOrderListSize / sizeof (UINT16); Index++) {\r
-    UnicodeSPrint (\r
-      DriverString,\r
-      sizeof (DriverString),\r
-      L"Driver%04x",\r
-      DriverOrderList[Index]\r
-      );\r
-    //\r
-    //  Get all loadoptions from the VAR\r
-    //\r
-    LoadOptionFromVar = BdsLibGetVariableAndSize (\r
-                          DriverString,\r
-                          &gEfiGlobalVariableGuid,\r
-                          &DriverOptionSize\r
-                          );\r
-    if (LoadOptionFromVar == NULL) {\r
-      continue;\r
-    }\r
-\r
-    LoadOption = AllocateZeroPool (DriverOptionSize);\r
-    if (LoadOption == NULL) {\r
-      continue;\r
-    }\r
-\r
-    CopyMem (LoadOption, LoadOptionFromVar, DriverOptionSize);\r
-    FreePool (LoadOptionFromVar);\r
-\r
-    NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);\r
-    if (NULL == NewMenuEntry) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-\r
-    NewLoadContext                      = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
-    LoadOptionPtr                       = LoadOption;\r
-    LoadOptionEnd                       = LoadOption + DriverOptionSize;\r
-    NewMenuEntry->OptionNumber          = DriverOrderList[Index];\r
-    NewLoadContext->LoadOptionModified  = FALSE;\r
-    NewLoadContext->Deleted             = FALSE;\r
-    NewLoadContext->IsLegacy            = FALSE;\r
-\r
-    //\r
-    // LoadOption is a pointer type of UINT8\r
-    // for easy use with following LOAD_OPTION\r
-    // embedded in this struct\r
-    //\r
-    NewLoadContext->LoadOption      = LoadOption;\r
-    NewLoadContext->LoadOptionSize  = DriverOptionSize;\r
-\r
-    NewLoadContext->Attributes      = *(UINT32 *) LoadOptionPtr;\r
-    NewLoadContext->IsActive        = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_ACTIVE);\r
-\r
-    NewLoadContext->ForceReconnect  = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);\r
-\r
-    LoadOptionPtr += sizeof (UINT32);\r
-\r
-    NewLoadContext->FilePathListLength = *(UINT16 *) LoadOptionPtr;\r
-    LoadOptionPtr += sizeof (UINT16);\r
-\r
-    StringSize                  = StrSize ((UINT16 *) LoadOptionPtr);\r
-    NewLoadContext->Description = AllocateZeroPool (StringSize);\r
-    ASSERT (NewLoadContext->Description != NULL);\r
-    CopyMem (\r
-      NewLoadContext->Description,\r
-      (UINT16 *) LoadOptionPtr,\r
-      StringSize\r
-      );\r
-    NewMenuEntry->DisplayString = NewLoadContext->Description;\r
-\r
-    LoadOptionPtr += StringSize;\r
-\r
-    NewLoadContext->FilePathList = AllocateZeroPool (NewLoadContext->FilePathListLength);\r
-    ASSERT (NewLoadContext->FilePathList != NULL);\r
-    CopyMem (\r
-      NewLoadContext->FilePathList,\r
-      (EFI_DEVICE_PATH_PROTOCOL *) LoadOptionPtr,\r
-      NewLoadContext->FilePathListLength\r
-      );\r
-\r
-    NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);\r
-    NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (\r
-                                        CallbackData,\r
-                                        DriverOptionStrDepository\r
-                                        );\r
-    NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (\r
-                                      CallbackData,\r
-                                      DriverOptionHelpStrDepository\r
-                                      );\r
-    LoadOptionPtr += NewLoadContext->FilePathListLength;\r
-\r
-    if (LoadOptionPtr < LoadOptionEnd) {\r
-      OptionalDataSize = DriverOptionSize -\r
-        sizeof (UINT32) -\r
-        sizeof (UINT16) -\r
-        StringSize -\r
-        NewLoadContext->FilePathListLength;\r
-\r
-      NewLoadContext->OptionalData = AllocateZeroPool (OptionalDataSize);\r
-      ASSERT (NewLoadContext->OptionalData != NULL);\r
-      CopyMem (\r
-        NewLoadContext->OptionalData,\r
-        LoadOptionPtr,\r
-        OptionalDataSize\r
-        );\r
-\r
-      NewLoadContext->OptionalDataSize = OptionalDataSize;\r
-    }\r
-\r
-    InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);\r
-\r
-  }\r
-\r
-  if (DriverOrderList != NULL) {\r
-    FreePool (DriverOrderList);\r
-  }\r
-  DriverOptionMenu.MenuNumber = Index;\r
-  return EFI_SUCCESS;\r
-\r
-}\r
-\r
-/**\r
-  Get option number according to Boot#### and BootOrder variable.\r
-  The value is saved as #### + 1.\r
-\r
-  @param CallbackData    The BMM context data.\r
-**/\r
-VOID\r
-GetBootOrder (\r
-  IN  BMM_CALLBACK_DATA    *CallbackData\r
-  )\r
-{\r
-  BMM_FAKE_NV_DATA          *BmmConfig;\r
-  UINT16                    Index;\r
-  UINT16                    OptionOrderIndex;\r
-  UINTN                     DeviceType;\r
-  BM_MENU_ENTRY             *NewMenuEntry;\r
-  BM_LOAD_CONTEXT           *NewLoadContext;\r
-\r
-  ASSERT (CallbackData != NULL);\r
-\r
-  DeviceType = (UINTN) -1;\r
-  BmmConfig  = &CallbackData->BmmFakeNvData;\r
-  ZeroMem (BmmConfig->BootOptionOrder, sizeof (BmmConfig->BootOptionOrder));\r
-\r
-  for (Index = 0, OptionOrderIndex = 0; ((Index < BootOptionMenu.MenuNumber) &&\r
-       (OptionOrderIndex < (sizeof (BmmConfig->BootOptionOrder) / sizeof (BmmConfig->BootOptionOrder[0]))));\r
-       Index++) {\r
-    NewMenuEntry   = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
-    NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
-\r
-    if (NewLoadContext->IsLegacy) {\r
-      if (((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType != DeviceType) {\r
-        DeviceType = ((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType;\r
-      } else {\r
-        //\r
-        // Only show one legacy boot option for the same device type\r
-        // assuming the boot options are grouped by the device type\r
-        //\r
-        continue;\r
-      }\r
-    }\r
-    BmmConfig->BootOptionOrder[OptionOrderIndex++] = (UINT32) (NewMenuEntry->OptionNumber + 1);\r
-  }\r
-}\r
-\r
-/**\r
-  According to LegacyDevOrder variable to get legacy FD\HD\CD\NET\BEV\r
-  devices list .\r
-\r
-  @param CallbackData    The BMM context data.\r
-**/\r
-VOID\r
-GetLegacyDeviceOrder (\r
-  IN  BMM_CALLBACK_DATA    *CallbackData\r
-  )\r
-{\r
-  UINTN                     Index;\r
-  UINTN                     OptionIndex;\r
-  UINT16                    PageIdList[5];\r
-  UINTN                     PageNum;\r
-  UINTN                     VarSize;\r
-  UINT8                     *VarData;\r
-  UINT8                     *WorkingVarData;\r
-  LEGACY_DEV_ORDER_ENTRY    *DevOrder;\r
-  UINT16                    VarDevOrder;\r
-  UINT8                     *DisMap;\r
-  BM_MENU_OPTION            *OptionMenu;\r
-  BBS_TYPE                  BbsType;\r
-  UINT8                     *LegacyOrder;\r
-  UINT8                     *OldData;\r
-  UINTN                     Pos;\r
-  UINTN                     Bit;\r
-\r
-  ASSERT (CallbackData != NULL);\r
-\r
-  PageIdList[0] = FORM_SET_FD_ORDER_ID;\r
-  PageIdList[1] = FORM_SET_HD_ORDER_ID;\r
-  PageIdList[2] = FORM_SET_CD_ORDER_ID;\r
-  PageIdList[3] = FORM_SET_NET_ORDER_ID;\r
-  PageIdList[4] = FORM_SET_BEV_ORDER_ID;\r
-  OptionMenu  = NULL;\r
-  BbsType     = 0;\r
-  LegacyOrder = NULL;\r
-  OldData     = NULL;\r
-  DisMap      = ZeroMem (CallbackData->BmmFakeNvData.DisableMap, sizeof (CallbackData->BmmFakeNvData.DisableMap));\r
-  PageNum     = ARRAY_SIZE (PageIdList);\r
-  VarData     = BdsLibGetVariableAndSize (\r
-                  VAR_LEGACY_DEV_ORDER,\r
-                  &gEfiLegacyDevOrderVariableGuid,\r
-                  &VarSize\r
-                  );\r
-\r
-  for (Index = 0; Index < PageNum; Index++) {\r
-    switch (PageIdList[Index]) {\r
-\r
-    case FORM_SET_FD_ORDER_ID:\r
-      OptionMenu  = (BM_MENU_OPTION *) &LegacyFDMenu;\r
-      BbsType     = BBS_FLOPPY;\r
-      LegacyOrder = CallbackData->BmmFakeNvData.LegacyFD;\r
-      OldData     = CallbackData->BmmOldFakeNVData.LegacyFD;\r
-      break;\r
-\r
-    case FORM_SET_HD_ORDER_ID:\r
-      OptionMenu  = (BM_MENU_OPTION *) &LegacyHDMenu;\r
-      BbsType     = BBS_HARDDISK;\r
-      LegacyOrder = CallbackData->BmmFakeNvData.LegacyHD;\r
-      OldData     = CallbackData->BmmOldFakeNVData.LegacyHD;\r
-      break;\r
-\r
-    case FORM_SET_CD_ORDER_ID:\r
-      OptionMenu  = (BM_MENU_OPTION *) &LegacyCDMenu;\r
-      BbsType     = BBS_CDROM;\r
-      LegacyOrder = CallbackData->BmmFakeNvData.LegacyCD;\r
-      OldData     = CallbackData->BmmOldFakeNVData.LegacyCD;\r
-      break;\r
-\r
-    case FORM_SET_NET_ORDER_ID:\r
-      OptionMenu  = (BM_MENU_OPTION *) &LegacyNETMenu;\r
-      BbsType     = BBS_EMBED_NETWORK;\r
-      LegacyOrder = CallbackData->BmmFakeNvData.LegacyNET;\r
-      OldData     = CallbackData->BmmOldFakeNVData.LegacyNET;\r
-      break;\r
-\r
-    default:\r
-      ASSERT (PageIdList[Index] == FORM_SET_BEV_ORDER_ID);\r
-      OptionMenu  = (BM_MENU_OPTION *) &LegacyBEVMenu;\r
-      BbsType     = BBS_BEV_DEVICE;\r
-      LegacyOrder = CallbackData->BmmFakeNvData.LegacyBEV;\r
-      OldData     = CallbackData->BmmOldFakeNVData.LegacyBEV;\r
-      break;\r
-    }\r
-\r
-    if (NULL != VarData) {\r
-      WorkingVarData = VarData;\r
-      DevOrder    = (LEGACY_DEV_ORDER_ENTRY *) WorkingVarData;\r
-      while (WorkingVarData < VarData + VarSize) {\r
-        if (DevOrder->BbsType == BbsType) {\r
-          break;\r
-        }\r
-\r
-        WorkingVarData  = (UINT8 *)((UINTN)WorkingVarData + sizeof (BBS_TYPE));\r
-        WorkingVarData += *(UINT16 *) WorkingVarData;\r
-        DevOrder = (LEGACY_DEV_ORDER_ENTRY *) WorkingVarData;\r
-      }\r
-      for (OptionIndex = 0; OptionIndex < OptionMenu->MenuNumber; OptionIndex++) {\r
-        VarDevOrder = *(UINT16 *) ((UINTN) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + OptionIndex * sizeof (UINT16));\r
-         if (0xFF00 == (VarDevOrder & 0xFF00)) {\r
-          LegacyOrder[OptionIndex]  = 0xFF;\r
-          Pos                       = (VarDevOrder & 0xFF) / 8;\r
-          Bit                       = 7 - ((VarDevOrder & 0xFF) % 8);\r
-          DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
-        } else {\r
-          LegacyOrder[OptionIndex] = (UINT8) (VarDevOrder & 0xFF);\r
-        }\r
-      }\r
-      CopyMem (OldData, LegacyOrder, 100);\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
-  Get driver option order from globalc DriverOptionMenu.\r
-\r
-  @param CallbackData    The BMM context data.\r
-\r
-**/\r
-VOID\r
-GetDriverOrder (\r
-  IN  BMM_CALLBACK_DATA    *CallbackData\r
-  )\r
-{\r
-  BMM_FAKE_NV_DATA          *BmmConfig;\r
-  UINT16                    Index;\r
-  UINT16                    OptionOrderIndex;\r
-  UINTN                     DeviceType;\r
-  BM_MENU_ENTRY             *NewMenuEntry;\r
-  BM_LOAD_CONTEXT           *NewLoadContext;\r
-\r
-  ASSERT (CallbackData != NULL);\r
-\r
-  DeviceType = (UINTN) -1;\r
-  BmmConfig  = &CallbackData->BmmFakeNvData;\r
-  ZeroMem (BmmConfig->DriverOptionOrder, sizeof (BmmConfig->DriverOptionOrder));\r
-\r
-  for (Index = 0, OptionOrderIndex = 0; ((Index < DriverOptionMenu.MenuNumber) &&\r
-       (OptionOrderIndex < (sizeof (BmmConfig->DriverOptionOrder) / sizeof (BmmConfig->DriverOptionOrder[0]))));\r
-       Index++) {\r
-    NewMenuEntry   = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
-    NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
-\r
-    if (NewLoadContext->IsLegacy) {\r
-      if (((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType != DeviceType) {\r
-        DeviceType = ((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType;\r
-      } else {\r
-        //\r
-        // Only show one legacy boot option for the same device type\r
-        // assuming the boot options are grouped by the device type\r
-        //\r
-        continue;\r
-      }\r
-    }\r
-    BmmConfig->DriverOptionOrder[OptionOrderIndex++] = (UINT32) (NewMenuEntry->OptionNumber + 1);\r
-  }\r
-}\r