git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4598 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			1479 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1479 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/**@file
 | 
						|
 | 
						|
 | 
						|
Copyright (c) 2006, Intel Corporation
 | 
						|
All rights reserved. This program and the accompanying materials
 | 
						|
are licensed and made available under the terms and conditions of the BSD License
 | 
						|
which accompanies this distribution.  The full text of the license may be found at
 | 
						|
http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "Setup.h"
 | 
						|
#include "Ui.h"
 | 
						|
#include "Colors.h"
 | 
						|
 | 
						|
VOID
 | 
						|
ClearLines (
 | 
						|
  UINTN                                       LeftColumn,
 | 
						|
  UINTN                                       RightColumn,
 | 
						|
  UINTN                                       TopRow,
 | 
						|
  UINTN                                       BottomRow,
 | 
						|
  UINTN                                       TextAttribute
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR16  *Buffer;
 | 
						|
  UINTN   Row;
 | 
						|
 | 
						|
  //
 | 
						|
  // For now, allocate an arbitrarily long buffer
 | 
						|
  //
 | 
						|
  Buffer = AllocateZeroPool (0x10000);
 | 
						|
  ASSERT (Buffer != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Set foreground and background as defined
 | 
						|
  //
 | 
						|
  gST->ConOut->SetAttribute (gST->ConOut, TextAttribute);
 | 
						|
 | 
						|
  //
 | 
						|
  // Much faster to buffer the long string instead of print it a character at a time
 | 
						|
  //
 | 
						|
  SetUnicodeMem (Buffer, RightColumn - LeftColumn, L' ');
 | 
						|
 | 
						|
  //
 | 
						|
  // Clear the desired area with the appropriate foreground/background
 | 
						|
  //
 | 
						|
  for (Row = TopRow; Row <= BottomRow; Row++) {
 | 
						|
    PrintStringAt (LeftColumn, Row, Buffer);
 | 
						|
  }
 | 
						|
 | 
						|
  gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow);
 | 
						|
 | 
						|
  FreePool (Buffer);
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
NewStrCat (
 | 
						|
  CHAR16                                      *Destination,
 | 
						|
  CHAR16                                      *Source
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN Length;
 | 
						|
 | 
						|
  for (Length = 0; Destination[Length] != 0; Length++)
 | 
						|
    ;
 | 
						|
 | 
						|
  //
 | 
						|
  // We now have the length of the original string
 | 
						|
  // We can safely assume for now that we are concatenating a narrow value to this string.
 | 
						|
  // For instance, the string is "XYZ" and cat'ing ">"
 | 
						|
  // If this assumption changes, we need to make this routine a bit more complex
 | 
						|
  //
 | 
						|
  Destination[Length] = (CHAR16) NARROW_CHAR;
 | 
						|
  Length++;
 | 
						|
 | 
						|
  StrCpy (Destination + Length, Source);
 | 
						|
}
 | 
						|
 | 
						|
UINTN
 | 
						|
GetStringWidth (
 | 
						|
  CHAR16                                      *String
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN Index;
 | 
						|
  UINTN Count;
 | 
						|
  UINTN IncrementValue;
 | 
						|
 | 
						|
  Index           = 0;
 | 
						|
  Count           = 0;
 | 
						|
  IncrementValue  = 1;
 | 
						|
 | 
						|
  do {
 | 
						|
    //
 | 
						|
    // Advance to the null-terminator or to the first width directive
 | 
						|
    //
 | 
						|
    for (;
 | 
						|
         (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);
 | 
						|
         Index++, Count = Count + IncrementValue
 | 
						|
        )
 | 
						|
      ;
 | 
						|
 | 
						|
    //
 | 
						|
    // We hit the null-terminator, we now have a count
 | 
						|
    //
 | 
						|
    if (String[Index] == 0) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
 | 
						|
    // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
 | 
						|
    //
 | 
						|
    if (String[Index] == NARROW_CHAR) {
 | 
						|
      //
 | 
						|
      // Skip to the next character
 | 
						|
      //
 | 
						|
      Index++;
 | 
						|
      IncrementValue = 1;
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Skip to the next character
 | 
						|
      //
 | 
						|
      Index++;
 | 
						|
      IncrementValue = 2;
 | 
						|
    }
 | 
						|
  } while (String[Index] != 0);
 | 
						|
 | 
						|
  //
 | 
						|
  // Increment by one to include the null-terminator in the size
 | 
						|
  //
 | 
						|
  Count++;
 | 
						|
 | 
						|
  return Count * sizeof (CHAR16);
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
DisplayPageFrame (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN             Index;
 | 
						|
  UINT8             Line;
 | 
						|
  UINT8             Alignment;
 | 
						|
  CHAR16            Character;
 | 
						|
  CHAR16            *Buffer;
 | 
						|
  CHAR16            *StrFrontPageBanner;
 | 
						|
  EFI_SCREEN_DESCRIPTOR LocalScreen;
 | 
						|
  UINTN             Row;
 | 
						|
 | 
						|
  ZeroMem (&LocalScreen, sizeof (EFI_SCREEN_DESCRIPTOR));
 | 
						|
  gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &LocalScreen.RightColumn, &LocalScreen.BottomRow);
 | 
						|
  ClearLines (0, LocalScreen.RightColumn, 0, LocalScreen.BottomRow, KEYHELP_BACKGROUND);
 | 
						|
 | 
						|
  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
 | 
						|
 | 
						|
  //
 | 
						|
  // For now, allocate an arbitrarily long buffer
 | 
						|
  //
 | 
						|
  Buffer = AllocateZeroPool (0x10000);
 | 
						|
  ASSERT (Buffer != NULL);
 | 
						|
 | 
						|
  Character = (CHAR16) BOXDRAW_HORIZONTAL;
 | 
						|
 | 
						|
  for (Index = 0; Index + 2 < (LocalScreen.RightColumn - LocalScreen.LeftColumn); Index++) {
 | 
						|
    Buffer[Index] = Character;
 | 
						|
  }
 | 
						|
 | 
						|
  if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) {
 | 
						|
    //
 | 
						|
    //    ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);
 | 
						|
    //
 | 
						|
    ClearLines (
 | 
						|
      LocalScreen.LeftColumn,
 | 
						|
      LocalScreen.RightColumn,
 | 
						|
      LocalScreen.TopRow,
 | 
						|
      FRONT_PAGE_HEADER_HEIGHT - 1 + LocalScreen.TopRow,
 | 
						|
      BANNER_TEXT | BANNER_BACKGROUND
 | 
						|
      );
 | 
						|
    //
 | 
						|
    //    for (Line = 0; Line < BANNER_HEIGHT; Line++) {
 | 
						|
    //
 | 
						|
    for (Line = (UINT8) LocalScreen.TopRow; Line < BANNER_HEIGHT + (UINT8) LocalScreen.TopRow; Line++) {
 | 
						|
      //
 | 
						|
      //      for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {
 | 
						|
      //
 | 
						|
      for (Alignment = (UINT8) LocalScreen.LeftColumn;
 | 
						|
           Alignment < BANNER_COLUMNS + (UINT8) LocalScreen.LeftColumn;
 | 
						|
           Alignment++
 | 
						|
          ) {
 | 
						|
        if (BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn] != 0x0000) {
 | 
						|
          StrFrontPageBanner = GetToken (
 | 
						|
                                BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn],
 | 
						|
                                FrontPageHandle
 | 
						|
                                );
 | 
						|
        } else {
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
 | 
						|
        switch (Alignment - LocalScreen.LeftColumn) {
 | 
						|
        case 0:
 | 
						|
          //
 | 
						|
          // Handle left column
 | 
						|
          //
 | 
						|
          PrintStringAt (LocalScreen.LeftColumn, Line, StrFrontPageBanner);
 | 
						|
          break;
 | 
						|
 | 
						|
        case 1:
 | 
						|
          //
 | 
						|
          // Handle center column
 | 
						|
          //
 | 
						|
          PrintStringAt (
 | 
						|
            LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
 | 
						|
            Line,
 | 
						|
            StrFrontPageBanner
 | 
						|
            );
 | 
						|
          break;
 | 
						|
 | 
						|
        case 2:
 | 
						|
          //
 | 
						|
          // Handle right column
 | 
						|
          //
 | 
						|
          PrintStringAt (
 | 
						|
            LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,
 | 
						|
            Line,
 | 
						|
            StrFrontPageBanner
 | 
						|
            );
 | 
						|
          break;
 | 
						|
        }
 | 
						|
 | 
						|
        FreePool (StrFrontPageBanner);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  ClearLines (
 | 
						|
    LocalScreen.LeftColumn,
 | 
						|
    LocalScreen.RightColumn,
 | 
						|
    LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT,
 | 
						|
    LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1,
 | 
						|
    KEYHELP_TEXT | KEYHELP_BACKGROUND
 | 
						|
    );
 | 
						|
 | 
						|
  if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {
 | 
						|
    ClearLines (
 | 
						|
      LocalScreen.LeftColumn,
 | 
						|
      LocalScreen.RightColumn,
 | 
						|
      LocalScreen.TopRow,
 | 
						|
      LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1,
 | 
						|
      TITLE_TEXT | TITLE_BACKGROUND
 | 
						|
      );
 | 
						|
    //
 | 
						|
    // Print Top border line
 | 
						|
    // +------------------------------------------------------------------------------+
 | 
						|
    // ?                                                                             ?
 | 
						|
    // +------------------------------------------------------------------------------+
 | 
						|
    //
 | 
						|
    Character = (CHAR16) BOXDRAW_DOWN_RIGHT;
 | 
						|
 | 
						|
    PrintChar (Character);
 | 
						|
    PrintString (Buffer);
 | 
						|
 | 
						|
    Character = (CHAR16) BOXDRAW_DOWN_LEFT;
 | 
						|
    PrintChar (Character);
 | 
						|
 | 
						|
    Character = (CHAR16) BOXDRAW_VERTICAL;
 | 
						|
    for (Row = LocalScreen.TopRow + 1; Row <= LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) {
 | 
						|
      PrintCharAt (LocalScreen.LeftColumn, Row, Character);
 | 
						|
      PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);
 | 
						|
    }
 | 
						|
 | 
						|
    Character = (CHAR16) BOXDRAW_UP_RIGHT;
 | 
						|
    PrintCharAt (LocalScreen.LeftColumn, LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character);
 | 
						|
    PrintString (Buffer);
 | 
						|
 | 
						|
    Character = (CHAR16) BOXDRAW_UP_LEFT;
 | 
						|
    PrintChar (Character);
 | 
						|
 | 
						|
    if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
 | 
						|
      //
 | 
						|
      // Print Bottom border line
 | 
						|
      // +------------------------------------------------------------------------------+
 | 
						|
      // ?                                                                             ?
 | 
						|
      // +------------------------------------------------------------------------------+
 | 
						|
      //
 | 
						|
      Character = (CHAR16) BOXDRAW_DOWN_RIGHT;
 | 
						|
      PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT, Character);
 | 
						|
 | 
						|
      PrintString (Buffer);
 | 
						|
 | 
						|
      Character = (CHAR16) BOXDRAW_DOWN_LEFT;
 | 
						|
      PrintChar (Character);
 | 
						|
      Character = (CHAR16) BOXDRAW_VERTICAL;
 | 
						|
      for (Row = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT + 1;
 | 
						|
           Row <= LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;
 | 
						|
           Row++
 | 
						|
          ) {
 | 
						|
        PrintCharAt (LocalScreen.LeftColumn, Row, Character);
 | 
						|
        PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);
 | 
						|
      }
 | 
						|
 | 
						|
      Character = (CHAR16) BOXDRAW_UP_RIGHT;
 | 
						|
      PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1, Character);
 | 
						|
 | 
						|
      PrintString (Buffer);
 | 
						|
 | 
						|
      Character = (CHAR16) BOXDRAW_UP_LEFT;
 | 
						|
      PrintChar (Character);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool (Buffer);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
+------------------------------------------------------------------------------+
 | 
						|
?F2=Previous Page                 Setup Page                                  ?
 | 
						|
+------------------------------------------------------------------------------+
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
+------------------------------------------------------------------------------+
 | 
						|
?F1=Scroll Help                 F9=Reset to Defaults        F10=Save and Exit ?
 | 
						|
| ^"=Move Highlight          <Spacebar> Toggles Checkbox   Esc=Discard Changes |
 | 
						|
+------------------------------------------------------------------------------+
 | 
						|
*/
 | 
						|
