+++ /dev/null
-/*++\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
-\r
- BootOption.c\r
-\r
-Abstract:\r
-\r
- Provide boot option support for Application "BootMaint"\r
-\r
- Include file system navigation, system handle selection\r
-\r
- Boot option manipulation\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include "BootMaint.h"\r
-#include "BBSsupport.h"\r
-\r
-BM_MENU_ENTRY *\r
-BOpt_CreateMenuEntry (\r
- UINTN MenuType\r
- )\r
-/*++\r
-\r
-Routine Description\r
- Create Menu Entry for future use, make all types together\r
- in order to reduce code size\r
-\r
-Arguments:\r
- MenuType Use this parameter to identify current\r
- Menu type\r
-\r
-Returns:\r
- NULL Cannot allocate memory for current menu\r
- entry\r
- Others A valid pointer pointing to the allocated\r
- memory pool for current menu entry\r
-\r
---*/\r
-{\r
- BM_MENU_ENTRY *MenuEntry;\r
- UINTN ContextSize;\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
-\r
- if (0 == ContextSize) {\r
- return NULL;\r
- }\r
-\r
- MenuEntry = AllocateZeroPool (sizeof (BM_MENU_ENTRY));\r
- if (NULL == MenuEntry) {\r
- return MenuEntry;\r
- }\r
-\r
- MenuEntry->VariableContext = AllocateZeroPool (ContextSize);\r
- if (NULL == MenuEntry->VariableContext) {\r
- SafeFreePool (MenuEntry);\r
- MenuEntry = NULL;\r
- return MenuEntry;\r
- }\r
-\r
- MenuEntry->Signature = BM_MENU_ENTRY_SIGNATURE;\r
- MenuEntry->ContextSelection = MenuType;\r
- return MenuEntry;\r
-}\r
-\r
-VOID\r
-BOpt_DestroyMenuEntry (\r
- BM_MENU_ENTRY *MenuEntry\r
- )\r
-/*++\r
- Routine Description :\r
- Destroy the menu entry passed in\r
-\r
- Arguments :\r
- The menu entry need to be destroyed\r
-\r
- Returns :\r
- None\r
-\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
- SafeFreePool (LoadContext->FilePathList);\r
- SafeFreePool (LoadContext->LoadOption);\r
- SafeFreePool (LoadContext->OptionalData);\r
- SafeFreePool (LoadContext);\r
- break;\r
-\r
- case BM_FILE_CONTEXT_SELECT:\r
- FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;\r
-\r
- if (!FileContext->IsRoot) {\r
- SafeFreePool (FileContext->DevicePath);\r
- } else {\r
- if (FileContext->FHandle != NULL) {\r
- FileContext->FHandle->Close (FileContext->FHandle);\r
- }\r
- }\r
-\r
- SafeFreePool (FileContext->FileName);\r
- SafeFreePool (FileContext->Info);\r
- SafeFreePool (FileContext);\r
- break;\r
-\r
- case BM_CONSOLE_CONTEXT_SELECT:\r
- ConsoleContext = (BM_CONSOLE_CONTEXT *) MenuEntry->VariableContext;\r
- SafeFreePool (ConsoleContext->DevicePath);\r
- SafeFreePool (ConsoleContext);\r
- break;\r
-\r
- case BM_TERMINAL_CONTEXT_SELECT:\r
- TerminalContext = (BM_TERMINAL_CONTEXT *) MenuEntry->VariableContext;\r
- SafeFreePool (TerminalContext->DevicePath);\r
- SafeFreePool (TerminalContext);\r
- break;\r
-\r
- case BM_HANDLE_CONTEXT_SELECT:\r
- HandleContext = (BM_HANDLE_CONTEXT *) MenuEntry->VariableContext;\r
- SafeFreePool (HandleContext);\r
- break;\r
-\r
- case BM_LEGACY_DEV_CONTEXT_SELECT:\r
- LegacyDevContext = (BM_LEGACY_DEVICE_CONTEXT *) MenuEntry->VariableContext;\r
- SafeFreePool (LegacyDevContext);\r
-\r
- default:\r
- break;\r
- }\r
-\r
- SafeFreePool (MenuEntry->DisplayString);\r
- if (NULL != MenuEntry->HelpString) {\r
- SafeFreePool (MenuEntry->HelpString);\r
- }\r
-\r
- SafeFreePool (MenuEntry);\r
-}\r
-\r
-BM_MENU_ENTRY *\r
-BOpt_GetMenuEntry (\r
- BM_MENU_OPTION *MenuOption,\r
- UINTN MenuNumber\r
- )\r
-/*++\r
- Rountine Description :\r
- Use this routine to get one particular menu entry in specified\r
- menu\r
-\r
- Arguments :\r
- MenuOption The menu that we will search\r
-\r
- MenuNumber The menunubmer that we want\r
-\r
- Returns :\r
- The desired menu entry\r
-\r
---*/\r
-{\r
- BM_MENU_ENTRY *NewMenuEntry;\r
- UINTN Index;\r
- LIST_ENTRY *List;\r
-\r
- if (MenuNumber >= MenuOption->MenuNumber) {\r
- return NULL;\r
- }\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
-EFI_STATUS\r
-BOpt_FindFileSystem (\r
- IN BMM_CALLBACK_DATA *CallbackData\r
- )\r
-/*++\r
-\r
-Routine Description\r
- Find file systems for current Extensible Firmware\r
- Including Handles that support Simple File System\r
- protocol, Load File protocol.\r
-\r
- Building up the FileSystem Menu for user selection\r
- All file system will be stored in FsOptionMenu\r
- for future use.\r
-\r
-Arguments:\r
- CallbackData - BMM context data\r
-\r
-Returns:\r
- EFI_SUCCESS - Success find the file system\r
- EFI_OUT_OF_RESOURCES - Can not create menu entry\r
-\r
---*/\r
-{\r
- UINTN NoSimpleFsHandles;\r
- UINTN NoLoadFileHandles;\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
- 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 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
- &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
- SafeFreePool (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) {\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 = FALSE;\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
- if (FileContext->Info->VolumeLabel == NULL) {\r
- VolumeLabel = L"NULL VOLUME LABEL";\r
- } else {\r
- VolumeLabel = FileContext->Info->VolumeLabel;\r
- if (*VolumeLabel == 0x0000) {\r
- VolumeLabel = L"NO VOLUME LABEL";\r
- }\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
- SafeFreePool (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
- SafeFreePool (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
-\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
- SafeFreePool (LoadFileHandle);\r
- }\r
-\r
- //\r
- // Add Legacy Boot Option Support Here\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiLegacyBiosProtocolGuid,\r
- NULL,\r
- &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
-VOID\r
-BOpt_FreeMenu (\r
- BM_MENU_OPTION *FreeMenu\r
- )\r
-/*++\r
-\r
-Routine Description\r
- Free resources allocated in Allocate Rountine\r
-\r
-Arguments:\r
- FreeMenu Menu to be freed\r
-\r
-Returns:\r
- VOID\r
-\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
-}\r
-\r
-EFI_STATUS\r
-BOpt_FindFiles (\r
- IN BMM_CALLBACK_DATA *CallbackData,\r
- IN BM_MENU_ENTRY *MenuEntry\r
- )\r
-/*++\r
-\r
-Routine Description\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
-Arguments:\r
- FileOption -- Pointer for Dir to explore\r
-\r
-Returns:\r
- TRUE -- Get files from current dir successfully\r
- FALSE -- Can't get files from current dir\r
-\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) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (!(DirInfo->Attribute & EFI_FILE_DIRECTORY)) {\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) {\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 && Pass == 2) ||\r
- (!(DirInfo->Attribute & EFI_FILE_DIRECTORY) && 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)) {\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
- SafeFreePool (DirInfo);\r
- return TRUE;\r
-}\r
-\r
-EFI_STATUS\r
-BOpt_GetLegacyOptions (\r
- VOID\r
- )\r
-/*++\r
-Routine Description:\r
-\r
- Build the LegacyFDMenu LegacyHDMenu LegacyCDMenu according to LegacyBios.GetBbsInfo().\r
-\r
-Arguments:\r
- None\r
-\r
-Returns:\r
- The device info of legacy device.\r
-\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
- UINTN 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
- &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
- (BBS_LOWEST_PRIORITY == 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->BbsTable = &BbsTable[Index];\r
- NewLegacyDevContext->Index = Index;\r
- NewLegacyDevContext->BbsCount = BbsCount;\r
- BdsBuildLegacyDevNameString (\r
- &BbsTable[Index],\r
- Index,\r
- sizeof (DescString),\r
- DescString\r
- );\r
- NewLegacyDevContext->Description = AllocateZeroPool (StrSize (DescString));\r
- if (NULL == NewLegacyDevContext->Description) {\r
- break;\r
- }\r
-\r
- CopyMem (NewLegacyDevContext->Description, DescString, StrSize (DescString));\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
-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
-EFI_STATUS\r
-BOpt_GetBootOptions (\r
- IN BMM_CALLBACK_DATA *CallbackData\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Build the BootOptionMenu according to BootOrder Variable.\r
- This Routine will access the Boot#### to get EFI_LOAD_OPTION\r
-\r
-Arguments:\r
- None\r
-\r
-Returns:\r
- The number of the Var Boot####\r
-\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
-\r
- //\r
- // Get the BootNext from the Var\r
- //\r
- BootNext = BdsLibGetVariableAndSize (\r
- L"BootNext",\r
- &gEfiGlobalVariableGuid,\r
- &BootNextSize\r
- );\r
-\r
- if (BootNext) {\r
- if (BootNextSize != sizeof (UINT16)) {\r
- SafeFreePool (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) {\r
- continue;\r
- }\r
-\r
- LoadOption = AllocateZeroPool (BootOptionSize);\r
- if (!LoadOption) {\r
- continue;\r
- }\r
-\r
- CopyMem (LoadOption, LoadOptionFromVar, BootOptionSize);\r
- SafeFreePool (LoadOptionFromVar);\r
-\r
- if (BootNext) {\r
- BootNextFlag = (BOOLEAN) (*BootNext == BootOrderList[Index]);\r
- } else {\r
- BootNextFlag = FALSE;\r
- }\r
-\r
- if (0 == (*((UINT32 *) LoadOption) & LOAD_OPTION_ACTIVE)) {\r
- SafeFreePool (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
- 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
- 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
- SafeFreePool (BootNext);\r
- SafeFreePool (BootOrderList);\r
- BootOptionMenu.MenuNumber = MenuCount;\r
- return MenuCount;\r
-}\r
-\r
-CHAR16 *\r
-BdsStrCpy (\r
- OUT CHAR16 *Destination,\r
- IN CONST CHAR16 *Source\r
- )\r
-{\r
- CHAR16 *ReturnValue;\r
-\r
- //\r
- // Destination cannot be NULL\r
- //\r
- ASSERT (Destination != NULL);\r
-\r
- ReturnValue = Destination;\r
- while (*Source) {\r
- *(Destination++) = *(Source++);\r
- }\r
- *Destination = 0;\r
- return ReturnValue;\r
-}\r
-\r
-CHAR16 *\r
-BOpt_AppendFileName (\r
- IN CHAR16 *Str1,\r
- IN CHAR16 *Str2\r
- )\r
-/*++\r
-\r
-Routine Description\r
- Append file name to existing file name.\r
-\r
-Arguments:\r
- Str1 - existing file name\r
- Str2 - file name to be appended\r
-\r
-Returns:\r
- Allocate a new string to hold the appended result.\r
- Caller is responsible to free the returned string.\r
-\r
---*/\r
-{\r
- UINTN Size1;\r
- UINTN Size2;\r
- CHAR16 *Str;\r
- CHAR16 *Ptr;\r
- CHAR16 *LastSlash;\r
-\r
- Size1 = StrSize (Str1);\r
- Size2 = StrSize (Str2);\r
- Str = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16));\r
- ASSERT (Str != NULL);\r
-\r
- StrCat (Str, Str1);\r
- if (!((*Str == '\\') && (*(Str + 1) == 0))) {\r
- StrCat (Str, L"\\");\r
- }\r
-\r
- StrCat (Str, Str2);\r
-\r
- Ptr = Str;\r
- LastSlash = Str;\r
- while (*Ptr != 0) {\r
- if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '.' && *(Ptr + 3) != 0) {\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
- BdsStrCpy (LastSlash, Ptr + 3);\r
- Ptr = LastSlash;\r
- } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') {\r
- //\r
- // Convert a \.\ to a \\r
- //\r
- BdsStrCpy (Ptr, Ptr + 2);\r
- Ptr = LastSlash;\r
- } else if (*Ptr == '\\') {\r
- LastSlash = Ptr;\r
- }\r
-\r
- Ptr++;\r
- }\r
-\r
- return Str;\r
-}\r
-\r
-BOOLEAN\r
-BOpt_IsEfiImageName (\r
- IN UINT16 *FileName\r
- )\r
-/*++\r
-\r
-Routine Description\r
- Check whether current FileName point to a valid\r
- Efi Image File.\r
-\r
-Arguments:\r
- FileName - File need to be checked.\r
-\r
-Returns:\r
- TRUE - Is Efi Image\r
- FALSE - Not a valid Efi Image\r
-\r
---*/\r
-{\r
- //\r
- // Search for ".efi" extension\r
- //\r
- while (*FileName) {\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
-RETURN_STATUS\r
-EFIAPI\r
-IsEfiAppReadFromFile (\r
- IN VOID *FileHandle,\r
- IN UINTN FileOffset,\r
- IN OUT UINTN *ReadSize,\r
- OUT VOID *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_FILE_HANDLE File;\r
-\r
- File = (EFI_FILE_HANDLE)FileHandle;\r
- Status = File->SetPosition (File, FileOffset);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return File->Read (File, ReadSize, Buffer);\r
-}\r
-\r
-\r
-\r
-BOOLEAN\r
-BOpt_IsEfiApp (\r
- IN EFI_FILE_HANDLE Dir,\r
- IN UINT16 *FileName\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Check whether current FileName point to a valid Efi Application\r
-\r
-Arguments:\r
- Dir - Pointer to current Directory\r
- FileName - Pointer to current File name.\r
-\r
-Returns:\r
- TRUE - Is a valid Efi Application\r
- FALSE - not a valid Efi Application\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
- EFI_FILE_HANDLE File;\r
-\r
- Status = Dir->Open (Dir, &File, FileName, EFI_FILE_MODE_READ, 0);\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- }\r
-\r
- ZeroMem (&ImageContext, sizeof (ImageContext));\r
- ImageContext.Handle = (VOID *)File;\r
- ImageContext.ImageRead = IsEfiAppReadFromFile;\r
-\r
- Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
- File->Close (File);\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- }\r
-\r
- if (ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {\r
- return TRUE;\r
- } else {\r
- return FALSE;\r
- }\r
- }\r
-\r
-\r
-EFI_STATUS\r
-BOpt_FindDrivers (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description\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
-Arguments:\r
- None\r
-\r
-Returns:\r
- EFI_SUCCESS\r
- Others\r
-\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
- //\r
- // Check whether this handle support\r
- // driver binding\r
- //\r
- Status = gBS->HandleProtocol (\r
- CurHandle,\r
- &gEfiSimpleFileSystemProtocolGuid,\r
- &SimpleFs\r
- );\r
- if (Status == EFI_SUCCESS) {\r
- continue;\r
- }\r
-\r
- Status = gBS->HandleProtocol (\r
- CurHandle,\r
- &gEfiLoadFileProtocolGuid,\r
- &LoadFile\r
- );\r
- if (Status == EFI_SUCCESS) {\r
- continue;\r
- }\r
-\r
- NewMenuEntry = BOpt_CreateMenuEntry (BM_HANDLE_CONTEXT_SELECT);\r
- if (NULL == NewMenuEntry) {\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
- DriverMenu.MenuNumber = OptionNumber;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-UINT16\r
-BOpt_GetBootOptionNumber (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Get the Option Number that does not used\r
-\r
-Arguments:\r
-\r
-Returns:\r
- The Option Number\r
-\r
---*/\r
-{\r
- BM_MENU_ENTRY *NewMenuEntry;\r
- UINT16 *BootOrderList;\r
- UINTN BootOrderListSize;\r
- UINT16 Number;\r
- UINTN Index;\r
- UINTN Index2;\r
- BOOLEAN Found;\r
- CHAR16 StrTemp[100];\r
- UINT16 *OptionBuffer;\r
- UINTN OptionSize;\r
-\r
- BootOrderListSize = 0;\r
- BootOrderList = NULL;\r
-\r
- BootOrderList = BdsLibGetVariableAndSize (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- &BootOrderListSize\r
- );\r
- if (BootOrderList) {\r
- //\r
- // already have Boot####\r
- //\r
- // AlreadyBootNumbers = BootOrderListSize / sizeof(UINT16);\r
- //\r
- for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) {\r
- Found = TRUE;\r
- for (Index2 = 0; Index2 < BootOptionMenu.MenuNumber; Index2++) {\r
- NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index2);\r
- if (Index == NewMenuEntry->OptionNumber) {\r
- Found = FALSE;\r
- break;\r
- }\r
- }\r
-\r
- if (Found) {\r
- UnicodeSPrint (StrTemp, 100, L"Boot%04x", Index);\r
- DEBUG((EFI_D_ERROR,"INdex= %s\n", StrTemp));\r
- OptionBuffer = BdsLibGetVariableAndSize (\r
- StrTemp,\r
- &gEfiGlobalVariableGuid,\r
- &OptionSize\r
- );\r
- if (NULL == OptionBuffer)\r
- break;\r
- }\r
- }\r
- //\r
- // end for Index\r
- //\r
- Number = (UINT16) Index;\r
- } else {\r
- //\r
- // No Boot####\r
- //\r
- Number = 0;\r
- }\r
-\r
- return Number;\r
-}\r
-\r
-UINT16\r
-BOpt_GetDriverOptionNumber (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Get the Option Number that does not used\r
-\r
-Arguments:\r
-\r
-Returns:\r
- The Option Number\r
-\r
---*/\r
-{\r
- BM_MENU_ENTRY *NewMenuEntry;\r
- UINT16 *DriverOrderList;\r
- UINTN DriverOrderListSize;\r
- UINT16 Number;\r
- UINTN Index;\r
- UINTN Index2;\r
- BOOLEAN Found;\r
-\r
- DriverOrderListSize = 0;\r
- DriverOrderList = NULL;\r
-\r
- DriverOrderList = BdsLibGetVariableAndSize (\r
- L"DriverOrder",\r
- &gEfiGlobalVariableGuid,\r
- &DriverOrderListSize\r
- );\r
- if (DriverOrderList) {\r
- //\r
- // already have Driver####\r
- //\r
- // AlreadyDriverNumbers = DriverOrderListSize / sizeof(UINT16);\r
- //\r
- for (Index = 0; Index < DriverOrderListSize / sizeof (UINT16); Index++) {\r
- Found = TRUE;\r
- for (Index2 = 0; Index2 < DriverOptionMenu.MenuNumber; Index2++) {\r
- NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index2);\r
- if (Index == NewMenuEntry->OptionNumber) {\r
- Found = FALSE;\r
- break;\r
- }\r
- }\r
-\r
- if (Found) {\r
- break;\r
- }\r
- }\r
- //\r
- // end for Index\r
- //\r
- Number = (UINT16) Index;\r
- } else {\r
- //\r
- // No Driver####\r
- //\r
- Number = 0;\r
- }\r
-\r
- return Number;\r
-}\r
-\r
-EFI_STATUS\r
-BOpt_GetDriverOptions (\r
- IN BMM_CALLBACK_DATA *CallbackData\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Build up all DriverOptionMenu\r
-\r
-Arguments:\r
-\r
-Returns:\r
- The Option Number\r
-\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
-\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) {\r
- continue;\r
- }\r
-\r
- LoadOption = AllocateZeroPool (DriverOptionSize);\r
- if (!LoadOption) {\r
- continue;\r
- }\r
-\r
- CopyMem (LoadOption, LoadOptionFromVar, DriverOptionSize);\r
- SafeFreePool (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
- SafeFreePool (DriverOrderList);\r
- DriverOptionMenu.MenuNumber = Index;\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-VOID\r
-SafeFreePool (\r
- IN VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Wrap original FreePool gBS call\r
- in order to decrease code length\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-{\r
- if (Buffer != NULL) {\r
- FreePool (Buffer);\r
- Buffer = NULL;\r
- }\r
-}\r