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 + -
显示快捷键?