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