setup.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,957 行 · 第 1/5 页

C
1,957
字号
      gBS->FreePool (Selection);
      UiFreeMenu ();

      //
      // Clean up the allocated data buffers
      //
      FreeData (FileFormTagsHead, NULL, NULL);

      gST->ConOut->ClearScreen (gST->ConOut);

      if (!Callback) {
        gBS->FreePool (CallbackData);
        return EFI_SUCCESS;
      }
    }

  } while (!EFI_ERROR (Status));

  gBS->FreePool (CallbackData);
  return Status;
}

EFI_STATUS
EFIAPI
InitializeSetup (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
/*++

Routine Description:
  Initialize Setup
  
Arguments:
  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

Returns: 
  EFI_SUCCESS - Setup loaded.
  other       - Setup Error

--*/
{
  EFI_STATUS                  Status;
  EFI_FORM_CONFIGURATION_DATA *FormData;
  EFI_FORM_BROWSER_PROTOCOL   *FormBrowser;
  EFI_HANDLE                  Handle;
  EFI_HII_PACKAGES            *PackageList;

  //
  // Initialize the library and our protocol.
  //
  EfiInitializeDriverLib (ImageHandle, SystemTable);

  //
  // There will be only one FormConfig in the system
  // If there is another out there, someone is trying to install us
  // again.  Fail that scenario.
  //
  Status = gBS->LocateProtocol (
                  &gEfiFormBrowserProtocolGuid,
                  NULL,
                  &FormBrowser
                  );

  gFirstIn = TRUE;

  //
  // If there was no error, assume there is an installation and fail to load
  //
  if (!EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  FormData = EfiLibAllocatePool (sizeof (EFI_FORM_CONFIGURATION_DATA));

  if (FormData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Fill in HII data
  //
  FormData->Signature               = EFI_FORM_DATA_SIGNATURE;
  FormData->FormConfig.SendForm     = SendForm;
  FormData->FormConfig.CreatePopUp  = CreateDialog;

  //
  // There should only be one HII image
  //
  Status = gBS->LocateProtocol (
                  &gEfiHiiProtocolGuid,
                  NULL,
                  &FormData->Hii
                  );

  ASSERT_EFI_ERROR (Status);

  Hii         = FormData->Hii;

  PackageList = PreparePackages (1, &gEfiFormBrowserProtocolGuid, SetupBrowserStrings);

  Status      = Hii->NewPack (Hii, PackageList, &gHiiHandle);

  gBS->FreePool (PackageList);

  //
  // Install protocol interface
  //
  Handle = NULL;
  Status = gBS->InstallProtocolInterface (
                  &Handle,
                  &gEfiFormBrowserProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &FormData->FormConfig
                  );

  ASSERT_EFI_ERROR (Status);

  BannerData = EfiLibAllocateZeroPool (sizeof (BANNER_DATA));
  ASSERT (BannerData != NULL);

  Status = InstallPrint ();
  return Status;
}

VOID
GetQuestionHeader (
  IN  EFI_TAG             *Tag,
  IN  UINT8               *RawFormSet,
  IN  UINT16              Index,
  IN  EFI_FILE_FORM_TAGS  *FileFormTags,
  IN  UINT16              CurrentVariable
  )
/*++

Routine Description:
  Initialize question tag's members.

Arguments:
  Tag              - Pointer of the current EFI_TAG structure.
  RawFormSet       - Pointer of the formset raw data.
  Index            - Offset of the current opcode in the Ifr raw data.
  FileFormTags     - Pointer of current EFI_FILE_FORM_TAGS structure.
  CurrentVariable  - Current variable number.
           
Returns:
  None.
--*/
{
  EFI_VARIABLE_DEFINITION *VariableDefinition;

  Tag->NumberOfLines  = 1;
  Tag->VariableNumber = CurrentVariable;
  EfiCopyMem (&Tag->Id, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));
  EfiCopyMem (&Tag->StorageStart, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));
  EfiCopyMem (&Tag->StorageWidth, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Width, sizeof (UINT8));
  EfiCopyMem (&Tag->Text, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Prompt, sizeof (UINT16));
  EfiCopyMem (&Tag->Help, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Help, sizeof (UINT16));

  VariableDefinition = FileFormTags->VariableDefinitions;

  for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {
    //
    // Have we found the correct variable for the request?
    //
    if (CurrentVariable == VariableDefinition->VariableId) {
      if (VariableDefinition->VariableSize < (UINTN) (Tag->StorageStart + Tag->StorageWidth)) {
        VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + Tag->StorageWidth);
      }

      if (VariableDefinition->NvRamMap != NULL) {
        //
        // If it is an 8bit or 16bit width, then move it to Tag->Value, otherwise
        // we will never be looking for the data in Tag->Value (e.g. strings, password, etc)
        //
        if (Tag->StorageWidth == (UINT16) 1) {
          EfiCopyMem (&Tag->Value, &VariableDefinition->NvRamMap[Tag->StorageStart], sizeof (UINT16));
        }

        if (Tag->StorageWidth == (UINT16) 2) {
          Index = (UINT16)
            (
              VariableDefinition->NvRamMap[Tag->StorageStart] +
              (VariableDefinition->NvRamMap[Tag->StorageStart + 1] * 0x100)
            );
          EfiCopyMem (&Tag->Value, &Index, sizeof (UINT16));
        }
      } else {
        Index = 0;
        EfiCopyMem (&Tag->Value, &Index, sizeof (UINT16));
      }
      break;
    } else {
      continue;
    }
  }
}

