setup.c

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

C
1,957
字号
/*++
Copyright (c) 2004 - 2005, 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:

  Setup.c

Abstract:

  Entry and initialization module for the browser

--*/

#include "Setup.h"
#include "Ui.h"

FUNCTIION_KEY_SETTING gFunctionKeySettingTable[] = {
  //
  // Boot Manager
  //
  {
    {
      0x847bc3fe,
      0xb974,
      0x446d,
      0x94,
      0x49,
      0x5a,
      0xd5,
      0x41,
      0x2e,
      0x99,
      0x3b
    },
    NONE_FUNCTION_KEY_SETTING
  },
  //
  // Device Manager
  //
  {
    {
      0x3ebfa8e6,
      0x511d,
      0x4b5b,
      0xa9,
      0x5f,
      0xfb,
      0x38,
      0x26,
      0xf,
      0x1c,
      0x27
    },
    NONE_FUNCTION_KEY_SETTING
  },
  //
  // BMM Formset.
  //
  {
    {
      0x642237c7,
      0x35d4,
      0x472d,
      0x83,
      0x65,
      0x12,
      0xe0,
      0xcc,
      0xf2,
      0x7a,
      0x22
    },
    NONE_FUNCTION_KEY_SETTING
  },
  //
  // BMM File Explorer Formset.
  //
  {
    {
      0x1f2d63e1,
      0xfebd,
      0x4dc7,
      0x9c,
      0xc5,
      0xba,
      0x2b,
      0x1c,
      0xef,
      0x9c,
      0x5b
    },
    NONE_FUNCTION_KEY_SETTING
  },
};

EFI_STATUS
InitializeBinaryStructures (
  IN  EFI_HII_HANDLE                           *Handle,
  IN  BOOLEAN                                  UseDatabase,
  IN  EFI_IFR_PACKET                           *Packet,
  IN  UINT8                                    *NvMapOverride,
  IN  UINTN                                    NumberOfIfrImages,
  EFI_FILE_FORM_TAGS                           **FileFormTagsHead
  );

EFI_STATUS
InitializeTagStructures (
  IN  EFI_IFR_BINARY                            *BinaryData,
  OUT EFI_FILE_FORM_TAGS                        *FileFormTags
  );

UI_MENU_OPTION        *
DisplayHomePage (
  IN UINTN                                    NumberOfIfrImages,
  IN EFI_FILE_FORM_TAGS                       *FileFormTagsHead,
  IN UINT8                                    *CallbackData
  );

EFI_STATUS
GetIfrBinaryData (
  IN EFI_HII_PROTOCOL *Hii,
  IN EFI_HII_HANDLE   HiiHandle,
  IN EFI_IFR_PACKET   *Packet,
  IN EFI_IFR_BINARY   *BinaryData
  );

EFI_STATUS
InstallPrint (
  VOID
  );

EFI_DRIVER_ENTRY_POINT (InitializeSetup)

EFI_STATUS
EFIAPI
SendForm (
  IN EFI_FORM_BROWSER_PROTOCOL        * This,
  IN BOOLEAN                          UseDatabase,
  IN EFI_HII_HANDLE                   * Handle,
  IN UINTN                            HandleCount,
  IN EFI_IFR_PACKET                   * Packet,
  IN EFI_HANDLE                       CallbackHandle,
  IN UINT8                            *NvMapOverride,
  IN SCREEN_DESCRIPTOR                * ScreenDimensions, OPTIONAL
  OUT BOOLEAN                         *ResetRequired OPTIONAL
  )
