bootmaint.c

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

C
1,330
字号

  UpdateBootDelPage (BmmCallbackInfo);
  UpdateDrvDelPage (BmmCallbackInfo);

  if (TerminalMenu.MenuNumber > 0) {
    BmmCallbackInfo->CurrentTerminal = 0;
    UpdateTerminalPage (BmmCallbackInfo);
  }

  Location  = (UINT8 *) &UpdateData->Data;
  Status    = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, &LegacyBios);
  if (!EFI_ERROR (Status)) {
    //
    // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
    // in BootOption form: legacy FD/HD/CD/NET/BEV
    //
    UpdateData->DataCount = 5;
    CreateGotoOpCode (
      FORM_SET_FD_ORDER_ID,
      STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
      STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,
      FORM_SET_FD_ORDER_ID,
      Location
      );

    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

    CreateGotoOpCode (
      FORM_SET_HD_ORDER_ID,
      STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
      STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,
      FORM_SET_HD_ORDER_ID,
      Location
      );

    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

    CreateGotoOpCode (
      FORM_SET_CD_ORDER_ID,
      STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
      STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,
      FORM_SET_CD_ORDER_ID,
      Location
      );

    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

    CreateGotoOpCode (
      FORM_SET_NET_ORDER_ID,
      STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
      STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,
      FORM_SET_NET_ORDER_ID,
      Location
      );

    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;

    CreateGotoOpCode (
      FORM_SET_BEV_ORDER_ID,
      STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
      STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,
      FORM_SET_BEV_ORDER_ID,
      Location
      );

    Hii->UpdateForm (
          Hii,
          BmmCallbackInfo->BmmHiiHandle,
          (EFI_FORM_LABEL) FORM_BOOT_LEGACY_DEVICE_ID,
          TRUE,
          UpdateData
          );
  }
  //
  // Dispatch BMM main formset and File Explorer formset.
  //
  FormSetDispatcher (BmmCallbackInfo);

  Hii->ResetStrings (Hii, HiiHandle);

  CleanUpStringDepository ();

  if (EFI_ERROR (Status)) {
    return Status;
  }

  FreeAllMenu ();

  SafeFreePool (BmmCallbackInfo->LoadContext);
  BmmCallbackInfo->LoadContext = NULL;
  SafeFreePool (BmmCallbackInfo);
  BmmCallbackInfo = NULL;
  SafeFreePool (UpdateData);
  UpdateData = NULL;

  return Status;
}

VOID
InitAllMenu (
  IN  BMM_CALLBACK_DATA    *CallbackData
  )
{
  InitializeListHead (&BootOptionMenu.Head);
  InitializeListHead (&DriverOptionMenu.Head);
  BOpt_GetBootOptions (CallbackData);
  BOpt_GetDriverOptions (CallbackData);
  BOpt_GetLegacyOptions ();
  InitializeListHead (&FsOptionMenu.Head);
  BOpt_FindDrivers ();
  InitializeListHead (&DirectoryMenu.Head);
  InitializeListHead (&ConsoleInpMenu.Head);
  InitializeListHead (&ConsoleOutMenu.Head);
  InitializeListHead (&ConsoleErrMenu.Head);
  InitializeListHead (&TerminalMenu.Head);
  LocateSerialIo ();
  GetAllConsoles ();
}

VOID
FreeAllMenu (
  VOID
  )
{
  BOpt_FreeMenu (&DirectoryMenu);
  BOpt_FreeMenu (&FsOptionMenu);
  BOpt_FreeMenu (&BootOptionMenu);
  BOpt_FreeMenu (&DriverOptionMenu);
  BOpt_FreeMenu (&DriverMenu);
  BOpt_FreeLegacyOptions ();
  FreeAllConsoles ();
}

VOID
InitializeStringDepository (
  VOID
  )
/*++
Routine Description:
  Intialize all the string depositories.

Arguments:
  None.

Returns:
  None.  
--*/
{
  STRING_DEPOSITORY *StringDepository;
  StringDepository              = EfiAllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);
  FileOptionStrDepository       = StringDepository++;
  ConsoleOptionStrDepository    = StringDepository++;
  BootOptionStrDepository       = StringDepository++;
  BootOptionHelpStrDepository   = StringDepository++;
  DriverOptionStrDepository     = StringDepository++;
  DriverOptionHelpStrDepository = StringDepository++;
  TerminalStrDepository         = StringDepository;
}

STRING_REF
GetStringTokenFromDepository (
  IN   BMM_CALLBACK_DATA     *CallbackData,
  IN   STRING_DEPOSITORY     *StringDepository
  )
/*++
Routine Description:
  Fetch a usable string node from the string depository and return the string token.

Arguments:
  StringDepository       - Pointer of the string depository.

Returns:
  STRING_REF             - String token.
--*/
{
  STRING_LIST_NODE  *CurrentListNode;
  STRING_LIST_NODE  *NextListNode;

  CurrentListNode = StringDepository->CurrentNode;

  if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {
    //
    // Fetch one reclaimed node from the list.
    //
    NextListNode = StringDepository->CurrentNode->Next;
  } else {
    //
    // If there is no usable node in the list, update the list.
    //
    NextListNode = EfiAllocateZeroPool (sizeof (STRING_LIST_NODE));

    CallbackData->Hii->NewString (
                        CallbackData->Hii,
                        NULL,
                        CallbackData->BmmHiiHandle,
                        &(NextListNode->StringToken),
                        L" "
                        );

    ASSERT (NextListNode->StringToken != 0);

    StringDepository->TotalNodeNumber++;

    if (NULL == CurrentListNode) {
      StringDepository->ListHead = NextListNode;
    } else {
      CurrentListNode->Next = NextListNode;
    }
  }

  StringDepository->CurrentNode = NextListNode;

  return StringDepository->CurrentNode->StringToken;
}

