bdsmisc.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,279 行 · 第 1/3 页
C
1,279 行
if (Variable == NULL) {
return NULL;
}
//
// Notes: careful defined the variable of Boot#### or
// Driver####, consider use some macro to abstract the code
//
//
// Get the option attribute
//
TempPtr = Variable;
Attribute = *(UINT32 *) Variable;
TempPtr += sizeof (UINT32);
//
// Get the option's device path size
//
FilePathSize = *(UINT16 *) TempPtr;
TempPtr += sizeof (UINT16);
//
// Get the option's description string
//
Description = (CHAR16 *) TempPtr;
//
// Get the option's description string size
//
TempPtr += EfiStrSize ((CHAR16 *) TempPtr);
//
// Get the option's device path
//
DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
TempPtr += FilePathSize;
LoadOptions = TempPtr;
LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable));
//
// The Console variables may have multiple device paths, so make
// an Entry for each one.
//
Option = EfiLibAllocateZeroPool (sizeof (BDS_COMMON_OPTION));
if (Option == NULL) {
return NULL;
}
Option->Signature = BDS_LOAD_OPTION_SIGNATURE;
Option->DevicePath = EfiLibAllocateZeroPool (EfiDevicePathSize (DevicePath));
EfiCopyMem (Option->DevicePath, DevicePath, EfiDevicePathSize (DevicePath));
Option->Attribute = Attribute;
Option->Description = EfiLibAllocateZeroPool (EfiStrSize (Description));
EfiCopyMem (Option->Description, Description, EfiStrSize (Description));
Option->LoadOptions = EfiLibAllocateZeroPool (LoadOptionsSize);
EfiCopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize);
Option->LoadOptionsSize = LoadOptionsSize;
//
// Insert active entry to BdsDeviceList
//
if ((Option->Attribute & LOAD_OPTION_ACTIVE) == LOAD_OPTION_ACTIVE) {
InsertTailList (BdsCommonOptionList, &Option->Link);
gBS->FreePool (Variable);
return Option;
}
gBS->FreePool (Variable);
gBS->FreePool (Option);
return NULL;
}
EFI_STATUS
BdsLibBuildOptionFromVar (
IN EFI_LIST_ENTRY *BdsCommonOptionList,
IN CHAR16 *VariableName
)
/*++
Routine Description:
Process BootOrder, or DriverOrder variables, by calling
BdsLibVariableToOption () for each UINT16 in the variables.
Arguments:
BdsCommonOptionList - The header of the option list base on variable
VariableName
VariableName - EFI Variable name indicate the BootOrder or DriverOrder
Returns:
EFI_SUCCESS - Success create the boot option or driver option list
EFI_OUT_OF_RESOURCES - Failed to get the boot option or driver option list
--*/
{
UINT16 *OptionOrder;
UINTN OptionOrderSize;
UINTN Index;
BDS_COMMON_OPTION *Option;
CHAR16 OptionName[20];
//
// Zero Buffer in order to get all BOOT#### variables
//
EfiZeroMem (OptionName, sizeof (OptionName));
//
// Read the BootOrder, or DriverOrder variable.
//
OptionOrder = BdsLibGetVariableAndSize (
VariableName,
&gEfiGlobalVariableGuid,
&OptionOrderSize
);
if (OptionOrder == NULL) {
return EFI_OUT_OF_RESOURCES;
}
for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) {
if (*VariableName == 'B') {
SPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionOrder[Index]);
} else {
SPrint (OptionName, sizeof (OptionName), L"Driver%04x", OptionOrder[Index]);
}
Option = BdsLibVariableToOption (BdsCommonOptionList, OptionName);
Option->BootCurrent = OptionOrder[Index];
}
gBS->FreePool (OptionOrder);
return EFI_SUCCESS;
}
EFI_STATUS
BdsLibGetBootMode (
OUT EFI_BOOT_MODE *BootMode
)
/*++
Routine Description:
Get boot mode by looking up configuration table and parsing HOB list
Arguments:
BootMode - Boot mode from PEI handoff HOB.
Returns:
EFI_SUCCESS - Successfully get boot mode
EFI_NOT_FOUND - Can not find the current system boot mode
--*/
{
VOID *HobList;
EFI_STATUS Status;
//
// Get Hob list
//
Status = EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "Hob list not found\n"));
*BootMode = 0;
return EFI_NOT_FOUND;
}
Status = GetHobBootMode (HobList, BootMode);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
VOID *
BdsLibGetVariableAndSize (
IN CHAR16 *Name,
IN EFI_GUID *VendorGuid,
OUT UINTN *VariableSize
)
/*++
Routine Description:
Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
buffer, and the size of the buffer. If failure return NULL.
Arguments:
Name - String part of EFI variable name
VendorGuid - GUID part of EFI variable name
VariableSize - Returns the size of the EFI variable that was read
Returns:
Dynamically allocated memory that contains a copy of the EFI variable.
Caller is responsible freeing the buffer.
NULL - Variable was not read
--*/
{
EFI_STATUS Status;
UINTN BufferSize;
VOID *Buffer;
Buffer = NULL;
//
// Pass in a zero size buffer to find the required buffer size.
//
BufferSize = 0;
Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
if (Status == EFI_BUFFER_TOO_SMALL) {
//
// Allocate the buffer to return
//
Buffer = EfiLibAllocateZeroPool (BufferSize);
if (Buffer == NULL) {
return NULL;
}
//
// Read variable into the allocated buffer.
//
Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
if (EFI_ERROR (Status)) {
BufferSize = 0;
}
}
*VariableSize = BufferSize;
return Buffer;
}
EFI_DEVICE_PATH_PROTOCOL *
BdsLibDelPartMatchInstance (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,
IN EFI_DEVICE_PATH_PROTOCOL *Single
)
/*++
Routine Description:
Delete the instance in Multi which matches partly with Single instance
Arguments:
Multi - A pointer to a multi-instance device path data structure.
Single - A pointer to a single-instance device path data structure.
Returns:
This function will remove the device path instances in Multi which partly
match with the Single, and return the result device path. If there is no
remaining device path as a result, this function will return NULL.
--*/
{
EFI_DEVICE_PATH_PROTOCOL *Instance;
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;
UINTN InstanceSize;
UINTN SingleDpSize;
UINTN Size;
NewDevicePath = NULL;
TempNewDevicePath = NULL;
if (Multi == NULL || Single == NULL) {
return Multi;
}
Instance = EfiDevicePathInstance (&Multi, &InstanceSize);
SingleDpSize = EfiDevicePathSize (Single) - END_DEVICE_PATH_LENGTH;
InstanceSize -= END_DEVICE_PATH_LENGTH;
while (Instance != NULL) {
Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize;
if ((EfiCompareMem (Instance, Single, Size) != 0)) {
//
// Append the device path instance which does not match with Single
//
TempNewDevicePath = NewDevicePath;
NewDevicePath = EfiAppendDevicePathInstance (NewDevicePath, Instance);
EfiLibSafeFreePool(TempNewDevicePath);
}
EfiLibSafeFreePool(Instance);
Instance = EfiDevicePathInstance (&Multi, &InstanceSize);
InstanceSize -= END_DEVICE_PATH_LENGTH;
}
return NewDevicePath;
}
BOOLEAN
BdsLibMatchDevicePaths (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,
IN EFI_DEVICE_PATH_PROTOCOL *Single
)
/*++
Routine Description:
Function compares a device path data structure to that of all the nodes of a
second device path instance.
Arguments:
Multi - A pointer to a multi-instance device path data structure.
Single - A pointer to a single-instance device path data structure.
Returns:
TRUE - If the Single is contained within Multi
FALSE - The Single is not match within Multi
--*/
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
UINTN Size;
if (!Multi || !Single) {
return FALSE;
}
DevicePath = Multi;
DevicePathInst = EfiDevicePathInstance (&DevicePath, &Size);
//
// Search for the match of 'Single' in 'Multi'
//
while (DevicePathInst != NULL) {
//
// If the single device path is found in multiple device paths,
// return success
//
if (EfiCompareMem (Single, DevicePathInst, Size) == 0) {
gBS->FreePool (DevicePathInst);
return TRUE;
}
gBS->FreePool (DevicePathInst);
DevicePathInst = EfiDevicePathInstance (&DevicePath, &Size);
}
return FALSE;
}
EFI_STATUS
BdsLibOutputStrings (
IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *ConOut,
...
)
/*++
Routine Description:
This function prints a series of strings.
Arguments:
ConOut - Pointer to EFI_SIMPLE_TEXT_OUT_PROTOCOL
... - A variable argument list containing series of strings,
the last string must be NULL.
Returns:
EFI_SUCCESS - Success print out the string using ConOut.
EFI_STATUS - Return the status of the ConOut->OutputString ().
--*/
{
VA_LIST args;
EFI_STATUS Status;
CHAR16 *String;
Status = EFI_SUCCESS;
VA_START (args, ConOut);
while (!EFI_ERROR (Status)) {
//
// If String is NULL, then it's the end of the list
//
String = VA_ARG (args, CHAR16 *);
if (!String) {
break;
}
Status = ConOut->OutputString (ConOut, String);
if (EFI_ERROR (Status)) {
break;
}
}
return Status;
}
//
// Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.
// Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if
// user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.
//
VOID
EnableResetReminderFeature (
VOID
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?