bootoption.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,669 行 · 第 1/4 页
C
1,669 行
if (NoLoadFileHandles != 0) {
SafeFreePool (LoadFileHandle);
}
//
// Add Legacy Boot Option Support Here
//
Status = gBS->LocateProtocol (
&gEfiLegacyBiosProtocolGuid,
NULL,
&LegacyBios
);
if (!EFI_ERROR (Status)) {
for (Index = BBS_TYPE_FLOPPY; Index <= BBS_TYPE_EMBEDDED_NETWORK; Index++) {
MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);
if (NULL == MenuEntry) {
return EFI_OUT_OF_RESOURCES;
}
FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;
FileContext->IsRemovableMedia = FALSE;
FileContext->IsLoadFile = TRUE;
FileContext->IsBootLegacy = TRUE;
DeviceType = (UINT16) Index;
BbsDevicePathNode.Header.Type = BBS_DEVICE_PATH;
BbsDevicePathNode.Header.SubType = BBS_BBS_DP;
SetDevicePathNodeLength (
&BbsDevicePathNode.Header,
sizeof (BBS_BBS_DEVICE_PATH)
);
BbsDevicePathNode.DeviceType = DeviceType;
BbsDevicePathNode.StatusFlag = 0;
BbsDevicePathNode.String[0] = 0;
DevicePath = EfiAppendDevicePathNode (
EndDevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &BbsDevicePathNode
);
FileContext->DevicePath = DevicePath;
MenuEntry->HelpString = DevicePathToStr (FileContext->DevicePath);
TempStr = MenuEntry->HelpString;
MenuEntry->DisplayString = EfiAllocateZeroPool (MAX_CHAR);
ASSERT (MenuEntry->DisplayString != NULL);
SPrint (
MenuEntry->DisplayString,
MAX_CHAR,
L"Boot Legacy [%s]",
TempStr
);
MenuEntry->OptionNumber = OptionNumber;
OptionNumber++;
InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link);
}
}
//
// Remember how many file system options are here
//
FsOptionMenu.MenuNumber = OptionNumber;
return EFI_SUCCESS;
}
VOID
BOpt_FreeMenu (
BM_MENU_OPTION *FreeMenu
)
/*++
Routine Description
Free resources allocated in Allocate Rountine
Arguments:
FreeMenu Menu to be freed
Returns:
VOID
--*/
{
BM_MENU_ENTRY *MenuEntry;
while (!IsListEmpty (&FreeMenu->Head)) {
MenuEntry = CR (
FreeMenu->Head.ForwardLink,
BM_MENU_ENTRY,
Link,
BM_MENU_ENTRY_SIGNATURE
);
RemoveEntryList (&MenuEntry->Link);
BOpt_DestroyMenuEntry (MenuEntry);
}
}
EFI_STATUS
BOpt_FindFiles (
IN BMM_CALLBACK_DATA *CallbackData,
IN BM_MENU_ENTRY *MenuEntry
)
/*++
Routine Description
Find files under current directory
All files and sub-directories in current directory
will be stored in DirectoryMenu for future use.
Arguments:
FileOption -- Pointer for Dir to explore
Returns:
TRUE -- Get files from current dir successfully
FALSE -- Can't get files from current dir
--*/
{
EFI_FILE_HANDLE NewDir;
EFI_FILE_HANDLE Dir;
EFI_FILE_INFO *DirInfo;
UINTN BufferSize;
UINTN DirBufferSize;
BM_MENU_ENTRY *NewMenuEntry;
BM_FILE_CONTEXT *FileContext;
BM_FILE_CONTEXT *NewFileContext;
UINTN Pass;
EFI_STATUS Status;
UINTN OptionNumber;
FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext;
Dir = FileContext->FHandle;
OptionNumber = 0;
//
// Open current directory to get files from it
//
Status = Dir->Open (
Dir,
&NewDir,
FileContext->FileName,
EFI_FILE_READ_ONLY,
0
);
if (!FileContext->IsRoot) {
Dir->Close (Dir);
}
if (EFI_ERROR (Status)) {
return Status;
}
DirInfo = EfiLibFileInfo (NewDir);
if (!DirInfo) {
return EFI_NOT_FOUND;
}
if (!(DirInfo->Attribute & EFI_FILE_DIRECTORY)) {
return EFI_INVALID_PARAMETER;
}
FileContext->DevicePath = EfiFileDevicePath (
FileContext->Handle,
FileContext->FileName
);
DirBufferSize = sizeof (EFI_FILE_INFO) + 1024;
DirInfo = EfiAllocateZeroPool (DirBufferSize);
if (!DirInfo) {
return EFI_OUT_OF_RESOURCES;
}
//
// Get all files in current directory
// Pass 1 to get Directories
// Pass 2 to get files that are EFI images
//
for (Pass = 1; Pass <= 2; Pass++) {
NewDir->SetPosition (NewDir, 0);
for (;;) {
BufferSize = DirBufferSize;
Status = NewDir->Read (NewDir, &BufferSize, DirInfo);
if (EFI_ERROR (Status) || BufferSize == 0) {
break;
}
if ((DirInfo->Attribute & EFI_FILE_DIRECTORY && Pass == 2) ||
(!(DirInfo->Attribute & EFI_FILE_DIRECTORY) && Pass == 1)
) {
//
// Pass 1 is for Directories
// Pass 2 is for file names
//
continue;
}
if (!(BOpt_IsEfiImageName (DirInfo->FileName) || DirInfo->Attribute & EFI_FILE_DIRECTORY)) {
//
// Slip file unless it is a directory entry or a .EFI file
//
continue;
}
NewMenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT);
if (NULL == NewMenuEntry) {
return EFI_OUT_OF_RESOURCES;
}
NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;
NewFileContext->Handle = FileContext->Handle;
NewFileContext->FileName = BOpt_AppendFileName (
FileContext->FileName,
DirInfo->FileName
);
NewFileContext->FHandle = NewDir;
NewFileContext->DevicePath = EfiFileDevicePath (
NewFileContext->Handle,
NewFileContext->FileName
);
NewMenuEntry->HelpString = NULL;
MenuEntry->DisplayStringToken = GetStringTokenFromDepository (
CallbackData,
FileOptionStrDepository
);
NewFileContext->IsDir = (BOOLEAN) ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY);
if (NewFileContext->IsDir) {
BufferSize = EfiStrLen (DirInfo->FileName) * 2 + 6;
NewMenuEntry->DisplayString = EfiAllocateZeroPool (BufferSize);
SPrint (
NewMenuEntry->DisplayString,
BufferSize,
L"<%s>",
DirInfo->FileName
);
} else {
NewMenuEntry->DisplayString = EfiStrDuplicate (DirInfo->FileName);
}
NewFileContext->IsRoot = FALSE;
NewFileContext->IsLoadFile = FALSE;
NewFileContext->IsRemovableMedia = FALSE;
NewMenuEntry->OptionNumber = OptionNumber;
OptionNumber++;
InsertTailList (&DirectoryMenu.Head, &NewMenuEntry->Link);
}
}
DirectoryMenu.MenuNumber = OptionNumber;
SafeFreePool (DirInfo);
return TRUE;
}
EFI_STATUS
BOpt_GetLegacyOptions (
VOID
)
/*++
Routine Description:
Build the LegacyFDMenu LegacyHDMenu LegacyCDMenu according to LegacyBios.GetBbsInfo().
Arguments:
None
Returns:
The device info of legacy device.
--*/
{
BM_MENU_ENTRY *NewMenuEntry;
BM_LEGACY_DEVICE_CONTEXT *NewLegacyDevContext;
EFI_STATUS Status;
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
UINT16 HddCount;
HDD_INFO *HddInfo;
UINT16 BbsCount;
BBS_TABLE *BbsTable;
UINTN Index;
CHAR16 DescString[100];
UINTN FDNum;
UINTN HDNum;
UINTN CDNum;
UINTN NETNum;
UINTN BEVNum;
NewMenuEntry = NULL;
HddInfo = NULL;
BbsTable = NULL;
BbsCount = 0;
//
// Initialize Bbs Table Context from BBS info data
//
InitializeListHead (&LegacyFDMenu.Head);
InitializeListHead (&LegacyHDMenu.Head);
InitializeListHead (&LegacyCDMenu.Head);
InitializeListHead (&LegacyNETMenu.Head);
InitializeListHead (&LegacyBEVMenu.Head);
Status = gBS->LocateProtocol (
&gEfiLegacyBiosProtocolGuid,
NULL,
&LegacyBios
);
if (!EFI_ERROR (Status)) {
Status = LegacyBios->GetBbsInfo (
LegacyBios,
&HddCount,
&HddInfo,
&BbsCount,
&BbsTable
);
if (EFI_ERROR (Status)) {
return Status;
}
}
FDNum = 0;
HDNum = 0;
CDNum = 0;
NETNum = 0;
BEVNum = 0;
for (Index = 0; Index < BbsCount; Index++) {
if ((BBS_IGNORE_ENTRY == BbsTable[Index].BootPriority) ||
(BBS_DO_NOT_BOOT_FROM == BbsTable[Index].BootPriority) ||
(BBS_LOWEST_PRIORITY == BbsTable[Index].BootPriority)
) {
continue;
}
NewMenuEntry = BOpt_CreateMenuEntry (BM_LEGACY_DEV_CONTEXT_SELECT);
if (NULL == NewMenuEntry) {
break;
}
NewLegacyDevContext = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;
NewLegacyDevContext->BbsTable = &BbsTable[Index];
NewLegacyDevContext->Index = Index;
NewLegacyDevContext->BbsCount = BbsCount;
BdsBuildLegacyDevNameString (
&BbsTable[Index],
Index,
sizeof (DescString),
DescString
);
NewLegacyDevContext->Description = EfiAllocateZeroPool (EfiStrSize (DescString));
if (NULL == NewLegacyDevContext->Description) {
break;
}
EfiCopyMem (NewLegacyDevContext->Description, DescString, EfiStrSize (DescString));
NewMenuEntry->DisplayString = NewLegacyDevContext->Description;
NewMenuEntry->HelpString = NULL;
switch (BbsTable[Index].DeviceType) {
case BBS_FLOPPY:
InsertTailList (&LegacyFDMenu.Head, &NewMenuEntry->Link);
FDNum++;
break;
case BBS_HARDDISK:
InsertTailList (&LegacyHDMenu.Head, &NewMenuEntry->Link);
HDNum++;
break;
case BBS_CDROM:
InsertTailList (&LegacyCDMenu.Head, &NewMenuEntry->Link);
CDNum++;
break;
case BBS_EMBED_NETWORK:
InsertTailList (&LegacyNETMenu.Head, &NewMenuEntry->Link);
NETNum++;
break;
case BBS_BEV_DEVICE:
InsertTailList (&LegacyBEVMenu.Head, &NewMenuEntry->Link);
BEVNum++;
break;
}
}
if (Index != BbsCount) {
BOpt_FreeLegacyOptions ();
return EFI_OUT_OF_RESOURCES;
}
LegacyFDMenu.MenuNumber = FDNum;
LegacyHDMenu.MenuNumber = HDNum;
LegacyCDMenu.MenuNumber = CDNum;
LegacyNETMenu.MenuNumber = NETNum;
LegacyBEVMenu.MenuNumber = BEVNum;
return EFI_SUCCESS;
}
VOID
BOpt_FreeLegacyOptions (
VOID
)
{
BOpt_FreeMenu (&LegacyFDMenu);
BOpt_FreeMenu (&LegacyHDMenu);
BOpt_FreeMenu (&LegacyCDMenu);
BOpt_FreeMenu (&LegacyNETMenu);
BOpt_FreeMenu (&LegacyBEVMenu);
}
EFI_STATUS
BOpt_GetBootOptions (
IN BMM_CALLBACK_DATA *CallbackData
)
/*++
Routine Description:
Build the BootOptionMenu according to BootOrder Variable.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?