mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-11-03 21:17:23 +01:00 
			
		
		
		
	3. Update EdkDxePrintLib instance to implement all interfaces defined in PrintLib class based on new EfiPrint protocol. 4. Update Nt32Pkg platform.dsc to use EdkDxePrintLib instance for UEFI_APPLICATION modules. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4109 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			2229 lines
		
	
	
		
			72 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2229 lines
		
	
	
		
			72 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/**@file
 | 
						|
  Entry and initialization module for the browser.
 | 
						|
 | 
						|
Copyright (c) 2006 - 2007 Intel Corporation. <BR>
 | 
						|
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.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
 | 
						|
#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
 | 
						|
  },
 | 
						|
};
 | 
						|
 | 
						|
STATIC
 | 
						|
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
 | 
						|
  );
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
InitializeTagStructures (
 | 
						|
  IN  EFI_IFR_BINARY                            *BinaryData,
 | 
						|
  OUT EFI_FILE_FORM_TAGS                        *FileFormTags
 | 
						|
  );
 | 
						|
 | 
						|
STATIC
 | 
						|
UI_MENU_OPTION        *
 | 
						|
DisplayHomePage (
 | 
						|
  IN UINTN                                    NumberOfIfrImages,
 | 
						|
  IN EFI_FILE_FORM_TAGS                       *FileFormTagsHead,
 | 
						|
  IN UINT8                                    *CallbackData
 | 
						|
  );
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
GetIfrBinaryData (
 | 
						|
  IN EFI_HII_PROTOCOL *Hii,
 | 
						|
  IN EFI_HII_HANDLE   HiiHandle,
 | 
						|
  IN EFI_IFR_PACKET   *Packet,
 | 
						|
  IN EFI_IFR_BINARY   *BinaryData
 | 
						|
  );
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
InstallPrint (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
STATIC
 | 
						|
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 EFI_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_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;
 | 
						|
 | 
						|
  ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
 | 
						|
 | 
						|
  gPreviousValue  = AllocatePool (0x1000);
 | 
						|
  CallbackData    = AllocatePool (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
 | 
						|
          )
 | 
						|
            ) {
 | 
						|
          CopyMem (&gScreenDimensions, ScreenDimensions, sizeof (EFI_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);
 | 
						|
    ZeroMem (CallbackData, 0x10000);
 | 
						|
 | 
						|
    //
 | 
						|
    // We can recurse through this and might need to re-allocate this particular buffer
 | 
						|
    //
 | 
						|
    if (gPreviousValue == NULL) {
 | 
						|
      gPreviousValue = AllocatePool (0x1000);
 | 
						|
      ASSERT (gPreviousValue != NULL);
 | 
						|
    }
 | 
						|
 | 
						|
    Callback      = FALSE;
 | 
						|
    FormCallback  = NULL;
 | 
						|
 | 
						|
    if (CallbackHandle != NULL) {
 | 
						|
      //
 | 
						|
      // Retrieve the Callback protocol interface
 | 
						|
      //
 | 
						|
      Status = gBS->HandleProtocol (
 | 
						|
                      CallbackHandle,
 | 
						|
                      &gEfiFormCallbackProtocolGuid,
 | 
						|
                      (VOID **) &FormCallback
 | 
						|
                      );
 | 
						|
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        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)) {
 | 
						|
      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 = AllocateZeroPool (sizeof (UI_MENU_OPTION));
 | 
						|
      ASSERT (Selection != NULL);
 | 
						|
      Selection->IfrNumber  = 0;
 | 
						|
      Selection->Handle     = Handle[0];
 | 
						|
      UiInitMenu ();
 | 
						|
    }
 | 
						|
 | 
						|
    UiInitMenuList ();
 | 
						|
 | 
						|
    if (UseDatabase && (HandleCount > 1)) {
 | 
						|
      if (Selection == NULL) {
 | 
						|
        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)) {
 | 
						|
      FreePool (CallbackData);
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    if (Callback && (AltSelection == NULL)) {
 | 
						|
      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
 | 
						|
        //
 | 
						|
        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);
 | 
						|
 | 
						|
        FreePool (CallbackData);
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      }
 | 
						|
 | 
						|
      FreePool (Selection);
 | 
						|
      UiFreeMenu ();
 | 
						|
 | 
						|
      //
 | 
						|
      // Clean up the allocated data buffers
 | 
						|
      //
 | 
						|
      FreeData (FileFormTagsHead, NULL, NULL);
 | 
						|
 | 
						|
      gST->ConOut->ClearScreen (gST->ConOut);
 | 
						|
 | 
						|
      if (!Callback) {
 | 
						|
        FreePool (CallbackData);
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
  } while (!EFI_ERROR (Status));
 | 
						|
 | 
						|
  FreePool (CallbackData);
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
InitializeSetup (
 | 
						|
  IN EFI_HANDLE           ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE     *SystemTable
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Initialize Setup
 | 
						|
 | 
						|
Arguments:
 | 
						|
  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
 | 
						|
 | 
						|
Returns:
 | 
						|
  EFI_SUCCESS - Setup loaded.
 | 
						|
  other       - Setup Error
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS                  Status;
 | 
						|
  EFI_FORM_CONFIGURATION_DATA *FormData;
 | 
						|
  EFI_FORM_BROWSER_PROTOCOL   *FormBrowser;
 | 
						|
  EFI_HANDLE                  Handle;
 | 
						|
  EFI_HII_PACKAGES            *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,
 | 
						|
                  (VOID **) &FormBrowser
 | 
						|
                  );
 | 
						|
 | 
						|
  gFirstIn = TRUE;
 | 
						|
 | 
						|
  //
 | 
						|
  // If there was no error, assume there is an installation and fail to load
 | 
						|
  //
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    return EFI_DEVICE_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  FormData = AllocatePool (sizeof (EFI_FORM_CONFIGURATION_DATA));
 | 
						|
 | 
						|
  if (FormData == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Fill in HII data
 | 
						|
  //
 | 
						|
  FormData->Signature               = EFI_FORM_DATA_SIGNATURE;
 | 
						|
  FormData->FormConfig.SendForm     = SendForm;
 | 
						|
  FormData->FormConfig.CreatePopUp  = CreateDialog;
 | 
						|
 | 
						|
  //
 | 
						|
  // There should only be one HII image
 | 
						|
  //
 | 
						|
  Status = gBS->LocateProtocol (
 | 
						|
                  &gEfiHiiProtocolGuid,
 | 
						|
                  NULL,
 | 
						|
                  (VOID **) &FormData->Hii
 | 
						|
                  );
 | 
						|
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  Hii         = FormData->Hii;
 | 
						|
 | 
						|
  PackageList = PreparePackages (1, &gEfiFormBrowserProtocolGuid, SetupBrowserStrings);
 | 
						|
 | 
						|
  Status      = Hii->NewPack (Hii, PackageList, &gHiiHandle);
 | 
						|
 | 
						|
  FreePool (PackageList);
 | 
						|
 | 
						|
  //
 | 
						|
  // Install protocol interface
 | 
						|
  //
 | 
						|
  Handle = NULL;
 | 
						|
  Status = gBS->InstallProtocolInterface (
 | 
						|
                  &Handle,
 | 
						|
                  &gEfiFormBrowserProtocolGuid,
 | 
						|
                  EFI_NATIVE_INTERFACE,
 | 
						|
                  &FormData->FormConfig
 | 
						|
                  );
 | 
						|
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  BannerData = AllocateZeroPool (sizeof (BANNER_DATA));
 | 
						|
  ASSERT (BannerData != NULL);
 | 
						|
 | 
						|
  Status = InstallPrint ();
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
GetQuestionHeader (
 | 
						|
  IN  EFI_TAG             *Tag,
 | 
						|
  IN  UINT8               *RawFormSet,
 | 
						|
  IN  UINT16              Index,
 | 
						|
  IN  EFI_FILE_FORM_TAGS  *FileFormTags,
 | 
						|
  IN  UINT16              CurrentVariable
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Initialize question tag's members.
 | 
						|
 | 
						|
Arguments:
 | 
						|
  Tag              - Pointer of the current EFI_TAG structure.
 | 
						|
  RawFormSet       - Pointer of the formset raw data.
 | 
						|
  Index            - Offset of the current opcode in the Ifr raw data.
 | 
						|
  FileFormTags     - Pointer of current EFI_FILE_FORM_TAGS structure.
 | 
						|
  CurrentVariable  - Current variable number.
 | 
						|
 | 
						|
Returns:
 | 
						|
  None.
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_VARIABLE_DEFINITION *VariableDefinition;
 | 
						|
 | 
						|
  Tag->NumberOfLines  = 1;
 | 
						|
  Tag->VariableNumber = CurrentVariable;
 | 
						|
  CopyMem (&Tag->Id, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));
 | 
						|
  CopyMem (&Tag->StorageStart, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));
 | 
						|
  CopyMem (&Tag->StorageWidth, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Width, sizeof (UINT8));
 | 
						|
  CopyMem (&Tag->Text, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Prompt, sizeof (UINT16));
 | 
						|
  CopyMem (&Tag->Help, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Help, sizeof (UINT16));
 | 
						|
 | 
						|
  VariableDefinition = FileFormTags->VariableDefinitions;
 | 
						|
 | 
						|
  for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {
 | 
						|
    //
 | 
						|
    // Have we found the correct variable for the request?
 | 
						|
    //
 | 
						|
    if (CurrentVariable == VariableDefinition->VariableId) {
 | 
						|
      if (VariableDefinition->VariableSize < (UINTN) (Tag->StorageStart + Tag->StorageWidth)) {
 | 
						|
        VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + Tag->StorageWidth);
 | 
						|
      }
 | 
						|
 | 
						|
      if (VariableDefinition->NvRamMap != NULL) {
 | 
						|
        //
 | 
						|
        // If it is an 8bit or 16bit width, then move it to Tag->Value, otherwise
 | 
						|
        // we will never be looking for the data in Tag->Value (e.g. strings, password, etc)
 | 
						|
        //
 | 
						|
        if (Tag->StorageWidth == (UINT16) 1) {
 | 
						|
          CopyMem (&Tag->Value, &VariableDefinition->NvRamMap[Tag->StorageStart], sizeof (UINT16));
 | 
						|
        }
 | 
						|
 | 
						|
        if (Tag->StorageWidth == (UINT16) 2) {
 | 
						|
          Index = (UINT16)
 | 
						|
            (
 | 
						|
              VariableDefinition->NvRamMap[Tag->StorageStart] +
 | 
						|
              (VariableDefinition->NvRamMap[Tag->StorageStart + 1] * 0x100)
 | 
						|
            );
 | 
						|
          CopyMem (&Tag->Value, &Index, sizeof (UINT16));
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        Index = 0;
 | 
						|
        CopyMem (&Tag->Value, &Index, sizeof (UINT16));
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
GetNumericHeader (
 | 
						|
  IN  EFI_TAG             *Tag,
 | 
						|
  IN  UINT8               *RawFormSet,
 | 
						|
  IN  UINT16              Index,
 | 
						|
  IN  UINT16              NumberOfLines,
 | 
						|
  IN  EFI_FILE_FORM_TAGS  *FileFormTags,
 | 
						|
  IN  UINT16              CurrentVariable
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Initialize numeric tag's members.
 | 
						|
 | 
						|
Arguments:
 | 
						|
  Tag              - Pointer of the current EFI_TAG structure.
 | 
						|
  RawFormSet       - Pointer of the formset raw data.
 | 
						|
  Index            - Offset of the current opcode in the Ifr raw data.
 | 
						|
  NumberOfLines    - Number of lines this opcode occupied.
 | 
						|
  FileFormTags     - Pointer of current EFI_FILE_FORM_TAGS structure.
 | 
						|
  CurrentVariable  - Current variable number.
 | 
						|
 | 
						|
Returns:
 | 
						|
  None.
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_VARIABLE_DEFINITION *VariableDefinition;
 | 
						|
 | 
						|
  Tag->NumberOfLines  = NumberOfLines;
 | 
						|
  Tag->VariableNumber = CurrentVariable;
 | 
						|
  CopyMem (&Tag->Id, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));
 | 
						|
  CopyMem (&Tag->StorageStart, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->QuestionId, sizeof (UINT16));
 | 
						|
  CopyMem (&Tag->StorageWidth, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Width, sizeof (UINT8));
 | 
						|
  CopyMem (&Tag->Text, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Prompt, sizeof (UINT16));
 | 
						|
  CopyMem (&Tag->Help, &((EFI_IFR_ONE_OF *) &RawFormSet[Index])->Help, sizeof (UINT16));
 | 
						|
  CopyMem (&Tag->Minimum, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Minimum, sizeof (UINT16));
 | 
						|
  CopyMem (&Tag->Maximum, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Maximum, sizeof (UINT16));
 | 
						|
  CopyMem (&Tag->Step, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Step, sizeof (UINT16));
 | 
						|
  CopyMem (&Tag->Default, &((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Default, sizeof (UINT16));
 | 
						|
  Tag->ResetRequired  = (BOOLEAN) (((EFI_IFR_NUMERIC *) &RawFormSet[Index])->Flags & EFI_IFR_FLAG_RESET_REQUIRED);
 | 
						|
 | 
						|
  VariableDefinition  = FileFormTags->VariableDefinitions;
 | 
						|
 | 
						|
  for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {
 | 
						|
    //
 | 
						|
    // Have we found the correct variable for the request?
 | 
						|
    //
 | 
						|
    if (CurrentVariable == VariableDefinition->VariableId) {
 | 
						|
      if (VariableDefinition->VariableSize <= (UINTN) (Tag->StorageStart + Tag->StorageWidth)) {
 | 
						|
        if (Tag->StorageWidth == 0) {
 | 
						|
          VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + 2);
 | 
						|
        } else {
 | 
						|
          VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + Tag->StorageWidth);
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (VariableDefinition->NvRamMap != NULL) {
 | 
						|
        //
 | 
						|
        // If it is an 8bit or 16bit width, then move it to Tag->Value, otherwise
 | 
						|
        // we will never be looking for the data in Tag->Value (e.g. strings, password, etc)
 | 
						|
        //
 | 
						|
        if (Tag->StorageWidth == (UINT16) 1) {
 | 
						|
          CopyMem (&Tag->Value, &VariableDefinition->NvRamMap[Tag->StorageStart], sizeof (UINT16));
 | 
						|
        }
 | 
						|
 | 
						|
        if (Tag->StorageWidth == (UINT16) 2) {
 | 
						|
          Index = (UINT16)
 | 
						|
            (
 | 
						|
              VariableDefinition->NvRamMap[Tag->StorageStart] +
 | 
						|
                (VariableDefinition->NvRamMap[Tag->StorageStart + 1] * 0x100)
 | 
						|
            );
 | 
						|
          CopyMem (&Tag->Value, &Index, sizeof (UINT16));
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        CopyMem (&Tag->Value, &Tag->Default, sizeof (UINT16));
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
GetTagCount (
 | 
						|
  IN      UINT8                                 *RawFormSet,
 | 
						|
  IN OUT  UINT16                                *NumberOfTags
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT16  Index;
 | 
						|
 | 
						|
  //
 | 
						|
  // Assume on entry we are pointing to an OpCode - reasonably this should
 | 
						|
  // be a FormOp since the purpose is to count the tags in a particular Form.
 | 
						|
  //
 | 
						|
  for (Index = 0; RawFormSet[Index] != EFI_IFR_END_FORM_OP;) {
 | 
						|
    //
 | 
						|
    // If we encounter the end of a form set, bail out
 | 
						|
    //
 | 
						|
    if (RawFormSet[Index] == EFI_IFR_END_FORM_SET_OP) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // We treat date/time internally as three op-codes
 | 
						|
    //
 | 
						|
    if (RawFormSet[Index] == EFI_IFR_DATE_OP || RawFormSet[Index] == EFI_IFR_TIME_OP) {
 | 
						|
      *NumberOfTags = (UINT16) (*NumberOfTags + 3);
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Assume that we could have no more tags than op-codes
 | 
						|
      //
 | 
						|
      (*NumberOfTags)++;
 | 
						|
    }
 | 
						|
 | 
						|
    Index = (UINT16) (Index + RawFormSet[Index + 1]);
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Increase the tag count by one so it is inclusive of the end_form_op
 | 
						|
  //
 | 
						|
  (*NumberOfTags)++;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
AddNextInconsistentTag (
 | 
						|
  IN OUT  EFI_INCONSISTENCY_DATA  **InconsistentTagsPtr
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Initialize the next inconsistent tag data and add it to the inconsistent tag list.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 InconsistentTagsPtr   - Pointer of the inconsistent tag's pointer.
 | 
						|
 | 
						|
Returns:
 | 
						|
  None.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_INCONSISTENCY_DATA  *PreviousInconsistentTags;
 | 
						|
  EFI_INCONSISTENCY_DATA  *InconsistentTags;
 | 
						|
 | 
						|
  InconsistentTags = *InconsistentTagsPtr;
 | 
						|
  //
 | 
						|
  // We just hit the end of an inconsistent expression.  Let's allocate the ->Next structure
 | 
						|
  //
 | 
						|
  InconsistentTags->Next = AllocatePool (sizeof (EFI_INCONSISTENCY_DATA));
 | 
						|
  ASSERT (InconsistentTags->Next != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Preserve current Tag entry
 | 
						|
  //
 | 
						|
  PreviousInconsistentTags  = InconsistentTags;
 | 
						|
 | 
						|
  InconsistentTags          = InconsistentTags->Next;
 | 
						|
 | 
						|
  //
 | 
						|
  // This will zero on the entry including the ->Next so I don't have to do it
 | 
						|
  //
 | 
						|
  ZeroMem (InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));
 | 
						|
 | 
						|
  //
 | 
						|
  // Point our Previous field to the previous entry
 | 
						|
  //
 | 
						|
  InconsistentTags->Previous  = PreviousInconsistentTags;
 | 
						|
 | 
						|
  *InconsistentTagsPtr        = InconsistentTags;
 | 
						|
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
InitializeTagStructures (
 | 
						|
  IN  EFI_IFR_BINARY                            *BinaryData,
 | 
						|
  OUT EFI_FILE_FORM_TAGS                        *FileFormTags
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS              Status;
 | 
						|
  UINT8                   *RawFormSet;
 | 
						|
  UINT16                  Index;
 | 
						|
  UINT16                  QuestionIndex;
 | 
						|
  UINT16                  NumberOfTags;
 | 
						|
  INT16                   CurrTag;
 | 
						|
  UINT8                   TagLength;
 | 
						|
  EFI_FORM_TAGS           *FormTags;
 | 
						|
  EFI_FORM_TAGS           *SavedFormTags;
 | 
						|
  EFI_INCONSISTENCY_DATA  *InconsistentTags;
 | 
						|
  EFI_VARIABLE_DEFINITION *VariableDefinitions;
 | 
						|
  UINTN                   Count;
 | 
						|
  UINT16                  Class;
 | 
						|
  UINT16                  SubClass;
 | 
						|
  UINT16                  TempValue;
 | 
						|
  UINT16                  CurrentVariable;
 | 
						|
  UINT16                  CurrentVariable2;
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize some Index variable and Status
 | 
						|
  //
 | 
						|
  Count             = 0;
 | 
						|
  Class             = 0;
 | 
						|
  SubClass          = 0;
 | 
						|
  CurrentVariable   = 0;
 | 
						|
  CurrentVariable2  = 0;
 | 
						|
  QuestionIndex     = 0;
 | 
						|
  NumberOfTags      = 1;
 | 
						|
  Status            = EFI_SUCCESS;
 | 
						|
  FormTags          = &FileFormTags->FormTags;
 | 
						|
  FormTags->Next    = NULL;
 | 
						|
  if (FileFormTags->InconsistentTags == NULL) {
 | 
						|
    InconsistentTags = NULL;
 | 
						|
  } else {
 | 
						|
    InconsistentTags = FileFormTags->InconsistentTags;
 | 
						|
  }
 | 
						|
 | 
						|
  if (FileFormTags->VariableDefinitions == NULL) {
 | 
						|
    VariableDefinitions = NULL;
 | 
						|
  } else {
 | 
						|
    VariableDefinitions = FileFormTags->VariableDefinitions;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // RawFormSet now points to the beginning of the forms portion of
 | 
						|
  // the specific IFR Binary.
 | 
						|
  //
 | 
						|
  RawFormSet = (UINT8 *) BinaryData->FormBinary;
 | 
						|
 | 
						|
  //
 | 
						|
  // Determine the number of tags for the first form
 | 
						|
  //
 | 
						|
  GetTagCount (&RawFormSet[0], &NumberOfTags);
 | 
						|
 | 
						|
  SavedFormTags = FormTags;
 | 
						|
 | 
						|
  if (FormTags->Tags != NULL) {
 | 
						|
    do {
 | 
						|
      //
 | 
						|
      // Advance FormTags to the last entry
 | 
						|
      //
 | 
						|
      for (; FormTags->Next != NULL; FormTags = FormTags->Next)
 | 
						|
        ;
 | 
						|
 | 
						|
      //
 | 
						|
      // Walk through each of the tags and free the IntList allocation
 | 
						|
      //
 | 
						|
      for (Index = 0; Index < NumberOfTags; Index++) {
 | 
						|
        if (FormTags->Tags[Index].IntList != NULL) {
 | 
						|
          FreePool (FormTags->Tags[Index].IntList);
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      FreePool (FormTags->Tags);
 | 
						|
 | 
						|
      ASSERT (FormTags->Next == NULL);
 | 
						|
 | 
						|
      FormTags->Tags  = NULL;
 | 
						|
 | 
						|
      FormTags        = SavedFormTags;
 | 
						|
 | 
						|
    } while (FormTags->Next != NULL);
 | 
						|
  }
 | 
						|
 | 
						|
  Index = 0;
 | 
						|
 | 
						|
  //
 | 
						|
  // Test for an allocated buffer.  If already allocated this is due to having called this routine
 | 
						|
  // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize
 | 
						|
  // the tag structure with current values from the NV
 | 
						|
  //
 | 
						|
  if (FormTags->Tags == NULL) {
 | 
						|
    //
 | 
						|
    // Allocate memory for our tags on the first form
 | 
						|
    //
 | 
						|
    FormTags->Tags = AllocateZeroPool (NumberOfTags * sizeof (EFI_TAG));
 | 
						|
    ASSERT (FormTags->Tags);
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Test for an allocated buffer.  If already allocated this is due to having called this routine
 | 
						|
  // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize
 | 
						|
  // the tag structure with current values from the NV
 | 
						|
  //
 | 
						|
  if (InconsistentTags == NULL) {
 | 
						|
    //
 | 
						|
    // We just hit the end of an inconsistent expression.  Let's allocate the ->Next structure
 | 
						|
    //
 | 
						|
    InconsistentTags = AllocateZeroPool (sizeof (EFI_INCONSISTENCY_DATA));
 | 
						|
    ASSERT (InconsistentTags != NULL);
 | 
						|
 | 
						|
    FileFormTags->InconsistentTags = InconsistentTags;
 | 
						|
  }
 | 
						|
 | 
						|
  ZeroMem (FormTags->Tags, NumberOfTags * sizeof (EFI_TAG));
 | 
						|
 | 
						|
  for (CurrTag = 0; RawFormSet[Index] != EFI_IFR_END_FORM_SET_OP; CurrTag++) {
 | 
						|
    //
 | 
						|
    // Operand = IFR OpCode
 | 
						|
    //
 | 
						|
    FormTags->Tags[CurrTag].Operand = RawFormSet[Index];
 | 
						|
 | 
						|
    //
 | 
						|
    // Assume for now 0 lines occupied by this OpCode
 | 
						|
    //
 | 
						|
    FormTags->Tags[CurrTag].NumberOfLines = 0;
 | 
						|
 | 
						|
    FormTags->Tags[CurrTag].Class         = Class;
 | 
						|
    FormTags->Tags[CurrTag].SubClass      = SubClass;
 | 
						|
 | 
						|
    //
 | 
						|
    // Determine the length of the Tag so we can later skip to the next tag in the form
 | 
						|
    //
 | 
						|
    TagLength = RawFormSet[Index + 1];
 | 
						|
    //
 | 
						|
    // get the length
 | 
						|
    //
 | 
						|
    // Operate on the Found OpCode
 | 
						|
    //
 | 
						|
    switch (RawFormSet[Index]) {
 | 
						|
 | 
						|
    case EFI_IFR_FORM_OP:
 | 
						|
      //
 | 
						|
      // If there was no variable op-code defined, create a dummy entry for one
 | 
						|
      //
 | 
						|
      if (FileFormTags->VariableDefinitions == NULL) {
 | 
						|
        FileFormTags->VariableDefinitions = AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION));
 | 
						|
        ASSERT (FileFormTags->VariableDefinitions != NULL);
 | 
						|
        IfrToFormTag (
 | 
						|
          RawFormSet[Index],
 | 
						|
          &FormTags->Tags[CurrTag],
 | 
						|
          (VOID *) &RawFormSet[Index],
 | 
						|
          FileFormTags->VariableDefinitions
 | 
						|
          );
 | 
						|
      } else {
 | 
						|
        IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_SUBTITLE_OP:
 | 
						|
    case EFI_IFR_TEXT_OP:
 | 
						|
    case EFI_IFR_REF_OP:
 | 
						|
      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_VARSTORE_OP:
 | 
						|
      if (FileFormTags->VariableDefinitions == NULL) {
 | 
						|
        VariableDefinitions = AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION));
 | 
						|
        ASSERT (VariableDefinitions != NULL);
 | 
						|
        FileFormTags->VariableDefinitions = VariableDefinitions;
 | 
						|
      }
 | 
						|
 | 
						|
      IfrToFormTag (
 | 
						|
        RawFormSet[Index],
 | 
						|
        &FormTags->Tags[CurrTag],
 | 
						|
        (VOID *) &RawFormSet[Index],
 | 
						|
        FileFormTags->VariableDefinitions
 | 
						|
        );
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_VARSTORE_SELECT_OP:
 | 
						|
      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
      CopyMem (&CurrentVariable, &((EFI_IFR_VARSTORE_SELECT *) &RawFormSet[Index])->VarId, sizeof (UINT16));
 | 
						|
      CurrentVariable2 = CurrentVariable;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_VARSTORE_SELECT_PAIR_OP:
 | 
						|
      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
      CopyMem(&CurrentVariable, &((EFI_IFR_VARSTORE_SELECT_PAIR *)&RawFormSet[Index])->VarId, sizeof (UINT16));
 | 
						|
      CopyMem (
 | 
						|
        &CurrentVariable2,
 | 
						|
        &((EFI_IFR_VARSTORE_SELECT_PAIR *) &RawFormSet[Index])->SecondaryVarId,
 | 
						|
        sizeof (UINT16)
 | 
						|
        );
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_END_FORM_OP:
 | 
						|
      //
 | 
						|
      // Test for an allocated buffer.  If already allocated this is due to having called this routine
 | 
						|
      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize
 | 
						|
      // the tag structure with current values from the NV
 | 
						|
      //
 | 
						|
      if (FormTags->Next == NULL) {
 | 
						|
        //
 | 
						|
        // We just hit the end of a form.  Let's allocate the ->Next structure
 | 
						|
        //
 | 
						|
        FormTags->Next = AllocatePool (sizeof (EFI_FORM_TAGS));
 | 
						|
        ASSERT (FormTags->Next);
 | 
						|
      }
 | 
						|
 | 
						|
      FormTags = FormTags->Next;
 | 
						|
      ZeroMem (FormTags, sizeof (EFI_FORM_TAGS));
 | 
						|
 | 
						|
      //
 | 
						|
      // Reset the tag count to one
 | 
						|
      //
 | 
						|
      NumberOfTags = 1;
 | 
						|
 | 
						|
      //
 | 
						|
      // Reset the CurrTag value (it will be incremented, after this case statement
 | 
						|
      // so set to a negative one so that we get the desired effect.)  Fish can beat me later.
 | 
						|
      //
 | 
						|
      CurrTag = -1;
 | 
						|
 | 
						|
      //
 | 
						|
      // Determine the number of tags after this form.  If this is the last
 | 
						|
      // form, then we will count the endformset and preserve that information
 | 
						|
      // in the tag structure.
 | 
						|
      //
 | 
						|
      GetTagCount (&RawFormSet[Index + TagLength], &NumberOfTags);
 | 
						|
 | 
						|
      //
 | 
						|
      // Allocate memory for our tags
 | 
						|
      //
 | 
						|
      FormTags->Tags = AllocateZeroPool (NumberOfTags * sizeof (EFI_TAG));
 | 
						|
      ASSERT (FormTags->Tags);
 | 
						|
      break;
 | 
						|
 | 
						|
    //
 | 
						|
    // Two types of tags constitute the One Of question: a one-of header and
 | 
						|
    // several one-of options.
 | 
						|
    //
 | 
						|
    case EFI_IFR_ONE_OF_OP:
 | 
						|
    case EFI_IFR_ORDERED_LIST_OP:
 | 
						|
      GetQuestionHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, FileFormTags, CurrentVariable);
 | 
						|
 | 
						|
      //
 | 
						|
      // Store away the CurrTag since what follows will be the answer that we
 | 
						|
      // need to place into the appropriate location in the tag array
 | 
						|
      //
 | 
						|
      //
 | 
						|
      // record for setting default later
 | 
						|
      //
 | 
						|
      QuestionIndex = (UINT16) CurrTag;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_ONE_OF_OPTION_OP:
 | 
						|
      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
      FormTags->Tags[QuestionIndex].Flags = ((EFI_IFR_ONE_OF_OPTION *) &RawFormSet[Index])->Flags;
 | 
						|
      CopyMem (
 | 
						|
        &FormTags->Tags[QuestionIndex].Key,
 | 
						|
        &((EFI_IFR_ONE_OF_OPTION *) &RawFormSet[Index])->Key,
 | 
						|
        sizeof (UINT16)
 | 
						|
        );
 | 
						|
      FormTags->Tags[QuestionIndex].ResetRequired = (BOOLEAN) (FormTags->Tags[QuestionIndex].Flags & EFI_IFR_FLAG_RESET_REQUIRED);
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_CHECKBOX_OP:
 | 
						|
      GetQuestionHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, FileFormTags, CurrentVariable);
 | 
						|
      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_NUMERIC_OP:
 | 
						|
      GetNumericHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, (UINT16) 1, FileFormTags, CurrentVariable);
 | 
						|
      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_DATE_OP:
 | 
						|
      //
 | 
						|
      // Date elements come in as a Year, Month, Day.  We need to process them as a country-based
 | 
						|
      // Order.  It is much easier to do it here than anywhere else.
 | 
						|
      //
 | 
						|
      // For US standards - we want Month/Day/Year, thus we advance "Index" +1, +2, +0 while CurrTag is +0, +1, +2
 | 
						|
      //
 | 
						|
      GetNumericHeader (
 | 
						|
        &FormTags->Tags[CurrTag],
 | 
						|
        RawFormSet,
 | 
						|
        (UINT16) (Index + TagLength),
 | 
						|
        (UINT16) 0,
 | 
						|
        FileFormTags,
 | 
						|
        CurrentVariable
 | 
						|
        );
 | 
						|
 | 
						|
      //
 | 
						|
      // The current language selected + the Date operand
 | 
						|
      //
 | 
						|
      FormTags->Tags[CurrTag + 1].Operand = RawFormSet[Index];
 | 
						|
      GetNumericHeader (
 | 
						|
        &FormTags->Tags[CurrTag + 1],
 | 
						|
        RawFormSet,
 | 
						|
        (UINT16) (Index + TagLength + RawFormSet[Index + TagLength + 1]),
 | 
						|
        (UINT16) 0,
 | 
						|
        FileFormTags,
 | 
						|
        CurrentVariable
 | 
						|
        );
 | 
						|
 | 
						|
      //
 | 
						|
      // The current language selected + the Date operand
 | 
						|
      //
 | 
						|
      FormTags->Tags[CurrTag + 2].Operand = RawFormSet[Index];
 | 
						|
      GetNumericHeader (&FormTags->Tags[CurrTag + 2], RawFormSet, Index, (UINT16) 1, FileFormTags, CurrentVariable);
 | 
						|
 | 
						|
      CurrTag   = (INT16) (CurrTag + 2);
 | 
						|
 | 
						|
      Index     = (UINT16) (Index + TagLength);
 | 
						|
      //
 | 
						|
      // get the length
 | 
						|
      //
 | 
						|
      TagLength = RawFormSet[Index + 1];
 | 
						|
      Index     = (UINT16) (Index + TagLength);
 | 
						|
      //
 | 
						|
      // get the length
 | 
						|
      //
 | 
						|
      TagLength = RawFormSet[Index + 1];
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_TIME_OP:
 | 
						|
      GetNumericHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, (UINT16) 0, FileFormTags, CurrentVariable);
 | 
						|
 | 
						|
      if (Count == 2) {
 | 
						|
        //
 | 
						|
        // Override the GetQuestionHeader information - date/time are treated very differently
 | 
						|
        //
 | 
						|
        FormTags->Tags[CurrTag].NumberOfLines = 1;
 | 
						|
        Count = 0;
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // The premise is that every date/time op-code have 3 elements, the first 2 have 0 lines
 | 
						|
        // associated with them, and the third has 1 line to allow to space beyond the choice.
 | 
						|
        //
 | 
						|
        Count++;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_PASSWORD_OP:
 | 
						|
    case EFI_IFR_STRING_OP:
 | 
						|
      GetQuestionHeader (&FormTags->Tags[CurrTag], RawFormSet, Index, FileFormTags, CurrentVariable);
 | 
						|
      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_SUPPRESS_IF_OP:
 | 
						|
    case EFI_IFR_GRAYOUT_IF_OP:
 | 
						|
      InconsistentTags->Operand = ((EFI_IFR_INCONSISTENT *) &RawFormSet[Index])->Header.OpCode;
 | 
						|
      gConsistencyId++;
 | 
						|
 | 
						|
      //
 | 
						|
      // Since this op-code doesn't use the next field(s), initialize them with something invalid.
 | 
						|
      // Unfortunately 0 is a valid offset value for a QuestionId
 | 
						|
      //
 | 
						|
      InconsistentTags->QuestionId1 = INVALID_OFFSET_VALUE;
 | 
						|
      InconsistentTags->QuestionId2 = INVALID_OFFSET_VALUE;
 | 
						|
 | 
						|
      //
 | 
						|
      // Test for an allocated buffer.  If already allocated this is due to having called this routine
 | 
						|
      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize
 | 
						|
      // the tag structure with current values from the NV
 | 
						|
      //
 | 
						|
      if (InconsistentTags->Next == NULL) {
 | 
						|
        AddNextInconsistentTag (&InconsistentTags);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      InconsistentTags = InconsistentTags->Next;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_FORM_SET_OP:
 | 
						|
      CopyMem (
 | 
						|
        &FormTags->Tags[CurrTag].GuidValue,
 | 
						|
        &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->Guid,
 | 
						|
        sizeof (EFI_GUID)
 | 
						|
        );
 | 
						|
      CopyMem (
 | 
						|
        &FormTags->Tags[CurrTag].CallbackHandle,
 | 
						|
        &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->CallbackHandle,
 | 
						|
        sizeof (EFI_PHYSICAL_ADDRESS)
 | 
						|
        );
 | 
						|
      CopyMem (&FormTags->Tags[CurrTag].Class, &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->Class, sizeof (UINT8));
 | 
						|
      CopyMem (
 | 
						|
        &FormTags->Tags[CurrTag].SubClass,
 | 
						|
        &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->SubClass,
 | 
						|
        sizeof (UINT8)
 | 
						|
        );
 | 
						|
      CopyMem (
 | 
						|
        &FormTags->Tags[CurrTag].NvDataSize,
 | 
						|
        &((EFI_IFR_FORM_SET *) &RawFormSet[Index])->NvDataSize,
 | 
						|
        sizeof (UINT16)
 | 
						|
        );
 | 
						|
      Class     = ((EFI_IFR_FORM_SET *) &RawFormSet[Index])->Class;
 | 
						|
      SubClass  = ((EFI_IFR_FORM_SET *) &RawFormSet[Index])->SubClass;
 | 
						|
      //
 | 
						|
      // If the formset has a size value, that means someone must be using this, so create a variable
 | 
						|
      // We also shall reserve the formid of 0 for this specific purpose.
 | 
						|
      //
 | 
						|
      if ((FileFormTags->VariableDefinitions == NULL) && (FormTags->Tags[CurrTag].NvDataSize > 0)) {
 | 
						|
        FileFormTags->VariableDefinitions = AllocateZeroPool (sizeof (EFI_VARIABLE_DEFINITION));
 | 
						|
        ASSERT (FileFormTags->VariableDefinitions != NULL);
 | 
						|
        IfrToFormTag (
 | 
						|
          RawFormSet[Index],
 | 
						|
          &FormTags->Tags[CurrTag],
 | 
						|
          (VOID *) &RawFormSet[Index],
 | 
						|
          FileFormTags->VariableDefinitions
 | 
						|
          );
 | 
						|
      } else {
 | 
						|
        IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_BANNER_OP:
 | 
						|
      if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) {
 | 
						|
        TempValue = 0;
 | 
						|
        CopyMem (&TempValue, &((EFI_IFR_BANNER *) &RawFormSet[Index])->Alignment, sizeof (UINT8));
 | 
						|
        //
 | 
						|
        // If this is the special timeout value, we will dynamically figure out where to put it
 | 
						|
        // Also the least significant byte refers to the TimeOut desired.
 | 
						|
        //
 | 
						|
        if (TempValue == EFI_IFR_BANNER_TIMEOUT) {
 | 
						|
          CopyMem (&FrontPageTimeOutTitle, &((EFI_IFR_BANNER *) &RawFormSet[Index])->Title, sizeof (UINT16));
 | 
						|
          if (FrontPageTimeOutValue != (INT16) -1) {
 | 
						|
            CopyMem (&FrontPageTimeOutValue, &((EFI_IFR_BANNER *) &RawFormSet[Index])->LineNumber, sizeof (UINT16));
 | 
						|
          }
 | 
						|
          break;
 | 
						|
        }
 | 
						|
 | 
						|
        CopyMem (
 | 
						|
          &BannerData->Banner[((EFI_IFR_BANNER *) &RawFormSet[Index])->LineNumber][
 | 
						|
          ((EFI_IFR_BANNER *) &RawFormSet[Index])->Alignment],
 | 
						|
          &((EFI_IFR_BANNER *) &RawFormSet[Index])->Title,
 | 
						|
          sizeof (STRING_REF)
 | 
						|
          );
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_INCONSISTENT_IF_OP:
 | 
						|
      CopyMem (
 | 
						|
        &FormTags->Tags[CurrTag].Text,
 | 
						|
        &((EFI_IFR_INCONSISTENT *) &RawFormSet[Index])->Popup,
 | 
						|
        sizeof (UINT16)
 | 
						|
        );
 | 
						|
      gConsistencyId++;
 | 
						|
 | 
						|
      InconsistentTags->Operand = ((EFI_IFR_INCONSISTENT *) &RawFormSet[Index])->Header.OpCode;
 | 
						|
      CopyMem (&InconsistentTags->Popup, &((EFI_IFR_INCONSISTENT *) &RawFormSet[Index])->Popup, sizeof (UINT16));
 | 
						|
 | 
						|
      //
 | 
						|
      // Since this op-code doesn't use the next field(s), initialize them with something invalid.
 | 
						|
      // Unfortunately 0 is a valid offset value for a QuestionId
 | 
						|
      //
 | 
						|
      InconsistentTags->QuestionId1     = INVALID_OFFSET_VALUE;
 | 
						|
      InconsistentTags->QuestionId2     = INVALID_OFFSET_VALUE;
 | 
						|
 | 
						|
      InconsistentTags->VariableNumber  = CurrentVariable;
 | 
						|
 | 
						|
      //
 | 
						|
      // Test for an allocated buffer.  If already allocated this is due to having called this routine
 | 
						|
      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize
 | 
						|
      // the tag structure with current values from the NV
 | 
						|
      //
 | 
						|
      if (InconsistentTags->Next == NULL) {
 | 
						|
        AddNextInconsistentTag (&InconsistentTags);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      InconsistentTags = InconsistentTags->Next;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_EQ_ID_VAL_OP:
 | 
						|
      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
 | 
						|
      InconsistentTags->Operand = ((EFI_IFR_EQ_ID_VAL *) &RawFormSet[Index])->Header.OpCode;
 | 
						|
      CopyMem (&InconsistentTags->Value, &((EFI_IFR_EQ_ID_VAL *) &RawFormSet[Index])->Value, sizeof (UINT16));
 | 
						|
      CopyMem (
 | 
						|
        &InconsistentTags->QuestionId1,
 | 
						|
        &((EFI_IFR_EQ_ID_VAL *) &RawFormSet[Index])->QuestionId,
 | 
						|
        sizeof (UINT16)
 | 
						|
        );
 | 
						|
 | 
						|
      //
 | 
						|
      // Since this op-code doesn't use the next field(s), initialize them with something invalid.
 | 
						|
      // Unfortunately 0 is a valid offset value for a QuestionId
 | 
						|
      //
 | 
						|
      InconsistentTags->Width               = FormTags->Tags[CurrTag].StorageWidth;
 | 
						|
      InconsistentTags->QuestionId2         = INVALID_OFFSET_VALUE;
 | 
						|
      InconsistentTags->ConsistencyId       = gConsistencyId;
 | 
						|
      FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;
 | 
						|
 | 
						|
      InconsistentTags->VariableNumber      = CurrentVariable;
 | 
						|
 | 
						|
      //
 | 
						|
      // Test for an allocated buffer.  If already allocated this is due to having called this routine
 | 
						|
      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize
 | 
						|
      // the tag structure with current values from the NV
 | 
						|
      //
 | 
						|
      if (InconsistentTags->Next == NULL) {
 | 
						|
        AddNextInconsistentTag (&InconsistentTags);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      InconsistentTags = InconsistentTags->Next;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_EQ_VAR_VAL_OP:
 | 
						|
      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
 | 
						|
      InconsistentTags->Operand = ((EFI_IFR_EQ_VAR_VAL *) &RawFormSet[Index])->Header.OpCode;
 | 
						|
      CopyMem (&InconsistentTags->Value, &((EFI_IFR_EQ_VAR_VAL *) &RawFormSet[Index])->Value, sizeof (UINT16));
 | 
						|
      CopyMem (
 | 
						|
        &InconsistentTags->QuestionId1,
 | 
						|
        &((EFI_IFR_EQ_VAR_VAL *) &RawFormSet[Index])->VariableId,
 | 
						|
        sizeof (UINT16)
 | 
						|
        );
 | 
						|
 | 
						|
      //
 | 
						|
      // Since this op-code doesn't use the next field(s), initialize them with something invalid.
 | 
						|
      // Unfortunately 0 is a valid offset value for a QuestionId
 | 
						|
      //
 | 
						|
      InconsistentTags->QuestionId2         = INVALID_OFFSET_VALUE;
 | 
						|
      InconsistentTags->ConsistencyId       = gConsistencyId;
 | 
						|
      FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;
 | 
						|
 | 
						|
      InconsistentTags->VariableNumber      = CurrentVariable;
 | 
						|
 | 
						|
      //
 | 
						|
      // Test for an allocated buffer.  If already allocated this is due to having called this routine
 | 
						|
      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize
 | 
						|
      // the tag structure with current values from the NV
 | 
						|
      //
 | 
						|
      if (InconsistentTags->Next == NULL) {
 | 
						|
        AddNextInconsistentTag (&InconsistentTags);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      InconsistentTags = InconsistentTags->Next;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_EQ_ID_ID_OP:
 | 
						|
      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
 | 
						|
      InconsistentTags->Operand = ((EFI_IFR_EQ_ID_ID *) &RawFormSet[Index])->Header.OpCode;
 | 
						|
      CopyMem (
 | 
						|
        &InconsistentTags->QuestionId1,
 | 
						|
        &((EFI_IFR_EQ_ID_ID *) &RawFormSet[Index])->QuestionId1,
 | 
						|
        sizeof (UINT16)
 | 
						|
        );
 | 
						|
      CopyMem (
 | 
						|
        &InconsistentTags->QuestionId2,
 | 
						|
        &((EFI_IFR_EQ_ID_ID *) &RawFormSet[Index])->QuestionId2,
 | 
						|
        sizeof (UINT16)
 | 
						|
        );
 | 
						|
 | 
						|
      InconsistentTags->Width               = FormTags->Tags[CurrTag].StorageWidth;
 | 
						|
      InconsistentTags->ConsistencyId       = gConsistencyId;
 | 
						|
      FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;
 | 
						|
 | 
						|
      InconsistentTags->VariableNumber      = CurrentVariable;
 | 
						|
      InconsistentTags->VariableNumber2     = CurrentVariable2;
 | 
						|
 | 
						|
      //
 | 
						|
      // Test for an allocated buffer.  If already allocated this is due to having called this routine
 | 
						|
      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize
 | 
						|
      // the tag structure with current values from the NV
 | 
						|
      //
 | 
						|
      if (InconsistentTags->Next == NULL) {
 | 
						|
        AddNextInconsistentTag (&InconsistentTags);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      InconsistentTags = InconsistentTags->Next;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_AND_OP:
 | 
						|
    case EFI_IFR_OR_OP:
 | 
						|
    case EFI_IFR_NOT_OP:
 | 
						|
    case EFI_IFR_GT_OP:
 | 
						|
    case EFI_IFR_GE_OP:
 | 
						|
    case EFI_IFR_TRUE_OP:
 | 
						|
    case EFI_IFR_FALSE_OP:
 | 
						|
      InconsistentTags->Operand = ((EFI_IFR_NOT *) &RawFormSet[Index])->Header.OpCode;
 | 
						|
 | 
						|
      //
 | 
						|
      // Since this op-code doesn't use the next field(s), initialize them with something invalid.
 | 
						|
      // Unfortunately 0 is a valid offset value for a QuestionId
 | 
						|
      //
 | 
						|
 | 
						|
      //
 | 
						|
      // Reserve INVALID_OFFSET_VALUE - 1 for TRUE or FALSE because they are inconsistency tags also, but
 | 
						|
      // have no coresponding id. The examination of id is needed by evaluating boolean expression.
 | 
						|
      //
 | 
						|
      if (RawFormSet[Index] == EFI_IFR_TRUE_OP ||
 | 
						|
          RawFormSet[Index] == EFI_IFR_FALSE_OP) {
 | 
						|
        InconsistentTags->QuestionId1         = INVALID_OFFSET_VALUE - 1;
 | 
						|
      } else {
 | 
						|
        InconsistentTags->QuestionId1         = INVALID_OFFSET_VALUE;
 | 
						|
      }
 | 
						|
      InconsistentTags->QuestionId2         = INVALID_OFFSET_VALUE;
 | 
						|
      InconsistentTags->ConsistencyId       = gConsistencyId;
 | 
						|
      FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;
 | 
						|
 | 
						|
      //
 | 
						|
      // Test for an allocated buffer.  If already allocated this is due to having called this routine
 | 
						|
      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize
 | 
						|
      // the tag structure with current values from the NV
 | 
						|
      //
 | 
						|
      if (InconsistentTags->Next == NULL) {
 | 
						|
        AddNextInconsistentTag (&InconsistentTags);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      InconsistentTags = InconsistentTags->Next;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_EQ_ID_LIST_OP:
 | 
						|
      IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
 | 
						|
      InconsistentTags->Operand = ((EFI_IFR_EQ_ID_LIST *) &RawFormSet[Index])->Header.OpCode;
 | 
						|
      CopyMem (
 | 
						|
        &InconsistentTags->QuestionId1,
 | 
						|
        &((EFI_IFR_EQ_ID_LIST *) &RawFormSet[Index])->QuestionId,
 | 
						|
        sizeof (UINT16)
 | 
						|
        );
 | 
						|
      CopyMem (
 | 
						|
        &InconsistentTags->ListLength,
 | 
						|
        &((EFI_IFR_EQ_ID_LIST *) &RawFormSet[Index])->ListLength,
 | 
						|
        sizeof (UINT16)
 | 
						|
        );
 | 
						|
      InconsistentTags->ValueList = FormTags->Tags[CurrTag].IntList;
 | 
						|
 | 
						|
      //
 | 
						|
      // Since this op-code doesn't use the next field(s), initialize them with something invalid.
 | 
						|
      // Unfortunately 0 is a valid offset value for a QuestionId
 | 
						|
      //
 | 
						|
      InconsistentTags->Width               = FormTags->Tags[CurrTag].StorageWidth;
 | 
						|
      InconsistentTags->QuestionId2         = INVALID_OFFSET_VALUE;
 | 
						|
      InconsistentTags->ConsistencyId       = gConsistencyId;
 | 
						|
      FormTags->Tags[CurrTag].ConsistencyId = gConsistencyId;
 | 
						|
 | 
						|
      //
 | 
						|
      // Test for an allocated buffer.  If already allocated this is due to having called this routine
 | 
						|
      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize
 | 
						|
      // the tag structure with current values from the NV
 | 
						|
      //
 | 
						|
      if (InconsistentTags->Next == NULL) {
 | 
						|
        AddNextInconsistentTag (&InconsistentTags);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      InconsistentTags = InconsistentTags->Next;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_END_IF_OP:
 | 
						|
      InconsistentTags->Operand = ((EFI_IFR_END_EXPR *) &RawFormSet[Index])->Header.OpCode;
 | 
						|
 | 
						|
      //
 | 
						|
      // Since this op-code doesn't use the next field(s), initialize them with something invalid.
 | 
						|
      // Unfortunately 0 is a valid offset value for a QuestionId
 | 
						|
      //
 | 
						|
      InconsistentTags->QuestionId1 = INVALID_OFFSET_VALUE;
 | 
						|
      InconsistentTags->QuestionId2 = INVALID_OFFSET_VALUE;
 | 
						|
 | 
						|
      //
 | 
						|
      // Test for an allocated buffer.  If already allocated this is due to having called this routine
 | 
						|
      // once for sizing of the NV storage.  We then loaded the NV variable and can correctly initialize
 | 
						|
      // the tag structure with current values from the NV
 | 
						|
      //
 | 
						|
      if (InconsistentTags->Next == NULL) {
 | 
						|
        AddNextInconsistentTag (&InconsistentTags);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      InconsistentTags = InconsistentTags->Next;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_END_ONE_OF_OP:
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // End of switch
 | 
						|
    //
 | 
						|
    // Per spec., we ignore ops that we don't know how to deal with.  Skip to next tag
 | 
						|
    //
 | 
						|
    Index = (UINT16) (Index + TagLength);
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // End of Index
 | 
						|
  //
 | 
						|
  // When we eventually exit, make sure we mark the last tag with an op-code
 | 
						|
  //
 | 
						|
  FormTags->Tags[CurrTag].Operand = RawFormSet[Index];
 | 
						|
 | 
						|
  IfrToFormTag (RawFormSet[Index], &FormTags->Tags[CurrTag], (VOID *) &RawFormSet[Index], NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Place this as an end of the database marker
 | 
						|
  //
 | 
						|
  InconsistentTags->Operand = 0xFF;
 | 
						|
 | 
						|
  //
 | 
						|
  // This is the Head of the linked list of pages.  Each page is an array of tags
 | 
						|
  //
 | 
						|
  FormTags          = &FileFormTags->FormTags;
 | 
						|
  InconsistentTags  = FileFormTags->InconsistentTags;
 | 
						|
 | 
						|
  for (; InconsistentTags->Operand != 0xFF;) {
 | 
						|
    if (InconsistentTags->QuestionId1 != INVALID_OFFSET_VALUE) {
 | 
						|
      //
 | 
						|
      // Search the tags for the tag which corresponds to this ID
 | 
						|
      //
 | 
						|
      for (CurrTag = 0; FormTags->Tags[0].Operand != EFI_IFR_END_FORM_SET_OP; CurrTag++) {
 | 
						|
        //
 | 
						|
        // If we hit the end of a form, go to the next set of Tags.
 | 
						|
        // Remember - EndFormSet op-codes sit on their own page after an end form.
 | 
						|
        //
 | 
						|
        if (FormTags->Tags[CurrTag].Operand == EFI_IFR_END_FORM_OP) {
 | 
						|
          //
 | 
						|
          // Reset the CurrTag value (it will be incremented, after this case statement
 | 
						|
          // so set to a negative one so that we get the desired effect.)  Fish can beat me later.
 | 
						|
          //
 | 
						|
          CurrTag   = -1;
 | 
						|
          FormTags  = FormTags->Next;
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
 | 
						|
        if (FormTags->Tags[CurrTag].Id == InconsistentTags->QuestionId1) {
 | 
						|
          FormTags->Tags[CurrTag].Consistency++;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    FormTags = &FileFormTags->FormTags;
 | 
						|
 | 
						|
    if (InconsistentTags->QuestionId2 != INVALID_OFFSET_VALUE) {
 | 
						|
      //
 | 
						|
      // Search the tags for the tag which corresponds to this ID
 | 
						|
      //
 | 
						|
      for (CurrTag = 0; FormTags->Tags[CurrTag].Operand != EFI_IFR_END_FORM_SET_OP; CurrTag++) {
 | 
						|
        //
 | 
						|
        // If we hit the end of a form, go to the next set of Tags.
 | 
						|
        // Remember - EndFormSet op-codes sit on their own page after an end form.
 | 
						|
        //
 | 
						|
        if (FormTags->Tags[CurrTag].Operand == EFI_IFR_END_FORM_OP) {
 | 
						|
          //
 | 
						|
          // Reset the CurrTag value (it will be incremented, after this case statement
 | 
						|
          // so set to a negative one so that we get the desired effect.)  Fish can beat me later.
 | 
						|
          //
 | 
						|
          CurrTag   = -1;
 | 
						|
          FormTags  = FormTags->Next;
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
 | 
						|
        if (FormTags->Tags[CurrTag].Id == InconsistentTags->QuestionId2) {
 | 
						|
          FormTags->Tags[CurrTag].Consistency++;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    InconsistentTags = InconsistentTags->Next;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
InitPage (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR16  *HomePageString;
 | 
						|
  CHAR16  *HomeEscapeString;
 | 
						|
 | 
						|
  //
 | 
						|
  // Displays the Header and Footer borders
 | 
						|
  //
 | 
						|
  DisplayPageFrame ();
 | 
						|
 | 
						|
  HomePageString    = GetToken (STRING_TOKEN (HOME_PAGE_TITLE), gHiiHandle);
 | 
						|
  HomeEscapeString  = GetToken (STRING_TOKEN (HOME_ESCAPE_STRING), gHiiHandle);
 | 
						|
 | 
						|
  gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);
 | 
						|
  //
 | 
						|
  //  PrintStringAt ((gScreenDimensions.RightColumn - GetStringWidth(HomePageString)/2)/2, 1, HomePageString);
 | 
						|
  //
 | 
						|
  PrintStringAt (
 | 
						|
    (gScreenDimensions.RightColumn + gScreenDimensions.LeftColumn - GetStringWidth (HomePageString) / 2) / 2,
 | 
						|
    1,
 | 
						|
    HomePageString
 | 
						|
    );
 | 
						|
  PrintAt (
 | 
						|
    gScreenDimensions.LeftColumn + 2,
 | 
						|
    gScreenDimensions.BottomRow - 3,
 | 
						|
    (CHAR16 *) L"%c%c%s",
 | 
						|
    ARROW_UP,
 | 
						|
    ARROW_DOWN,
 | 
						|
    gMoveHighlight
 | 
						|
    );
 | 
						|
  PrintAt (
 | 
						|
    gScreenDimensions.RightColumn - (GetStringWidth (HomeEscapeString) / 2) - 2,
 | 
						|
    gScreenDimensions.BottomRow - 3,
 | 
						|
    (CHAR16 *) L" %s",
 | 
						|
    HomeEscapeString
 | 
						|
    );
 | 
						|
  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
 | 
						|
  FreePool (HomeEscapeString);
 | 
						|
  FreePool (HomePageString);
 | 
						|
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
CHAR16 *
 | 
						|
GetToken (
 | 
						|
  IN  STRING_REF                              Token,
 | 
						|
  IN  EFI_HII_HANDLE                          HiiHandle
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Get the string based on the TokenID and HII Handle.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Token       - The Token ID.
 | 
						|
  HiiHandle   - Handle of Ifr to be fetched.
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  The output string.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  CHAR16      *Buffer;
 | 
						|
  UINTN       BufferLength;
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  //
 | 
						|
  // Set default string size assumption at no more than 256 bytes
 | 
						|
  //
 | 
						|
  BufferLength  = 0x100;
 | 
						|
 | 
						|
  Buffer        = AllocateZeroPool (BufferLength);
 | 
						|
  ASSERT (Buffer != NULL);
 | 
						|
 | 
						|
  Status = Hii->GetString (Hii, HiiHandle, Token, TRUE, NULL, &BufferLength, Buffer);
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    if (Status == EFI_BUFFER_TOO_SMALL) {
 | 
						|
      //
 | 
						|
      // Free the old pool
 | 
						|
      //
 | 
						|
      FreePool (Buffer);
 | 
						|
 | 
						|
      //
 | 
						|
      // Allocate new pool with correct value
 | 
						|
      //
 | 
						|
      Buffer = AllocatePool (BufferLength);
 | 
						|
      ASSERT (Buffer != NULL);
 | 
						|
 | 
						|
      Status = Hii->GetString (Hii, HiiHandle, Token, TRUE, NULL, &BufferLength, Buffer);
 | 
						|
 | 
						|
      if (!EFI_ERROR (Status)) {
 | 
						|
        return Buffer;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    ASSERT_EFI_ERROR (Status);
 | 
						|
  }
 | 
						|
 | 
						|
  return Buffer;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
PopulateHomePage (
 | 
						|
  IN UINTN                                    NumberOfIfrImages,
 | 
						|
  IN EFI_FILE_FORM_TAGS                       *FileFormTagsHead
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  UINTN               Index;
 | 
						|
  EFI_IFR_BINARY      *IfrBinary;
 | 
						|
  CHAR16              *StringPtr;
 | 
						|
  EFI_FILE_FORM_TAGS  *FileFormTags;
 | 
						|
  EFI_FORM_TAGS       LocalTags;
 | 
						|
 | 
						|
  FileFormTags = FileFormTagsHead;
 | 
						|
 | 
						|
  UiInitMenu ();
 | 
						|
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
  //
 | 
						|
  // If there are no images
 | 
						|
  //
 | 
						|
  if (NumberOfIfrImages == 0) {
 | 
						|
    Status = EFI_NO_MEDIA;
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // IfrBinary points to the beginning of the Binary data linked-list
 | 
						|
  //
 | 
						|
  IfrBinary = gBinaryDataHead;
 | 
						|
 | 
						|
  //
 | 
						|
  // Print the entries which were in the default language.
 | 
						|
  //
 | 
						|
  for (Index = 0; Index < NumberOfIfrImages; Index++) {
 | 
						|
    LocalTags = FileFormTags->FormTags;
 | 
						|
 | 
						|
    //
 | 
						|
    // Populate the Menu
 | 
						|
    //
 | 
						|
    StringPtr = GetToken (IfrBinary->TitleToken, IfrBinary->Handle);
 | 
						|
 | 
						|
    //
 | 
						|
    // If the default language doesn't exist, don't add a menu option yet
 | 
						|
    //
 | 
						|
    if (StringPtr[0] != CHAR_NULL) {
 | 
						|
      //
 | 
						|
      // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do
 | 
						|
      // it in UiFreeMenu.
 | 
						|
      //
 | 
						|
      UiAddMenuOption (StringPtr, IfrBinary->Handle, LocalTags.Tags, IfrBinary->FormBinary, Index);
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // Advance to the next HII handle
 | 
						|
    //
 | 
						|
    IfrBinary     = IfrBinary->Next;
 | 
						|
    FileFormTags  = FileFormTags->NextFile;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
UI_MENU_OPTION *
 | 
						|
DisplayHomePage (
 | 
						|
  IN UINTN                                    NumberOfIfrImages,
 | 
						|
  IN EFI_FILE_FORM_TAGS                       *FileFormTagsHead,
 | 
						|
  IN UINT8                                    *CallbackData
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS      Status;
 | 
						|
  UI_MENU_OPTION  *Selection;
 | 
						|
 | 
						|
  //
 | 
						|
  // This prints the basic home page template which the user sees
 | 
						|
  //
 | 
						|
  InitPage ();
 | 
						|
 | 
						|
  Status = PopulateHomePage (NumberOfIfrImages, FileFormTagsHead);
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    Selection = NULL;
 | 
						|
    return Selection;
 | 
						|
  }
 | 
						|
 | 
						|
  Selection = UiDisplayMenu (FALSE, FileFormTagsHead, (EFI_IFR_DATA_ARRAY *) CallbackData);
 | 
						|
 | 
						|
  return Selection;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
InitializeBinaryStructures (
 | 
						|
  IN  EFI_HII_HANDLE                        *Handle,
 | 
						|
  IN  BOOLEAN                               UseDatabase,
 | 
						|
  IN  EFI_IFR_PACKET                        *Packet,
 | 
						|
  IN  UINT8                                 *NvMapOverride,
 | 
						|
  IN  UINTN                                 NumberOfIfrImages,
 | 
						|
  OUT EFI_FILE_FORM_TAGS                    **FileFormTagsHead
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN                       HandleIndex;
 | 
						|
  EFI_STATUS                  Status;
 | 
						|
  EFI_IFR_BINARY              *BinaryData;
 | 
						|
  EFI_FILE_FORM_TAGS          *FileFormTags;
 | 
						|
  UINTN                       SizeOfNvStore;
 | 
						|
  EFI_FORM_CALLBACK_PROTOCOL  *FormCallback;
 | 
						|
  EFI_VARIABLE_DEFINITION     *VariableDefinition;
 | 
						|
  EFI_VARIABLE_DEFINITION     *OverrideDefinition;
 | 
						|
  VOID                        *NvMap;
 | 
						|
  UINTN                       NvMapSize;
 | 
						|
  EFI_HII_VARIABLE_PACK_LIST  *NvMapListHead;
 | 
						|
  EFI_HII_VARIABLE_PACK_LIST  *NvMapListNode;
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize some variables to avoid warnings
 | 
						|
  //
 | 
						|
  BinaryData        = NULL;
 | 
						|
  *FileFormTagsHead = NULL;
 | 
						|
  FileFormTags      = NULL;
 | 
						|
  gBinaryDataHead   = NULL;
 | 
						|
  Status            = EFI_SUCCESS;
 | 
						|
  FormCallback      = NULL;
 | 
						|
  NvMap             = NULL;
 | 
						|
  NvMapSize         = 0;
 | 
						|
 | 
						|
  if (NumberOfIfrImages > 1) {
 | 
						|
    NvMapOverride = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  for (HandleIndex = 0; HandleIndex < NumberOfIfrImages; HandleIndex += 1) {
 | 
						|
    //
 | 
						|
    // If the buffers are uninitialized, allocate them, otherwise work on the ->Next members
 | 
						|
    //
 | 
						|
    if ((BinaryData == NULL) || (FileFormTags == NULL)) {
 | 
						|
      //
 | 
						|
      // Allocate memory for our Binary Data
 | 
						|
      //
 | 
						|
      BinaryData = AllocateZeroPool (sizeof (EFI_IFR_BINARY));
 | 
						|
      ASSERT (BinaryData);
 | 
						|
 | 
						|
      //
 | 
						|
      // Preserve the Head of what will be a linked-list.
 | 
						|
      //
 | 
						|
      gBinaryDataHead       = BinaryData;
 | 
						|
      gBinaryDataHead->Next = NULL;
 | 
						|
 | 
						|
      if (UseDatabase) {
 | 
						|
        Status = GetIfrBinaryData (Hii, Handle[HandleIndex], NULL, BinaryData);
 | 
						|
      } else {
 | 
						|
        Status = GetIfrBinaryData (Hii, Handle[HandleIndex], Packet, BinaryData);
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // Allocate memory for our File Form Tags
 | 
						|
      //
 | 
						|
      FileFormTags = AllocateZeroPool (sizeof (EFI_FILE_FORM_TAGS));
 | 
						|
      ASSERT (FileFormTags);
 | 
						|
 | 
						|
      //
 | 
						|
      // Preserve the Head of what will be a linked-list.
 | 
						|
      //
 | 
						|
      *FileFormTagsHead             = FileFormTags;
 | 
						|
      (*FileFormTagsHead)->NextFile = NULL;
 | 
						|
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Allocate memory for our Binary Data linked-list
 | 
						|
      // Each handle represents a Binary and we will store that data away.
 | 
						|
      //
 | 
						|
      BinaryData->Next = AllocateZeroPool (sizeof (EFI_IFR_BINARY));
 | 
						|
      ASSERT (BinaryData->Next);
 | 
						|
 | 
						|
      BinaryData        = BinaryData->Next;
 | 
						|
      BinaryData->Next  = NULL;
 | 
						|
 | 
						|
      if (UseDatabase) {
 | 
						|
        Status = GetIfrBinaryData (Hii, Handle[HandleIndex], NULL, BinaryData);
 | 
						|
      } else {
 | 
						|
        Status = GetIfrBinaryData (Hii, Handle[HandleIndex], Packet, BinaryData);
 | 
						|
      }
 | 
						|
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        return EFI_DEVICE_ERROR;
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // Allocate memory for our FileFormTags linked-list
 | 
						|
      // Each allocation reserves handle represents a Binary and we will store that data away.
 | 
						|
      //
 | 
						|
      FileFormTags->NextFile = AllocateZeroPool (sizeof (EFI_FILE_FORM_TAGS));
 | 
						|
      ASSERT (FileFormTags->NextFile);
 | 
						|
 | 
						|
      FileFormTags = FileFormTags->NextFile;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // endif
 | 
						|
    //
 | 
						|
    // Tag Structure Initialization
 | 
						|
    //
 | 
						|
    Status              = InitializeTagStructures (BinaryData, FileFormTags);
 | 
						|
 | 
						|
    VariableDefinition  = FileFormTags->VariableDefinitions;
 | 
						|
 | 
						|
    //
 | 
						|
    // Allocate memory for our NVRAM Maps for all of our variables
 | 
						|
    //
 | 
						|
    for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {
 | 
						|
      //
 | 
						|
      // Pad the fake variable size accordingly - this value should reflect the size of information that is not accounted by
 | 
						|
      // the mainstream NVRAM variable such as DATE/TIME information that the browser needs to track but is saved to an RTC
 | 
						|
      //
 | 
						|
      VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableSize + VariableDefinition->VariableFakeSize);
 | 
						|
 | 
						|
      //
 | 
						|
      // In the case where a file has no "real" NV data, we should pad the buffer accordingly
 | 
						|
      //
 | 
						|
      if (VariableDefinition->VariableSize == 0) {
 | 
						|
        if (VariableDefinition->VariableFakeSize != 0) {
 | 
						|
          VariableDefinition->NvRamMap = AllocateZeroPool (VariableDefinition->VariableFakeSize);
 | 
						|
          ASSERT (VariableDefinition->NvRamMap != NULL);
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        VariableDefinition->NvRamMap = AllocateZeroPool (VariableDefinition->VariableSize);
 | 
						|
        ASSERT (VariableDefinition->NvRamMap != NULL);
 | 
						|
      }
 | 
						|
 | 
						|
      if (VariableDefinition->VariableFakeSize != 0) {
 | 
						|
        VariableDefinition->FakeNvRamMap = AllocateZeroPool (VariableDefinition->VariableFakeSize);
 | 
						|
        ASSERT (VariableDefinition->FakeNvRamMap != NULL);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    Status = gBS->HandleProtocol (
 | 
						|
                    (VOID *) (UINTN) FileFormTags->FormTags.Tags[0].CallbackHandle,
 | 
						|
                    &gEfiFormCallbackProtocolGuid,
 | 
						|
                    (VOID **) &FormCallback
 | 
						|
                    );
 | 
						|
 | 
						|
    //
 | 
						|
    // Since we might have multiple variables, if there is an NvMapOverride we need to use the EFI_VARIABLE_DEFINITION
 | 
						|
    // information as the information that we pass back and forth.  NOTE that callbacks that are initiated will only have the
 | 
						|
    // NVRAM data refreshed based on the op-code that initiated the callback.  In other words, we will pass to the caller a single
 | 
						|
    // NVRAM map for a single variable based on the op-code that the user selected.
 | 
						|
    //
 | 
						|
    if (NvMapOverride != NULL) {
 | 
						|
      VariableDefinition  = FileFormTags->VariableDefinitions;
 | 
						|
      OverrideDefinition  = ((EFI_VARIABLE_DEFINITION *) NvMapOverride);
 | 
						|
 | 
						|
      //
 | 
						|
      // Search through the variable definitions.  There should be sufficient passed in settings for the variable op-codes specified
 | 
						|
      //
 | 
						|
      for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {
 | 
						|
        if ((!CompareMem (VariableDefinition->VariableName, L"Setup", 10)) && (VariableDefinition->Next == NULL)) {
 | 
						|
          if (VariableDefinition->VariableSize != 0) {
 | 
						|
            CopyMem (VariableDefinition->NvRamMap, NvMapOverride, VariableDefinition->VariableSize);
 | 
						|
          } else {
 | 
						|
            CopyMem (VariableDefinition->NvRamMap, NvMapOverride, VariableDefinition->VariableFakeSize);
 | 
						|
          }
 | 
						|
          break;
 | 
						|
        } else {
 | 
						|
          VariableDefinition->NvRamMap = OverrideDefinition->NvRamMap;
 | 
						|
        }
 | 
						|
        //
 | 
						|
        // There should NEVER be a ->Next for VariableDefinition and a NULL ->Next for the OverrideDefinition
 | 
						|
        //
 | 
						|
        ASSERT (OverrideDefinition->Next);
 | 
						|
        OverrideDefinition = OverrideDefinition->Next;
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      VariableDefinition = FileFormTags->VariableDefinitions;
 | 
						|
 | 
						|
      //
 | 
						|
      // Search through the variable definitions.  There should be sufficient passed in settings for the variable op-codes specified
 | 
						|
      //
 | 
						|
      for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {
 | 
						|
        SizeOfNvStore = VariableDefinition->VariableSize;
 | 
						|
 | 
						|
        //
 | 
						|
        // Getting the NvStore and placing it into our Global Data
 | 
						|
        //
 | 
						|
        if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {
 | 
						|
          Status = FormCallback->NvRead (
 | 
						|
                                  FormCallback,
 | 
						|
                                  VariableDefinition->VariableName,
 | 
						|
                                  &VariableDefinition->Guid,
 | 
						|
                                  NULL,
 | 
						|
                                  &SizeOfNvStore,
 | 
						|
                                  (VOID *) VariableDefinition->NvRamMap
 | 
						|
                                  );
 | 
						|
        } else {
 | 
						|
          Status = gRT->GetVariable (
 | 
						|
                          VariableDefinition->VariableName,
 | 
						|
                          &VariableDefinition->Guid,
 | 
						|
                          NULL,
 | 
						|
                          &SizeOfNvStore,
 | 
						|
                          (VOID *) VariableDefinition->NvRamMap
 | 
						|
                          );
 | 
						|
        }
 | 
						|
 | 
						|
        if (EFI_ERROR (Status)) {
 | 
						|
          //
 | 
						|
          // If there is a variable that exists already and it is larger than what we calculated the
 | 
						|
          // storage needs to be, we must assume the variable size from GetVariable is correct and not
 | 
						|
          // allow the truncation of the variable.  It is very possible that the user who created the IFR
 | 
						|
          // we are cracking is not referring to a variable that was in a previous map, however we cannot
 | 
						|
          // allow it's truncation.
 | 
						|
          //
 | 
						|
          if (Status == EFI_BUFFER_TOO_SMALL) {
 | 
						|
            //
 | 
						|
            // If the buffer was too small, we should have the expanded size requirement in SizeOfNvStore now.
 | 
						|
            //
 | 
						|
            VariableDefinition->VariableSize = (UINT16) SizeOfNvStore;
 | 
						|
 | 
						|
            //
 | 
						|
            // Free the buffer that was allocated that was too small
 | 
						|
            //
 | 
						|
            FreePool (VariableDefinition->NvRamMap);
 | 
						|
            FreePool (VariableDefinition->FakeNvRamMap);
 | 
						|
 | 
						|
            VariableDefinition->NvRamMap = AllocateZeroPool (SizeOfNvStore);
 | 
						|
            VariableDefinition->FakeNvRamMap = AllocateZeroPool (SizeOfNvStore + VariableDefinition->VariableFakeSize);
 | 
						|
            ASSERT (VariableDefinition->NvRamMap);
 | 
						|
            ASSERT (VariableDefinition->FakeNvRamMap);
 | 
						|
 | 
						|
            if ((FormCallback != NULL) && (FormCallback->NvRead != NULL)) {
 | 
						|
              Status = FormCallback->NvRead (
 | 
						|
                                      FormCallback,
 | 
						|
                                      VariableDefinition->VariableName,
 | 
						|
                                      &VariableDefinition->Guid,
 | 
						|
                                      NULL,
 | 
						|
                                      &SizeOfNvStore,
 | 
						|
                                      (VOID *) VariableDefinition->NvRamMap
 | 
						|
                                      );
 | 
						|
            } else {
 | 
						|
              Status = gRT->GetVariable (
 | 
						|
                              VariableDefinition->VariableName,
 | 
						|
                              &VariableDefinition->Guid,
 | 
						|
                              NULL,
 | 
						|
                              &SizeOfNvStore,
 | 
						|
                              (VOID *) VariableDefinition->NvRamMap
 | 
						|
                              );
 | 
						|
            }
 | 
						|
          }
 | 
						|
          //
 | 
						|
          // if the variable was not found, we will retrieve default values
 | 
						|
          //
 | 
						|
          if (Status == EFI_NOT_FOUND) {
 | 
						|
 | 
						|
            if (0 == CompareMem (VariableDefinition->VariableName, L"Setup", 10)) {
 | 
						|
 | 
						|
              NvMapListHead = NULL;
 | 
						|
 | 
						|
              Status = Hii->GetDefaultImage (Hii, Handle[HandleIndex], EFI_IFR_FLAG_DEFAULT, &NvMapListHead);
 | 
						|
 | 
						|
              if (!EFI_ERROR (Status)) {
 | 
						|
                ASSERT_EFI_ERROR (NULL != NvMapListHead);
 | 
						|
 | 
						|
                NvMapListNode = NvMapListHead;
 | 
						|
 | 
						|
                while (NULL != NvMapListNode) {
 | 
						|
                  if (VariableDefinition->VariableId == NvMapListNode->VariablePack->VariableId) {
 | 
						|
                    NvMap     = (VOID *) ((CHAR8 *) NvMapListNode->VariablePack + sizeof (EFI_HII_VARIABLE_PACK) + NvMapListNode->VariablePack->VariableNameLength);
 | 
						|
                    NvMapSize = NvMapListNode->VariablePack->Header.Length  - sizeof (EFI_HII_VARIABLE_PACK) - NvMapListNode->VariablePack->VariableNameLength;
 | 
						|
                    break;
 | 
						|
                    }
 | 
						|
                  NvMapListNode = NvMapListNode->NextVariablePack;
 | 
						|
                }
 | 
						|
 | 
						|
                //
 | 
						|
                // Free the buffer that was allocated.
 | 
						|
                //
 | 
						|
                FreePool (VariableDefinition->NvRamMap);
 | 
						|
                FreePool (VariableDefinition->FakeNvRamMap);
 | 
						|
 | 
						|
                //
 | 
						|
                // Allocate, copy the NvRamMap.
 | 
						|
                //
 | 
						|
                VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize - VariableDefinition->VariableSize);
 | 
						|
                VariableDefinition->VariableSize = (UINT16) NvMapSize;
 | 
						|
                VariableDefinition->VariableFakeSize = (UINT16) (VariableDefinition->VariableFakeSize + VariableDefinition->VariableSize);
 | 
						|
 | 
						|
                VariableDefinition->NvRamMap = AllocateZeroPool (VariableDefinition->VariableSize);
 | 
						|
                VariableDefinition->FakeNvRamMap = AllocateZeroPool (NvMapSize + VariableDefinition->VariableFakeSize);
 | 
						|
 | 
						|
                CopyMem (VariableDefinition->NvRamMap, NvMap, NvMapSize);
 | 
						|
                FreePool (NvMapListHead);
 | 
						|
              }
 | 
						|
 | 
						|
            }
 | 
						|
            Status = EFI_SUCCESS;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    InitializeTagStructures (BinaryData, FileFormTags);
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // endfor
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
GetIfrBinaryData (
 | 
						|
  IN      EFI_HII_PROTOCOL *Hii,
 | 
						|
  IN      EFI_HII_HANDLE   HiiHandle,
 | 
						|
  IN      EFI_IFR_PACKET   *Packet,
 | 
						|
  IN OUT  EFI_IFR_BINARY   *BinaryData
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Fetch the Ifr binary data.
 | 
						|
 | 
						|
Arguments:
 | 
						|
  Hii         - Point to HII protocol.
 | 
						|
  HiiHandle   - Handle of Ifr to be fetched.
 | 
						|
  Packet      - Pointer to IFR packet.
 | 
						|
  BinaryData  - Buffer to copy the string into
 | 
						|
 | 
						|
Returns:
 | 
						|
  Returns the number of CHAR16 characters that were copied into the OutputString buffer.
 | 
						|
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS        Status;
 | 
						|
  EFI_HII_PACKAGES  *PackageList;
 | 
						|
  UINTN             BufferSize;
 | 
						|
  VOID              *Buffer;
 | 
						|
  UINT8             *RawFormBinary;
 | 
						|
  EFI_IFR_FORM_SET  *FormOp;
 | 
						|
  UINT16            Index;
 | 
						|
  UINT16            Index2;
 | 
						|
  UINT16            TitleToken;
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize the TitleToken to 0 just in case not found
 | 
						|
  //
 | 
						|
  TitleToken = 0;
 | 
						|
 | 
						|
  //
 | 
						|
  // Try for a 32K Buffer
 | 
						|
  //
 | 
						|
  BufferSize = 0x8000;
 | 
						|
 | 
						|
  //
 | 
						|
  // Allocate memory for our Form binary
 | 
						|
  //
 | 
						|
  Buffer = AllocateZeroPool (BufferSize);
 | 
						|
  ASSERT (Buffer);
 | 
						|
 | 
						|
  if (Packet == NULL) {
 | 
						|
    Status = Hii->GetForms (Hii, HiiHandle, 0, &BufferSize, Buffer);
 | 
						|
 | 
						|
    if (Status == EFI_BUFFER_TOO_SMALL) {
 | 
						|
 | 
						|
      FreePool (Buffer);
 | 
						|
 | 
						|
      //
 | 
						|
      // Allocate memory for our Form binary
 | 
						|
      //
 | 
						|
      Buffer = AllocatePool (BufferSize);
 | 
						|
      ASSERT (Buffer);
 | 
						|
 | 
						|
      Status = Hii->GetForms (Hii, HiiHandle, 0, &BufferSize, Buffer);
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // Copies the data to local usable buffer
 | 
						|
    //
 | 
						|
    CopyMem (Buffer, Packet->IfrData, Packet->IfrData->Header.Length);
 | 
						|
 | 
						|
    //
 | 
						|
    // Register the string data with HII
 | 
						|
    //
 | 
						|
    PackageList = PreparePackages (2, NULL, Packet->IfrData, Packet->StringData);
 | 
						|
 | 
						|
    Status      = Hii->NewPack (Hii, PackageList, &HiiHandle);
 | 
						|
 | 
						|
    FreePool (PackageList);
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // We now have the IFR binary in our Buffer
 | 
						|
  //
 | 
						|
  BinaryData->IfrPackage  = Buffer;
 | 
						|
  RawFormBinary           = (UINT8 *) ((CHAR8 *) (Buffer) + sizeof (EFI_HII_PACK_HEADER));
 | 
						|
  BinaryData->FormBinary  = (UINT8 *) ((CHAR8 *) (Buffer) + sizeof (EFI_HII_PACK_HEADER));
 | 
						|
  BinaryData->Handle      = HiiHandle;
 | 
						|
 | 
						|
  //
 | 
						|
  // If a packet was passed in, remove the string data when exiting.
 | 
						|
  //
 | 
						|
  if (Packet != NULL) {
 | 
						|
    BinaryData->UnRegisterOnExit = TRUE;
 | 
						|
  } else {
 | 
						|
    BinaryData->UnRegisterOnExit = FALSE;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Walk through the FormSet Opcodes looking for the FormSet opcode
 | 
						|
  // If we hit EFI_IFR_END_SET_OP we know we hit the end of the FormSet.
 | 
						|
  //
 | 
						|
  for (Index = 0; RawFormBinary[Index] != EFI_IFR_END_FORM_SET_OP;) {
 | 
						|
    FormOp  = (EFI_IFR_FORM_SET *) &RawFormBinary[Index];
 | 
						|
    Index   = (UINT16) (Index + FormOp->Header.Length);
 | 
						|
 | 
						|
    if (FormOp->Header.OpCode == EFI_IFR_FORM_SET_OP) {
 | 
						|
      TitleToken = FormOp->FormSetTitle;
 | 
						|
      //
 | 
						|
      // If displaying FrontPage - set the flag signifying it
 | 
						|
      //
 | 
						|
      switch (FormOp->SubClass) {
 | 
						|
      case EFI_FRONT_PAGE_SUBCLASS:
 | 
						|
        FrontPageHandle = HiiHandle;
 | 
						|
 | 
						|
      default:
 | 
						|
        gClassOfVfr = FormOp->SubClass;
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // Match GUID to find out the function key setting. If match fail, use the default setting.
 | 
						|
      //
 | 
						|
      for (Index2 = 0; Index2 < sizeof (gFunctionKeySettingTable) / sizeof (FUNCTIION_KEY_SETTING); Index2++) {
 | 
						|
        if (CompareGuid ((EFI_GUID *)(UINTN)&FormOp->Guid, &(gFunctionKeySettingTable[Index2].FormSetGuid))) {
 | 
						|
          //
 | 
						|
          // Update the function key setting.
 | 
						|
          //
 | 
						|
          gFunctionKeySetting = gFunctionKeySettingTable[Index2].KeySetting;
 | 
						|
          //
 | 
						|
          // Function key prompt can not be displayed if the function key has been disabled.
 | 
						|
          //
 | 
						|
          if ((gFunctionKeySetting & FUNCTION_ONE) != FUNCTION_ONE) {
 | 
						|
            gFunctionOneString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
 | 
						|
          }
 | 
						|
 | 
						|
          if ((gFunctionKeySetting & FUNCTION_TWO) != FUNCTION_TWO) {
 | 
						|
            gFunctionTwoString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
 | 
						|
          }
 | 
						|
 | 
						|
          if ((gFunctionKeySetting & FUNCTION_NINE) != FUNCTION_NINE) {
 | 
						|
            gFunctionNineString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
 | 
						|
          }
 | 
						|
 | 
						|
          if ((gFunctionKeySetting & FUNCTION_TEN) != FUNCTION_TEN) {
 | 
						|
            gFunctionTenString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  BinaryData->TitleToken = TitleToken;
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_HANDLE          PrintHandle     = NULL;
 | 
						|
EFI_PRINT_PROTOCOL  mPrintProtocol  = 
 | 
						|
{
 | 
						|
  UnicodeVSPrint,
 | 
						|
  UnicodeVSPrintAsciiFormat,
 | 
						|
  UnicodeValueToString,
 | 
						|
  AsciiVSPrint,
 | 
						|
  AsciiVSPrintUnicodeFormat,
 | 
						|
  AsciiValueToString
 | 
						|
};
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
InstallPrint (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  return gBS->InstallProtocolInterface (
 | 
						|
                &PrintHandle,
 | 
						|
                &gEfiPrintProtocolGuid,
 | 
						|
                EFI_NATIVE_INTERFACE,
 | 
						|
                &mPrintProtocol
 | 
						|
                );
 | 
						|
}
 |