STATIC
 | 
						|
UI_MENU_OPTION *
 | 
						|
DisplayForm (
 | 
						|
  OUT UI_MENU_OPTION              *Selection,
 | 
						|
  IN  UINT16                      FormHandle,
 | 
						|
  IN  UINT16                      TitleToken,
 | 
						|
  IN  EFI_FORM_TAGS               FormTags,
 | 
						|
  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,
 | 
						|
  IN  UINT8                       *CallbackData
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR16              *StringPtr;
 | 
						|
  UINTN               Index;
 | 
						|
  UINTN               Count;
 | 
						|
  UINT16              MenuItemCount;
 | 
						|
  FRAMEWORK_EFI_HII_HANDLE       Handle;
 | 
						|
  UINT16              FormId;
 | 
						|
  STRING_REF          String;
 | 
						|
  EFI_FILE_FORM_TAGS  *FileFormTags;
 | 
						|
  BOOLEAN             SuppressIf;
 | 
						|
  BOOLEAN             Suppress;
 | 
						|
  BOOLEAN             GrayOut;
 | 
						|
  BOOLEAN             Conditional;
 | 
						|
  EFI_SCREEN_DESCRIPTOR   LocalScreen;
 | 
						|
  UINT16              Width;
 | 
						|
  UINTN               ArrayEntry;
 | 
						|
  CHAR16              *OutputString;
 | 
						|
 | 
						|
  Handle        = Selection->Handle;
 | 
						|
  FormId        = 0;
 | 
						|
  String        = 0;
 | 
						|
  MenuItemCount = 0;
 | 
						|
  ArrayEntry    = 0;
 | 
						|
  OutputString  = NULL;
 | 
						|
 | 
						|
  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
 | 
						|
 | 
						|
  //
 | 
						|
  // If we hit a F2 (previous) we already nuked the menu and are simply carrying around what information we need
 | 
						|
  //
 | 
						|
  if (Selection->Previous) {
 | 
						|
    Selection->Previous = FALSE;
 | 
						|
  } else {
 | 
						|
    UiFreeMenu ();
 | 
						|
    UiInitMenu ();
 | 
						|
  }
 | 
						|
 | 
						|
  StringPtr = GetToken (TitleToken, Handle);
 | 
						|
 | 
						|
  if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {
 | 
						|
    gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);
 | 
						|
    PrintStringAt (
 | 
						|
      (LocalScreen.RightColumn + LocalScreen.LeftColumn - GetStringWidth (StringPtr) / 2) / 2,
 | 
						|
      LocalScreen.TopRow + 1,
 | 
						|
      StringPtr
 | 
						|
      );
 | 
						|
  }
 | 
						|
 | 
						|
  if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
 | 
						|
    gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);
 | 
						|
 | 
						|
    //
 | 
						|
    // Display the infrastructure strings
 | 
						|
    //
 | 
						|
    if (!IsListEmpty (&gMenuList)) {
 | 
						|
      PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.TopRow + 1, gFunctionTwoString);
 | 
						|
    }
 | 
						|
 | 
						|
    PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 4, gFunctionOneString);
 | 
						|
    PrintStringAt (
 | 
						|
      LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
 | 
						|
      LocalScreen.BottomRow - 4,
 | 
						|
      gFunctionNineString
 | 
						|
      );
 | 
						|
    PrintStringAt (
 | 
						|
      LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,
 | 
						|
      LocalScreen.BottomRow - 4,
 | 
						|
      gFunctionTenString
 | 
						|
      );
 | 
						|
    PrintAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 3, (CHAR16 *) L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
 | 
						|
    PrintStringAt (
 | 
						|
      LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
 | 
						|
      LocalScreen.BottomRow - 3,
 | 
						|
      gEscapeString
 | 
						|
      );
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Remove Buffer allocated for StringPtr after it has been used.
 | 
						|
  //
 | 
						|
  FreePool (StringPtr);
 | 
						|
 | 
						|
  for (Index = 0; FormTags.Tags[Index].Operand != FRAMEWORK_EFI_IFR_END_FORM_OP; Index++) {
 | 
						|
    GrayOut       = FALSE;
 | 
						|
    Suppress      = FALSE;
 | 
						|
    SuppressIf    = FALSE;
 | 
						|
    Conditional   = FALSE;
 | 
						|
    FileFormTags  = FileFormTagsHead;
 | 
						|
 | 
						|
    if (FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_FORM_OP) {
 | 
						|
      FormId = FormTags.Tags[Index].Id;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // This gives us visibility to the FileFormTags->NvRamMap to check things
 | 
						|
    // ActiveIfr is a global maintained by the menuing code to ensure that we
 | 
						|
    // are pointing to the correct formset's file data.
 | 
						|
    //
 | 
						|
    for (Count = 0; Count < gActiveIfr; Count++) {
 | 
						|
      FileFormTags = FileFormTags->NextFile;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    //  GrayoutIf [SuppressIf]
 | 
						|
    //    <BOOLEANS>
 | 
						|
    //      OpCode(s)
 | 
						|
    //  EndIf
 | 
						|
    //
 | 
						|
    //  SuppressIf [GrayoutIf]
 | 
						|
    //    <BOOLEANS>
 | 
						|
    //      OpCode(s)
 | 
						|
    //  EndIf
 | 
						|
    //
 | 
						|
    Count = 0;
 | 
						|
 | 
						|
    do {
 | 
						|
      switch (FormTags.Tags[Index].Operand) {
 | 
						|
      case FRAMEWORK_EFI_IFR_SUPPRESS_IF_OP:
 | 
						|
        SuppressIf = TRUE;
 | 
						|
 | 
						|
      case FRAMEWORK_EFI_IFR_GRAYOUT_IF_OP:
 | 
						|
 | 
						|
        Conditional = TRUE;
 | 
						|
 | 
						|
        //
 | 
						|
        // Advance to the next op-code
 | 
						|
        //
 | 
						|
        Index++;
 | 
						|
 | 
						|
        //
 | 
						|
        // We are now pointing to the beginning of the consistency checking.  Let's fast forward
 | 
						|
        // through the AND/OR/NOT data to come up with some meaningful ID data.
 | 
						|
        //
 | 
						|
        for (;
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_AND_OP   ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_OR_OP    ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_GT_OP    ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_GE_OP    ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_NOT_OP;
 | 
						|
           Index++
 | 
						|
            )
 | 
						|
          ;
 | 
						|
 | 
						|
        //
 | 
						|
        // We need to walk through the consistency checks until we hit the end of the consistency
 | 
						|
        // FALSE means evaluate this single expression
 | 
						|
        // The ConsistencyId refers to which expression in the Consistency database to use
 | 
						|
        //
 | 
						|
        if (SuppressIf) {
 | 
						|
          Suppress = ValueIsNotValid (
 | 
						|
                      FALSE,
 | 
						|
                      FormTags.Tags[Index].ConsistencyId,
 | 
						|
                      &FormTags.Tags[Index],
 | 
						|
                      FileFormTags,
 | 
						|
                      &String
 | 
						|
                      );
 | 
						|
          SuppressIf = FALSE;
 | 
						|
        } else {
 | 
						|
          GrayOut = ValueIsNotValid (
 | 
						|
                      FALSE,
 | 
						|
                      FormTags.Tags[Index].ConsistencyId,
 | 
						|
                      &FormTags.Tags[Index],
 | 
						|
                      FileFormTags,
 | 
						|
                      &String
 | 
						|
                      );
 | 
						|
        }
 | 
						|
        //
 | 
						|
        // Advance to the end of the expression (Will land us at a grayoutif/suppressif or the op-code being affected)
 | 
						|
        //
 | 
						|
        for (;
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_EQ_ID_VAL_OP ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_EQ_VAR_VAL_OP ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_EQ_ID_ID_OP ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_EQ_ID_LIST_OP ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_NOT_OP ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_AND_OP ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_OR_OP ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_TRUE_OP ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_FALSE_OP ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_GT_OP    ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_GE_OP    ||
 | 
						|
             FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_LABEL_OP;
 | 
						|
           Index++
 | 
						|
            )
 | 
						|
          ;
 | 
						|
        break;
 | 
						|
 | 
						|
      default:
 | 
						|
        goto GetOut;
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // Do this two times (at most will see a suppress and grayout combination
 | 
						|
      //
 | 
						|
      Count++;
 | 
						|
    } while (Count < 2);
 | 
						|
 | 
						|
GetOut:
 | 
						|
    do {
 | 
						|
      if (GrayOut) {
 | 
						|
        FormTags.Tags[Index].GrayOut = TRUE;
 | 
						|
      } else {
 | 
						|
        FormTags.Tags[Index].GrayOut = FALSE;
 | 
						|
      }
 | 
						|
      if (Suppress && FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP) {
 | 
						|
        //
 | 
						|
        // Only need .Suppress field when the tag is a one_of_option. For other cases, omit them directly.
 | 
						|
        //
 | 
						|
        FormTags.Tags[Index].Suppress = TRUE;
 | 
						|
      } else {
 | 
						|
        FormTags.Tags[Index].Suppress = FALSE;
 | 
						|
      }
 | 
						|
 | 
						|
      if ((
 | 
						|
            FormTags.Tags[Index].NumberOfLines > 0 ||
 | 
						|
            FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_DATE_OP ||
 | 
						|
            FormTags.Tags[Index].Operand == FRAMEWORK_EFI_IFR_TIME_OP
 | 
						|
          ) &&
 | 
						|
          !Suppress
 | 
						|
          ) {
 | 
						|
 | 
						|
        StringPtr = GetToken (FormTags.Tags[Index].Text, Handle);
 | 
						|
 | 
						|
        Width     = GetWidth (&FormTags.Tags[Index], Handle);
 | 
						|
 | 
						|
        //
 | 
						|
        // This data can be retrieved over and over again.  Therefore, reset to original values
 | 
						|
        // before processing otherwise things will start growing linearly
 | 
						|
        //
 | 
						|
        if (FormTags.Tags[Index].NumberOfLines > 1) {
 | 
						|
          FormTags.Tags[Index].NumberOfLines = 1;
 | 
						|
        }
 | 
						|
 | 
						|
        for (Count = 0; GetLineByWidth (StringPtr, Width, &ArrayEntry, &OutputString) != 0x0000;) {
 | 
						|
          //
 | 
						|
          // If there is more string to process print on the next row and increment the Skip value
 | 
						|
          //
 | 
						|
          if (StrLen (&StringPtr[ArrayEntry])) {
 | 
						|
            FormTags.Tags[Index].NumberOfLines++;
 | 
						|
          }
 | 
						|
 | 
						|
          FreePool (OutputString);
 | 
						|
        }
 | 
						|
 | 
						|
        ArrayEntry = 0;
 | 
						|
 | 
						|
        //
 | 
						|
        // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do
 | 
						|
        // it in UiFreeMenu.
 | 
						|
        //
 | 
						|
        UiAddSubMenuOption (StringPtr, Handle, FormTags.Tags, Index, FormId, MenuItemCount);
 | 
						|
        MenuItemCount++;
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // Keep processing menu entries based on the resultant suppress/grayout results until we hit an end-if
 | 
						|
      //
 | 
						|
      Index++;
 | 
						|
    } while (FormTags.Tags[Index].Operand != FRAMEWORK_EFI_IFR_END_IF_OP && Conditional);
 | 
						|
 | 
						|
    //
 | 
						|
    // We advanced the index for the above conditional, rewind it to keep harmony with the for loop logic
 | 
						|
    //
 | 
						|
    Index--;
 | 
						|
  }
 | 
						|
 | 
						|
  Selection = UiDisplayMenu (TRUE, FileFormTagsHead, (FRAMEWORK_EFI_IFR_DATA_ARRAY *) CallbackData);
 | 
						|
 | 
						|
  return Selection;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
InitializeBrowserStrings (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  gFunctionOneString    = GetToken (STRING_TOKEN (FUNCTION_ONE_STRING), gHiiHandle);
 | 
						|
  gFunctionTwoString    = GetToken (STRING_TOKEN (FUNCTION_TWO_STRING), gHiiHandle);
 | 
						|
  gFunctionNineString   = GetToken (STRING_TOKEN (FUNCTION_NINE_STRING), gHiiHandle);
 | 
						|
  gFunctionTenString    = GetToken (STRING_TOKEN (FUNCTION_TEN_STRING), gHiiHandle);
 | 
						|
  gEnterString          = GetToken (STRING_TOKEN (ENTER_STRING), gHiiHandle);
 | 
						|
  gEnterCommitString    = GetToken (STRING_TOKEN (ENTER_COMMIT_STRING), gHiiHandle);
 | 
						|
  gEscapeString         = GetToken (STRING_TOKEN (ESCAPE_STRING), gHiiHandle);
 | 
						|
  gMoveHighlight        = GetToken (STRING_TOKEN (MOVE_HIGHLIGHT), gHiiHandle);
 | 
						|
  gMakeSelection        = GetToken (STRING_TOKEN (MAKE_SELECTION), gHiiHandle);
 | 
						|
  gNumericInput         = GetToken (STRING_TOKEN (NUMERIC_INPUT), gHiiHandle);
 | 
						|
  gToggleCheckBox       = GetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), gHiiHandle);
 | 
						|
  gPromptForPassword    = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);
 | 
						|
  gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);
 | 
						|
  gConfirmPassword      = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle);
 | 
						|
  gConfirmError         = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle);
 | 
						|
  gPressEnter           = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle);
 | 
						|
  gEmptyString          = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
 | 
						|
  gAreYouSure           = GetToken (STRING_TOKEN (ARE_YOU_SURE), gHiiHandle);
 | 
						|
  gYesResponse          = GetToken (STRING_TOKEN (ARE_YOU_SURE_YES), gHiiHandle);
 | 
						|
  gNoResponse           = GetToken (STRING_TOKEN (ARE_YOU_SURE_NO), gHiiHandle);
 | 
						|
  gMiniString           = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle);
 | 
						|
  gPlusString           = GetToken (STRING_TOKEN (PLUS_STRING), gHiiHandle);
 | 
						|
  gMinusString          = GetToken (STRING_TOKEN (MINUS_STRING), gHiiHandle);
 | 
						|
  gAdjustNumber         = GetToken (STRING_TOKEN (ADJUST_NUMBER), gHiiHandle);
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
UpdateKeyHelp (
 | 
						|
  IN  UI_MENU_OPTION              *Selection,
 | 
						|
  IN  BOOLEAN                     Selected
 | 
						|
  )
 | 
						|
