3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 This routine will evaluate the IFR inconsistency data to determine if
19 something is a valid entry for a particular expression
27 // Global stack used to evaluate boolean expresions
29 BOOLEAN
*mBooleanEvaluationStack
= (BOOLEAN
) 0;
30 BOOLEAN
*mBooleanEvaluationStackEnd
= (BOOLEAN
) 0;
35 IN OUT BOOLEAN
**Stack
,
36 IN UINTN StackSizeInBoolean
42 Grow size of the boolean stack
46 Stack - Old stack on the way in and new stack on the way out
48 StackSizeInBoolean - New size of the stack
58 NewStack
= AllocatePool (StackSizeInBoolean
* sizeof (BOOLEAN
));
59 ASSERT (NewStack
!= NULL
);
63 // Copy to Old Stack to the New Stack
67 mBooleanEvaluationStack
,
68 (mBooleanEvaluationStackEnd
- mBooleanEvaluationStack
) * sizeof (BOOLEAN
)
72 // Make the Stack pointer point to the old data in the new stack
74 *Stack
= NewStack
+ (*Stack
- mBooleanEvaluationStack
);
79 FreePool (mBooleanEvaluationStack
);
82 mBooleanEvaluationStack
= NewStack
;
83 mBooleanEvaluationStackEnd
= NewStack
+ StackSizeInBoolean
;
88 InitializeBooleanEvaluator (
95 Allocate a global stack for boolean processing.
110 GrowBooleanStack (&NullStack
, 0x1000);
116 IN OUT BOOLEAN
**Stack
,
117 IN BOOLEAN BoolResult
123 Push an element onto the Boolean Stack
127 Stack - Current stack location.
128 BoolResult - BOOLEAN to push.
136 CopyMem (*Stack
, &BoolResult
, sizeof (BOOLEAN
));
139 if (*Stack
>= mBooleanEvaluationStackEnd
) {
141 // If we run out of stack space make a new one that is 2X as big. Copy
142 // the old data into the new stack and update Stack to point to the old
143 // data in the new stack.
147 (mBooleanEvaluationStackEnd
- mBooleanEvaluationStack
) * sizeof (BOOLEAN
) * 2
155 IN OUT BOOLEAN
**Stack
161 Pop an element from the Boolean stack.
165 Stack - Current stack location
169 Top of the BOOLEAN stack.
176 CopyMem (&ReturnValue
, *Stack
, sizeof (BOOLEAN
));
182 GrowBooleanExpression (
183 IN EFI_INCONSISTENCY_DATA
*InconsistentTags
,
184 OUT VOID
**BooleanExpression
,
185 IN OUT UINTN
*BooleanExpressionLength
188 UINT8
*NewExpression
;
190 NewExpression
= AllocatePool (*BooleanExpressionLength
+ sizeof (EFI_INCONSISTENCY_DATA
));
191 ASSERT (NewExpression
!= NULL
);
193 if (*BooleanExpression
!= NULL
) {
195 // Copy Old buffer to the New buffer
197 CopyMem (NewExpression
, *BooleanExpression
, *BooleanExpressionLength
);
199 CopyMem (&NewExpression
[*BooleanExpressionLength
], InconsistentTags
, sizeof (EFI_INCONSISTENCY_DATA
));
202 // Free The Old buffer
204 FreePool (*BooleanExpression
);
207 // Copy data into new buffer
209 CopyMem (NewExpression
, InconsistentTags
, sizeof (EFI_INCONSISTENCY_DATA
));
212 *BooleanExpressionLength
= *BooleanExpressionLength
+ sizeof (EFI_INCONSISTENCY_DATA
);
213 *BooleanExpression
= (VOID
*) NewExpression
;
219 CreateBooleanExpression (
220 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
224 OUT VOID
**BooleanExpression
,
225 OUT UINTN
*BooleanExpressionLength
238 EFI_INCONSISTENCY_DATA
*InconsistentTags
;
239 EFI_INCONSISTENCY_DATA FakeInconsistentTags
;
241 InconsistentTags
= FileFormTags
->InconsistentTags
;
244 // Did we run into a question that contains the Id we are looking for?
246 for (Count
= 0; InconsistentTags
->Operand
!= 0xFF; Count
++) {
249 // Reserve INVALID_OFFSET_VALUE - 1 for TURE and FALSE, because we need to treat them as well
250 // as ideqid etc. but they have no coresponding id, so we reserve this value.
252 if (InconsistentTags
->QuestionId1
== Id
||
253 InconsistentTags
->QuestionId1
== INVALID_OFFSET_VALUE
- 1) {
255 // If !Complex - means evaluate a single if/endif expression
259 // If the ConsistencyId does not match the expression we are looking for
260 // skip to the next consistency database entry
262 if (InconsistentTags
->ConsistencyId
!= Value
) {
267 // We need to rewind to the beginning of the Inconsistent expression
270 (InconsistentTags
->Operand
!= EFI_IFR_INCONSISTENT_IF_OP
) &&
271 (InconsistentTags
->Operand
!= EFI_IFR_GRAYOUT_IF_OP
) &&
272 (InconsistentTags
->Operand
!= EFI_IFR_SUPPRESS_IF_OP
);
274 InconsistentTags
= InconsistentTags
->Previous
;
277 // Store the consistency check expression, ensure the next for loop starts at the op-code afterwards
279 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
280 InconsistentTags
= InconsistentTags
->Next
;
283 // Keep growing until we hit the End expression op-code or we hit the beginning of another
284 // consistency check like grayout/suppress
287 InconsistentTags
->Operand
!= EFI_IFR_END_IF_OP
&&
288 InconsistentTags
->Operand
!= EFI_IFR_GRAYOUT_IF_OP
&&
289 InconsistentTags
->Operand
!= EFI_IFR_SUPPRESS_IF_OP
;
291 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
292 InconsistentTags
= InconsistentTags
->Next
;
295 // Store the EndExpression Op-code
297 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
301 if (InconsistentTags
->Next
!= NULL
) {
303 // Skip to next entry
305 InconsistentTags
= InconsistentTags
->Next
;
309 FakeInconsistentTags
.Operand
= 0;
312 // Add one last expression which will signify we have definitely hit the end
314 GrowBooleanExpression (&FakeInconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
319 BooleanVariableWorker (
320 IN CHAR16
*VariableName
,
321 IN EFI_VARIABLE_DEFINITION
*VariableDefinition
,
322 IN BOOLEAN
*StackPtr
,
323 IN OUT UINTN
*SizeOfVariable
,
324 IN OUT VOID
**VariableData
339 Status
= gRT
->GetVariable (
341 &VariableDefinition
->Guid
,
347 if (EFI_ERROR (Status
)) {
349 if (Status
== EFI_BUFFER_TOO_SMALL
) {
350 *VariableData
= AllocatePool (*SizeOfVariable
);
351 ASSERT (*VariableData
!= NULL
);
353 Status
= gRT
->GetVariable (
355 &VariableDefinition
->Guid
,
362 if (Status
== EFI_NOT_FOUND
) {
364 // This is a serious flaw, we must have some standard result if a variable
365 // is not found. Our default behavior must either be return a TRUE or FALSE
366 // since there is nothing else we can really do. Therefore, my crystal ball
367 // says I will return a FALSE
369 PushBool (&StackPtr
, FALSE
);
379 IN EFI_INCONSISTENCY_DATA
*Iterator
384 This routine is for the purpose of predicate whether the Ifr is generated by a VfrCompiler greater than or equal to 1.88 or
385 less than 1.88 which is legacy.
388 Iterator - The pointer to inconsistency tags
392 0x2 - If IFR is not legacy
394 0x1 - If IFR is legacy
399 // legacy Ifr cover the states:
401 // Operand Opcode Operand
403 // while Operand means ideqval, TRUE, or other what can be evaluated to True or False,
404 // and Opcode means AND or OR.
406 if (Iterator
->Operand
== EFI_IFR_NOT_OP
||
407 Iterator
->Operand
== 0) {
409 } else if (Iterator
->Operand
== EFI_IFR_EQ_VAR_VAL_OP
||
410 Iterator
->Operand
== EFI_IFR_EQ_ID_VAL_OP
||
411 Iterator
->Operand
== EFI_IFR_EQ_ID_ID_OP
||
412 Iterator
->Operand
== EFI_IFR_EQ_ID_LIST_OP
) {
414 if (Iterator
->Operand
== EFI_IFR_AND_OP
||
415 Iterator
->Operand
== EFI_IFR_OR_OP
) {
427 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
429 IN OUT EFI_INCONSISTENCY_DATA
**PIterator
,
430 IN OUT BOOLEAN
**StackPtr
435 PostOrderEvaluate is used for Ifr generated by VfrCompiler greater than or equal to 1.88,
436 which generate Operand Operand Opcode type Ifr.
437 PostOrderEvaluete only evaluate boolean expression part, not suppressif/grayoutif. TRUE,
438 FALSE, >=, >, (, ) are supported.
442 FileFormTags - The pointer to the tags of the form
444 Width - Width of Operand, recognized every iteration
446 PIterator - The pointer to inconsistency tags
448 StackPtr - The pointer to the evaluation stack
452 TRUE - If value is valid
454 FALSE - If value is not valid
464 UINTN SizeOfVariable
;
465 CHAR16 VariableName
[MAXIMUM_VALUE_CHARACTERS
];
467 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
481 if ((*PIterator
)->Operand
== 0) {
485 Width
= (*PIterator
)->Width
;
488 // Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.
490 if ((*PIterator
)->QuestionId1
!= INVALID_OFFSET_VALUE
&&
491 (*PIterator
)->QuestionId1
!= INVALID_OFFSET_VALUE
- 1) {
492 ExtractNvValue (FileFormTags
, (*PIterator
)->VariableNumber
, Width
, (*PIterator
)->QuestionId1
, (VOID
**) &MapBuffer
);
493 ExtractNvValue (FileFormTags
, (*PIterator
)->VariableNumber2
, Width
, (*PIterator
)->QuestionId2
, (VOID
**) &MapBuffer2
);
494 if (MapBuffer
!= NULL
) {
496 MapValue
= *MapBuffer
;
498 MapValue
= (UINT8
) *MapBuffer
;
501 FreePool (MapBuffer
);
504 if (MapBuffer2
!= NULL
) {
506 MapValue2
= *MapBuffer2
;
508 MapValue2
= (UINT8
) *MapBuffer2
;
511 FreePool (MapBuffer2
);
515 switch ((*PIterator
)->Operand
) {
516 case EFI_IFR_EQ_VAR_VAL_OP
:
517 UnicodeValueToString (
520 (UINTN
) (*PIterator
)->QuestionId1
,
521 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
526 ExtractRequestedNvMap (FileFormTags
, (*PIterator
)->VariableNumber
, &VariableDefinition
);
528 Status
= BooleanVariableWorker (
536 if (!EFI_ERROR (Status
)) {
537 if (SizeOfVariable
== 1) {
538 CopyMem (&MapValue
, VariableData
, 1);
540 CopyMem (&MapValue
, VariableData
, 2);
544 // Do operation after knowing the compare operator.
546 MapValue2
= (*PIterator
)->Value
;
548 if ((*PIterator
)->Operand
== EFI_IFR_GT_OP
) {
549 PushValue
= (BOOLEAN
) (MapValue
> MapValue2
);
550 } else if ((*PIterator
)->Operand
== EFI_IFR_GE_OP
) {
551 PushValue
= (BOOLEAN
) (MapValue
>= MapValue2
);
554 PushValue
= (BOOLEAN
) (MapValue
== MapValue2
);
556 PushBool (StackPtr
, PushValue
);
561 case EFI_IFR_EQ_ID_VAL_OP
:
563 // Do operation after knowing the compare operator.
565 MapValue2
= (*PIterator
)->Value
;
567 if ((*PIterator
)->Operand
== EFI_IFR_GT_OP
) {
568 PushValue
= (BOOLEAN
) (MapValue
> MapValue2
);
569 } else if ((*PIterator
)->Operand
== EFI_IFR_GE_OP
) {
570 PushValue
= (BOOLEAN
) (MapValue
>= MapValue2
);
573 PushValue
= (BOOLEAN
) (MapValue
== MapValue2
);
575 PushBool (StackPtr
, PushValue
);
578 case EFI_IFR_EQ_ID_ID_OP
:
580 // Do operation after knowing the compare operator.
583 if ((*PIterator
)->Operand
== EFI_IFR_GT_OP
) {
584 PushValue
= (BOOLEAN
) (MapValue
> MapValue2
);
585 } else if ((*PIterator
)->Operand
== EFI_IFR_GE_OP
) {
586 PushValue
= (BOOLEAN
) (MapValue
>= MapValue2
);
589 PushValue
= (BOOLEAN
) (MapValue
== MapValue2
);
591 PushBool (StackPtr
, PushValue
);
594 case EFI_IFR_EQ_ID_LIST_OP
:
595 for (Index
= 0; Index
< (*PIterator
)->ListLength
; Index
++) {
596 Operator
= (BOOLEAN
) (MapValue
== (*PIterator
)->ValueList
[Index
]);
602 PushBool (StackPtr
, Operator
);
605 case EFI_IFR_TRUE_OP
:
606 PushBool (StackPtr
, TRUE
);
609 case EFI_IFR_FALSE_OP
:
610 PushBool (StackPtr
, FALSE
);
614 Operator
= PopBool (StackPtr
);
615 Operator2
= PopBool (StackPtr
);
616 PushBool (StackPtr
, (BOOLEAN
) (Operator
&& Operator2
));
619 Operator
= PopBool (StackPtr
);
620 Operator2
= PopBool (StackPtr
);
621 PushBool (StackPtr
, (BOOLEAN
) (Operator
|| Operator2
));
624 Operator
= PopBool (StackPtr
);
625 PushBool (StackPtr
, (BOOLEAN
) (!Operator
));
628 case EFI_IFR_SUPPRESS_IF_OP
:
629 case EFI_IFR_GRAYOUT_IF_OP
:
630 case EFI_IFR_INCONSISTENT_IF_OP
:
633 // Return to the previous tag if runs out of boolean expression.
647 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
659 TRUE - If value is valid
661 FALSE - If value is not valid
666 EFI_INCONSISTENCY_DATA
*Iterator
;
670 VOID
*BooleanExpression
;
671 UINTN BooleanExpressionLength
;
675 BOOLEAN ArtificialEnd
;
680 UINTN SizeOfVariable
;
681 CHAR16 VariableName
[MAXIMUM_VALUE_CHARACTERS
];
686 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
687 BOOLEAN CosmeticConsistency
;
691 BooleanExpressionLength
= 0;
692 BooleanExpression
= NULL
;
694 ArtificialEnd
= FALSE
;
695 CosmeticConsistency
= TRUE
;
699 if (Tag
->StorageWidth
== 1) {
704 CreateBooleanExpression (FileFormTags
, Value
, Id
, Complex
, &BooleanExpression
, &BooleanExpressionLength
);
706 if (mBooleanEvaluationStack
== 0) {
707 InitializeBooleanEvaluator ();
710 if (BooleanExpression
== NULL
) {
714 StackPtr
= mBooleanEvaluationStack
;
715 Iterator
= BooleanExpression
;
726 if (Iterator
->Operand
== 0) {
731 // Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.
733 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
&&
734 Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
-1) {
735 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
736 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
737 if (MapBuffer
!= NULL
) {
739 MapValue
= *MapBuffer
;
741 MapValue
= (UINT8
) *MapBuffer
;
744 FreePool (MapBuffer
);
747 if (MapBuffer2
!= NULL
) {
749 MapValue2
= *MapBuffer2
;
751 MapValue2
= (UINT8
) *MapBuffer2
;
754 FreePool (MapBuffer2
);
758 switch (Iterator
->Operand
) {
759 case EFI_IFR_SUPPRESS_IF_OP
:
761 // Must have hit a suppress followed by a grayout or vice-versa
764 ArtificialEnd
= FALSE
;
765 Operator
= PopBool (&StackPtr
);
767 Tag
->Suppress
= TRUE
;
773 ArtificialEnd
= TRUE
;
774 *PopUp
= Iterator
->Popup
;
777 case EFI_IFR_GRAYOUT_IF_OP
:
779 // Must have hit a suppress followed by a grayout or vice-versa
782 ArtificialEnd
= FALSE
;
783 Operator
= PopBool (&StackPtr
);
791 ArtificialEnd
= TRUE
;
792 *PopUp
= Iterator
->Popup
;
795 case EFI_IFR_INCONSISTENT_IF_OP
:
796 CosmeticConsistency
= FALSE
;
797 *PopUp
= Iterator
->Popup
;
801 // In the case of external variable values, we must read the variable which is
802 // named by the human readable version of the OpCode->VariableId and the guid of the formset
804 case EFI_IFR_EQ_VAR_VAL_OP
:
806 // To check whether Ifr is legacy. Once every boolean expression.
809 IsLegacy
= PredicateIfrType (Iterator
);
811 if (IsLegacy
== 0x2) {
812 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
816 UnicodeValueToString (
819 (UINTN
) Iterator
->QuestionId1
,
820 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
825 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
827 Status
= BooleanVariableWorker (
835 if (!EFI_ERROR (Status
)) {
836 if (SizeOfVariable
== 1) {
837 CopyMem (&MapValue
, VariableData
, 1);
839 CopyMem (&MapValue
, VariableData
, 2);
842 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
847 case EFI_IFR_EQ_ID_VAL_OP
:
849 // To check whether Ifr is legacy. Once every boolean expression.
852 IsLegacy
= PredicateIfrType (Iterator
);
854 if (IsLegacy
== 0x2) {
855 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
859 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
862 case EFI_IFR_EQ_ID_ID_OP
:
864 // To check whether Ifr is legacy. Once every boolean expression.
867 IsLegacy
= PredicateIfrType (Iterator
);
869 if (IsLegacy
== 0x2) {
870 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
874 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== MapValue2
));
877 case EFI_IFR_EQ_ID_LIST_OP
:
879 // To check whether Ifr is legacy. Once every boolean expression.
882 IsLegacy
= PredicateIfrType (Iterator
);
884 if (IsLegacy
== 0x2) {
885 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
889 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
890 Operator
= (BOOLEAN
) (MapValue
== Iterator
->ValueList
[Index
]);
896 PushBool (&StackPtr
, Operator
);
901 if (Iterator
->Operand
== EFI_IFR_NOT_OP
) {
906 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
907 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
908 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
909 if (MapBuffer
!= NULL
) {
911 MapValue
= *MapBuffer
;
913 MapValue
= (UINT8
) *MapBuffer
;
916 FreePool (MapBuffer
);
919 if (MapBuffer2
!= NULL
) {
921 MapValue2
= *MapBuffer2
;
923 MapValue2
= (UINT8
) *MapBuffer2
;
926 FreePool (MapBuffer2
);
930 switch (Iterator
->Operand
) {
931 case EFI_IFR_EQ_ID_VAL_OP
:
933 // If Not - flip the results
936 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->Value
);
938 Operator
= (BOOLEAN
) (MapValue
== Iterator
->Value
);
941 PushBool (&StackPtr
, Operator
);
945 // In the case of external variable values, we must read the variable which is
946 // named by the human readable version of the OpCode->VariableId and the guid of the formset
948 case EFI_IFR_EQ_VAR_VAL_OP
:
949 UnicodeValueToString (
952 (UINTN
) Iterator
->QuestionId1
,
953 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
958 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
960 Status
= BooleanVariableWorker (
968 if (!EFI_ERROR (Status
)) {
969 if (SizeOfVariable
== 1) {
970 CopyMem (&MapValue
, VariableData
, 1);
972 CopyMem (&MapValue
, VariableData
, 2);
975 // If Not - flip the results
978 PushBool (&StackPtr
, (BOOLEAN
)!(MapValue
== Iterator
->Value
));
980 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
985 case EFI_IFR_EQ_ID_ID_OP
:
987 // If Not - flip the results
990 Operator
= (BOOLEAN
)!(MapValue
== MapValue2
);
992 Operator
= (BOOLEAN
) (MapValue
== MapValue2
);
995 PushBool (&StackPtr
, Operator
);
998 case EFI_IFR_EQ_ID_LIST_OP
:
999 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
1001 // If Not - flip the results
1004 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->ValueList
[Index
]);
1006 Operator
= (BOOLEAN
) (MapValue
== Iterator
->ValueList
[Index
]);
1009 // If We are trying to make sure that MapValue != Item[x], keep looking through
1010 // the list to make sure we don't equal any other items
1012 if (Operator
&& NotOperator
) {
1016 // If MapValue == Item, then we have succeeded (first found is good enough)
1023 PushBool (&StackPtr
, Operator
);
1030 Operator
= PopBool (&StackPtr
);
1031 Operator2
= PopBool (&StackPtr
);
1032 PushBool (&StackPtr
, (BOOLEAN
) (Operator
&& Operator2
));
1037 if (Iterator
->Operand
== EFI_IFR_NOT_OP
) {
1042 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
1043 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
1044 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
1045 if (MapBuffer
!= NULL
) {
1047 MapValue
= *MapBuffer
;
1049 MapValue
= (UINT8
) *MapBuffer
;
1052 FreePool (MapBuffer
);
1055 if (MapBuffer2
!= NULL
) {
1057 MapValue2
= *MapBuffer2
;
1059 MapValue2
= (UINT8
) *MapBuffer2
;
1062 FreePool (MapBuffer2
);
1066 switch (Iterator
->Operand
) {
1067 case EFI_IFR_EQ_ID_VAL_OP
:
1069 // If Not - flip the results
1072 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->Value
);
1074 Operator
= (BOOLEAN
) (MapValue
== Iterator
->Value
);
1077 PushBool (&StackPtr
, Operator
);
1081 // In the case of external variable values, we must read the variable which is
1082 // named by the human readable version of the OpCode->VariableId and the guid of the formset
1084 case EFI_IFR_EQ_VAR_VAL_OP
:
1085 UnicodeValueToString (
1088 (UINTN
) Iterator
->QuestionId1
,
1089 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
1094 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
1096 Status
= BooleanVariableWorker (
1104 if (!EFI_ERROR (Status
)) {
1105 if (SizeOfVariable
== 1) {
1106 CopyMem (&MapValue
, VariableData
, 1);
1108 CopyMem (&MapValue
, VariableData
, 2);
1111 // If Not - flip the results
1114 PushBool (&StackPtr
, (BOOLEAN
)!(MapValue
== Iterator
->Value
));
1116 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
1121 case EFI_IFR_EQ_ID_ID_OP
:
1123 // If Not - flip the results
1126 Operator
= (BOOLEAN
)!(MapValue
== MapValue2
);
1128 Operator
= (BOOLEAN
) (MapValue
== MapValue2
);
1131 PushBool (&StackPtr
, Operator
);
1134 case EFI_IFR_EQ_ID_LIST_OP
:
1135 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
1137 // If Not - flip the results
1140 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->ValueList
[Index
]);
1142 Operator
= (BOOLEAN
) (MapValue
== Iterator
->ValueList
[Index
]);
1145 // If We are trying to make sure that MapValue != Item[x], keep looking through
1146 // the list to make sure we don't equal any other items
1148 if (Operator
&& NotOperator
) {
1152 // If MapValue == Item, then we have succeeded (first found is good enough)
1159 PushBool (&StackPtr
, Operator
);
1166 Operator
= PopBool (&StackPtr
);
1167 Operator2
= PopBool (&StackPtr
);
1168 PushBool (&StackPtr
, (BOOLEAN
) (Operator
|| Operator2
));
1171 case EFI_IFR_NOT_OP
:
1173 // To check whether Ifr is legacy. Once every boolean expression.
1175 if (IsLegacy
== 0) {
1176 IsLegacy
= PredicateIfrType (Iterator
);
1178 if (IsLegacy
== 0x2) {
1179 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
1184 // I don't need to set the NotOperator (I know that I have to NOT this in this case
1188 if (Iterator
->Operand
== EFI_IFR_OR_OP
) {
1193 if (Iterator
->Operand
== EFI_IFR_AND_OP
) {
1198 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
1199 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
1200 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
1201 if (MapBuffer
!= NULL
) {
1203 MapValue
= *MapBuffer
;
1205 MapValue
= (UINT8
) *MapBuffer
;
1208 FreePool (MapBuffer
);
1211 if (MapBuffer2
!= NULL
) {
1213 MapValue2
= *MapBuffer2
;
1215 MapValue2
= (UINT8
) *MapBuffer2
;
1218 FreePool (MapBuffer2
);
1222 switch (Iterator
->Operand
) {
1223 case EFI_IFR_EQ_ID_VAL_OP
:
1224 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->Value
);
1225 PushBool (&StackPtr
, Operator
);
1229 // In the case of external variable values, we must read the variable which is
1230 // named by the human readable version of the OpCode->VariableId and the guid of the formset
1232 case EFI_IFR_EQ_VAR_VAL_OP
:
1233 UnicodeValueToString (
1236 (UINTN
) Iterator
->QuestionId1
,
1237 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
1242 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
1244 Status
= BooleanVariableWorker (
1252 if (!EFI_ERROR (Status
)) {
1253 if (SizeOfVariable
== 1) {
1254 CopyMem (&MapValue
, VariableData
, 1);
1256 CopyMem (&MapValue
, VariableData
, 2);
1259 PushBool (&StackPtr
, (BOOLEAN
)!(MapValue
== Iterator
->Value
));
1263 case EFI_IFR_EQ_ID_ID_OP
:
1264 Operator
= (BOOLEAN
)!(MapValue
== MapValue2
);
1265 PushBool (&StackPtr
, Operator
);
1268 case EFI_IFR_EQ_ID_LIST_OP
:
1269 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
1270 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->ValueList
[Index
]);
1276 PushBool (&StackPtr
, Operator
);
1283 Operator
= PopBool (&StackPtr
);
1284 Operator2
= PopBool (&StackPtr
);
1287 PushBool (&StackPtr
, (BOOLEAN
) (Operator
|| Operator2
));
1291 PushBool (&StackPtr
, (BOOLEAN
) (Operator
&& Operator2
));
1294 if (!OrOperator
&& !AndOperator
) {
1295 PushBool (&StackPtr
, Operator
);
1299 case EFI_IFR_TRUE_OP
:
1301 // To check whether Ifr is legacy. Once every boolean expression.
1303 if (IsLegacy
== 0) {
1304 IsLegacy
= PredicateIfrType (Iterator
);
1306 if (IsLegacy
== 0x2) {
1307 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
1312 case EFI_IFR_FALSE_OP
:
1314 // To check whether Ifr is legacy. Once every boolean expression.
1316 if (IsLegacy
== 0) {
1317 IsLegacy
= PredicateIfrType (Iterator
);
1319 if (IsLegacy
== 0x2) {
1320 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
1325 case EFI_IFR_END_IF_OP
:
1326 Operator
= PopBool (&StackPtr
);
1328 // If there is an error, return, otherwise keep looking - there might
1329 // be another test that causes an error
1332 if (Complex
&& CosmeticConsistency
) {
1339 // If not doing a global consistency check, the endif is the REAL terminator of this operation
1340 // This is used for grayout/suppress operations. InconsistentIf is a global operation so the EndIf is
1341 // not the end-all be-all of terminators.
1351 // Must have hit a non-consistency related op-code after a suppress/grayout
1353 if (ArtificialEnd
) {
1354 ArtificialEnd
= FALSE
;
1355 Operator
= PopBool (&StackPtr
);