/*++

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.             

Module Name:

  Boolean.c

Abstract:

  This routine will evaluate the IFR inconsistency data to determine if
  something is a valid entry for a particular expression

--*/

#include "Setup.h"
#include "Ui.h"

//
// Global stack used to evaluate boolean expresions
//
BOOLEAN *mBooleanEvaluationStack    = (BOOLEAN) 0;
BOOLEAN *mBooleanEvaluationStackEnd = (BOOLEAN) 0;

STATIC
VOID
GrowBooleanStack (
  IN OUT BOOLEAN  **Stack,
  IN     UINTN    StackSizeInBoolean
  )
/*++

Routine Description:

  Grow size of the boolean stack

Arguments:

  Stack     - Old stack on the way in and new stack on the way out

  StackSizeInBoolean - New size of the stack

Returns:

  NONE 

--*/
{
  BOOLEAN *NewStack;

  NewStack = AllocatePool (StackSizeInBoolean * sizeof (BOOLEAN));
  ASSERT (NewStack != NULL);

  if (*Stack != NULL) {
    //
    // Copy to Old Stack to the New Stack
    //
    CopyMem (
      NewStack,
      mBooleanEvaluationStack,
      (mBooleanEvaluationStackEnd - mBooleanEvaluationStack) * sizeof (BOOLEAN)
      );

    //
    // Make the Stack pointer point to the old data in the new stack
    //
    *Stack = NewStack + (*Stack - mBooleanEvaluationStack);

    //
    // Free The Old Stack
    //
    gBS->FreePool (mBooleanEvaluationStack);
  }

  mBooleanEvaluationStack     = NewStack;
  mBooleanEvaluationStackEnd  = NewStack + StackSizeInBoolean;
}

VOID
InitializeBooleanEvaluator (
  VOID
  )
/*++

Routine Description:

  Allocate a global stack for boolean processing.

Arguments:

  NONE 

Returns:

  NONE 

--*/
{
  BOOLEAN *NullStack;

  NullStack = NULL;
  GrowBooleanStack (&NullStack, 0x1000);
}

STATIC
VOID
PushBool (
  IN OUT BOOLEAN  **Stack,
  IN BOOLEAN      BoolResult
  )
/*++

Routine Description:

  Push an element onto the Boolean Stack

Arguments:

  Stack      - Current stack location.
  BoolResult - BOOLEAN to push.

Returns:

  None.

--*/
{
  CopyMem (*Stack, &BoolResult, sizeof (BOOLEAN));
  *Stack += 1;

  if (*Stack >= mBooleanEvaluationStackEnd) {
    //
    // If we run out of stack space make a new one that is 2X as big. Copy
    // the old data into the new stack and update Stack to point to the old
    // data in the new stack.
    //
    GrowBooleanStack (
      Stack,
      (mBooleanEvaluationStackEnd - mBooleanEvaluationStack) * sizeof (BOOLEAN) * 2
      );
  }
}

STATIC
BOOLEAN
PopBool (
  IN OUT BOOLEAN **Stack
  )
/*++

Routine Description:

  Pop an element from the Boolean stack.

Arguments:

  Stack - Current stack location

Returns:

  Top of the BOOLEAN stack.

--*/
{
  BOOLEAN ReturnValue;

  *Stack -= 1;
  CopyMem (&ReturnValue, *Stack, sizeof (BOOLEAN));
  return ReturnValue;
}

EFI_STATUS
GrowBooleanExpression (
  IN      EFI_INCONSISTENCY_DATA  *InconsistentTags,
  OUT     VOID                    **BooleanExpression,
  IN OUT  UINTN                   *BooleanExpressionLength
  )
{
  UINT8 *NewExpression;

  NewExpression = AllocatePool (*BooleanExpressionLength + sizeof (EFI_INCONSISTENCY_DATA));
  ASSERT (NewExpression != NULL);

  if (*BooleanExpression != NULL) {
    //
    // Copy Old buffer to the New buffer
    //
    CopyMem (NewExpression, *BooleanExpression, *BooleanExpressionLength);

    CopyMem (&NewExpression[*BooleanExpressionLength], InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));

    //
    // Free The Old buffer
    //
    gBS->FreePool (*BooleanExpression);
  } else {
    //
    // Copy data into new buffer
    //
    CopyMem (NewExpression, InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));
  }

  *BooleanExpressionLength  = *BooleanExpressionLength + sizeof (EFI_INCONSISTENCY_DATA);
  *BooleanExpression        = (VOID *) NewExpression;
  return EFI_SUCCESS;
}

VOID
CreateBooleanExpression (
  IN  EFI_FILE_FORM_TAGS    *FileFormTags,
  IN  UINT16                Value,
  IN  UINT16                Id,
  IN  BOOLEAN               Complex,
  OUT VOID                  **BooleanExpression,
  OUT UINTN                 *BooleanExpressionLength
  )
