2. Added NULL pointer check before calling FreePool () to fix bugs when free memory. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2513 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			1368 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1368 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*++
 | 
						|
 | 
						|
Copyright (c) 2006 - 2007, 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
 | 
						|
    //
 | 
						|
    FreePool (mBooleanEvaluationStack);
 | 
						|
  }
 | 
						|
 | 
						|
  mBooleanEvaluationStack     = NewStack;
 | 
						|
  mBooleanEvaluationStackEnd  = NewStack + StackSizeInBoolean;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
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
 | 
						|
    //
 | 
						|
    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;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
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);
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
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[MAXIMUM_VALUE_CHARACTERS];
 | 
						|
  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;
 | 
						|
        }
 | 
						|
 | 
						|
        FreePool (MapBuffer);
 | 
						|
      }
 | 
						|
 | 
						|
      if (MapBuffer2 != NULL) {
 | 
						|
        if (Width == 2) {
 | 
						|
          MapValue2 = *MapBuffer2;
 | 
						|
        } else {
 | 
						|
          MapValue2 = (UINT8) *MapBuffer2;
 | 
						|
        }
 | 
						|
 | 
						|
        FreePool (MapBuffer2);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    switch ((*PIterator)->Operand) {
 | 
						|
    case EFI_IFR_EQ_VAR_VAL_OP:
 | 
						|
      UnicodeValueToString (
 | 
						|
        VariableName,
 | 
						|
        FALSE,
 | 
						|
        (UINTN) (*PIterator)->QuestionId1,
 | 
						|
        (sizeof (VariableName) / sizeof (VariableName[0])) - 1
 | 
						|
        );
 | 
						|
 | 
						|
      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, (BOOLEAN) (!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[MAXIMUM_VALUE_CHARACTERS];
 | 
						|
  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;
 | 
						|
        }
 | 
						|
 | 
						|
        FreePool (MapBuffer);
 | 
						|
      }
 | 
						|
 | 
						|
      if (MapBuffer2 != NULL) {
 | 
						|
        if (Width == 2) {
 | 
						|
          MapValue2 = *MapBuffer2;
 | 
						|
        } else {
 | 
						|
          MapValue2 = (UINT8) *MapBuffer2;
 | 
						|
        }
 | 
						|
 | 
						|
        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])) - 1
 | 
						|
        );
 | 
						|
 | 
						|
      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;
 | 
						|
          }
 | 
						|
 | 
						|
          FreePool (MapBuffer);
 | 
						|
        }
 | 
						|
 | 
						|
        if (MapBuffer2 != NULL) {
 | 
						|
          if (Width == 2) {
 | 
						|
            MapValue2 = *MapBuffer2;
 | 
						|
          } else {
 | 
						|
            MapValue2 = (UINT8) *MapBuffer2;
 | 
						|
          }
 | 
						|
 | 
						|
          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])) - 1
 | 
						|
          );
 | 
						|
 | 
						|
        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;
 | 
						|
          }
 | 
						|
 | 
						|
          FreePool (MapBuffer);
 | 
						|
        }
 | 
						|
 | 
						|
        if (MapBuffer2 != NULL) {
 | 
						|
          if (Width == 2) {
 | 
						|
            MapValue2 = *MapBuffer2;
 | 
						|
          } else {
 | 
						|
            MapValue2 = (UINT8) *MapBuffer2;
 | 
						|
          }
 | 
						|
 | 
						|
          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])) - 1
 | 
						|
          );
 | 
						|
 | 
						|
        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;
 | 
						|
          }
 | 
						|
 | 
						|
          FreePool (MapBuffer);
 | 
						|
        }
 | 
						|
 | 
						|
        if (MapBuffer2 != NULL) {
 | 
						|
          if (Width == 2) {
 | 
						|
            MapValue2 = *MapBuffer2;
 | 
						|
          } else {
 | 
						|
            MapValue2 = (UINT8) *MapBuffer2;
 | 
						|
          }
 | 
						|
 | 
						|
          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])) - 1
 | 
						|
          );
 | 
						|
 | 
						|
        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;
 | 
						|
      }
 | 
						|
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
 | 
						|
    Iterator++;
 | 
						|
  }
 | 
						|
 | 
						|
Done:
 | 
						|
  return FALSE;
 | 
						|
}
 |