VOID
GetNumericHeader (
  IN  EFI_TAG             *Tag,
  IN  UINT8               *RawFormSet,
  IN  UINT16              Index,
  IN  UINT16              NumberOfLines,
  IN  EFI_FILE_FORM_TAGS  *FileFormTags,
  IN  UINT16              CurrentVariable
  )
/*++

Routine Description:
  Initialize numeric tag's members.

Arguments:
  Tag              - Pointer of the current EFI_TAG structure.
  RawFormSet       - Pointer of the formset raw data.
  Index            - Offset of the current opcode in the Ifr raw data.
  NumberOfLines    - Number of lines this opcode occupied.
  FileFormTags     - Pointer of current EFI_FILE_FORM_TAGS structure.
  CurrentVariable  - Current variable number.
           
Returns:
  None.
--*/
{
  EFI_VARIABLE_DEFINITION *VariableDefinition;

  Tag->NumberOfLines  = NumberOfLines;
  Tag->VariableNumber = CurrentVariable;
  EfiCopyMem (&Tag->Id, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));
  EfiCopyMem (&Tag->StorageStart, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));
  EfiCopyMem (&Tag->StorageWidth, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Width, sizeof (UINT8));
  EfiCopyMem (&Tag->Text, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Prompt, sizeof (UINT16));
  EfiCopyMem (&Tag->Help, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Help, sizeof (UINT16));
  EfiCopyMem (&Tag->Minimum, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Minimum, sizeof (UINT16));
  EfiCopyMem (&Tag->Maximum, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Maximum, sizeof (UINT16));
  EfiCopyMem (&Tag->Step, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Step, sizeof (UINT16));
  EfiCopyMem (&Tag->Default, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Default, sizeof (UINT16));
  Tag->ResetRequired  = (BOOLEAN) (((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Flags & EFI_IFR_FLAG_RESET_REQUIRED);

  VariableDefinition  = FileFormTags->VariableDefinitions;

  for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {
    //
    // Have we found the correct variable for the request?
    //
    if (CurrentVariable == VariableDefinition->VariableId) {
      if (VariableDefinition->VariableSize <= (UINTN) (Tag->StorageStart + Tag->StorageWidth)) {
        if (Tag->StorageWidth == 0) {
          VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + 2);
        } else {
          VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + Tag->StorageWidth);
        }
      }

      if (VariableDefinition->NvRamMap != NULL) {
        //
        // If it is an 8bit or 16bit width, then move it to Tag->Value, otherwise
        // we will never be looking for the data in Tag->Value (e.g. strings, password, etc)
        //
        if (Tag->StorageWidth == (UINT16) 1) {
          EfiCopyMem (&Tag->Value, &VariableDefinition->NvRamMap[Tag->StorageStart], sizeof (UINT16));
        }

        if (Tag->StorageWidth == (UINT16) 2) {
          Index = (UINT16)
            (
              VariableDefinition->NvRamMap[Tag->StorageStart] +
                (VariableDefinition->NvRamMap[Tag->StorageStart + 1] * 0x100)
            );
          EfiCopyMem (&Tag->Value, &Index, sizeof (UINT16));
        }
      } else {
        EfiCopyMem (&Tag->Value, &Tag->Default, sizeof (UINT16));
      }
      break;
    } else {
      continue;
    }
  }
}

