bdsboot.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,112 行 · 第 1/3 页
C
1,112 行
HARDDRIVE_DEVICE_PATH *TmpHdPath;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
UINTN Index;
BOOLEAN DevicePathMatch;
HARDDRIVE_DEVICE_PATH *TempPath;
*ExitDataSize = 0;
*ExitData = NULL;
if ( !((DevicePathType (&HardDriveDevicePath->Header) == MEDIA_DEVICE_PATH) &&
(DevicePathSubType (&HardDriveDevicePath->Header) == MEDIA_HARDDRIVE_DP))
) {
//
// If the HardDriveDevicePath does not start with a Hard Drive Device Path
// exit.
//
return EFI_NOT_FOUND;
}
//
// The boot device have already been connected
//
Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &BlockIoHandleCount, &BlockIoBuffer);
if (EFI_ERROR (Status) || BlockIoHandleCount == 0) {
//
// If there was an error or there are no device handles that support
// the BLOCK_IO Protocol, then return.
//
return EFI_NOT_FOUND;
}
//
// Loop through all the device handles that support the BLOCK_IO Protocol
//
for (Index = 0; Index < BlockIoHandleCount; Index++) {
Status = gBS->HandleProtocol (BlockIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *) &BlockIoDevicePath);
if (EFI_ERROR (Status) || BlockIoDevicePath == NULL) {
continue;
}
//
// Make PreviousDevicePath == the device path node before the end node
//
DevicePath = BlockIoDevicePath;
BlockIoHdDevicePath = NULL;
//
// find HardDriver device path node
//
while (!IsDevicePathEnd (DevicePath)) {
if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
(DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)
) {
BlockIoHdDevicePath = DevicePath;
break;
}
DevicePath = NextDevicePathNode (DevicePath);
}
if (BlockIoHdDevicePath == NULL) {
continue;
}
//
// See if the harddrive device path in blockio matches the orig Hard Drive Node
//
DevicePathMatch = FALSE;
TmpHdPath = (HARDDRIVE_DEVICE_PATH *) BlockIoHdDevicePath;
TempPath = (HARDDRIVE_DEVICE_PATH *) BdsLibUnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath);
//
// Only several fields will be checked. NOT whole NODE
//
if ( TmpHdPath->PartitionNumber == TempPath->PartitionNumber &&
TmpHdPath->MBRType == TempPath->MBRType &&
TmpHdPath->SignatureType == TempPath->SignatureType &&
EfiCompareGuid ((EFI_GUID *) TmpHdPath->Signature, (EFI_GUID *) TempPath->Signature)) {
//
// Get the matched device path
//
DevicePathMatch = TRUE;
}
//
// Only do the boot, when devicepath match
//
if (DevicePathMatch) {
//
// Combine the Block IO and Hard Drive Device path together and try
// to boot from it.
//
DevicePath = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath);
NewDevicePath = EfiAppendDevicePath (BlockIoDevicePath, DevicePath);
//
// Recursive boot with new device path
//
Status = BdsLibBootViaBootOption (Option, NewDevicePath, ExitDataSize, ExitData);
if (!EFI_ERROR (Status)) {
break;
}
}
}
gBS->FreePool (BlockIoBuffer);
return Status;
}
EFI_STATUS
BdsLibDeleteOptionFromHandle (
IN EFI_HANDLE Handle
)
/*++
Routine Description:
Delete the boot option associated with the handle passed in
Arguments:
Handle - The handle which present the device path to create boot option
Returns:
EFI_SUCCESS - Delete the boot option success
EFI_NOT_FOUND - If the Device Path is not found in the system
EFI_OUT_OF_RESOURCES - Lack of memory resource
Other - Error return value from SetVariable()
--*/
{
UINT16 *BootOrder;
UINT8 *BootOptionVar;
UINTN BootOrderSize;
UINTN BootOptionSize;
EFI_STATUS Status;
UINTN Index;
UINT16 BootOption[BOOT_OPTION_MAX_CHAR];
UINTN DevicePathSize;
UINTN OptionDevicePathSize;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath;
UINT8 *TempPtr;
CHAR16 *Description;
Status = EFI_SUCCESS;
BootOrder = NULL;
BootOrderSize = 0;
BootOrder = BdsLibGetVariableAndSize (
L"BootOrder",
&gEfiGlobalVariableGuid,
&BootOrderSize
);
if (NULL == BootOrder) {
return EFI_NOT_FOUND;
}
DevicePath = EfiDevicePathFromHandle (Handle);
if (DevicePath == NULL) {
return EFI_NOT_FOUND;
}
DevicePathSize = EfiDevicePathSize (DevicePath);
Index = 0;
while (Index < BootOrderSize / sizeof (UINT16)) {
SPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
BootOptionVar = BdsLibGetVariableAndSize (
BootOption,
&gEfiGlobalVariableGuid,
&BootOptionSize
);
if (NULL == BootOptionVar) {
gBS->FreePool (BootOrder);
return EFI_OUT_OF_RESOURCES;
}
TempPtr = BootOptionVar;
TempPtr += sizeof (UINT32) + sizeof (UINT16);
Description = (CHAR16 *) TempPtr;
TempPtr += EfiStrSize ((CHAR16 *) TempPtr);
OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
OptionDevicePathSize = EfiDevicePathSize (OptionDevicePath);
//
// Check whether the device path match
//
if ((OptionDevicePathSize == DevicePathSize) &&
(EfiCompareMem (DevicePath, OptionDevicePath, DevicePathSize) == 0)) {
BdsDeleteBootOption (BootOrder[Index], BootOrder, &BootOrderSize);
gBS->FreePool (BootOptionVar);
break;
}
gBS->FreePool (BootOptionVar);
Index++;
}
Status = gRT->SetVariable (
L"BootOrder",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
BootOrderSize,
BootOrder
);
gBS->FreePool (BootOrder);
return Status;
}
EFI_STATUS
BdsDeleteAllInvalidEfiBootOption (
VOID
)
/*++
Routine Description:
Delete all invalid EFI boot options. The probable invalid boot option could
be Removable media or Network boot device.
Arguments:
VOID
Returns:
EFI_SUCCESS - Delete all invalid boot option success
EFI_NOT_FOUND - Variable "BootOrder" is not found
EFI_OUT_OF_RESOURCES - Lack of memory resource
Other - Error return value from SetVariable()
--*/
{
UINT16 *BootOrder;
UINT8 *BootOptionVar;
UINTN BootOrderSize;
UINTN BootOptionSize;
EFI_STATUS Status;
UINTN Index;
UINTN Index2;
UINT16 BootOption[BOOT_OPTION_MAX_CHAR];
UINTN OptionDevicePathSize;
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode;
EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath;
UINT8 *TempPtr;
CHAR16 *Description;
EFI_HANDLE Handle;
BOOLEAN NeedDelete;
Status = EFI_SUCCESS;
BootOrder = NULL;
BootOrderSize = 0;
BootOrder = BdsLibGetVariableAndSize (
L"BootOrder",
&gEfiGlobalVariableGuid,
&BootOrderSize
);
if (NULL == BootOrder) {
return EFI_NOT_FOUND;
}
Index = 0;
while (Index < BootOrderSize / sizeof (UINT16)) {
SPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
BootOptionVar = BdsLibGetVariableAndSize (
BootOption,
&gEfiGlobalVariableGuid,
&BootOptionSize
);
if (NULL == BootOptionVar) {
gBS->FreePool (BootOrder);
return EFI_OUT_OF_RESOURCES;
}
TempPtr = BootOptionVar;
TempPtr += sizeof (UINT32) + sizeof (UINT16);
Description = (CHAR16 *) TempPtr;
TempPtr += EfiStrSize ((CHAR16 *) TempPtr);
OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
OptionDevicePathSize = EfiDevicePathSize (OptionDevicePath);
//
// Skip legacy boot option (BBS boot device)
//
if ((DevicePathType (OptionDevicePath) == BBS_DEVICE_PATH) &&
(DevicePathSubType (OptionDevicePath) == BBS_BBS_DP)) {
gBS->FreePool (BootOptionVar);
Index++;
continue;
}
TempDevicePath = OptionDevicePath;
LastDeviceNode = OptionDevicePath;
while (!EfiIsDevicePathEnd (TempDevicePath)) {
LastDeviceNode = TempDevicePath;
TempDevicePath = EfiNextDevicePathNode (TempDevicePath);
}
//
// Skip the boot option that point to a file, since the device path in
// removable media boot option doesn't contains a file name.
//
if (((DevicePathType (LastDeviceNode) == MEDIA_DEVICE_PATH) &&
(DevicePathSubType (LastDeviceNode) == MEDIA_FILEPATH_DP)) ||
//
// Skip boot option for internal Shell, it's always valid
//
(EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode) != NULL)) {
gBS->FreePool (BootOptionVar);
Index++;
continue;
}
NeedDelete = TRUE;
//
// Check if it's a valid boot option for removable media
//
TempDevicePath = OptionDevicePath;
Status = gBS->LocateDevicePath (
&gEfiSimpleFileSystemProtocolGuid,
&TempDevicePath,
&Handle
);
if (!EFI_ERROR (Status)) {
NeedDelete = FALSE;
}
//
// Check if it's a valid boot option for network boot device
//
TempDevicePath = OptionDevicePath;
Status = gBS->LocateDevicePath (
&gEfiLoadFileProtocolGuid,
&TempDevicePath,
&Handle
);
if (!EFI_ERROR (Status)) {
NeedDelete = FALSE;
}
if (NeedDelete) {
//
// Delete this invalid boot option "Boot####"
//
Status = gRT->SetVariable (
BootOption,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
NULL
);
//
// Mark this boot option in boot order as deleted
//
BootOrder[Index] = 0xffff;
}
gBS->FreePool (BootOptionVar);
Index++;
}
//
// Adjust boot order array
//
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?