bootoption.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,669 行 · 第 1/4 页
C
1,669 行
/*++
Copyright (c) 2004, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
bootoption.c
Abstract:
Provide boot option support for Application "BootMaint"
Include file system navigation, system handle selection
Boot option manipulation
Revision History
--*/
#include "bootmaint.h"
#include "BBSsupport.h"
BM_MENU_ENTRY *
BOpt_CreateMenuEntry (
UINTN MenuType
)
/*++
Routine Description
Create Menu Entry for future use, make all types together
in order to reduce code size
Arguments:
MenuType Use this parameter to identify current
Menu type
Returns:
NULL Cannot allocate memory for current menu
entry
Others A valid pointer pointing to the allocated
memory pool for current menu entry
--*/
{
BM_MENU_ENTRY *MenuEntry;
UINTN ContextSize;
switch (MenuType) {
case BM_LOAD_CONTEXT_SELECT:
ContextSize = sizeof (BM_LOAD_CONTEXT);
break;
case BM_FILE_CONTEXT_SELECT:
ContextSize = sizeof (BM_FILE_CONTEXT);
break;
case BM_CONSOLE_CONTEXT_SELECT:
ContextSize = sizeof (BM_CONSOLE_CONTEXT);
break;
case BM_TERMINAL_CONTEXT_SELECT:
ContextSize = sizeof (BM_TERMINAL_CONTEXT);
break;
case BM_HANDLE_CONTEXT_SELECT:
ContextSize = sizeof (BM_HANDLE_CONTEXT);
break;
case BM_LEGACY_DEV_CONTEXT_SELECT:
ContextSize = sizeof (BM_LEGACY_DEVICE_CONTEXT);
break;
default:
ContextSize = 0;
break;
}
if (0 == ContextSize) {
return NULL;
}
MenuEntry = EfiAllocateZeroPool (sizeof (BM_MENU_ENTRY));
if (NULL == MenuEntry) {
return MenuEntry;
}
MenuEntry->VariableContext = EfiAllocateZeroPool (ContextSize);
if (NULL == MenuEntry->VariableContext) {
SafeFreePool (MenuEntry);
MenuEntry = NULL;
return MenuEntry;
}
MenuEntry->Signature = BM_MENU_ENTRY_SIGNATURE;
MenuEntry->ContextSelection = MenuType;
return MenuEntry;
}
VOID
BOpt_DestroyMenuEntry (
BM_MENU_ENTRY *MenuEntry
)
/*++
Routine Description :
Destroy the menu entry passed in
Arguments :
The menu entry need to be destroyed
Returns :
None
--*/
{
BM_LOAD_CONTEXT *LoadContext;
BM_FILE_CONTEXT *FileContext;
BM_CONSOLE_CONTEXT *ConsoleContext;
BM_TERMINAL_CONTEXT *TerminalContext;
BM_HANDLE_CONTEXT *HandleContext;
BM_LEGACY_DEVICE_CONTEXT *LegacyDevContext;
//
// Select by the type in Menu entry for current context type
//
switch (MenuEntry->ContextSelection) {
case BM_LOAD_CONTEXT_SELECT:
LoadContext = (BM_LOAD_CONTEXT *) MenuEntry->VariableContext;
SafeFreePool (LoadContext->FilePathList);
SafeFreePool (LoadContext->LoadOption);
SafeFreePool (LoadContext->OptionalData);
SafeFreePool (LoadContext);
break;
case BM_FILE_CONTEXT_SELECT:
FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;
if (!FileContext->IsRoot) {
SafeFreePool (FileContext->DevicePath);
} else {
if (FileContext->FHandle != NULL) {
FileContext->FHandle->Close (FileContext->FHandle);
}
}
SafeFreePool (FileContext->FileName);
SafeFreePool (FileContext->Info);
SafeFreePool (FileContext);
break;
case BM_CONSOLE_CONTEXT_SELECT:
ConsoleContext = (BM_CONSOLE_CONTEXT *) MenuEntry->VariableContext;
SafeFreePool (ConsoleContext->DevicePath);
SafeFreePool (ConsoleContext);
break;
case BM_TERMINAL_CONTEXT_SELECT:
TerminalContext = (BM_TERMINAL_CONTEXT *) MenuEntry->VariableContext;
SafeFreePool (TerminalContext->DevicePath);
SafeFreePool (TerminalContext);
break;
case BM_HANDLE_CONTEXT_SELECT:
HandleContext = (BM_HANDLE_CONTEXT *) MenuEntry->VariableContext;
SafeFreePool (HandleContext);
break;
case BM_LEGACY_DEV_CONTEXT_SELECT:
LegacyDevContext = (BM_LEGACY_DEVICE_CONTEXT *) MenuEntry->VariableContext;
SafeFreePool (LegacyDevContext);
default:
break;
}
SafeFreePool (MenuEntry->DisplayString);
if (NULL != MenuEntry->HelpString) {
SafeFreePool (MenuEntry->HelpString);
}
SafeFreePool (MenuEntry);
}
BM_MENU_ENTRY *
BOpt_GetMenuEntry (
BM_MENU_OPTION *MenuOption,
UINTN MenuNumber
)
/*++
Rountine Description :
Use this routine to get one particular menu entry in specified
menu
Arguments :
MenuOption The menu that we will search
MenuNumber The menunubmer that we want
Returns :
The desired menu entry
--*/
{
BM_MENU_ENTRY *NewMenuEntry;
UINTN Index;
EFI_LIST_ENTRY *List;
if (MenuNumber >= MenuOption->MenuNumber) {
return NULL;
}
List = MenuOption->Head.ForwardLink;
for (Index = 0; Index < MenuNumber; Index++) {
List = List->ForwardLink;
}
NewMenuEntry = CR (List, BM_MENU_ENTRY, Link, BM_MENU_ENTRY_SIGNATURE);
return NewMenuEntry;
}
EFI_STATUS
BOpt_FindFileSystem (
IN BMM_CALLBACK_DATA *CallbackData
)
/*++
Routine Description
Find file systems for current Extensible Firmware
Including Handles that support Simple File System
protocol, Load File protocol.
Building up the FileSystem Menu for user selection
All file system will be stored in FsOptionMenu
for future use.
Arguments:
CallbackData - BMM context data
Returns:
EFI_SUCCESS - Success find the file system
EFI_OUT_OF_RESOURCES - Can not create menu entry
--*/
{
UINTN NoSimpleFsHandles;
UINTN NoLoadFileHandles;
EFI_HANDLE *SimpleFsHandle;
EFI_HANDLE *LoadFileHandle;
UINT16 *VolumeLabel;
EFI_BLOCK_IO_PROTOCOL *BlkIo;
UINTN Index;
EFI_STATUS Status;
BM_MENU_ENTRY *MenuEntry;
BM_FILE_CONTEXT *FileContext;
UINT16 *TempStr;
UINTN OptionNumber;
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
UINT16 DeviceType;
BBS_BBS_DEVICE_PATH BbsDevicePathNode;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
BOOLEAN RemovableMedia;
NoSimpleFsHandles = 0;
NoLoadFileHandles = 0;
OptionNumber = 0;
InitializeListHead (&FsOptionMenu.Head);
//
// Locate Handles that support Simple File System protocol
//
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleFileSystemProtocolGuid,
NULL,
&NoSimpleFsHandles,
&SimpleFsHandle
);
if (!EFI_ERROR (Status)) {
//
// Find all the instances of the File System prototocol
//
for (Index = 0; Index < NoSimpleFsHandles; Index++) {
Status = gBS->HandleProtocol (
SimpleFsHandle[Index],
&gEfiBlockIoProtocolGuid,
&BlkIo
);
if (EFI_ERROR (Status)) {
//
// If no block IO exists assume it's NOT a removable media
//
RemovableMedia = FALSE;
} else {
//
// If block IO exists check to see if it's remobable media
//
RemovableMedia = BlkIo->Media->RemovableMedia;
}
//
// Allocate pool for this load option
//
MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);
if (NULL == MenuEntry) {
SafeFreePool (SimpleFsHandle);
return EFI_OUT_OF_RESOURCES;
}
FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;
FileContext->Handle = SimpleFsHandle[Index];
MenuEntry->OptionNumber = Index;
FileContext->FHandle = EfiLibOpenRoot (FileContext->Handle);
if (!FileContext->FHandle) {
BOpt_DestroyMenuEntry (MenuEntry);
continue;
}
MenuEntry->HelpString = DevicePathToStr (EfiDevicePathFromHandle (FileContext->Handle));
FileContext->Info = EfiLibFileSystemVolumeLabelInfo (FileContext->FHandle);
FileContext->FileName = EfiStrDuplicate (L"\\");
FileContext->DevicePath = EfiFileDevicePath (
FileContext->Handle,
FileContext->FileName
);
FileContext->IsDir = TRUE;
FileContext->IsRoot = TRUE;
FileContext->IsRemovableMedia = FALSE;
FileContext->IsLoadFile = FALSE;
//
// Get current file system's Volume Label
//
if (FileContext->Info == NULL) {
VolumeLabel = L"NO FILE SYSTEM INFO";
} else {
if (FileContext->Info->VolumeLabel == NULL) {
VolumeLabel = L"NULL VOLUME LABEL";
} else {
VolumeLabel = FileContext->Info->VolumeLabel;
if (*VolumeLabel == 0x0000) {
VolumeLabel = L"NO VOLUME LABEL";
}
}
}
TempStr = MenuEntry->HelpString;
MenuEntry->DisplayString = EfiAllocateZeroPool (MAX_CHAR);
ASSERT (MenuEntry->DisplayString != NULL);
SPrint (
MenuEntry->DisplayString,
MAX_CHAR,
L"%s, [%s]",
VolumeLabel,
TempStr
);
OptionNumber++;
InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link);
}
}
if (NoSimpleFsHandles != 0) {
SafeFreePool (SimpleFsHandle);
}
//
// Searching for handles that support Load File protocol
//
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiLoadFileProtocolGuid,
NULL,
&NoLoadFileHandles,
&LoadFileHandle
);
if (!EFI_ERROR (Status)) {
for (Index = 0; Index < NoLoadFileHandles; Index++) {
MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);
if (NULL == MenuEntry) {
SafeFreePool (LoadFileHandle);
return EFI_OUT_OF_RESOURCES;
}
FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;
FileContext->IsRemovableMedia = FALSE;
FileContext->IsLoadFile = TRUE;
FileContext->Handle = LoadFileHandle[Index];
FileContext->IsRoot = TRUE;
FileContext->DevicePath = EfiDevicePathFromHandle (FileContext->Handle);
MenuEntry->HelpString = DevicePathToStr (FileContext->DevicePath);
TempStr = MenuEntry->HelpString;
MenuEntry->DisplayString = EfiAllocateZeroPool (MAX_CHAR);
ASSERT (MenuEntry->DisplayString != NULL);
SPrint (
MenuEntry->DisplayString,
MAX_CHAR,
L"Load File [%s]",
TempStr
);
MenuEntry->OptionNumber = OptionNumber;
OptionNumber++;
InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?