/*++

Routine Description:

Arguments:

Returns:

--*/
{
  UINTN                   Count;
  EFI_INCONSISTENCY_DATA  *InconsistentTags;
  EFI_INCONSISTENCY_DATA  FakeInconsistentTags;

  InconsistentTags = FileFormTags->InconsistentTags;

  //
  // Did we run into a question that contains the Id we are looking for?
  //
  for (Count = 0; InconsistentTags->Operand != 0xFF; Count++) {

    //
    // Reserve INVALID_OFFSET_VALUE - 1 for TURE and FALSE, because we need to treat them as well
    // as ideqid etc. but they have no coresponding id, so we reserve this value.
    //
    if (InconsistentTags->QuestionId1 == Id ||
        InconsistentTags->QuestionId1 == INVALID_OFFSET_VALUE - 1) {
      //
      // If !Complex - means evaluate a single if/endif expression
      //
      if (!Complex) {
        //
        // If the ConsistencyId does not match the expression we are looking for
        // skip to the next consistency database entry
        //
        if (InconsistentTags->ConsistencyId != Value) {
          goto NextEntry;
        }
      }
      //
      // We need to rewind to the beginning of the Inconsistent expression
      //
      for (;
           (InconsistentTags->Operand != EFI_IFR_INCONSISTENT_IF_OP) &&
             (InconsistentTags->Operand != EFI_IFR_GRAYOUT_IF_OP) &&
             (InconsistentTags->Operand != EFI_IFR_SUPPRESS_IF_OP);
              ) {
        InconsistentTags = InconsistentTags->Previous;
      }
      //
      // Store the consistency check expression, ensure the next for loop starts at the op-code afterwards
      //
      GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);
      InconsistentTags = InconsistentTags->Next;

      //
      // Keep growing until we hit the End expression op-code or we hit the beginning of another
      // consistency check like grayout/suppress
      //
      for (;
           InconsistentTags->Operand != EFI_IFR_END_IF_OP &&
           InconsistentTags->Operand != EFI_IFR_GRAYOUT_IF_OP &&
           InconsistentTags->Operand != EFI_IFR_SUPPRESS_IF_OP;
            ) {
        GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);
        InconsistentTags = InconsistentTags->Next;
      }
      //
      // Store the EndExpression Op-code
      //
      GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);
    }

NextEntry:
    if (InconsistentTags->Next != NULL) {
      //
      // Skip to next entry
      //
      InconsistentTags = InconsistentTags->Next;
    }
  }

  FakeInconsistentTags.Operand = 0;

  //
  // Add one last expression which will signify we have definitely hit the end
  //
  GrowBooleanExpression (&FakeInconsistentTags, BooleanExpression, BooleanExpressionLength);
}

EFI_STATUS
BooleanVariableWorker (
  IN     CHAR16                   *VariableName,
  IN     EFI_VARIABLE_DEFINITION  *VariableDefinition,
  IN     BOOLEAN                  *StackPtr,
  IN OUT UINTN                    *SizeOfVariable,
  IN OUT VOID                     **VariableData
  )
/*++

Routine Description:


Arguments:

Returns:

--*/
{
  EFI_STATUS  Status;

  Status = gRT->GetVariable (
                  VariableName,
                  &VariableDefinition->Guid,
                  NULL,
                  SizeOfVariable,
                  *VariableData
                  );

  if (EFI_ERROR (Status)) {

    if (Status == EFI_BUFFER_TOO_SMALL) {
      *VariableData = AllocatePool (*SizeOfVariable);
      ASSERT (*VariableData != NULL);

      Status = gRT->GetVariable (
                      VariableName,
                      &VariableDefinition->Guid,
                      NULL,
                      SizeOfVariable,
                      *VariableData
                      );
    }

    if (Status == EFI_NOT_FOUND) {
      //
      // This is a serious flaw, we must have some standard result if a variable
      // is not found.  Our default behavior must either be return a TRUE or FALSE
      // since there is nothing else we can really do.  Therefore, my crystal ball
      // says I will return a FALSE
      //
      PushBool (&StackPtr, FALSE);
    }
  }

  return Status;
}

UINT8
PredicateIfrType (
  IN  EFI_INCONSISTENCY_DATA      *Iterator
  )
