setup.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,957 行 · 第 1/5 页
C
1,957 行
);
PrintAt (
gScreenDimensions.RightColumn - (GetStringWidth (HomeEscapeString) / 2) - 2,
gScreenDimensions.BottomRow - 3,
L" %s",
HomeEscapeString
);
gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
gBS->FreePool (HomeEscapeString);
gBS->FreePool (HomePageString);
return ;
}
CHAR16 *
GetToken (
IN STRING_REF Token,
IN EFI_HII_HANDLE HiiHandle
)
/*++
Routine Description:
Get the string based on the TokenID and HII Handle.
Arguments:
Token - The Token ID.
HiiHandle - Handle of Ifr to be fetched.
Returns:
The output string.
--*/
{
CHAR16 *Buffer;
UINTN BufferLength;
EFI_STATUS Status;
//
// Set default string size assumption at no more than 256 bytes
//
BufferLength = 0x100;
Buffer = EfiLibAllocateZeroPool (BufferLength);
ASSERT (Buffer != NULL);
Status = Hii->GetString (Hii, HiiHandle, Token, TRUE, NULL, &BufferLength, Buffer);
if (EFI_ERROR (Status)) {
if (Status == EFI_BUFFER_TOO_SMALL) {
//
// Free the old pool
//
gBS->FreePool (Buffer);
//
// Allocate new pool with correct value
//
Buffer = EfiLibAllocatePool (BufferLength);
ASSERT (Buffer != NULL);
Status = Hii->GetString (Hii, HiiHandle, Token, TRUE, NULL, &BufferLength, Buffer);
if (!EFI_ERROR (Status)) {
return Buffer;
}
}
ASSERT_EFI_ERROR (Status);
}
return Buffer;
}
EFI_STATUS
PopulateHomePage (
IN UINTN NumberOfIfrImages,
IN EFI_FILE_FORM_TAGS *FileFormTagsHead
)
{
EFI_STATUS Status;
UINTN Index;
EFI_IFR_BINARY *IfrBinary;
CHAR16 *StringPtr;
EFI_FILE_FORM_TAGS *FileFormTags;
EFI_FORM_TAGS LocalTags;
FileFormTags = FileFormTagsHead;
UiInitMenu ();
Status = EFI_SUCCESS;
//
// If there are no images
//
if (NumberOfIfrImages == 0) {
Status = EFI_NO_MEDIA;
return Status;
}
//
// IfrBinary points to the beginning of the Binary data linked-list
//
IfrBinary = gBinaryDataHead;
//
// Print the entries which were in the default language.
//
for (Index = 0; Index < NumberOfIfrImages; Index++) {
LocalTags = FileFormTags->FormTags;
//
// Populate the Menu
//
StringPtr = GetToken (IfrBinary->TitleToken, IfrBinary->Handle);
//
// If the default language doesn't exist, don't add a menu option yet
//
if (StringPtr[0] != CHAR_NULL) {
//
// We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do
// it in UiFreeMenu.
//
UiAddMenuOption (StringPtr, IfrBinary->Handle, LocalTags.Tags, IfrBinary->FormBinary, Index);
}
//
// Advance to the next HII handle
//
IfrBinary = IfrBinary->Next;
FileFormTags = FileFormTags->NextFile;
}
return Status;
}
UI_MENU_OPTION *
DisplayHomePage (
IN UINTN NumberOfIfrImages,
IN EFI_FILE_FORM_TAGS *FileFormTagsHead,
IN UINT8 *CallbackData
)
{
EFI_STATUS Status;
UI_MENU_OPTION *Selection;
//
// This prints the basic home page template which the user sees
//
InitPage ();
Status = PopulateHomePage (NumberOfIfrImages, FileFormTagsHead);
if (EFI_ERROR (Status)) {
Selection = NULL;
return Selection;
}
Selection = UiDisplayMenu (FALSE, FileFormTagsHead, (EFI_IFR_DATA_ARRAY *) CallbackData);
return Selection;
}
EFI_STATUS
InitializeBinaryStructures (
IN EFI_HII_HANDLE *Handle,
IN BOOLEAN UseDatabase,
IN EFI_IFR_PACKET *Packet,
IN UINT8 *NvMapOverride,
IN UINTN NumberOfIfrImages,
OUT EFI_FILE_FORM_TAGS **FileFormTagsHead
)
{
UINTN HandleIndex;
EFI_STATUS Status;
EFI_IFR_BINARY *BinaryData;
EFI_FILE_FORM_TAGS *FileFormTags;
UINTN SizeOfNvStore;
EFI_FORM_CALLBACK_PROTOCOL *FormCallback;
EFI_VARIABLE_DEFINITION *VariableDefinition;
EFI_VARIABLE_DEFINITION *OverrideDefinition;
VOID *NvMap;
UINTN NvMapSize;
EFI_HII_VARIABLE_PACK_LIST *NvMapListHead;
EFI_HII_VARIABLE_PACK_LIST *NvMapListNode;
//
// Initialize some variables to avoid warnings
//
BinaryData = NULL;
*FileFormTagsHead = NULL;
FileFormTags = NULL;
gBinaryDataHead = NULL;
Status = EFI_SUCCESS;
FormCallback = NULL;
NvMap = NULL;
NvMapSize = 0;
if (NumberOfIfrImages > 1) {
NvMapOverride = NULL;
}
for (HandleIndex = 0; HandleIndex < NumberOfIfrImages; HandleIndex += 1) {
//
// If the buffers are uninitialized, allocate them, otherwise work on the ->Next members
//
if ((BinaryData == NULL) || (FileFormTags == NULL)) {
//
// Allocate memory for our Binary Data
//
BinaryData = EfiLibAllocateZeroPool (sizeof (EFI_IFR_BINARY));
ASSERT (BinaryData);
//
// Preserve the Head of what will be a linked-list.
//
gBinaryDataHead = BinaryData;
gBinaryDataHead->Next = NULL;
if (UseDatabase) {
Status = GetIfrBinaryData (Hii, Handle[HandleIndex], NULL, BinaryData);
} else {
Status = GetIfrBinaryData (Hii, Handle[HandleIndex], Packet, BinaryData);
}
//
// Allocate memory for our File Form Tags
//
FileFormTags = EfiLibAllocateZeroPool (sizeof (EFI_FILE_FORM_TAGS));
ASSERT (FileFormTags);
//
// Preserve the Head of what will be a linked-list.
//
*FileFormTagsHead = FileFormTags;
(*FileFormTagsHead)->NextFile = NULL;
} else {
//
// Allocate memory for our Binary Data linked-list
// Each handle represents a Binary and we will store that data away.
//
BinaryData->Next = EfiLibAllocateZeroPool (sizeof (EFI_IFR_BINARY));
ASSERT (BinaryData->Next);
BinaryData = BinaryData->Next;
BinaryData->Next = NULL;
if (UseDatabase) {
Status = GetIfrBinaryData (Hii, Handle[HandleIndex], NULL, BinaryData);
} else {
Status = GetIfrBinaryData (Hii, Handle[HandleIndex], Packet, BinaryData);
}
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
//
// Allocate memory for our FileFormTags linked-list
// Each allocation reserves handle represents a Binary and we will store that data away.
//
FileFormTags->NextFile = EfiLibAllocateZeroPool (sizeof (EFI_FILE_FORM_TAGS));
ASSERT (FileFormTags->NextFile);
FileFormTags = FileFormTags->NextFile;
}
//
// endif
//
// Tag Structure Initialization
//
Status = InitializeTagStructures (BinaryData, FileFormTags);
VariableDefinition = FileFormTags->VariableDefinitions;
//
// Allocate memory for our NVRAM Maps for all of our variables
//
for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {
//
// Pad the fake variable size accordingly - this value should reflect the size of information that is not accounted by
// the mainstream NVRAM variable such as DATE/TIME information that the browser needs to track but is saved to an RTC
//
VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableSize + VariableDefinition->VariableFakeSize);
//
// In the case where a file has no "real" NV data, we should pad the buffer accordingly
//
if (VariableDefinition->VariableSize == 0) {
VariableDefinition->NvRamMap = EfiLibAllocateZeroPool (VariableDefinition->VariableFakeSize);
} else {
VariableDefinition->NvRamMap = EfiLibAllocateZeroPool (VariableDefinition->VariableSize);
}
VariableDefinition->FakeNvRamMap = EfiLibAllocateZeroPool (VariableDefinition->VariableFakeSize);
ASSERT (VariableDefinition->NvRamMap);
ASSERT (VariableDefinition->FakeNvRamMap);
}
Status = gBS->HandleProtocol (
(VOID *) (UINTN) FileFormTags->FormTags.Tags[0].CallbackHandle,
&gEfiFormCallbackProtocolGuid,
&FormCallback
);
//
// Since we might have multiple variables, if there is an NvMapOverride we need to use the EFI_VARIABLE_DEFINITION
// information as the information that we pass back and forth. NOTE that callbacks that are initiated will only have the
// NVRAM data refreshed based on the op-code that initiated the callback. In other words, we will pass to the caller a single
// NVRAM map for a single variable based on the op-code that the user selected.
//
if (NvMapOverride != NULL) {
VariableDefinition = FileFormTags->VariableDefinitions;
OverrideDefinition = ((EFI_VARIABLE_DEFINITION *) NvMapOverride);
//
// Search through the variable definitions. There should be sufficient passed in settings for the variable op-codes specified
//
for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {
if ((!EfiCompareMem (VariableDefinition->VariableName, L"Setup", 10)) && (VariableDefinition->Next == NULL)) {
if (VariableDefinition->VariableSize != 0) {
EfiCopyMem (VariableDefinition->NvRamMap, NvMapOverride, VariableDefinition->VariableSize);
} else {
EfiCopyMem (VariableDefinition->NvRamMap, NvMapOverride, VariableDefinition->VariableFakeSize);
}
break;
} else {
VariableDefinition->NvRamMap = OverrideDefinition->NvRamMap;
}
//
// There should NEVER be a ->Next for VariableDefinition and a NULL ->Next for the OverrideDefinition
//
ASSERT (OverrideDefinition->Next);
OverrideDefinition = OverrideDefinition->Next;
}
} else {
VariableDefinition = FileFormTags->VariableDefinitions;
//
// Search through the variable definitions. There should be sufficient passed in settings for the variable op-codes specified
//
for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {
SizeOfNvStore = VariableDefinition->VariableSize;
//
// Getting the NvStore and placing it into our Global Data
//
if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {
Status = FormCallback->NvRead (
FormCallback,
VariableDefinition->VariableName,
&VariableDefinition->Guid,
NULL,
&SizeOfNvStore,
(VOID *) VariableDefinition->NvRamMap
);
} else {
Status = gRT->GetVariable (
VariableDefinition->VariableName,
&VariableDefinition->Guid,
NULL,
&SizeOfNvStore,
(VOID *) VariableDefinition->NvRamMap
);
}
if (EFI_ERROR (Status)) {
//
// If there is a variable that exists already and it is larger than what we calculated the
// storage needs to be, we must assume the variable size from GetVariable is correct and not
// allow the truncation of the variable. It is very possible that the user who created the IFR
// we are cracking is not referring to a variable that was in a previous map, however we cannot
// allow it's truncation.
//
if (Status == EFI_BUFFER_TOO_SMALL) {
//
// If the buffer was too small, we should have the expanded size requirement in SizeOfNvStore now.
//
VariableDefinition->VariableSize = (UINT16) SizeOfNvStore;
//
// Free the buffer that was allocated that was too small
//
gBS->FreePool (VariableDefinition->NvRamMap);
gBS->FreePool (VariableDefinition->FakeNvRamMap);
VariableDefinition->NvRamMap = EfiLibAllocateZeroPool (SizeOfNvStore);
Vari
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?