/*++
 | 
						|
Routine Description:
 | 
						|
  Update key's help imformation
 | 
						|
 | 
						|
Arguments:
 | 
						|
  Selection C The form that current display
 | 
						|
  Selected C  Whether or not a tag be selected
 | 
						|
 | 
						|
Returns:
 | 
						|
  None
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINTN             SecCol;
 | 
						|
  UINTN             ThdCol;
 | 
						|
  UINTN             LeftColumnOfHelp;
 | 
						|
  UINTN             RightColumnOfHelp;
 | 
						|
  UINTN             TopRowOfHelp;
 | 
						|
  UINTN             BottomRowOfHelp;
 | 
						|
  UINTN             StartColumnOfHelp;
 | 
						|
  EFI_SCREEN_DESCRIPTOR LocalScreen;
 | 
						|
 | 
						|
  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
 | 
						|
 | 
						|
  SecCol            = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;
 | 
						|
  ThdCol            = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3;
 | 
						|
 | 
						|
  StartColumnOfHelp = LocalScreen.LeftColumn + 2;
 | 
						|
  LeftColumnOfHelp  = LocalScreen.LeftColumn + 1;
 | 
						|
  RightColumnOfHelp = LocalScreen.RightColumn - 2;
 | 
						|
  TopRowOfHelp      = LocalScreen.BottomRow - 4;
 | 
						|
  BottomRowOfHelp   = LocalScreen.BottomRow - 3;
 | 
						|
 | 
						|
  if (gClassOfVfr == EFI_GENERAL_APPLICATION_SUBCLASS) {
 | 
						|
    return ;
 | 
						|
  }
 | 
						|
 | 
						|
  gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);
 | 
						|
 | 
						|
  switch (Selection->ThisTag->Operand) {
 | 
						|
  case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP:
 | 
						|
  case FRAMEWORK_EFI_IFR_ONE_OF_OP:
 | 
						|
  case FRAMEWORK_EFI_IFR_NUMERIC_OP:
 | 
						|
  case FRAMEWORK_EFI_IFR_TIME_OP:
 | 
						|
  case FRAMEWORK_EFI_IFR_DATE_OP:
 | 
						|
    ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
 | 
						|
 | 
						|
    if (!Selected) {
 | 
						|
      if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
 | 
						|
        PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);
 | 
						|
        PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
 | 
						|
        PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
 | 
						|
        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
 | 
						|
 | 
						|
      }
 | 
						|
 | 
						|
      if ((Selection->ThisTag->Operand == FRAMEWORK_EFI_IFR_DATE_OP) || (Selection->ThisTag->Operand == FRAMEWORK_EFI_IFR_TIME_OP)) {
 | 
						|
        PrintAt (
 | 
						|
          StartColumnOfHelp,
 | 
						|
          BottomRowOfHelp,
 | 
						|
          (CHAR16 *) L"%c%c%c%c%s",
 | 
						|
          ARROW_UP,
 | 
						|
          ARROW_DOWN,
 | 
						|
          ARROW_RIGHT,
 | 
						|
          ARROW_LEFT,
 | 
						|
          gMoveHighlight
 | 
						|
          );
 | 
						|
        PrintStringAt (SecCol, BottomRowOfHelp, gAdjustNumber);
 | 
						|
      } else {
 | 
						|
        PrintAt (StartColumnOfHelp, BottomRowOfHelp, (CHAR16 *) L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
 | 
						|
        PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      PrintStringAt (SecCol, BottomRowOfHelp, gEnterCommitString);
 | 
						|
 | 
						|
      //
 | 
						|
      // If it is a selected numeric with manual input, display different message
 | 
						|
      //
 | 
						|
      if ((Selection->ThisTag->Operand == FRAMEWORK_EFI_IFR_NUMERIC_OP) && (Selection->ThisTag->Step == 0)) {
 | 
						|
        PrintStringAt (SecCol, TopRowOfHelp, gNumericInput);
 | 
						|
      } else if (Selection->ThisTag->Operand != FRAMEWORK_EFI_IFR_ORDERED_LIST_OP) {
 | 
						|
        PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
 | 
						|
      }
 | 
						|
 | 
						|
      if (Selection->ThisTag->Operand == FRAMEWORK_EFI_IFR_ORDERED_LIST_OP) {
 | 
						|
        PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gPlusString);
 | 
						|
        PrintStringAt (ThdCol, TopRowOfHelp, gMinusString);
 | 
						|
      }
 | 
						|
 | 
						|
      PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
 | 
						|
  case FRAMEWORK_EFI_IFR_CHECKBOX_OP:
 | 
						|
    ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
 | 
						|
 | 
						|
    if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
 | 
						|
      PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);
 | 
						|
      PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
 | 
						|
      PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
 | 
						|
      PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
 | 
						|
    }
 | 
						|
 | 
						|
    PrintAt (StartColumnOfHelp, BottomRowOfHelp, (CHAR16 *) L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
 | 
						|
    PrintStringAt (SecCol, BottomRowOfHelp, gToggleCheckBox);
 | 
						|
    break;
 | 
						|
 | 
						|
  case FRAMEWORK_EFI_IFR_REF_OP:
 | 
						|
  case FRAMEWORK_EFI_IFR_PASSWORD_OP:
 | 
						|
  case FRAMEWORK_EFI_IFR_STRING_OP:
 | 
						|
    ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
 | 
						|
 | 
						|
    if (!Selected) {
 | 
						|
      if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
 | 
						|
        PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);
 | 
						|
        PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
 | 
						|
        PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
 | 
						|
        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
 | 
						|
      }
 | 
						|
 | 
						|
      PrintAt (StartColumnOfHelp, BottomRowOfHelp, (CHAR16 *) L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
 | 
						|
      PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
 | 
						|
    } else {
 | 
						|
      if (Selection->ThisTag->Operand != FRAMEWORK_EFI_IFR_REF_OP) {
 | 
						|
        PrintStringAt (
 | 
						|
          (LocalScreen.RightColumn - GetStringWidth (gEnterCommitString) / 2) / 2,
 | 
						|
          BottomRowOfHelp,
 | 
						|
          gEnterCommitString
 | 
						|
          );
 | 
						|
        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
ExtractFormHandle (
 | 
						|
  IN  UI_MENU_OPTION              *Selection,
 | 
						|
  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,
 | 
						|
  IN  UINTN                       IdValue,
 | 
						|
  OUT UINT16                      *FormHandle,
 | 
						|
  OUT UINT16                      *TitleToken,
 | 
						|
  OUT EFI_FORM_TAGS               *FormTags
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN               Index;
 | 
						|
  EFI_FILE_FORM_TAGS  *FileFormTags;
 | 
						|
  EFI_FORM_TAGS       LocalTags;
 | 
						|
 | 
						|
  FileFormTags = FileFormTagsHead;
 | 
						|
 | 
						|
  //
 | 
						|
  // Advance FileFormTags to the correct file's tag information.
 | 
						|
  // For instance, if Selection->IfrNumber is 3, that means the 4th
 | 
						|
  // file (0-based) in the FileFormTags linked-list contains the tag
 | 
						|
  // information.
 | 
						|
  //
 | 
						|
  for (Index = 0; Index < Selection->IfrNumber; Index++) {
 | 
						|
    FileFormTags = FileFormTags->NextFile;
 | 
						|
  }
 | 
						|
 | 
						|
  LocalTags = FileFormTags->FormTags;
 | 
						|
 | 
						|
  if (IdValue == 0) {
 | 
						|
    //
 | 
						|
    // Advance Index to the first FormOp tag information
 | 
						|
    //
 | 
						|
    for (Index = 0; FileFormTags->FormTags.Tags[Index].Operand != FRAMEWORK_EFI_IFR_FORM_OP; Index++)
 | 
						|
      ;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // Advance Index to the FormOp with the correct ID value
 | 
						|
    //
 | 
						|
    for (; LocalTags.Next != NULL; LocalTags = *LocalTags.Next) {
 | 
						|
      for (Index = 0; LocalTags.Tags[Index].Operand != FRAMEWORK_EFI_IFR_FORM_OP; Index++)
 | 
						|
        ;
 | 
						|
      if (LocalTags.Tags[Index].Id == IdValue) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // return the Form Id, Text, and the File's FormTags structure
 | 
						|
  //
 | 
						|
  *FormHandle = LocalTags.Tags[Index].Id;
 | 
						|
  *TitleToken = LocalTags.Tags[Index].Text;
 | 
						|
  *FormTags   = LocalTags;
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
UpdateNewTagData (
 | 
						|
  IN  UINT8                                     *FormData,
 | 
						|
  IN  UINT16                                    ConsistencyId,
 | 
						|
  IN  UINT16                                    CurrentVariable,
 | 
						|
  IN  EFI_FORM_TAGS                             *FormTags,
 | 
						|
  OUT EFI_FILE_FORM_TAGS                        *FileFormTags
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  UINT16      Index;
 | 
						|
  UINT16      QuestionIndex;
 | 
						|
  UINT16      NumberOfTags;
 | 
						|
  INT16       CurrTag;
 | 
						|
  UINT8       TagLength;
 | 
						|
  UINTN       Count;
 | 
						|
  BOOLEAN     Finished;
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize some Index variable and Status
 | 
						|
  //
 | 
						|
  Count         = 0;
 | 
						|
  QuestionIndex = 0;
 | 
						|
  NumberOfTags  = 1;
 | 
						|
  Index         = 0;
 | 
						|
  Status        = EFI_SUCCESS;
 | 
						|
  Finished      = FALSE;
 | 
						|
 | 
						|
  //
 | 
						|
  // Determine the number of tags for the first form
 | 
						|
  //
 | 
						|
  GetTagCount (&FormData[Index], &NumberOfTags);
 | 
						|
 | 
						|
  //
 | 
						|
  // Allocate memory for our tags on the first form
 | 
						|
  //
 | 
						|
  FormTags->Tags = AllocateZeroPool (NumberOfTags * sizeof (EFI_TAG));
 | 
						|
  ASSERT (FormTags->Tags != NULL);
 | 
						|
 | 
						|
  for (CurrTag = 0; FormData[Index] != FRAMEWORK_EFI_IFR_END_FORM_SET_OP; CurrTag++) {
 | 
						|
    //
 | 
						|
    // Operand = IFR OpCode
 | 
						|
    //
 | 
						|
    FormTags->Tags[CurrTag].Operand = FormData[Index];
 | 
						|
 | 
						|
    //
 | 
						|
    // Assume for now 0 lines occupied by this OpCode
 | 
						|
    //
 | 
						|
    FormTags->Tags[CurrTag].NumberOfLines = 0;
 | 
						|
 | 
						|
    //
 | 
						|
    // Determine the length of the Tag so we can later skip to the next tag in the form
 | 
						|
    //
 | 
						|
    //
 | 
						|
    // get the length
 | 
						|
    //
 | 
						|
    TagLength = FormData[Index + 1];
 | 
						|
    //
 | 
						|
    // Operate on the Found OpCode
 | 
						|
    //
 | 
						|
    switch (FormData[Index]) {
 | 
						|
 | 
						|
    case FRAMEWORK_EFI_IFR_FORM_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_SUBTITLE_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_TEXT_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_REF_OP:
 | 
						|
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
 | 
						|
      break;
 | 
						|
 | 
						|
    case FRAMEWORK_EFI_IFR_VARSTORE_SELECT_OP:
 | 
						|
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
 | 
						|
      CopyMem (&CurrentVariable, &((FRAMEWORK_EFI_IFR_VARSTORE_SELECT *) &FormData[Index])->VarId, sizeof (UINT16));
 | 
						|
      break;
 | 
						|
 | 
						|
    case FRAMEWORK_EFI_IFR_END_FORM_OP:
 | 
						|
      FormTags->Tags[CurrTag].Operand       = FormData[Index];
 | 
						|
      FormTags->Tags[CurrTag].NumberOfLines = 0;
 | 
						|
 | 
						|
      Finished = TRUE;
 | 
						|
      break;
 | 
						|
 | 
						|
    case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_ONE_OF_OP:
 | 
						|
      GetQuestionHeader (&FormTags->Tags[CurrTag], FormData, 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 FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP:
 | 
						|
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
 | 
						|
      FormTags->Tags[QuestionIndex].Key = ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) &FormData[Index])->Key;
 | 
						|
      FormTags->Tags[QuestionIndex].ResetRequired = (BOOLEAN) (FormTags->Tags[QuestionIndex].Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED);
 | 
						|
      break;
 | 
						|
 | 
						|
    case FRAMEWORK_EFI_IFR_CHECKBOX_OP:
 | 
						|
      GetQuestionHeader (&FormTags->Tags[CurrTag], FormData, Index, FileFormTags, CurrentVariable);
 | 
						|
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
 | 
						|
      break;
 | 
						|
 | 
						|
    case FRAMEWORK_EFI_IFR_NUMERIC_OP:
 | 
						|
      GetNumericHeader (&FormTags->Tags[CurrTag], FormData, Index, (UINT16) 1, FileFormTags, CurrentVariable);
 | 
						|
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
 | 
						|
      break;
 | 
						|
 | 
						|
    case FRAMEWORK_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 "i" +1, +2, +0 while CurrTag is +0, +1, +2
 | 
						|
      //
 | 
						|
      GetNumericHeader (
 | 
						|
        &FormTags->Tags[CurrTag],
 | 
						|
        FormData,
 | 
						|
        (UINT16) (Index + TagLength),
 | 
						|
        (UINT16) 0,
 | 
						|
        FileFormTags,
 | 
						|
        CurrentVariable
 | 
						|
        );
 | 
						|
 | 
						|
      //
 | 
						|
      // The current language selected + the Date operand
 | 
						|
      //
 | 
						|
      FormTags->Tags[CurrTag + 1].Operand = FormData[Index];
 | 
						|
      GetNumericHeader (
 | 
						|
        &FormTags->Tags[CurrTag + 1],
 | 
						|
        FormData,
 | 
						|
        (UINT16) (Index + TagLength + FormData[Index + TagLength + 1]),
 | 
						|
        (UINT16) 0,
 | 
						|
        FileFormTags,
 | 
						|
        CurrentVariable
 | 
						|
        );
 | 
						|
 | 
						|
      //
 | 
						|
      // The current language selected + the Date operand
 | 
						|
      //
 | 
						|
      FormTags->Tags[CurrTag + 2].Operand = FormData[Index];
 | 
						|
      GetNumericHeader (&FormTags->Tags[CurrTag + 2], FormData, Index, (UINT16) 1, FileFormTags, CurrentVariable);
 | 
						|
 | 
						|
      CurrTag   = (INT16) (CurrTag + 2);
 | 
						|
 | 
						|
      Index     = (UINT16) (Index + TagLength);
 | 
						|
      //
 | 
						|
      // get the length
 | 
						|
      //
 | 
						|
      TagLength = FormData[Index + 1];
 | 
						|
      Index     = (UINT16) (Index + TagLength);
 | 
						|
      //
 | 
						|
      // get the length
 | 
						|
      //
 | 
						|
      TagLength = FormData[Index + 1];
 | 
						|
      break;
 | 
						|
 | 
						|
    case FRAMEWORK_EFI_IFR_TIME_OP:
 | 
						|
      GetNumericHeader (&FormTags->Tags[CurrTag], FormData, 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 FRAMEWORK_EFI_IFR_PASSWORD_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_STRING_OP:
 | 
						|
      GetQuestionHeader (&FormTags->Tags[CurrTag], FormData, Index, FileFormTags, CurrentVariable);
 | 
						|
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
 | 
						|
      break;
 | 
						|
 | 
						|
    case FRAMEWORK_EFI_IFR_INCONSISTENT_IF_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_SUPPRESS_IF_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_GRAYOUT_IF_OP:
 | 
						|
      ConsistencyId++;
 | 
						|
      break;
 | 
						|
 | 
						|
    case FRAMEWORK_EFI_IFR_EQ_ID_VAL_OP:
 | 
						|
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
 | 
						|
      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;
 | 
						|
      break;
 | 
						|
 | 
						|
    case FRAMEWORK_EFI_IFR_EQ_VAR_VAL_OP:
 | 
						|
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
 | 
						|
      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;
 | 
						|
      break;
 | 
						|
 | 
						|
    case FRAMEWORK_EFI_IFR_EQ_ID_ID_OP:
 | 
						|
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
 | 
						|
      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;
 | 
						|
      break;
 | 
						|
 | 
						|
    case FRAMEWORK_EFI_IFR_AND_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_OR_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_NOT_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_TRUE_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_FALSE_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_GT_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_GE_OP:
 | 
						|
      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;
 | 
						|
      break;
 | 
						|
 | 
						|
    case FRAMEWORK_EFI_IFR_EQ_ID_LIST_OP:
 | 
						|
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
 | 
						|
 | 
						|
      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // End of switch
 | 
						|
    //
 | 
						|
    if (Finished) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // 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
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
ExtractDynamicFormHandle (
 | 
						|
  IN  UI_MENU_OPTION              *Selection,
 | 
						|
  IN  UINT8                       *CallbackData,
 | 
						|
  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,
 | 
						|
  IN  UINTN                       IdValue,
 | 
						|
  OUT UINT16                      *FormHandle,
 | 
						|
  OUT UINT16                      *TitleToken,
 | 
						|
  OUT EFI_FORM_TAGS               *FormTags
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  The function does the most of the works when the EFI_TAG that
 | 
						|
  user selects on is FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE or FRAMEWORK_EFI_IFR_PASSWORD_OP:
 | 
						|
  invoke CallBack, update the new form data.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Selection         - The current selection of the form.
 | 
						|
  CallbackData      - The pointer to host the data passed back by the callback function.
 | 
						|
  FileFormTagsHead  - Prompt string token of the one-of box
 | 
						|
  IdValue           - The current page number.
 | 
						|
  FormHandle        - Output the  the handle of the form.
 | 
						|
  TitleToken        - Output the  TitleToken of the new page.
 | 
						|
  FormTags          - Output the  FormFags of the new page.
 | 
						|
 | 
						|
Returns:
 | 
						|
  VOID
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINTN                       Index;
 | 
						|
  UINTN                       BackupIndex;
 | 
						|
  EFI_FILE_FORM_TAGS          *FileFormTags;
 | 
						|
  EFI_FORM_TAGS               *LocalTags;
 | 
						|
  EFI_FORM_CALLBACK_PROTOCOL  *FormCallback;
 | 
						|
  EFI_STATUS                  Status;
 | 
						|
  UINTN                       Length;
 | 
						|
  UINT8                       *Buffer;
 | 
						|
  EFI_PHYSICAL_ADDRESS        CallbackHandle;
 | 
						|
  EFI_GUID                    TagGuid;
 | 
						|
  UINT16                      TargetPage;
 | 
						|
  EFI_HII_CALLBACK_PACKET     *Packet;
 | 
						|
  UINTN                       ScreenSize;
 | 
						|
  CHAR16                      NullCharacter;
 | 
						|
  EFI_INPUT_KEY               Key;
 | 
						|
  UINT16                      ConsistencyId;
 | 
						|
  UINT16                      CurrentVariable;
 | 
						|
  EFI_VARIABLE_DEFINITION     *VariableDefinition;
 | 
						|
  FRAMEWORK_EFI_IFR_DATA_ENTRY          *DataEntry;
 | 
						|
 | 
						|
  VariableDefinition  = NULL;
 | 
						|
  NullCharacter       = CHAR_NULL;
 | 
						|
 | 
						|
  CurrentVariable     = 0;
 | 
						|
  FileFormTags        = FileFormTagsHead;
 | 
						|
  Length              = 0;
 | 
						|
  CallbackHandle      = 0;
 | 
						|
  TargetPage          = (UINT16) IdValue;
 | 
						|
  Packet              = NULL;
 | 
						|
  ConsistencyId       = 0;
 | 
						|
 | 
						|
  //
 | 
						|
  // Advance FileFormTags to the correct file's tag information.
 | 
						|
  // For instance, if Selection->IfrNumber is 3, that means the 4th
 | 
						|
  // file (0-based) in the FileFormTags linked-list contains the tag
 | 
						|
  // information.
 | 
						|
  //
 | 
						|
  for (Index = 0; Index < Selection->IfrNumber; Index++) {
 | 
						|
    FileFormTags = FileFormTags->NextFile;
 | 
						|
  }
 | 
						|
 | 
						|
  LocalTags = &FileFormTags->FormTags;
 | 
						|
 | 
						|
  //
 | 
						|
  // Advance Index to the FormOp with the correct ID value
 | 
						|
  //
 | 
						|
  for (; LocalTags->Next != NULL; LocalTags = LocalTags->Next) {
 | 
						|
    if ((LocalTags->Tags[0].CallbackHandle != 0) && (CallbackHandle == 0)) {
 | 
						|
      CallbackHandle = LocalTags->Tags[0].CallbackHandle;
 | 
						|
      CopyMem (&TagGuid, &LocalTags->Tags[0].GuidValue, sizeof (EFI_GUID));
 | 
						|
    }
 | 
						|
 | 
						|
    for (Index = 0; LocalTags->Tags[Index].Operand != FRAMEWORK_EFI_IFR_FORM_OP; Index++)
 | 
						|
      ;
 | 
						|
    if (LocalTags->Tags[Index].Id == IdValue) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // If we are going to callback on a non-goto opcode, make sure we don't change pages
 | 
						|
  //
 | 
						|
  if (Selection->ThisTag->Operand != FRAMEWORK_EFI_IFR_REF_OP) {
 | 
						|
    TargetPage = Selection->FormId;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // The first tag below should be the form op-code.  We need to store away the
 | 
						|
  // current variable setting to ensure if we have to reload the page, that we
 | 
						|
  // can correctly restore the values for the active variable
 | 
						|
  //
 | 
						|
  CurrentVariable = Selection->Tags[0].VariableNumber;
 | 
						|
 | 
						|
  //
 | 
						|
  // Remember that dynamic pages in an environment where all pages are not
 | 
						|
  // dynamic require us to call back to the user to give them an opportunity
 | 
						|
  // to register fresh information in the HII database so that we can extract it.
 | 
						|
  //
 | 
						|
  Status = gBS->HandleProtocol (
 | 
						|
                  (VOID *) (UINTN) CallbackHandle,
 | 
						|
                  &gEfiFormCallbackProtocolGuid,
 | 
						|
                  (VOID **) &FormCallback
 | 
						|
                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    FreePool (LocalTags->Tags);
 | 
						|
    return ;
 | 
						|
  }
 | 
						|
 | 
						|
  ExtractRequestedNvMap (FileFormTags, CurrentVariable, &VariableDefinition);
 | 
						|
 | 
						|
  if (Selection->ThisTag->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_NV_ACCESS)) {
 | 
						|
    ((FRAMEWORK_EFI_IFR_DATA_ARRAY *) CallbackData)->NvRamMap = VariableDefinition->NvRamMap;
 | 
						|
  } else {
 | 
						|
    ((FRAMEWORK_EFI_IFR_DATA_ARRAY *) CallbackData)->NvRamMap = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {
 | 
						|
    Status = FormCallback->Callback (
 | 
						|
                            FormCallback,
 | 
						|
                            Selection->ThisTag->Key,
 | 
						|
                            (FRAMEWORK_EFI_IFR_DATA_ARRAY *) CallbackData,
 | 
						|
                            &Packet
 | 
						|
                            );
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    //
 | 
						|
    // Restore Previous Value
 | 
						|
    //
 | 
						|
    CopyMem (
 | 
						|
      &VariableDefinition->NvRamMap[Selection->ThisTag->StorageStart],
 | 
						|
      gPreviousValue,
 | 
						|
      Selection->ThisTag->StorageWidth
 | 
						|
      );
 | 
						|
 | 
						|
    if (Packet != NULL && Packet->String != NULL) {
 | 
						|
      //
 | 
						|
      // Upon error, we will likely receive a string to print out
 | 
						|
      //
 | 
						|
      ScreenSize = GetStringWidth (Packet->String) / 2;
 | 
						|
 | 
						|
      //
 | 
						|
      // Display error popup
 | 
						|
      //
 | 
						|
      CreatePopUp (ScreenSize, 3, &NullCharacter, Packet->String, &NullCharacter);
 | 
						|
 | 
						|
      do {
 | 
						|
        Status = WaitForKeyStroke (&Key);
 | 
						|
      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
 | 
						|
    } else {
 | 
						|
      UpdateStatusBar (INPUT_ERROR, (UINT8) 0, TRUE);
 | 
						|
    }
 | 
						|
 | 
						|
  } else {
 | 
						|
    if (Packet != NULL) {
 | 
						|
      //
 | 
						|
      // We need to on a non-error, look in the outbound Packet for information and update the NVRAM
 | 
						|
      // location associated with the op-code specified there.  This is used on single op-code instances
 | 
						|
      // and not for when a hyperlink sent us a whole page of data.
 | 
						|
      //
 | 
						|
      DataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) (&Packet->DataArray + 1);
 | 
						|
      if (Packet->DataArray.EntryCount == 1) {
 | 
						|
        switch (DataEntry->OpCode) {
 | 
						|
        case FRAMEWORK_EFI_IFR_STRING_OP:
 | 
						|
        case FRAMEWORK_EFI_IFR_NUMERIC_OP:
 | 
						|
        case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP:
 | 
						|
        case FRAMEWORK_EFI_IFR_ONE_OF_OP:
 | 
						|
        case FRAMEWORK_EFI_IFR_CHECKBOX_OP:
 | 
						|
          CopyMem (
 | 
						|
            &VariableDefinition->NvRamMap[Selection->ThisTag->StorageStart],
 | 
						|
            &DataEntry->Data,
 | 
						|
            Selection->ThisTag->StorageWidth
 | 
						|
            );
 | 
						|
          break;
 | 
						|
 | 
						|
        case FRAMEWORK_EFI_IFR_NV_ACCESS_COMMAND:
 | 
						|
          CopyMem (
 | 
						|
            &VariableDefinition->NvRamMap[((FRAMEWORK_EFI_IFR_NV_DATA *) Packet)->QuestionId],
 | 
						|
            ((FRAMEWORK_EFI_IFR_NV_DATA *) Packet) + 1,
 | 
						|
            ((FRAMEWORK_EFI_IFR_NV_DATA *) Packet)->StorageWidth
 | 
						|
            );
 | 
						|
          break;
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
        if (DataEntry->Flags & RESET_REQUIRED) {
 | 
						|
          gResetRequired = TRUE;
 | 
						|
        }
 | 
						|
 | 
						|
        if (DataEntry->Flags & EXIT_REQUIRED) {
 | 
						|
          gExitRequired = TRUE;
 | 
						|
        }
 | 
						|
 | 
						|
        if (DataEntry->Flags & SAVE_REQUIRED) {
 | 
						|
          gSaveRequired = TRUE;
 | 
						|
        }
 | 
						|
 | 
						|
        if (DataEntry->Flags & NV_CHANGED) {
 | 
						|
          gNvUpdateRequired = TRUE;
 | 
						|
        }
 | 
						|
 | 
						|
        if (DataEntry->Flags & NV_NOT_CHANGED) {
 | 
						|
          gNvUpdateRequired = FALSE;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (Packet != NULL) {
 | 
						|
    FreePool (Packet);
 | 
						|
  }
 | 
						|
 | 
						|
  for (BackupIndex = 0; LocalTags->Tags[BackupIndex].Operand != FRAMEWORK_EFI_IFR_END_FORM_OP; BackupIndex++) {
 | 
						|
    switch (LocalTags->Tags[BackupIndex].Operand) {
 | 
						|
    case FRAMEWORK_EFI_IFR_EQ_VAR_VAL_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_EQ_ID_VAL_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_EQ_ID_ID_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_AND_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_OR_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_NOT_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_TRUE_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_FALSE_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_GT_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_GE_OP:
 | 
						|
    case FRAMEWORK_EFI_IFR_EQ_ID_LIST_OP:
 | 
						|
      //
 | 
						|
      // If we encountered a ConsistencyId value, on this page they will be incremental
 | 
						|
      // So register the first value we encounter.  We will pass this in when we re-create this page
 | 
						|
      //
 | 
						|
      if ((LocalTags->Tags[BackupIndex].ConsistencyId != 0) && (ConsistencyId == 0)) {
 | 
						|
        ConsistencyId = (UINT16) (LocalTags->Tags[BackupIndex].ConsistencyId - 1);
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Delete the buffer associated with previous dynamic page
 | 
						|
  // We will re-allocate a buffer....
 | 
						|
  //
 | 
						|
  FreePool (LocalTags->Tags);
 | 
						|
 | 
						|
  Length  = 0xF000;
 | 
						|
  Buffer  = AllocateZeroPool (Length);
 | 
						|
  ASSERT (Buffer != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the form that was updated by the callback
 | 
						|
  //
 | 
						|
  Hii->GetForms (
 | 
						|
        Hii,
 | 
						|
        Selection->Handle,
 | 
						|
        TargetPage,
 | 
						|
        &Length,
 | 
						|
        Buffer
 | 
						|
        );
 | 
						|
 | 
						|
  //
 | 
						|
  // Ok, we have the new page.....now we must purge the old page and re-allocate
 | 
						|
  // the tag page with the new data
 | 
						|
  //
 | 
						|
  UpdateNewTagData (
 | 
						|
    Buffer,
 | 
						|
    ConsistencyId,
 | 
						|
    CurrentVariable,
 | 
						|
    LocalTags,
 | 
						|
    FileFormTags
 | 
						|
    );
 | 
						|
 | 
						|
  //
 | 
						|
  // return the Form Id, Text, and the File's FormTags structure
 | 
						|
  //
 | 
						|
  *FormHandle                       = LocalTags->Tags[0].Id;
 | 
						|
  *TitleToken                       = LocalTags->Tags[0].Text;
 | 
						|
  *FormTags                         = *LocalTags;
 | 
						|
 | 
						|
  FormTags->Tags[0].CallbackHandle  = CallbackHandle;
 | 
						|
  CopyMem (&FormTags->Tags[0].GuidValue, &TagGuid, sizeof (EFI_GUID));
 | 
						|
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
UI_MENU_OPTION *
 | 
						|
SetupBrowser (
 | 
						|
  IN  UI_MENU_OPTION              *Selection,
 | 
						|
  IN  BOOLEAN                     Callback,
 | 
						|
  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,
 | 
						|
  IN  UINT8                       *CallbackData
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT16        FormHandle;
 | 
						|
  UINT16        TitleToken;
 | 
						|
  EFI_FORM_TAGS FormTags;
 | 
						|
 | 
						|
  gEntryNumber  = -1;
 | 
						|
  gLastOpr      = FALSE;
 | 
						|
  //
 | 
						|
  // Displays the Header and Footer borders
 | 
						|
  //
 | 
						|
  DisplayPageFrame ();
 | 
						|
 | 
						|
  //
 | 
						|
  // Id of 0 yields the getting of the top form whatever the ID is.  Usually the first form in the IFR
 | 
						|
  //
 | 
						|
  ExtractFormHandle (Selection, FileFormTagsHead, 0, &FormHandle, &TitleToken, &FormTags);
 | 
						|
 | 
						|
  Selection = DisplayForm (Selection, FormHandle, TitleToken, FormTags, FileFormTagsHead, CallbackData);
 | 
						|
 | 
						|
  //
 | 
						|
  // If selection is null use the former selection
 | 
						|
  //
 | 
						|
  if (Selection == NULL) {
 | 
						|
    return Selection;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Callback) {
 | 
						|
    return Selection;
 | 
						|
  }
 | 
						|
 | 
						|
  while (Selection->Tags != NULL) {
 | 
						|
    if (Selection->Previous) {
 | 
						|
      ExtractFormHandle (Selection, FileFormTagsHead, Selection->FormId, &FormHandle, &TitleToken, &FormTags);
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // True if a hyperlink/jump is selected
 | 
						|
      //
 | 
						|
      if (Selection->ThisTag->Operand == FRAMEWORK_EFI_IFR_REF_OP && Selection->ThisTag->Id != 0x0000) {
 | 
						|
        if (Selection->ThisTag->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) {
 | 
						|
          ExtractDynamicFormHandle (
 | 
						|
            Selection,
 | 
						|
            CallbackData,
 | 
						|
            FileFormTagsHead,
 | 
						|
            Selection->ThisTag->Id,
 | 
						|
            &FormHandle,
 | 
						|
            &TitleToken,
 | 
						|
            &FormTags
 | 
						|
            );
 | 
						|
          goto DisplayPage;
 | 
						|
        } else {
 | 
						|
          ExtractFormHandle (Selection, FileFormTagsHead, Selection->ThisTag->Id, &FormHandle, &TitleToken, &FormTags);
 | 
						|
          goto DisplayPage;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if ((Selection->ThisTag->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) &&
 | 
						|
          (Selection->ThisTag->Operand != FRAMEWORK_EFI_IFR_PASSWORD_OP)
 | 
						|
          ) {
 | 
						|
        ExtractDynamicFormHandle (
 | 
						|
          Selection,
 | 
						|
          CallbackData,
 | 
						|
          FileFormTagsHead,
 | 
						|
          Selection->FormId,
 | 
						|
          &FormHandle,
 | 
						|
          &TitleToken,
 | 
						|
          &FormTags
 | 
						|
          );
 | 
						|
      } else {
 | 
						|
        ExtractFormHandle (Selection, FileFormTagsHead, Selection->FormId, &FormHandle, &TitleToken, &FormTags);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
DisplayPage:
 | 
						|
    //
 | 
						|
    // Displays the Header and Footer borders
 | 
						|
    //
 | 
						|
    DisplayPageFrame ();
 | 
						|
 | 
						|
    Selection = DisplayForm (Selection, FormHandle, TitleToken, FormTags, FileFormTagsHead, CallbackData);
 | 
						|
 | 
						|
    if (Selection == NULL) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  return Selection;
 | 
						|
}
 |