/*++

Routine Description:
  This routine is for the purpose of predicate whether the Ifr is generated by a VfrCompiler greater than or equal to 1.88 or
  less than 1.88 which is legacy.

Arguments:
  Iterator    - The pointer to inconsistency tags

Returns:

  0x2         - If IFR is not legacy

  0x1         - If IFR is legacy

--*/
{
  //
  // legacy Ifr cover the states:
  // Not ...
  // Operand Opcode Operand
  //
  // while Operand means ideqval, TRUE, or other what can be evaluated to True or False,
  // and Opcode means AND or OR.
  //
  if (Iterator->Operand == EFI_IFR_NOT_OP   ||
      Iterator->Operand == 0) {
    return 0x1;
  } else if (Iterator->Operand == EFI_IFR_EQ_VAR_VAL_OP ||
             Iterator->Operand == EFI_IFR_EQ_ID_VAL_OP  ||
             Iterator->Operand == EFI_IFR_EQ_ID_ID_OP   ||
             Iterator->Operand == EFI_IFR_EQ_ID_LIST_OP) {
    Iterator++;
    if (Iterator->Operand == EFI_IFR_AND_OP ||
        Iterator->Operand == EFI_IFR_OR_OP) {
      Iterator--;
      return 0x1;
    }
    Iterator--;
  }
  return 0x2;
}

VOID
PostOrderEvaluate (
  IN      EFI_FILE_FORM_TAGS          *FileFormTags,
  IN      UINT16                      Width,
  IN OUT  EFI_INCONSISTENCY_DATA      **PIterator,
  IN OUT  BOOLEAN                     **StackPtr
  )
