setup.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,957 行 · 第 1/5 页
C
1,957 行
//
// Initialize some Index variable and Status
//
Count = 0;
Class = 0;
SubClass = 0;
CurrentVariable = 0;
CurrentVariable2 = 0;
QuestionIndex = 0;
NumberOfTags = 1;
Status = EFI_SUCCESS;
FormTags = &FileFormTags->FormTags;
FormTags->Next = NULL;
if (FileFormTags->InconsistentTags == NULL) {
InconsistentTags = NULL;
} else {
InconsistentTags = FileFormTags->InconsistentTags;
}
if (FileFormTags->VariableDefinitions == NULL) {
VariableDefinitions = NULL;
} else {
VariableDefinitions = FileFormTags->VariableDefinitions;
}
//
// RawFormSet now points to the beginning of the forms portion of
// the specific IFR Binary.
//
RawFormSet = (UINT8 *) BinaryData->FormBinary;
//
// Determine the number of tags for the first form
//
GetTagCount (&RawFormSet[0], &NumberOfTags);
SavedFormTags = FormTags;
if (FormTags->Tags != NULL) {
do {
//
// Advance FormTags to the last entry
//
for (; FormTags->Next != NULL; FormTags = FormTags->Next)
;
//
// Walk through each of the tags and free the IntList allocation
//
for (Index = 0; Index < NumberOfTags; Index++) {
if (FormTags->Tags[Index].IntList != NULL) {
gBS->FreePool (FormTags->Tags[Index].IntList);
}
}
gBS->FreePool (FormTags->Tags);
gBS->FreePool (FormTags->Next);
FormTags->Next = NULL;
FormTags->Tags = NULL;
FormTags = SavedFormTags;
} while (FormTags->Next != NULL);
}
Index = 0;
//
// Test for an allocated buffer. If already allocated this is due to having called this routine
// once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
// the tag structure with current values from the NV
//
if (FormTags->Tags == NULL) {
//
// Allocate memory for our tags on the first form
//
FormTags->Tags = EfiLibAllocateZeroPool (NumberOfTags * sizeof (EFI_TAG));
ASSERT (FormTags->Tags);
}
//
// Test for an allocated buffer. If already allocated this is due to having called this routine
// once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
// the tag structure with current values from the NV
//
if (InconsistentTags == NULL) {
//
// We just hit the end of an inconsistent expression. Let's allocate the ->Next structure
//
InconsistentTags = EfiLibAllocateZeroPool (sizeof (EFI_INCONSISTENCY_DATA));
ASSERT (InconsistentTags != NULL);
FileFormTags->InconsistentTags = InconsistentTags;
}
EfiZeroMem (FormTags->Tags, NumberOfTags * sizeof (EFI_TAG));
for (CurrTag = 0; RawFormSet[Index] != EFI_IFR_END_FORM_SET_OP; CurrTag++) {
//
// Operand = IFR OpCode
//
FormTags->Tags[CurrTag].Operand = RawFormSet[Index];
//
// Assume for now 0 lines occupied by this OpCode
//
FormTags->Tags[CurrTag].NumberOfLines = 0;
FormTags->Tags[CurrTag].Class = Class;
FormTags->Tags[CurrTag].SubClass = SubClass;
//
// Determine the length of the Tag so we can later skip to the next tag in the form
//
TagLength = RawFormSet[Index + 1];
//
// get the length
//
// Operate on the Found OpCode
//
switch (RawFormSet[Index]) {
case EFI_IFR_FORM_OP:
//
// If there was no variable op-code defined, create a dummy entry for one
//
if (FileFormTags->VariableDefinitions == NULL) {
FileFormTags->VariableDefinitions = EfiLibAllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION));
ASSERT (FileFormTags->VariableDefinitions != NULL);
IfrToFormTag (
RawFormSet[Index],
&FormTags->Tags[CurrTag],
(VOID *) &RawFormSet[Index],
FileFormTags->VariableDefinitions
);
} else {
IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
}
break;
case EFI_IFR_SUBTITLE_OP:
case EFI_IFR_TEXT_OP:
case EFI_IFR_REF_OP:
IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
break;
case EFI_IFR_VARSTORE_OP:
if (FileFormTags->VariableDefinitions == NULL) {
VariableDefinitions = EfiLibAllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION));
ASSERT (VariableDefinitions != NULL);
FileFormTags->VariableDefinitions = VariableDefinitions;
}
IfrToFormTag (
RawFormSet[Index],
&FormTags->Tags[CurrTag],
(VOID *) &RawFormSet[Index],
FileFormTags->VariableDefinitions
);
break;
case EFI_IFR_VARSTORE_SELECT_OP:
IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
EfiCopyMem (&CurrentVariable, &((EFI_IFR_VARSTORE_SELECT *) &RawFormSet[Index])->VarId, sizeof (UINT16));
CurrentVariable2 = CurrentVariable;
break;
case EFI_IFR_VARSTORE_SELECT_PAIR_OP:
IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
EfiCopyMem(&CurrentVariable, &((EFI_IFR_VARSTORE_SELECT_PAIR *)&RawFormSet[Index])->VarId, sizeof (UINT16));
EfiCopyMem (
&CurrentVariable2,
&((EFI_IFR_VARSTORE_SELECT_PAIR *) &RawFormSet[Index])->SecondaryVarId,
sizeof (UINT16)
);
break;
case EFI_IFR_END_FORM_OP:
//
// Test for an allocated buffer. If already allocated this is due to having called this routine
// once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
// the tag structure with current values from the NV
//
if (FormTags->Next == NULL) {
//
// We just hit the end of a form. Let's allocate the ->Next structure
//
FormTags->Next = EfiLibAllocatePool (sizeof (EFI_FORM_TAGS));
ASSERT (FormTags->Next);
}
FormTags = FormTags->Next;
EfiZeroMem (FormTags, sizeof (EFI_FORM_TAGS));
//
// Reset the tag count to one
//
NumberOfTags = 1;
//
// Reset the CurrTag value (it will be incremented, after this case statement
// so set to a negative one so that we get the desired effect.) Fish can beat me later.
//
CurrTag = -1;
//
// Determine the number of tags after this form. If this is the last
// form, then we will count the endformset and preserve that information
// in the tag structure.
//
GetTagCount (&RawFormSet[Index + TagLength], &NumberOfTags);
//
// Allocate memory for our tags
//
FormTags->Tags = EfiLibAllocateZeroPool (NumberOfTags * sizeof (EFI_TAG));
ASSERT (FormTags->Tags);
break;
//
// Two types of tags constitute the One Of question: a one-of header and
// several one-of options.
//
case EFI_IFR_ONE_OF_OP:
case EFI_IFR_ORDERED_LIST_OP:
GetQuestionHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, FileFormTags, CurrentVariable);
//
// Store away the CurrTag since what follows will be the answer that we
// need to place into the appropriate location in the tag array
//
//
// record for setting default later
//
QuestionIndex = (UINT16) CurrTag;
break;
case EFI_IFR_ONE_OF_OPTION_OP:
IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
FormTags->Tags[QuestionIndex].Flags = ((EFI_IFR_ONE_OF_OPTION *) &RawFormSet[Index])->Flags;
EfiCopyMem (
&FormTags->Tags[QuestionIndex].Key,
&((EFI_IFR_ONE_OF_OPTION *) &RawFormSet[Index])->Key,
sizeof (UINT16)
);
FormTags->Tags[QuestionIndex].ResetRequired = (BOOLEAN) (FormTags->Tags[QuestionIndex].Flags & EFI_IFR_FLAG_RESET_REQUIRED);
break;
case EFI_IFR_CHECKBOX_OP:
GetQuestionHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, FileFormTags, CurrentVariable);
IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
break;
case EFI_IFR_NUMERIC_OP:
GetNumericHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, (UINT16) 1, FileFormTags, CurrentVariable);
IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
break;
case EFI_IFR_DATE_OP:
//
// Date elements come in as a Year, Month, Day. We need to process them as a country-based
// Order. It is much easier to do it here than anywhere else.
//
// For US standards - we want Month/Day/Year, thus we advance "Index" +1, +2, +0 while CurrTag is +0, +1, +2
//
GetNumericHeader (
&FormTags->Tags[CurrTag],
RawFormSet,
(UINT16) (Index + TagLength),
(UINT16) 0,
FileFormTags,
CurrentVariable
);
//
// The current language selected + the Date operand
//
FormTags->Tags[CurrTag + 1].Operand = RawFormSet[Index];
GetNumericHeader (
&FormTags->Tags[CurrTag + 1],
RawFormSet,
(UINT16) (Index + TagLength + RawFormSet[Index + TagLength + 1]),
(UINT16) 0,
FileFormTags,
CurrentVariable
);
//
// The current language selected + the Date operand
//
FormTags->Tags[CurrTag + 2].Operand = RawFormSet[Index];
GetNumericHeader (&FormTags->Tags[CurrTag + 2], RawFormSet, Index, (UINT16) 1, FileFormTags, CurrentVariable);
CurrTag = (INT16) (CurrTag + 2);
Index = (UINT16) (Index + TagLength);
//
// get the length
//
TagLength = RawFormSet[Index + 1];
Index = (UINT16) (Index + TagLength);
//
// get the length
//
TagLength = RawFormSet[Index + 1];
break;
case EFI_IFR_TIME_OP:
GetNumericHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, (UINT16) 0, FileFormTags, CurrentVariable);
if (Count == 2) {
//
// Override the GetQuestionHeader information - date/time are treated very differently
//
FormTags->Tags[CurrTag].NumberOfLines = 1;
Count = 0;
} else {
//
// The premise is that every date/time op-code have 3 elements, the first 2 have 0 lines
// associated with them, and the third has 1 line to allow to space beyond the choice.
//
Count++;
}
break;
case EFI_IFR_PASSWORD_OP:
case EFI_IFR_STRING_OP:
GetQuestionHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, FileFormTags, CurrentVariable);
IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
break;
case EFI_IFR_SUPPRESS_IF_OP:
case EFI_IFR_GRAYOUT_IF_OP:
InconsistentTags->Operand = ((EFI_IFR_INCONSISTENT *) &RawFormSet[Index])->Header.OpCode;
gConsistencyId++;
//
// Since this op-code doesn't use the next field(s), initialize them with something invalid.
// Unfortunately 0 is a valid offset value for a QuestionId
//
InconsistentTags->QuestionId1 = INVALID_OFFSET_VALUE;
InconsistentTags->QuestionId2 = INVALID_OFFSET_VALUE;
//
// Test for an allocated buffer. If already allocated this is due to having called this routine
// once for sizing of the NV storage. We then loaded the NV variable and can correctly initialize
// the tag structure with current values from the NV
//
if (InconsistentTags->Next == NULL) {
AddNextInconsistentTag (&InconsistentTags);
break;
}
InconsistentTags = InconsistentTags->Next;
break;
case EFI_IFR_FORM_SET_OP:
EfiCopyMem (
&FormTags->Tags[CurrTag].GuidValue,
&((EFI_IFR_FORM_SET *) &RawFormSet[Index])->Guid,
sizeof (EFI_GUID)
);
EfiCopyMem (
&FormTags->Tags[CurrTag].CallbackHandle,
&((EFI_IFR_FORM_SET *) &RawFormSet[Index])->CallbackHandle,
sizeof (EFI_PHYSICAL_ADDRESS)
);
EfiCopyMem (&FormTags->Tags[CurrTag].Class, &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->Class, sizeof (UINT8));
EfiCopyMem (
&FormTags->Tags[CurrTag].SubClass,
&((EFI_IFR_FORM_SET *) &RawFormSet[Index])->SubClass,
sizeof (UINT8)
);
EfiCopyMem (
&FormTags->Tags[CurrTag].NvDataSize,
&((EFI_IFR_FORM_SET *) &RawFormSet[Index])->NvDataSize,
sizeof (UINT16)
);
Class = ((EFI_IFR_FORM_SET *) &RawFormSet[Index])->Class;
SubClass = ((EFI_IFR_FORM_SET *) &RawFormSet[Index])->SubClass;
//
// If the formset has a size value, that means someone must be using this, so create a variable
// We also shall reserve the formid of 0 for this specific purpose.
//
if ((FileFormTags->VariableDefinitions == NULL) && (FormTags->Tags[CurrTag].NvDataSize > 0)) {
FileFormTags->VariableDefinitions = EfiLibAllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION));
ASSERT (FileFormTags->VariableDefinitions != NULL);
IfrToFormTag (
RawFormSet[Index],
&FormTags->Tags[CurrTag],
(VOID *) &RawFormSet[Index],
FileFormTags->VariableDefinitions
);
} else {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?