/*++

Routine Description:

  This is the routine which an external caller uses to direct the browser
  where to obtain it's information.  

Arguments:

  UseDatabase -     If set to TRUE, then all information is retrieved from the HII database handle specified
                    If set to FALSE, then the passed in Packet and CallbackHandle is used and Handle is ignored

  Handle -          A pointer to an array of Handles.  If HandleCount > 1 we display a list of the formsets for the handles specified

  HandleCount -     The number of Handles specified in Handle.

  Packet -          Valid only if UseDatabase is FALSE.  Packet defines the pages being passed into
                    the browser.  This is composed of IFR data as well as String information.

  CallbackHandle -  The handle which contains the calling driver's EFI_FORM_CALLBACK_PROTOCOL interface.

  ScreenDimenions - This allows the browser to be called so that it occupies a portion of the physical screen instead of
                    dynamically determining the screen dimensions.

  NvMapOverride -   This buffer is used only when there is no NV variable to define the current settings and the caller
                    needs to provide to the browser the current settings for the "fake" NV variable.  If used, no saving
                    of an NV variable will be possible.  This parameter is also ignored if HandleCount > 1.

Returns: 

--*/
{
  EFI_FORM_CONFIGURATION_DATA *FormData;
  EFI_FORM_CALLBACK_PROTOCOL  *FormCallback;
  EFI_FILE_FORM_TAGS          *FileFormTagsHead;
  UI_MENU_OPTION              *Selection;
  UI_MENU_OPTION              *AltSelection;
  EFI_STATUS                  Status;
  BOOLEAN                     Callback;
  VOID                        *CallbackData;
  EFI_HII_HANDLE              BackupHandle;

  EfiZeroMem (&gScreenDimensions, sizeof (SCREEN_DESCRIPTOR));

  gPreviousValue  = EfiLibAllocatePool (0x1000);
  CallbackData    = EfiLibAllocatePool (0x10000);
  ASSERT (gPreviousValue != NULL);
  ASSERT (CallbackData != NULL);

  do {
    //
    // Seed the dimensions in the global
    //
    gST->ConOut->QueryMode (
                  gST->ConOut,
                  gST->ConOut->Mode->Mode,
                  &gScreenDimensions.RightColumn,
                  &gScreenDimensions.BottomRow
                  );

    if (ScreenDimensions != NULL) {
      //
      // Check local dimension vs. global dimension.
      //
      if ((gScreenDimensions.RightColumn < ScreenDimensions->RightColumn) ||
          (gScreenDimensions.BottomRow < ScreenDimensions->BottomRow)
          ) {
        return EFI_INVALID_PARAMETER;
      } else {
        //
        // Local dimension validation.
        //
        if ((ScreenDimensions->RightColumn > ScreenDimensions->LeftColumn) &&
            (ScreenDimensions->BottomRow > ScreenDimensions->TopRow) &&
            ((ScreenDimensions->RightColumn - ScreenDimensions->LeftColumn) > 2) &&
            (
              (ScreenDimensions->BottomRow - ScreenDimensions->TopRow) > STATUS_BAR_HEIGHT +
            SCROLL_ARROW_HEIGHT *
            2 +
            FRONT_PAGE_HEADER_HEIGHT +
            FOOTER_HEIGHT +
            1
          )
            ) {
          EfiCopyMem (&gScreenDimensions, ScreenDimensions, sizeof (SCREEN_DESCRIPTOR));
        } else {
          return EFI_INVALID_PARAMETER;
        }
      }
    }

    gOptionBlockWidth = (CHAR16) ((gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3);
    gHelpBlockWidth   = gOptionBlockWidth;
    gPromptBlockWidth = gOptionBlockWidth;

    //
    // Initialize the strings for the browser, upon exit of the browser, the strings will be freed
    //
    InitializeBrowserStrings ();

    gFunctionKeySetting = DEFAULT_FUNCTION_KEY_SETTING;
    gClassOfVfr         = EFI_SETUP_APPLICATION_SUBCLASS;
    gResetRequired      = FALSE;
    gExitRequired       = FALSE;
    gSaveRequired       = FALSE;
    gNvUpdateRequired   = FALSE;
    gActiveIfr          = 0;
    gConsistencyId      = 0;
    gPriorMenuEntry     = 0;
    BackupHandle        = *Handle;
    gMenuRefreshHead    = NULL;
    ASSERT (CallbackData);
    EfiZeroMem (CallbackData, 0x10000);

    //
    // We can recurse through this and might need to re-allocate this particular buffer
    //
    if (gPreviousValue == NULL) {
      gPreviousValue = EfiLibAllocatePool (0x1000);
      ASSERT (gPreviousValue != NULL);
    }

    FormData      = EFI_FORM_DATA_FROM_THIS (This);
    Callback      = FALSE;
    FormCallback  = NULL;

    if (CallbackHandle != NULL) {
      //
      // Retrieve the Callback protocol interface
      //
      Status = gBS->HandleProtocol (
                      CallbackHandle,
                      &gEfiFormCallbackProtocolGuid,
                      &FormCallback
                      );

      if (EFI_ERROR (Status)) {
        gBS->FreePool (CallbackData);
        return Status;;
      }

      Callback = TRUE;
    }
    //
    // Initializes all the internal state structures for all IFR images in system
    //
    Status = InitializeBinaryStructures (Handle, UseDatabase, Packet, NvMapOverride, HandleCount, &FileFormTagsHead);

    if (EFI_ERROR (Status)) {
      gBS->FreePool (CallbackData);
      return Status;
    }
    //
    // Beginning of the Presentation of the Data
    //
    if (UseDatabase && (HandleCount > 1)) {
      Selection = DisplayHomePage (HandleCount, FileFormTagsHead, CallbackData);
    } else {
      //
      // If passing something specific, we know there is only one Ifr
      //
      Selection = EfiLibAllocateZeroPool (sizeof (UI_MENU_OPTION));
      ASSERT (Selection != NULL);
      Selection->IfrNumber  = 0;
      Selection->Handle     = Handle[0];
      UiInitMenu ();
    }

    UiInitMenuList ();

    if (UseDatabase && (HandleCount > 1)) {
      if (Selection == NULL) {
        gBS->FreePool (CallbackData);
        return EFI_SUCCESS;
      }
    }
    //
    // Launch the setup browser with the user's selection information
    //
    AltSelection = SetupBrowser (Selection, Callback, FileFormTagsHead, CallbackData);

    //
    // If the caller cares about Reset status, we can return to the caller if something happened that required a reset
    //
    if (ResetRequired != NULL) {
      *ResetRequired = gResetRequired;
    }

    if (Callback && (AltSelection != NULL)) {
      if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {
        Status = FormCallback->Callback (
                                FormCallback,
                                AltSelection->ThisTag->Key,
                                CallbackData,
                                (EFI_HII_CALLBACK_PACKET **) &Packet
                                );
      }
    }

    *Handle = BackupHandle;

    if (EFI_ERROR (Status)) {
      gBS->FreePool (CallbackData);
      return Status;
    }

    if (Callback && (AltSelection == NULL)) {
      gBS->FreePool (CallbackData);
      return Status;
    }

    if (UseDatabase && (HandleCount > 1)) {
    } else {

      if (gBinaryDataHead->UnRegisterOnExit) {
        Hii->RemovePack (Hii, Handle[0]);
      }

      if (Callback &&
        ((AltSelection->ThisTag->SubClass == EFI_FRONT_PAGE_SUBCLASS) ||
        (AltSelection->ThisTag->SubClass == EFI_SINGLE_USE_SUBCLASS))) {
        //
        // If this is the FrontPage, return after every selection
        //
        gBS->FreePool (Selection);
        UiFreeMenu ();

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

        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
        gST->ConOut->ClearScreen (gST->ConOut);

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

⌨️ 快捷键说明

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