/*++

Routine Description:
  PostOrderEvaluate is used for Ifr generated by VfrCompiler greater than or equal to 1.88,
  which generate Operand Operand Opcode type Ifr.
  PostOrderEvaluete only evaluate boolean expression part, not suppressif/grayoutif. TRUE,
  FALSE, >=, >, (, ) are supported.

Arguments:

  FileFormTags     - The pointer to the tags of the form

  Width            - Width of Operand, recognized every iteration

  PIterator        - The pointer to inconsistency tags

  StackPtr         - The pointer to the evaluation stack

Returns:

  TRUE             - If value is valid

  FALSE            - If value is not valid

--*/
{
  BOOLEAN                 Operator;
  BOOLEAN                 Operator2;
  UINT16                  *MapBuffer;
  UINT16                  *MapBuffer2;
  UINT16                  MapValue;
  UINT16                  MapValue2;
  UINTN                   SizeOfVariable;
  CHAR16                  VariableName[40];
  VOID                    *VariableData;
  EFI_VARIABLE_DEFINITION *VariableDefinition;
  EFI_STATUS              Status;
  UINTN                   Index;
  BOOLEAN                 PushValue;

  Operator        = FALSE;
  Operator2       = FALSE;
  MapBuffer       = NULL;
  MapBuffer2      = NULL;
  MapValue        = 0;
  MapValue2       = 0;
  VariableData    = NULL;

  while (TRUE) {
    if ((*PIterator)->Operand == 0) {
      return;
    }

    Width = (*PIterator)->Width;

    // 
    //  Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.
    //
    if ((*PIterator)->QuestionId1 != INVALID_OFFSET_VALUE &&
        (*PIterator)->QuestionId1 != INVALID_OFFSET_VALUE - 1) {
      ExtractNvValue (FileFormTags, (*PIterator)->VariableNumber, Width, (*PIterator)->QuestionId1, (VOID **) &MapBuffer);
      ExtractNvValue (FileFormTags, (*PIterator)->VariableNumber2, Width, (*PIterator)->QuestionId2, (VOID **) &MapBuffer2);
      if (MapBuffer != NULL) {
        if (Width == 2) {
          MapValue = *MapBuffer;
        } else {
          MapValue = (UINT8) *MapBuffer;
        }

        gBS->FreePool (MapBuffer);
      }

      if (MapBuffer2 != NULL) {
        if (Width == 2) {
          MapValue2 = *MapBuffer2;
        } else {
          MapValue2 = (UINT8) *MapBuffer2;
        }

        gBS->FreePool (MapBuffer2);
      }
    }

    switch ((*PIterator)->Operand) {
    case EFI_IFR_EQ_VAR_VAL_OP:
      UnicodeValueToString (
        VariableName, 
        FALSE, 
        (UINTN) (*PIterator)->QuestionId1, 
        (sizeof (VariableName) / sizeof (VariableName[0]))
        );

      SizeOfVariable = 0;

      ExtractRequestedNvMap (FileFormTags, (*PIterator)->VariableNumber, &VariableDefinition);

      Status = BooleanVariableWorker (
                VariableName,
                VariableDefinition,
                *StackPtr,
                &SizeOfVariable,
                &VariableData
                );

      if (!EFI_ERROR (Status)) {
        if (SizeOfVariable == 1) {
          CopyMem (&MapValue, VariableData, 1);
        } else {
          CopyMem (&MapValue, VariableData, 2);
        }

        //
        // Do operation after knowing the compare operator.
        //
        MapValue2 = (*PIterator)->Value;
        (*PIterator)++;
        if ((*PIterator)->Operand == EFI_IFR_GT_OP) {
          PushValue = (BOOLEAN) (MapValue > MapValue2);
        } else if ((*PIterator)->Operand == EFI_IFR_GE_OP) {
          PushValue = (BOOLEAN) (MapValue >= MapValue2);
        } else {
          (*PIterator)--;
          PushValue = (BOOLEAN) (MapValue == MapValue2);
        }
        PushBool (StackPtr, PushValue);
      }

      break;

    case EFI_IFR_EQ_ID_VAL_OP:
      //
      // Do operation after knowing the compare operator.
      //
      MapValue2 = (*PIterator)->Value;
      (*PIterator)++;
      if ((*PIterator)->Operand == EFI_IFR_GT_OP) {
        PushValue = (BOOLEAN) (MapValue > MapValue2);
      } else if ((*PIterator)->Operand == EFI_IFR_GE_OP) {
        PushValue = (BOOLEAN) (MapValue >= MapValue2);
      } else {
        (*PIterator)--;
        PushValue = (BOOLEAN) (MapValue == MapValue2);
      }
      PushBool (StackPtr, PushValue);
      break;

    case EFI_IFR_EQ_ID_ID_OP:
      //
      // Do operation after knowing the compare operator.
      //
      (*PIterator)++;
      if ((*PIterator)->Operand == EFI_IFR_GT_OP) {
        PushValue = (BOOLEAN) (MapValue > MapValue2);
      } else if ((*PIterator)->Operand == EFI_IFR_GE_OP) {
        PushValue = (BOOLEAN) (MapValue >= MapValue2);
      } else {
        (*PIterator)--;
        PushValue = (BOOLEAN) (MapValue == MapValue2);
      }
      PushBool (StackPtr, PushValue);
      break;

    case EFI_IFR_EQ_ID_LIST_OP:
      for (Index = 0; Index < (*PIterator)->ListLength; Index++) {
        Operator = (BOOLEAN) (MapValue == (*PIterator)->ValueList[Index]);
        if (Operator) {
          break;
        }
      }

      PushBool (StackPtr, Operator);
      break;

    case EFI_IFR_TRUE_OP:
      PushBool (StackPtr, TRUE);
      break;

    case EFI_IFR_FALSE_OP:
      PushBool (StackPtr, FALSE);
      break;

    case EFI_IFR_AND_OP:
      Operator  = PopBool (StackPtr);
      Operator2 = PopBool (StackPtr);
      PushBool (StackPtr, (BOOLEAN) (Operator && Operator2));
      break;
    case EFI_IFR_OR_OP:
      Operator  = PopBool (StackPtr);
      Operator2 = PopBool (StackPtr);
      PushBool (StackPtr, (BOOLEAN) (Operator || Operator2));
      break;
    case EFI_IFR_NOT_OP:
      Operator  = PopBool (StackPtr);
      PushBool (StackPtr, !Operator);
      break;

    case EFI_IFR_SUPPRESS_IF_OP:
    case EFI_IFR_GRAYOUT_IF_OP:
    case EFI_IFR_INCONSISTENT_IF_OP:
    default:
      //
      // Return to the previous tag if runs out of boolean expression.
      //
      (*PIterator)--;
      return;
    }
    (*PIterator)++;
  }
}

BOOLEAN
ValueIsNotValid (
  IN  BOOLEAN                     Complex,
  IN  UINT16                      Value,
  IN  EFI_TAG                     *Tag,
  IN  EFI_FILE_FORM_TAGS          *FileFormTags,
  IN  STRING_REF                  *PopUp
  )