VOID
ReclaimStringDepository (
  VOID
  )
/*++
Routine Description:
  Reclaim string depositories by moving the current node pointer to list head..

Arguments:
  None.

Returns:
  None.
--*/
{
  UINTN             DepositoryIndex;
  STRING_DEPOSITORY *StringDepository;

  StringDepository = FileOptionStrDepository;
  for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
    StringDepository->CurrentNode = StringDepository->ListHead;
    StringDepository++;
  }
}

VOID
CleanUpStringDepository (
  VOID
  )
/*++
Routine Description:
  Release resource for all the string depositories.

Arguments:
  None.

Returns:
  None.
--*/
{
  UINTN             NodeIndex;
  UINTN             DepositoryIndex;
  STRING_LIST_NODE  *CurrentListNode;
  STRING_LIST_NODE  *NextListNode;
  STRING_DEPOSITORY *StringDepository;

  //
  // Release string list nodes.
  //
  StringDepository = FileOptionStrDepository;
  for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
    CurrentListNode = StringDepository->ListHead;
    for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {
      NextListNode = CurrentListNode->Next;
      SafeFreePool (CurrentListNode);
      CurrentListNode = NextListNode;
    }

    StringDepository++;
  }
  //
  // Release string depository.
  //
  SafeFreePool (FileOptionStrDepository);
}

EFI_STATUS
BdsStartBootMaint (
  VOID
  )
/*++

Routine Description:
  Start boot maintenance manager

Arguments:

Returns:

--*/
{
  EFI_STATUS      Status;
  EFI_LIST_ENTRY  BdsBootOptionList;

  InitializeListHead (&BdsBootOptionList);

  //
  // Connect all prior to entering the platform setup menu.
  //
  if (!gConnectAllHappened) {
    BdsLibConnectAllDriversToAllControllers ();
    gConnectAllHappened = TRUE;
  }
  //
  // Have chance to enumerate boot device
  //
  BdsLibEnumerateAllBootOption (&BdsBootOptionList);

  //
  // Drop the TPL level from EFI_TPL_DRIVER to EFI_TPL_APPLICATION
  //
  gBS->RestoreTPL (EFI_TPL_APPLICATION);

  //
  // Init the BMM
  //
  Status = InitializeBM ();

  //
  // Raise the TPL level back to EFI_TPL_DRIVER
  //
  gBS->RaiseTPL (EFI_TPL_DRIVER);

  return Status;
}

EFI_STATUS
FormSetDispatcher (
  IN  BMM_CALLBACK_DATA    *CallbackData
  )
/*++

Routine Description:
  Dispatch BMM formset and FileExplorer formset.

Arguments:

Returns:

--*/
{
  EFI_FORM_BROWSER_PROTOCOL *FormConfig;
  UINT8                     *Location;
  EFI_STATUS                Status;
  UINTN                     Index;
  BM_MENU_ENTRY             *NewMenuEntry;
  BM_FILE_CONTEXT           *NewFileContext;
  BOOLEAN	                  BootMaintMenuResetRequired;

  Location        = NULL;
  Index           = 0;
  NewMenuEntry    = NULL;
  NewFileContext  = NULL;

  //
  // There should only be one Form Configuration protocol
  //
  Status = EfiLibLocateProtocol (&gEfiFormBrowserProtocolGuid, &FormConfig);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  while (1) {
    UpdatePageId (CallbackData, FORM_MAIN_ID);
    
    BootMaintMenuResetRequired = FALSE;
    Status = FormConfig->SendForm (
                          FormConfig,
                          TRUE,
                          &(CallbackData->BmmHiiHandle),
                          1,
                          NULL,
                          NULL,
                          (UINT8 *) CallbackData->BmmFakeNvData,
                          NULL,
                          &BootMaintMenuResetRequired
                          );

    if (BootMaintMenuResetRequired) {
      EnableResetRequired ();
    }

    ReclaimStringDepository ();

    //
    // When this Formset returns, check if we are going to explore files.
    //
    if (INACTIVE_STATE != CallbackData->FeCurrentState) {
      UpdateFileExplorer (CallbackData, 0);
      
      BootMaintMenuResetRequired = FALSE;
      Status = FormConfig->SendForm (
                            FormConfig,
                            TRUE,
                            &(CallbackData->FeHiiHandle),
                            1,
                            NULL,
                            NULL,
                            NULL,
                            NULL,
                            &BootMaintMenuResetRequired
                            );

      if (BootMaintMenuResetRequired) {
        EnableResetRequired ();
      }

      CallbackData->FeCurrentState    = INACTIVE_STATE;
      CallbackData->FeDisplayContext  = UNKNOWN_CONTEXT;
      ReclaimStringDepository ();
    } else {
      break;
    }
  }

  return Status;
}

VOID
CreateCallbackPacket (
  OUT EFI_HII_CALLBACK_PACKET         **Packet,
  IN  UINT16                          Flags
  )
{
  *Packet = (EFI_HII_CALLBACK_PACKET *) EfiAllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + 2);
  ASSERT (*Packet != NULL);

  (*Packet)->DataArray.EntryCount   = 1;
  (*Packet)->DataArray.NvRamMap     = NULL;
  (*Packet)->DataArray.Data->Flags  = Flags;
}

⌨️ 快捷键说明

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