bootmaint.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,330 行 · 第 1/3 页
C
1,330 行
/*++
Copyright (c) 2004 - 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
BootMaint.c
Abstract:
Boot Maintainence Main File
--*/
#include "BootMaint.h"
#include "BdsStrDefs.h"
#include "formguid.h"
#include "Bds.h"
//
// Form binary for Boot Maintenance
//
extern UINT8 bmBin[];
extern UINT8 FEBin[];
extern EFI_GUID gBdsStringPackGuid;
extern BOOLEAN gConnectAllHappened;
EFI_GUID EfiLegacyDevOrderGuid = EFI_LEGACY_DEV_ORDER_VARIABLE_GUID;
VOID
InitAllMenu (
IN BMM_CALLBACK_DATA *CallbackData
);
VOID
FreeAllMenu (
VOID
);
EFI_STATUS
CreateMenuStringToken (
IN BMM_CALLBACK_DATA *CallbackData,
IN EFI_HII_HANDLE HiiHandle,
IN BM_MENU_OPTION *MenuOption
)
/*++
Routine Description:
Create string tokens for a menu from its help strings and display strings
Arguments:
HiiHandle - Hii Handle of the package to be updated.
MenuOption - The Menu whose string tokens need to be created
Returns:
EFI_SUCCESS - string tokens created successfully
others - contain some errors
--*/
{
BM_MENU_ENTRY *NewMenuEntry;
UINTN Index;
for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);
CallbackData->Hii->NewString (
CallbackData->Hii,
NULL,
HiiHandle,
&NewMenuEntry->DisplayStringToken,
NewMenuEntry->DisplayString
);
if (NULL == NewMenuEntry->HelpString) {
NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;
} else {
CallbackData->Hii->NewString (
CallbackData->Hii,
NULL,
HiiHandle,
&NewMenuEntry->HelpStringToken,
NewMenuEntry->HelpString
);
}
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
DriverCallback (
IN EFI_FORM_CALLBACK_PROTOCOL *This,
IN UINT16 KeyValue,
IN EFI_IFR_DATA_ARRAY *Data,
OUT EFI_HII_CALLBACK_PACKET **Packet
)
/*++
Routine Description:
Callback Function for boot maintenance utility user interface interaction.
Arguments:
This - File explorer callback protocol pointer.
KeyValue - Key value to identify the type of data to expect.
Data - A pointer to the data being sent to the original exporting driver.
Packet - A pointer to a packet of information which a driver passes back to the browser.
Returns:
EFI_SUCCESS - Callback ended successfully.
Others - Contain some errors.
--*/
{
BMM_CALLBACK_DATA *Private;
BM_MENU_ENTRY *NewMenuEntry;
BMM_FAKE_NV_DATA *CurrentFakeNVMap;
EFI_STATUS Status;
UINTN OldValue;
UINTN NewValue;
UINTN Number;
UINTN Pos;
UINTN Bit;
UINT16 NewValuePos;
UINT16 Index2;
UINT16 Index;
UINT8 *OldLegacyDev;
UINT8 *NewLegacyDev;
UINT8 *Location;
UINT8 *DisMap;
FORM_ID FormId;
OldValue = 0;
NewValue = 0;
Number = 0;
OldLegacyDev = NULL;
NewLegacyDev = NULL;
NewValuePos = 0;
DisMap = NULL;
Private = BMM_CALLBACK_DATA_FROM_THIS (This);
UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) Private->BmmCallbackHandle;
CurrentFakeNVMap = (BMM_FAKE_NV_DATA *) Data->NvRamMap;
Private->BmmFakeNvData = CurrentFakeNVMap;
Location = (UINT8 *) &UpdateData->Data;
UpdatePageId (Private, KeyValue);
//
// need to be subtituded.
//
// Update Select FD/HD/CD/NET/BEV Order Form
//
if (FORM_SET_FD_ORDER_ID == Private->BmmPreviousPageId ||
FORM_SET_HD_ORDER_ID == Private->BmmPreviousPageId ||
FORM_SET_CD_ORDER_ID == Private->BmmPreviousPageId ||
FORM_SET_NET_ORDER_ID == Private->BmmPreviousPageId ||
FORM_SET_BEV_ORDER_ID == Private->BmmPreviousPageId ||
((FORM_BOOT_SETUP_ID == Private->BmmPreviousPageId) &&
(KeyValue >= LEGACY_FD_QUESTION_ID) &&
(KeyValue < (LEGACY_BEV_QUESTION_ID + 100)) )
) {
DisMap = Private->BmmOldFakeNVData.DisableMap;
FormId = Private->BmmPreviousPageId;
if (FormId == FORM_BOOT_SETUP_ID) {
FormId = Private->BmmCurrentPageId;
}
switch (FormId) {
case FORM_SET_FD_ORDER_ID:
Number = (UINT16) LegacyFDMenu.MenuNumber;
OldLegacyDev = Private->BmmOldFakeNVData.LegacyFD;
NewLegacyDev = CurrentFakeNVMap->LegacyFD;
break;
case FORM_SET_HD_ORDER_ID:
Number = (UINT16) LegacyHDMenu.MenuNumber;
OldLegacyDev = Private->BmmOldFakeNVData.LegacyHD;
NewLegacyDev = CurrentFakeNVMap->LegacyHD;
break;
case FORM_SET_CD_ORDER_ID:
Number = (UINT16) LegacyCDMenu.MenuNumber;
OldLegacyDev = Private->BmmOldFakeNVData.LegacyCD;
NewLegacyDev = CurrentFakeNVMap->LegacyCD;
break;
case FORM_SET_NET_ORDER_ID:
Number = (UINT16) LegacyNETMenu.MenuNumber;
OldLegacyDev = Private->BmmOldFakeNVData.LegacyNET;
NewLegacyDev = CurrentFakeNVMap->LegacyNET;
break;
case FORM_SET_BEV_ORDER_ID:
Number = (UINT16) LegacyBEVMenu.MenuNumber;
OldLegacyDev = Private->BmmOldFakeNVData.LegacyBEV;
NewLegacyDev = CurrentFakeNVMap->LegacyBEV;
break;
default:
break;
}
//
// First, find the different position
// if there is change, it should be only one
//
for (Index = 0; Index < Number; Index++) {
if (OldLegacyDev[Index] != NewLegacyDev[Index]) {
OldValue = OldLegacyDev[Index];
NewValue = NewLegacyDev[Index];
break;
}
}
if (Index != Number) {
//
// there is change, now process
//
if (0xFF == NewValue) {
//
// This item will be disable
// Just move the items behind this forward to overlap it
//
Pos = OldValue / 8;
Bit = 7 - (OldValue % 8);
DisMap[Pos] |= (UINT8) (1 << Bit);
for (Index2 = Index; Index2 < Number - 1; Index2++) {
NewLegacyDev[Index2] = NewLegacyDev[Index2 + 1];
}
NewLegacyDev[Index2] = 0xFF;
} else {
for (Index2 = 0; Index2 < Number; Index2++) {
if (Index2 == Index) {
continue;
}
if (OldLegacyDev[Index2] == NewValue) {
//
// If NewValue is in OldLegacyDev array
// remember its old position
//
NewValuePos = Index2;
break;
}
}
if (Index2 != Number) {
//
// We will change current item to an existing item
// (It's hard to describe here, please read code, it's like a cycle-moving)
//
for (Index2 = NewValuePos; Index2 != Index;) {
if (NewValuePos < Index) {
NewLegacyDev[Index2] = OldLegacyDev[Index2 + 1];
Index2++;
} else {
NewLegacyDev[Index2] = OldLegacyDev[Index2 - 1];
Index2--;
}
}
} else {
//
// If NewValue is not in OldlegacyDev array, we are changing to a disabled item
// so we should modify DisMap to reflect the change
//
Pos = NewValue / 8;
Bit = 7 - (NewValue % 8);
DisMap[Pos] &= ~ (UINT8) (1 << Bit);
if (0xFF != OldValue) {
//
// Because NewValue is a item that was disabled before
// so after changing the OldValue should be disabled
// actually we are doing a swap of enable-disable states of two items
//
Pos = OldValue / 8;
Bit = 7 - (OldValue % 8);
DisMap[Pos] |= (UINT8) (1 << Bit);
}
}
}
//
// To prevent DISABLE appears in the middle of the list
// we should perform a re-ordering
//
Index = 0;
while (Index < Number) {
if (0xFF != NewLegacyDev[Index]) {
Index++;
continue;
}
Index2 = Index;
Index2++;
while (Index2 < Number) {
if (0xFF != NewLegacyDev[Index2]) {
break;
}
Index2++;
}
if (Index2 < Number) {
NewLegacyDev[Index] = NewLegacyDev[Index2];
NewLegacyDev[Index2] = 0xFF;
}
Index++;
}
EfiCopyMem (
OldLegacyDev,
NewLegacyDev,
Number
);
}
}
if (KeyValue < FILE_OPTION_OFFSET) {
if (KeyValue < NORMAL_GOTO_OFFSET) {
switch (KeyValue) {
case KEY_VALUE_BOOT_FROM_FILE:
Private->FeCurrentState = BOOT_FROM_FILE_STATE;
//
// Exit Bmm main formset to send File Explorer formset.
//
CreateCallbackPacket (Packet, EXIT_REQUIRED);
break;
case FORM_BOOT_ADD_ID:
Private->FeCurrentState = ADD_BOOT_OPTION_STATE;
//
// Exit Bmm main formset to send File Explorer formset.
//
CreateCallbackPacket (Packet, EXIT_REQUIRED);
break;
case FORM_DRV_ADD_FILE_ID:
Private->FeCurrentState = ADD_DRIVER_OPTION_STATE;
//
// Exit Bmm main formset to send File Explorer formset.
//
CreateCallbackPacket (Packet, EXIT_REQUIRED);
break;
case FORM_DRV_ADD_HANDLE_ID:
CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
UpdateDrvAddHandlePage (Private);
break;
case FORM_BOOT_DEL_ID:
CleanUpPage (FORM_BOOT_DEL_ID, Private);
UpdateBootDelPage (Private);
break;
case FORM_BOOT_CHG_ID:
case FORM_DRV_CHG_ID:
UpdatePageBody (KeyValue, Private);
break;
case FORM_DRV_DEL_ID:
CleanUpPage (FORM_DRV_DEL_ID, Private);
UpdateDrvDelPage (Private);
break;
case FORM_BOOT_NEXT_ID:
CleanUpPage (FORM_BOOT_NEXT_ID, Private);
UpdateBootNextPage (Private);
break;
case FORM_TIME_OUT_ID:
CleanUpPage (FORM_TIME_OUT_ID, Private);
UpdateTimeOutPage (Private);
break;
case FORM_RESET:
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
return EFI_UNSUPPORTED;
case FORM_CON_IN_ID:
case FORM_CON_OUT_ID:
case FORM_CON_ERR_ID:
UpdatePageBody (KeyValue, Private);
break;
case FORM_CON_COM_ID:
CleanUpPage (FORM_CON_COM_ID, Private);
UpdateConCOMPage (Private);
break;
case FORM_SET_FD_ORDER_ID:
case FORM_SET_HD_ORDER_ID:
case FORM_SET_CD_ORDER_ID:
case FORM_SET_NET_ORDER_ID:
case FORM_SET_BEV_ORDER_ID:
CleanUpPage (KeyValue, Private);
UpdateSetLegacyDeviceOrderPage (KeyValue, Private);
break;
case KEY_VALUE_SAVE_AND_EXIT:
case KEY_VALUE_NO_SAVE_AND_EXIT:
if (KeyValue == KEY_VALUE_SAVE_AND_EXIT) {
Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);
if (EFI_ERROR (Status)) {
return Status;
}
} else if (KeyValue == KEY_VALUE_NO_SAVE_AND_EXIT) {
DiscardChangeHandler (Private, CurrentFakeNVMap);
}
//
// Tell browser not to ask for confirmation of changes,
// since we have already applied or discarded.
//
CreateCallbackPacket (Packet, NV_NOT_CHANGED);
break;
default:
break;
}
} else if ((KeyValue >= TERMINAL_OPTION_OFFSET) && (KeyValue < CONSOLE_OPTION_OFFSET)) {
Index2 = (UINT16) (KeyValue - TERMINAL_OPTION_OFFSET);
Private->CurrentTerminal = Index2;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?