/*++

Routine Description:


Arguments:

Returns:

  TRUE - If value is valid

  FALSE - If value is not valid

--*/
{
  BOOLEAN                 *StackPtr;
  EFI_INCONSISTENCY_DATA  *Iterator;
  BOOLEAN                 Operator;
  BOOLEAN                 Operator2;
  UINTN                   Index;
  VOID                    *BooleanExpression;
  UINTN                   BooleanExpressionLength;
  BOOLEAN                 NotOperator;
  BOOLEAN                 OrOperator;
  BOOLEAN                 AndOperator;
  BOOLEAN                 ArtificialEnd;
  UINT16                  *MapBuffer;
  UINT16                  *MapBuffer2;
  UINT16                  MapValue;
  UINT16                  MapValue2;
  UINTN                   SizeOfVariable;
  CHAR16                  VariableName[40];
  VOID                    *VariableData;
  EFI_STATUS              Status;
  UINT16                  Id;
  UINT16                  Width;
  EFI_VARIABLE_DEFINITION *VariableDefinition;
  BOOLEAN                 CosmeticConsistency;
  UINT8                   IsLegacy;

  VariableData            = NULL;
  BooleanExpressionLength = 0;
  BooleanExpression       = NULL;
  Operator                = FALSE;
  ArtificialEnd           = FALSE;
  CosmeticConsistency     = TRUE;
  IsLegacy                = 0;

  Id                      = Tag->Id;
  if (Tag->StorageWidth == 1) {
    Width = 1;
  } else {
    Width = 2;
  }
  CreateBooleanExpression (FileFormTags, Value, Id, Complex, &BooleanExpression, &BooleanExpressionLength);

  if (mBooleanEvaluationStack == 0) {
    InitializeBooleanEvaluator ();
  }

  if (BooleanExpression == NULL) {
    return FALSE;
  }

  StackPtr    = mBooleanEvaluationStack;
  Iterator    = BooleanExpression;
  MapBuffer   = NULL;
  MapBuffer2  = NULL;
  MapValue    = 0;
  MapValue2   = 0;

  while (TRUE) {
    NotOperator = FALSE;
    OrOperator  = FALSE;
    AndOperator = FALSE;

    if (Iterator->Operand == 0) {
      return Operator;
    }

    // 
    //  Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.
    //
    if (Iterator->QuestionId1 != INVALID_OFFSET_VALUE &&
        Iterator->QuestionId1 != INVALID_OFFSET_VALUE-1) {
      ExtractNvValue (FileFormTags, Iterator->VariableNumber, Width, Iterator->QuestionId1, (VOID **) &MapBuffer);
      ExtractNvValue (FileFormTags, Iterator->VariableNumber2, Width, Iterator->QuestionId2, (VOID **) &MapBuffer2);
      if (MapBuffer != NULL) {
        if (Width == 2) {
          MapValue = *MapBuffer;
        } else {
          MapValue = (UINT8) *MapBuffer;
        }

        gBS->FreePool (MapBuffer);
      }

      if (MapBuffer2 != NULL) {
        if (Width == 2) {
          MapValue2 = *MapBuffer2;
        } else {
          MapValue2 = (UINT8) *MapBuffer2;
        }

        gBS->FreePool (MapBuffer2);
      }
    }

    switch (Iterator->Operand) {
    case EFI_IFR_SUPPRESS_IF_OP:
      //
      // Must have hit a suppress followed by a grayout or vice-versa
      //
      if (ArtificialEnd) {
        ArtificialEnd = FALSE;
        Operator      = PopBool (&StackPtr);
        if (Operator) {
          Tag->Suppress = TRUE;
        }

        return Operator;
      }

      ArtificialEnd = TRUE;
      *PopUp        = Iterator->Popup;
      break;

    case EFI_IFR_GRAYOUT_IF_OP:
      //
      // Must have hit a suppress followed by a grayout or vice-versa
      //
      if (ArtificialEnd) {
        ArtificialEnd = FALSE;
        Operator      = PopBool (&StackPtr);
        if (Operator) {
          Tag->GrayOut = TRUE;
        }

        return Operator;
      }

      ArtificialEnd = TRUE;
      *PopUp        = Iterator->Popup;
      break;

    case EFI_IFR_INCONSISTENT_IF_OP:
      CosmeticConsistency = FALSE;
      *PopUp              = Iterator->Popup;
      break;

    //
    // In the case of external variable values, we must read the variable which is
    // named by the human readable version of the OpCode->VariableId and the guid of the formset
    //
    case EFI_IFR_EQ_VAR_VAL_OP:
      //
      // To check whether Ifr is legacy. Once every boolean expression.
      //
      if (IsLegacy == 0) {
        IsLegacy = PredicateIfrType (Iterator);
      }
      if (IsLegacy == 0x2) {
        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
        break;
      }

      UnicodeValueToString (
        VariableName, 
        FALSE, 
        (UINTN) Iterator->QuestionId1, 
        (sizeof (VariableName) / sizeof (VariableName[0]))
        );

      SizeOfVariable = 0;

      ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);

      Status = BooleanVariableWorker (
                VariableName,
                VariableDefinition,
                StackPtr,
                &SizeOfVariable,
                &VariableData
                );

      if (!EFI_ERROR (Status)) {
        if (SizeOfVariable == 1) {
          CopyMem (&MapValue, VariableData, 1);
        } else {
          CopyMem (&MapValue, VariableData, 2);
        }

        PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));
      }

      break;

    case EFI_IFR_EQ_ID_VAL_OP:
      //
      // To check whether Ifr is legacy. Once every boolean expression.
      //
      if (IsLegacy == 0) {
        IsLegacy = PredicateIfrType (Iterator);
      }
      if (IsLegacy == 0x2) {
        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
        break;
      }

      PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));
      break;

    case EFI_IFR_EQ_ID_ID_OP:
      //
      // To check whether Ifr is legacy. Once every boolean expression.
      //
      if (IsLegacy == 0) {
        IsLegacy = PredicateIfrType (Iterator);
      }
      if (IsLegacy == 0x2) {
        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
        break;
      }

      PushBool (&StackPtr, (BOOLEAN) (MapValue == MapValue2));
      break;

    case EFI_IFR_EQ_ID_LIST_OP:
      //
      // To check whether Ifr is legacy. Once every boolean expression.
      //
      if (IsLegacy == 0) {
        IsLegacy = PredicateIfrType (Iterator);
      }
      if (IsLegacy == 0x2) {
        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
        break;
      }

      for (Index = 0; Index < Iterator->ListLength; Index++) {
        Operator = (BOOLEAN) (MapValue == Iterator->ValueList[Index]);
        if (Operator) {
          break;
        }
      }

      PushBool (&StackPtr, Operator);
      break;

    case EFI_IFR_AND_OP:
      Iterator++;
      if (Iterator->Operand == EFI_IFR_NOT_OP) {
        NotOperator = TRUE;
        Iterator++;
      }

      if (Iterator->QuestionId1 != INVALID_OFFSET_VALUE) {
        ExtractNvValue (FileFormTags, Iterator->VariableNumber, Width, Iterator->QuestionId1, (VOID **) &MapBuffer);
        ExtractNvValue (FileFormTags, Iterator->VariableNumber2, Width, Iterator->QuestionId2, (VOID **) &MapBuffer2);
        if (MapBuffer != NULL) {
          if (Width == 2) {
            MapValue = *MapBuffer;
          } else {
            MapValue = (UINT8) *MapBuffer;
          }

          gBS->FreePool (MapBuffer);
        }

        if (MapBuffer2 != NULL) {
          if (Width == 2) {
            MapValue2 = *MapBuffer2;
          } else {
            MapValue2 = (UINT8) *MapBuffer2;
          }

          gBS->FreePool (MapBuffer2);
        }
      }

      switch (Iterator->Operand) {
      case EFI_IFR_EQ_ID_VAL_OP:
        //
        // If Not - flip the results
        //
        if (NotOperator) {
          Operator = (BOOLEAN)!(MapValue == Iterator->Value);
        } else {
          Operator = (BOOLEAN) (MapValue == Iterator->Value);
        }

        PushBool (&StackPtr, Operator);
        break;

      //
      // In the case of external variable values, we must read the variable which is
      // named by the human readable version of the OpCode->VariableId and the guid of the formset
      //
      case EFI_IFR_EQ_VAR_VAL_OP:
        UnicodeValueToString (
          VariableName, 
          FALSE, 
          (UINTN) Iterator->QuestionId1, 
          (sizeof (VariableName) / sizeof (VariableName[0]))
          );

        SizeOfVariable = 0;

        ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);

        Status = BooleanVariableWorker (
                  VariableName,
                  VariableDefinition,
                  StackPtr,
                  &SizeOfVariable,
                  &VariableData
                  );

        if (!EFI_ERROR (Status)) {
          if (SizeOfVariable == 1) {
            CopyMem (&MapValue, VariableData, 1);
          } else {
            CopyMem (&MapValue, VariableData, 2);
          }
          //
          // If Not - flip the results
          //
          if (NotOperator) {
            PushBool (&StackPtr, (BOOLEAN)!(MapValue == Iterator->Value));
          } else {
            PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));
          }
        }
        break;

      case EFI_IFR_EQ_ID_ID_OP:
        //
        // If Not - flip the results
        //
        if (NotOperator) {
          Operator = (BOOLEAN)!(MapValue == MapValue2);
        } else {
          Operator = (BOOLEAN) (MapValue == MapValue2);
        }

        PushBool (&StackPtr, Operator);
        break;

      case EFI_IFR_EQ_ID_LIST_OP:
        for (Index = 0; Index < Iterator->ListLength; Index++) {
          //
          // If Not - flip the results
          //
          if (NotOperator) {
            Operator = (BOOLEAN)!(MapValue == Iterator->ValueList[Index]);
          } else {
            Operator = (BOOLEAN) (MapValue == Iterator->ValueList[Index]);
          }
          //
          // If We are trying to make sure that MapValue != Item[x], keep looking through
          // the list to make sure we don't equal any other items
          //
          if (Operator && NotOperator) {
            continue;
          }
          //
          // If MapValue == Item, then we have succeeded (first found is good enough)
          //
          if (Operator) {
            break;
          }
        }

        PushBool (&StackPtr, Operator);
        break;

      default:
        return FALSE;
      }

      Operator  = PopBool (&StackPtr);
      Operator2 = PopBool (&StackPtr);
      PushBool (&StackPtr, (BOOLEAN) (Operator && Operator2));
      break;

    case EFI_IFR_OR_OP:
      Iterator++;
      if (Iterator->Operand == EFI_IFR_NOT_OP) {
        NotOperator = TRUE;
        Iterator++;
      }

      if (Iterator->QuestionId1 != INVALID_OFFSET_VALUE) {
        ExtractNvValue (FileFormTags, Iterator->VariableNumber, Width, Iterator->QuestionId1, (VOID **) &MapBuffer);
        ExtractNvValue (FileFormTags, Iterator->VariableNumber2, Width, Iterator->QuestionId2, (VOID **) &MapBuffer2);
        if (MapBuffer != NULL) {
          if (Width == 2) {
            MapValue = *MapBuffer;
          } else {
            MapValue = (UINT8) *MapBuffer;
          }

          gBS->FreePool (MapBuffer);
        }

        if (MapBuffer2 != NULL) {
          if (Width == 2) {
            MapValue2 = *MapBuffer2;
          } else {
            MapValue2 = (UINT8) *MapBuffer2;
          }

          gBS->FreePool (MapBuffer2);
        }
      }

      switch (Iterator->Operand) {
      case EFI_IFR_EQ_ID_VAL_OP:
        //
        // If Not - flip the results
        //
        if (NotOperator) {
          Operator = (BOOLEAN)!(MapValue == Iterator->Value);
        } else {
          Operator = (BOOLEAN) (MapValue == Iterator->Value);
        }

        PushBool (&StackPtr, Operator);
        break;

      //
      // In the case of external variable values, we must read the variable which is
      // named by the human readable version of the OpCode->VariableId and the guid of the formset
      //
      case EFI_IFR_EQ_VAR_VAL_OP:
        UnicodeValueToString (
          VariableName, 
          FALSE, 
          (UINTN) Iterator->QuestionId1, 
          (sizeof (VariableName) / sizeof (VariableName[0]))
          );

        SizeOfVariable = 0;

        ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);

        Status = BooleanVariableWorker (
                  VariableName,
                  VariableDefinition,
                  StackPtr,
                  &SizeOfVariable,
                  &VariableData
                  );

        if (!EFI_ERROR (Status)) {
          if (SizeOfVariable == 1) {
            CopyMem (&MapValue, VariableData, 1);
          } else {
            CopyMem (&MapValue, VariableData, 2);
          }
          //
          // If Not - flip the results
          //
          if (NotOperator) {
            PushBool (&StackPtr, (BOOLEAN)!(MapValue == Iterator->Value));
          } else {
            PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));
          }
        }
        break;

      case EFI_IFR_EQ_ID_ID_OP:
        //
        // If Not - flip the results
        //
        if (NotOperator) {
          Operator = (BOOLEAN)!(MapValue == MapValue2);
        } else {
          Operator = (BOOLEAN) (MapValue == MapValue2);
        }

        PushBool (&StackPtr, Operator);
        break;

      case EFI_IFR_EQ_ID_LIST_OP:
        for (Index = 0; Index < Iterator->ListLength; Index++) {
          //
          // If Not - flip the results
          //
          if (NotOperator) {
            Operator = (BOOLEAN)!(MapValue == Iterator->ValueList[Index]);
          } else {
            Operator = (BOOLEAN) (MapValue == Iterator->ValueList[Index]);
          }
          //
          // If We are trying to make sure that MapValue != Item[x], keep looking through
          // the list to make sure we don't equal any other items
          //
          if (Operator && NotOperator) {
            continue;
          }
          //
          // If MapValue == Item, then we have succeeded (first found is good enough)
          //
          if (Operator) {
            break;
          }
        }

        PushBool (&StackPtr, Operator);
        break;

      default:
        return FALSE;
      }

      Operator  = PopBool (&StackPtr);
      Operator2 = PopBool (&StackPtr);
      PushBool (&StackPtr, (BOOLEAN) (Operator || Operator2));
      break;

    case EFI_IFR_NOT_OP:
      //
      // To check whether Ifr is legacy. Once every boolean expression.
      //
      if (IsLegacy == 0) {
        IsLegacy = PredicateIfrType (Iterator);
      }
      if (IsLegacy == 0x2) {
        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
        break;
      }

      //
      // I don't need to set the NotOperator (I know that I have to NOT this in this case
      //
      Iterator++;

      if (Iterator->Operand == EFI_IFR_OR_OP) {
        OrOperator = TRUE;
        Iterator++;
      }

      if (Iterator->Operand == EFI_IFR_AND_OP) {
        AndOperator = TRUE;
        Iterator++;
      }

      if (Iterator->QuestionId1 != INVALID_OFFSET_VALUE) {
        ExtractNvValue (FileFormTags, Iterator->VariableNumber, Width, Iterator->QuestionId1, (VOID **) &MapBuffer);
        ExtractNvValue (FileFormTags, Iterator->VariableNumber2, Width, Iterator->QuestionId2, (VOID **) &MapBuffer2);
        if (MapBuffer != NULL) {
          if (Width == 2) {
            MapValue = *MapBuffer;
          } else {
            MapValue = (UINT8) *MapBuffer;
          }

          gBS->FreePool (MapBuffer);
        }

        if (MapBuffer2 != NULL) {
          if (Width == 2) {
            MapValue2 = *MapBuffer2;
          } else {
            MapValue2 = (UINT8) *MapBuffer2;
          }

          gBS->FreePool (MapBuffer2);
        }
      }

      switch (Iterator->Operand) {
      case EFI_IFR_EQ_ID_VAL_OP:
        Operator = (BOOLEAN)!(MapValue == Iterator->Value);
        PushBool (&StackPtr, Operator);
        break;

      //
      // In the case of external variable values, we must read the variable which is
      // named by the human readable version of the OpCode->VariableId and the guid of the formset
      //
      case EFI_IFR_EQ_VAR_VAL_OP:
        UnicodeValueToString (
          VariableName, 
          FALSE, 
          (UINTN) Iterator->QuestionId1, 
          (sizeof (VariableName) / sizeof (VariableName[0]))
          );

        SizeOfVariable = 0;

        ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);

        Status = BooleanVariableWorker (
                  VariableName,
                  VariableDefinition,
                  StackPtr,
                  &SizeOfVariable,
                  &VariableData
                  );

        if (!EFI_ERROR (Status)) {
          if (SizeOfVariable == 1) {
            CopyMem (&MapValue, VariableData, 1);
          } else {
            CopyMem (&MapValue, VariableData, 2);
          }

          PushBool (&StackPtr, (BOOLEAN)!(MapValue == Iterator->Value));
        }
        break;

      case EFI_IFR_EQ_ID_ID_OP:
        Operator = (BOOLEAN)!(MapValue == MapValue2);
        PushBool (&StackPtr, Operator);
        break;

      case EFI_IFR_EQ_ID_LIST_OP:
        for (Index = 0; Index < Iterator->ListLength; Index++) {
          Operator = (BOOLEAN)!(MapValue == Iterator->ValueList[Index]);
          if (Operator) {
            continue;
          }
        }

        PushBool (&StackPtr, Operator);
        break;

      default:
        return FALSE;
      }

      Operator  = PopBool (&StackPtr);
      Operator2 = PopBool (&StackPtr);

      if (OrOperator) {
        PushBool (&StackPtr, (BOOLEAN) (Operator || Operator2));
      }

      if (AndOperator) {
        PushBool (&StackPtr, (BOOLEAN) (Operator && Operator2));
      }

      if (!OrOperator && !AndOperator) {
        PushBool (&StackPtr, Operator);
      }
      break;
    
    case EFI_IFR_TRUE_OP:
      //
      // To check whether Ifr is legacy. Once every boolean expression.
      //
      if (IsLegacy == 0) {
        IsLegacy = PredicateIfrType (Iterator);
      }
      if (IsLegacy == 0x2) {
        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
        break;
      }
      break;

    case EFI_IFR_FALSE_OP:
      //
      // To check whether Ifr is legacy. Once every boolean expression.
      //
      if (IsLegacy == 0) {
        IsLegacy = PredicateIfrType (Iterator);
      }
      if (IsLegacy == 0x2) {
        PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
        break;
      }
      break;

    case EFI_IFR_END_IF_OP:
      Operator = PopBool (&StackPtr);
      //
      // If there is an error, return, otherwise keep looking - there might
      // be another test that causes an error
      //
      if (Operator) {
        if (Complex && CosmeticConsistency) {
          return EFI_SUCCESS;
        } else {
          return Operator;
        }
      } else {
        //
        // If not doing a global consistency check, the endif is the REAL terminator of this operation
        // This is used for grayout/suppress operations.  InconsistentIf is a global operation so the EndIf is
        // not the end-all be-all of terminators.
        //
        if (!Complex) {
          return Operator;
        }
        break;
      }

    default:
      //
      // Must have hit a non-consistency related op-code after a suppress/grayout
      //
      if (ArtificialEnd) {
        ArtificialEnd = FALSE;
        Operator      = PopBool (&StackPtr);
        return Operator;
      }

      return FALSE;
    }

    Iterator++;
  }

  return FALSE;
}