VOID
GetTagCount (
  IN      UINT8                                 *RawFormSet,
  IN OUT  UINT16                                *NumberOfTags
  )
{
  UINT16  Index;

  //
  // Assume on entry we are pointing to an OpCode - reasonably this should
  // be a FormOp since the purpose is to count the tags in a particular Form.
  //
  for (Index = 0; RawFormSet[Index] != EFI_IFR_END_FORM_OP;) {
    //
    // If we encounter the end of a form set, bail out
    //
    if (RawFormSet[Index] == EFI_IFR_END_FORM_SET_OP) {
      break;
    }
    //
    // We treat date/time internally as three op-codes
    //
    if (RawFormSet[Index] == EFI_IFR_DATE_OP || RawFormSet[Index] == EFI_IFR_TIME_OP) {
      *NumberOfTags = (UINT16) (*NumberOfTags + 3);
    } else {
      //
      // Assume that we could have no more tags than op-codes
      //
      (*NumberOfTags)++;
    }

    Index = (UINT16) (Index + RawFormSet[Index + 1]);
  }
  //
  // Increase the tag count by one so it is inclusive of the end_form_op
  //
  (*NumberOfTags)++;
}

VOID
AddNextInconsistentTag (
  IN OUT  EFI_INCONSISTENCY_DATA  **InconsistentTagsPtr
  )
/*++

Routine Description:
  Initialize the next inconsistent tag data and add it to the inconsistent tag list.
  
Arguments:
 InconsistentTagsPtr   - Pointer of the inconsistent tag's pointer.

Returns: 
  None.

--*/
{
  EFI_INCONSISTENCY_DATA  *PreviousInconsistentTags;
  EFI_INCONSISTENCY_DATA  *InconsistentTags;

  InconsistentTags = *InconsistentTagsPtr;
  //
  // We just hit the end of an inconsistent expression.  Let's allocate the ->Next structure
  //
  InconsistentTags->Next = EfiLibAllocatePool (sizeof (EFI_INCONSISTENCY_DATA));
  ASSERT (InconsistentTags->Next != NULL);

  //
  // Preserve current Tag entry
  //
  PreviousInconsistentTags  = InconsistentTags;

  InconsistentTags          = InconsistentTags->Next;

  //
  // This will zero on the entry including the ->Next so I don't have to do it
  //
  EfiZeroMem (InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));

  //
  // Point our Previous field to the previous entry
  //
  InconsistentTags->Previous  = PreviousInconsistentTags;

  *InconsistentTagsPtr        = InconsistentTags;

  return ;
}

EFI_STATUS
InitializeTagStructures (
  IN  EFI_IFR_BINARY                            *BinaryData,
  OUT EFI_FILE_FORM_TAGS                        *FileFormTags
  )
{
  EFI_STATUS              Status;
  UINT8                   *RawFormSet;
  UINT16                  Index;
  UINT16                  QuestionIndex;
  UINT16                  NumberOfTags;
  INT16                   CurrTag;
  UINT8                   TagLength;
  EFI_FORM_TAGS           *FormTags;
  EFI_FORM_TAGS           *SavedFormTags;
  EFI_INCONSISTENCY_DATA  *InconsistentTags;
  EFI_VARIABLE_DEFINITION *VariableDefinitions;
  UINTN                   Count;
  UINT16                  Class;
  UINT16                  SubClass;
  UINT16                  TempValue;
  UINT16                  CurrentVariable;
  UINT16                  CurrentVariable2;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?