frontpage.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 915 行 · 第 1/2 页
C
915 行
/*++
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:
FrontPage.c
Abstract:
FrontPage routines to handle the callbacks and browser calls
--*/
#include "Bds.h"
#include "BdsLib.h"
#include "BdsPlatform.h"
#include "FrontPage.h"
#include "String.h"
EFI_GUID mProcessorSubClass = EFI_PROCESSOR_SUBCLASS_GUID;
EFI_GUID mMemorySubClass = EFI_MEMORY_SUBCLASS_GUID;
EFI_GUID mMiscSubClass = EFI_MISC_SUBCLASS_GUID;
UINT16 mLastSelection;
EFI_HII_HANDLE gFrontPageHandle;
EFI_HANDLE FrontPageCallbackHandle;
EFI_FORM_CALLBACK_PROTOCOL FrontPageCallback;
EFI_FORM_BROWSER_PROTOCOL *gBrowser;
UINTN gCallbackKey;
BOOLEAN gConnectAllHappened = FALSE;
extern EFI_HII_HANDLE gFrontPageHandle;
extern EFI_GUID gBdsStringPackGuid;
EFI_STATUS
EFIAPI
FrontPageCallbackRoutine (
IN EFI_FORM_CALLBACK_PROTOCOL *This,
IN UINT16 KeyValue,
IN EFI_IFR_DATA_ARRAY *DataArray,
OUT EFI_HII_CALLBACK_PACKET **Packet
)
/*++
Routine Description:
This is the function that is called to provide results data to the driver. This data
consists of a unique key which is used to identify what data is either being passed back
or being asked for.
Arguments:
KeyValue - A unique value which is sent to the original exporting driver so that it
can identify the type of data to expect. The format of the data tends to
vary based on the op-code that geerated the callback.
Data - A pointer to the data being sent to the original exporting driver.
Returns:
--*/
{
CHAR16 *LanguageString;
UINTN Count;
CHAR16 UnicodeLang[3];
CHAR8 Lang[3];
EFI_STATUS Status;
UINTN Index;
CHAR16 *TmpStr;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
EfiSetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
EfiSetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
EfiSetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
Count = 0;
//
// The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can
// describe to their customers in documentation how to find their setup information (namely
// under the device manager and specific buckets)
//
switch (KeyValue) {
case 0x0001:
//
// This is the continue - clear the screen and return an error to get out of FrontPage loop
//
gCallbackKey = 1;
break;
case 0x1234:
//
// Collect the languages from what our current Language support is based on our VFR
//
Hii->GetPrimaryLanguages (Hii, gFrontPageHandle, &LanguageString);
//
// Based on the DataArray->Data->Data value, we can determine
// which language was chosen by the user
//
for (Index = 0; Count != (UINTN) DataArray->Data->Data; Index += 3) {
Count++;
}
//
// Preserve the choice the user made
//
mLastSelection = (UINT16) Count;
//
// The Language (in Unicode format) the user chose
//
EfiCopyMem (UnicodeLang, &LanguageString[Index], 6);
//
// Convert Unicode to ASCII (Since the ISO standard assumes ASCII equivalent abbreviations
// we can be safe in converting this Unicode stream to ASCII without any loss in meaning.
//
for (Index = 0; Index < 3; Index++) {
Lang[Index] = (CHAR8) UnicodeLang[Index];
}
Status = gRT->SetVariable (
L"Lang",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
3,
Lang
);
gBS->FreePool (LanguageString);
gCallbackKey = 2;
break;
case 0x1064:
//
// Boot Manager
//
gCallbackKey = 3;
break;
case 0x8567:
//
// Device Manager
//
gCallbackKey = 4;
break;
case 0x9876:
//
// Boot Maintenance Manager
//
gCallbackKey = 5;
break;
case 0xFFFE:
break;
case 0xFFFF:
//
// FrontPage TimeOut Callback
//
TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));
if (TmpStr != NULL) {
PlatformBdsShowProgress (
Foreground,
Background,
TmpStr,
Color,
(UINTN) DataArray->Data->Data,
0
);
gBS->FreePool (TmpStr);
}
break;
default:
gCallbackKey = 0;
break;
}
return EFI_SUCCESS;
}
EFI_STATUS
InitializeFrontPage (
BOOLEAN ReInitializeStrings
)
/*++
Routine Description:
Initialize HII information for the FrontPage
Arguments:
None
Returns:
EFI_SUCCESS - The operation is successful.
EFI_DEVICE_ERROR - If the dynamic opcode creation failed.
--*/
{
EFI_STATUS Status;
EFI_HII_PACKAGES *PackageList;
EFI_HII_UPDATE_DATA *UpdateData;
IFR_OPTION *OptionList;
CHAR16 *LanguageString;
UINTN OptionCount;
UINTN Index;
STRING_REF Token;
UINT16 Key;
CHAR8 AsciiLang[4];
CHAR16 UnicodeLang[4];
CHAR16 Lang[4];
CHAR16 *StringBuffer;
UINTN BufferSize;
UINT8 *TempBuffer;
UpdateData = NULL;
OptionList = NULL;
if (ReInitializeStrings) {
//
// BugBug: Dont' use a goto
//
goto ReInitStrings;
}
//
// Go ahead and initialize the Device Manager
//
InitializeDeviceManager ();
//
// BugBug: if FrontPageVfrBin is generated by a tool, why are we patching it here
//
TempBuffer = (UINT8 *) FrontPageVfrBin;
TempBuffer = TempBuffer + sizeof (EFI_HII_PACK_HEADER);
TempBuffer = (UINT8 *) &((EFI_IFR_FORM_SET *) TempBuffer)->NvDataSize;
*TempBuffer = 1;
gCallbackKey = 0;
PackageList = PreparePackages (1, &gBdsStringPackGuid, FrontPageVfrBin);
Status = Hii->NewPack (Hii, PackageList, &gFrontPageHandle);
gBS->FreePool (PackageList);
//
// 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,
&gBrowser
);
//
// This example does not implement worker functions
// for the NV accessor functions. Only a callback evaluator
//
FrontPageCallback.NvRead = NULL;
FrontPageCallback.NvWrite = NULL;
FrontPageCallback.Callback = FrontPageCallbackRoutine;
//
// Install protocol interface
//
FrontPageCallbackHandle = NULL;
Status = gBS->InstallProtocolInterface (
&FrontPageCallbackHandle,
&gEfiFormCallbackProtocolGuid,
EFI_NATIVE_INTERFACE,
&FrontPageCallback
);
ASSERT_EFI_ERROR (Status);
ReInitStrings:
//
// BugBug: This logic is in BdsInitLanguage. It should not be in two places!
//
BufferSize = 4;
Status = gRT->GetVariable (
L"Lang",
&gEfiGlobalVariableGuid,
NULL,
&BufferSize,
AsciiLang
);
for (Index = 0; Index < 3; Index++) {
UnicodeLang[Index] = (CHAR16) AsciiLang[Index];
}
UnicodeLang[3] = 0;
//
// Allocate space for creation of UpdateData Buffer
//
UpdateData = EfiLibAllocateZeroPool (0x1000);
ASSERT (UpdateData != NULL);
OptionList = EfiLibAllocateZeroPool (0x1000);
ASSERT (OptionList != NULL);
//
// Flag update pending in FormSet
//
UpdateData->FormSetUpdate = TRUE;
//
// Register CallbackHandle data for FormSet
//
UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) FrontPageCallbackHandle;
UpdateData->FormUpdate = FALSE;
UpdateData->FormTitle = 0;
UpdateData->DataCount = 1;
//
// Collect the languages from what our current Language support is based on our VFR
//
Hii->GetPrimaryLanguages (Hii, gFrontPageHandle, &LanguageString);
OptionCount = 0;
//
// Try for a 512 byte Buffer
//
BufferSize = 0x200;
//
// Allocate memory for our Form binary
//
StringBuffer = EfiLibAllocateZeroPool (BufferSize);
ASSERT (StringBuffer != NULL);
for (Index = 0; LanguageString[Index] != 0; Index += 3) {
Token = 0;
EfiCopyMem (Lang, &LanguageString[Index], 6);
Lang[3] = 0;
if (!EfiStrCmp (Lang, UnicodeLang)) {
mLastSelection = (UINT16) OptionCount;
}
Status = Hii->GetString (Hii, gStringPackHandle, 1, TRUE, Lang, &BufferSize, StringBuffer);
Hii->NewString (Hii, NULL, gStringPackHandle, &Token, StringBuffer);
EfiCopyMem (&OptionList[OptionCount].StringToken, &Token, sizeof (UINT16));
EfiCopyMem (&OptionList[OptionCount].Value, &OptionCount, sizeof (UINT16));
Key = 0x1234;
EfiCopyMem (&OptionList[OptionCount].Key, &Key, sizeof (UINT16));
OptionList[OptionCount].Flags = EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS;
OptionCount++;
}
gBS->FreePool (LanguageString);
if (ReInitializeStrings) {
gBS->FreePool (StringBuffer);
gBS->FreePool (OptionList);
return EFI_SUCCESS;
}
Status = CreateOneOfOpCode (
FRONT_PAGE_QUESTION_ID, // Question ID
FRONT_PAGE_DATA_WIDTH, // Data Width
(STRING_REF) STRING_TOKEN (STR_LANGUAGE_SELECT), // Prompt Token
(STRING_REF) STRING_TOKEN (STR_LANGUAGE_SELECT_HELP), // Help Token
OptionList, // List of Options
OptionCount, // Number of Options
&UpdateData->Data // Data Buffer
);
//
// Assign the number of options and the oneof and endoneof op-codes to count
//
UpdateData->DataCount = (UINT8) (OptionCount + 2);
Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);
gBS->FreePool (UpdateData);
//
// gBS->FreePool (OptionList);
//
gBS->FreePool (StringBuffer);
return Status;
}
EFI_STATUS
CallFrontPage (
VOID
)
/*++
Routine Description:
Call the browser and display the front page
Arguments:
None
Returns:
--*/
{
EFI_STATUS Status;
UINT8 FakeNvRamMap[1];
BOOLEAN FrontPageMenuResetRequired;
//
// Begin waiting for USER INPUT
//
EfiLibReportStatusCode (
EFI_PROGRESS_CODE,
(EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT),
0,
&gEfiBdsArchProtocolGuid,
NULL
);
//
// Drop the TPL level from EFI_TPL_DRIVER to EFI_TPL_APPLICATION
//
gBS->RestoreTPL (EFI_TPL_APPLICATION);
FakeNvRamMap[0] = (UINT8) mLastSelection;
FrontPageMenuResetRequired = FALSE;
Status = gBrowser->SendForm (
gBrowser,
TRUE, // Use the database
&gFrontPageHandle, // The HII Handle
1,
NULL,
FrontPageCallbackHandle, // This is the handle that the interface to the callback was installed on
FakeNvRamMap,
NULL,
&FrontPageMenuResetRequired
);
//
// Check whether user change any option setting which needs a reset to be effective
//
if (FrontPageMenuResetRequired) {
EnableResetRequired ();
}
Hii->ResetStrings (Hii, gFrontPageHandle);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?