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
24 // Include common header file for this module.
26 #include "CommonHeader.h"
32 // Global stack used to evaluate boolean expresions
34 BOOLEAN
*mBooleanEvaluationStack
= (BOOLEAN
) 0;
35 BOOLEAN
*mBooleanEvaluationStackEnd
= (BOOLEAN
) 0;
40 IN OUT BOOLEAN
**Stack
,
41 IN UINTN StackSizeInBoolean
47 Grow size of the boolean stack
51 Stack - Old stack on the way in and new stack on the way out
53 StackSizeInBoolean - New size of the stack
63 NewStack
= AllocatePool (StackSizeInBoolean
* sizeof (BOOLEAN
));
64 ASSERT (NewStack
!= NULL
);
68 // Copy to Old Stack to the New Stack
72 mBooleanEvaluationStack
,
73 (mBooleanEvaluationStackEnd
- mBooleanEvaluationStack
) * sizeof (BOOLEAN
)
77 // Make the Stack pointer point to the old data in the new stack
79 *Stack
= NewStack
+ (*Stack
- mBooleanEvaluationStack
);
84 FreePool (mBooleanEvaluationStack
);
87 mBooleanEvaluationStack
= NewStack
;
88 mBooleanEvaluationStackEnd
= NewStack
+ StackSizeInBoolean
;
93 InitializeBooleanEvaluator (
100 Allocate a global stack for boolean processing.
115 GrowBooleanStack (&NullStack
, 0x1000);
121 IN OUT BOOLEAN
**Stack
,
122 IN BOOLEAN BoolResult
128 Push an element onto the Boolean Stack
132 Stack - Current stack location.
133 BoolResult - BOOLEAN to push.
141 CopyMem (*Stack
, &BoolResult
, sizeof (BOOLEAN
));
144 if (*Stack
>= mBooleanEvaluationStackEnd
) {
146 // If we run out of stack space make a new one that is 2X as big. Copy
147 // the old data into the new stack and update Stack to point to the old
148 // data in the new stack.
152 (mBooleanEvaluationStackEnd
- mBooleanEvaluationStack
) * sizeof (BOOLEAN
) * 2
160 IN OUT BOOLEAN
**Stack
166 Pop an element from the Boolean stack.
170 Stack - Current stack location
174 Top of the BOOLEAN stack.
181 CopyMem (&ReturnValue
, *Stack
, sizeof (BOOLEAN
));
187 GrowBooleanExpression (
188 IN EFI_INCONSISTENCY_DATA
*InconsistentTags
,
189 OUT VOID
**BooleanExpression
,
190 IN OUT UINTN
*BooleanExpressionLength
193 UINT8
*NewExpression
;
195 NewExpression
= AllocatePool (*BooleanExpressionLength
+ sizeof (EFI_INCONSISTENCY_DATA
));
196 ASSERT (NewExpression
!= NULL
);
198 if (*BooleanExpression
!= NULL
) {
200 // Copy Old buffer to the New buffer
202 CopyMem (NewExpression
, *BooleanExpression
, *BooleanExpressionLength
);
204 CopyMem (&NewExpression
[*BooleanExpressionLength
], InconsistentTags
, sizeof (EFI_INCONSISTENCY_DATA
));
207 // Free The Old buffer
209 FreePool (*BooleanExpression
);
212 // Copy data into new buffer
214 CopyMem (NewExpression
, InconsistentTags
, sizeof (EFI_INCONSISTENCY_DATA
));
217 *BooleanExpressionLength
= *BooleanExpressionLength
+ sizeof (EFI_INCONSISTENCY_DATA
);
218 *BooleanExpression
= (VOID
*) NewExpression
;
224 CreateBooleanExpression (
225 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
229 OUT VOID
**BooleanExpression
,
230 OUT UINTN
*BooleanExpressionLength
243 EFI_INCONSISTENCY_DATA
*InconsistentTags
;
244 EFI_INCONSISTENCY_DATA FakeInconsistentTags
;
246 InconsistentTags
= FileFormTags
->InconsistentTags
;
249 // Did we run into a question that contains the Id we are looking for?
251 for (Count
= 0; InconsistentTags
->Operand
!= 0xFF; Count
++) {
254 // Reserve INVALID_OFFSET_VALUE - 1 for TURE and FALSE, because we need to treat them as well
255 // as ideqid etc. but they have no coresponding id, so we reserve this value.
257 if (InconsistentTags
->QuestionId1
== Id
||
258 InconsistentTags
->QuestionId1
== INVALID_OFFSET_VALUE
- 1) {
260 // If !Complex - means evaluate a single if/endif expression
264 // If the ConsistencyId does not match the expression we are looking for
265 // skip to the next consistency database entry
267 if (InconsistentTags
->ConsistencyId
!= Value
) {
272 // We need to rewind to the beginning of the Inconsistent expression
275 (InconsistentTags
->Operand
!= EFI_IFR_INCONSISTENT_IF_OP
) &&
276 (InconsistentTags
->Operand
!= EFI_IFR_GRAYOUT_IF_OP
) &&
277 (InconsistentTags
->Operand
!= EFI_IFR_SUPPRESS_IF_OP
);
279 InconsistentTags
= InconsistentTags
->Previous
;
282 // Store the consistency check expression, ensure the next for loop starts at the op-code afterwards
284 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
285 InconsistentTags
= InconsistentTags
->Next
;
288 // Keep growing until we hit the End expression op-code or we hit the beginning of another
289 // consistency check like grayout/suppress
292 InconsistentTags
->Operand
!= EFI_IFR_END_IF_OP
&&
293 InconsistentTags
->Operand
!= EFI_IFR_GRAYOUT_IF_OP
&&
294 InconsistentTags
->Operand
!= EFI_IFR_SUPPRESS_IF_OP
;
296 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
297 InconsistentTags
= InconsistentTags
->Next
;
300 // Store the EndExpression Op-code
302 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
306 if (InconsistentTags
->Next
!= NULL
) {
308 // Skip to next entry
310 InconsistentTags
= InconsistentTags
->Next
;
314 FakeInconsistentTags
.Operand
= 0;
317 // Add one last expression which will signify we have definitely hit the end
319 GrowBooleanExpression (&FakeInconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
324 BooleanVariableWorker (
325 IN CHAR16
*VariableName
,
326 IN EFI_VARIABLE_DEFINITION
*VariableDefinition
,
327 IN BOOLEAN
*StackPtr
,
328 IN OUT UINTN
*SizeOfVariable
,
329 IN OUT VOID
**VariableData
344 Status
= gRT
->GetVariable (
346 &VariableDefinition
->Guid
,
352 if (EFI_ERROR (Status
)) {
354 if (Status
== EFI_BUFFER_TOO_SMALL
) {
355 *VariableData
= AllocatePool (*SizeOfVariable
);
356 ASSERT (*VariableData
!= NULL
);
358 Status
= gRT
->GetVariable (
360 &VariableDefinition
->Guid
,
367 if (Status
== EFI_NOT_FOUND
) {
369 // This is a serious flaw, we must have some standard result if a variable
370 // is not found. Our default behavior must either be return a TRUE or FALSE
371 // since there is nothing else we can really do. Therefore, my crystal ball
372 // says I will return a FALSE
374 PushBool (&StackPtr
, FALSE
);
384 IN EFI_INCONSISTENCY_DATA
*Iterator
389 This routine is for the purpose of predicate whether the Ifr is generated by a VfrCompiler greater than or equal to 1.88 or
390 less than 1.88 which is legacy.
393 Iterator - The pointer to inconsistency tags
397 0x2 - If IFR is not legacy
399 0x1 - If IFR is legacy
404 // legacy Ifr cover the states:
406 // Operand Opcode Operand
408 // while Operand means ideqval, TRUE, or other what can be evaluated to True or False,
409 // and Opcode means AND or OR.
411 if (Iterator
->Operand
== EFI_IFR_NOT_OP
||
412 Iterator
->Operand
== 0) {
414 } else if (Iterator
->Operand
== EFI_IFR_EQ_VAR_VAL_OP
||
415 Iterator
->Operand
== EFI_IFR_EQ_ID_VAL_OP
||
416 Iterator
->Operand
== EFI_IFR_EQ_ID_ID_OP
||
417 Iterator
->Operand
== EFI_IFR_EQ_ID_LIST_OP
) {
419 if (Iterator
->Operand
== EFI_IFR_AND_OP
||
420 Iterator
->Operand
== EFI_IFR_OR_OP
) {
432 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
434 IN OUT EFI_INCONSISTENCY_DATA
**PIterator
,
435 IN OUT BOOLEAN
**StackPtr
440 PostOrderEvaluate is used for Ifr generated by VfrCompiler greater than or equal to 1.88,
441 which generate Operand Operand Opcode type Ifr.
442 PostOrderEvaluete only evaluate boolean expression part, not suppressif/grayoutif. TRUE,
443 FALSE, >=, >, (, ) are supported.
447 FileFormTags - The pointer to the tags of the form
449 Width - Width of Operand, recognized every iteration
451 PIterator - The pointer to inconsistency tags
453 StackPtr - The pointer to the evaluation stack
457 TRUE - If value is valid
459 FALSE - If value is not valid
469 UINTN SizeOfVariable
;
470 CHAR16 VariableName
[MAXIMUM_VALUE_CHARACTERS
];
472 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
486 if ((*PIterator
)->Operand
== 0) {
490 Width
= (*PIterator
)->Width
;
493 // Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.
495 if ((*PIterator
)->QuestionId1
!= INVALID_OFFSET_VALUE
&&
496 (*PIterator
)->QuestionId1
!= INVALID_OFFSET_VALUE
- 1) {
497 ExtractNvValue (FileFormTags
, (*PIterator
)->VariableNumber
, Width
, (*PIterator
)->QuestionId1
, (VOID
**) &MapBuffer
);
498 ExtractNvValue (FileFormTags
, (*PIterator
)->VariableNumber2
, Width
, (*PIterator
)->QuestionId2
, (VOID
**) &MapBuffer2
);
499 if (MapBuffer
!= NULL
) {
501 MapValue
= *MapBuffer
;
503 MapValue
= (UINT8
) *MapBuffer
;
506 FreePool (MapBuffer
);
509 if (MapBuffer2
!= NULL
) {
511 MapValue2
= *MapBuffer2
;
513 MapValue2
= (UINT8
) *MapBuffer2
;
516 FreePool (MapBuffer2
);
520 switch ((*PIterator
)->Operand
) {
521 case EFI_IFR_EQ_VAR_VAL_OP
:
522 UnicodeValueToString (
525 (UINTN
) (*PIterator
)->QuestionId1
,
526 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
531 ExtractRequestedNvMap (FileFormTags
, (*PIterator
)->VariableNumber
, &VariableDefinition
);
533 Status
= BooleanVariableWorker (
541 if (!EFI_ERROR (Status
)) {
542 if (SizeOfVariable
== 1) {
543 CopyMem (&MapValue
, VariableData
, 1);
545 CopyMem (&MapValue
, VariableData
, 2);
549 // Do operation after knowing the compare operator.
551 MapValue2
= (*PIterator
)->Value
;
553 if ((*PIterator
)->Operand
== EFI_IFR_GT_OP
) {
554 PushValue
= (BOOLEAN
) (MapValue
> MapValue2
);
555 } else if ((*PIterator
)->Operand
== EFI_IFR_GE_OP
) {
556 PushValue
= (BOOLEAN
) (MapValue
>= MapValue2
);
559 PushValue
= (BOOLEAN
) (MapValue
== MapValue2
);
561 PushBool (StackPtr
, PushValue
);
566 case EFI_IFR_EQ_ID_VAL_OP
:
568 // Do operation after knowing the compare operator.
570 MapValue2
= (*PIterator
)->Value
;
572 if ((*PIterator
)->Operand
== EFI_IFR_GT_OP
) {
573 PushValue
= (BOOLEAN
) (MapValue
> MapValue2
);
574 } else if ((*PIterator
)->Operand
== EFI_IFR_GE_OP
) {
575 PushValue
= (BOOLEAN
) (MapValue
>= MapValue2
);
578 PushValue
= (BOOLEAN
) (MapValue
== MapValue2
);
580 PushBool (StackPtr
, PushValue
);
583 case EFI_IFR_EQ_ID_ID_OP
:
585 // Do operation after knowing the compare operator.
588 if ((*PIterator
)->Operand
== EFI_IFR_GT_OP
) {
589 PushValue
= (BOOLEAN
) (MapValue
> MapValue2
);
590 } else if ((*PIterator
)->Operand
== EFI_IFR_GE_OP
) {
591 PushValue
= (BOOLEAN
) (MapValue
>= MapValue2
);
594 PushValue
= (BOOLEAN
) (MapValue
== MapValue2
);
596 PushBool (StackPtr
, PushValue
);
599 case EFI_IFR_EQ_ID_LIST_OP
:
600 for (Index
= 0; Index
< (*PIterator
)->ListLength
; Index
++) {
601 Operator
= (BOOLEAN
) (MapValue
== (*PIterator
)->ValueList
[Index
]);
607 PushBool (StackPtr
, Operator
);
610 case EFI_IFR_TRUE_OP
:
611 PushBool (StackPtr
, TRUE
);
614 case EFI_IFR_FALSE_OP
:
615 PushBool (StackPtr
, FALSE
);
619 Operator
= PopBool (StackPtr
);
620 Operator2
= PopBool (StackPtr
);
621 PushBool (StackPtr
, (BOOLEAN
) (Operator
&& Operator2
));
624 Operator
= PopBool (StackPtr
);
625 Operator2
= PopBool (StackPtr
);
626 PushBool (StackPtr
, (BOOLEAN
) (Operator
|| Operator2
));
629 Operator
= PopBool (StackPtr
);
630 PushBool (StackPtr
, (BOOLEAN
) (!Operator
));
633 case EFI_IFR_SUPPRESS_IF_OP
:
634 case EFI_IFR_GRAYOUT_IF_OP
:
635 case EFI_IFR_INCONSISTENT_IF_OP
:
638 // Return to the previous tag if runs out of boolean expression.
652 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
664 TRUE - If value is valid
666 FALSE - If value is not valid
671 EFI_INCONSISTENCY_DATA
*Iterator
;
675 VOID
*BooleanExpression
;
676 UINTN BooleanExpressionLength
;
680 BOOLEAN ArtificialEnd
;
685 UINTN SizeOfVariable
;
686 CHAR16 VariableName
[MAXIMUM_VALUE_CHARACTERS
];
691 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
692 BOOLEAN CosmeticConsistency
;
696 BooleanExpressionLength
= 0;
697 BooleanExpression
= NULL
;
699 ArtificialEnd
= FALSE
;
700 CosmeticConsistency
= TRUE
;
704 if (Tag
->StorageWidth
== 1) {
709 CreateBooleanExpression (FileFormTags
, Value
, Id
, Complex
, &BooleanExpression
, &BooleanExpressionLength
);
711 if (mBooleanEvaluationStack
== 0) {
712 InitializeBooleanEvaluator ();
715 if (BooleanExpression
== NULL
) {
719 StackPtr
= mBooleanEvaluationStack
;
720 Iterator
= BooleanExpression
;
731 if (Iterator
->Operand
== 0) {
736 // Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.
738 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
&&
739 Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
-1) {
740 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
741 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
742 if (MapBuffer
!= NULL
) {
744 MapValue
= *MapBuffer
;
746 MapValue
= (UINT8
) *MapBuffer
;
749 FreePool (MapBuffer
);
752 if (MapBuffer2
!= NULL
) {
754 MapValue2
= *MapBuffer2
;
756 MapValue2
= (UINT8
) *MapBuffer2
;
759 FreePool (MapBuffer2
);
763 switch (Iterator
->Operand
) {
764 case EFI_IFR_SUPPRESS_IF_OP
:
766 // Must have hit a suppress followed by a grayout or vice-versa
769 ArtificialEnd
= FALSE
;
770 Operator
= PopBool (&StackPtr
);
772 Tag
->Suppress
= TRUE
;
778 ArtificialEnd
= TRUE
;
779 *PopUp
= Iterator
->Popup
;
782 case EFI_IFR_GRAYOUT_IF_OP
:
784 // Must have hit a suppress followed by a grayout or vice-versa
787 ArtificialEnd
= FALSE
;
788 Operator
= PopBool (&StackPtr
);
796 ArtificialEnd
= TRUE
;
797 *PopUp
= Iterator
->Popup
;
800 case EFI_IFR_INCONSISTENT_IF_OP
:
801 CosmeticConsistency
= FALSE
;
802 *PopUp
= Iterator
->Popup
;
806 // In the case of external variable values, we must read the variable which is
807 // named by the human readable version of the OpCode->VariableId and the guid of the formset
809 case EFI_IFR_EQ_VAR_VAL_OP
:
811 // To check whether Ifr is legacy. Once every boolean expression.
814 IsLegacy
= PredicateIfrType (Iterator
);
816 if (IsLegacy
== 0x2) {
817 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
821 UnicodeValueToString (
824 (UINTN
) Iterator
->QuestionId1
,
825 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
830 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
832 Status
= BooleanVariableWorker (
840 if (!EFI_ERROR (Status
)) {
841 if (SizeOfVariable
== 1) {
842 CopyMem (&MapValue
, VariableData
, 1);
844 CopyMem (&MapValue
, VariableData
, 2);
847 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
852 case EFI_IFR_EQ_ID_VAL_OP
:
854 // To check whether Ifr is legacy. Once every boolean expression.
857 IsLegacy
= PredicateIfrType (Iterator
);
859 if (IsLegacy
== 0x2) {
860 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
864 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
867 case EFI_IFR_EQ_ID_ID_OP
:
869 // To check whether Ifr is legacy. Once every boolean expression.
872 IsLegacy
= PredicateIfrType (Iterator
);
874 if (IsLegacy
== 0x2) {
875 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
879 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== MapValue2
));
882 case EFI_IFR_EQ_ID_LIST_OP
:
884 // To check whether Ifr is legacy. Once every boolean expression.
887 IsLegacy
= PredicateIfrType (Iterator
);
889 if (IsLegacy
== 0x2) {
890 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
894 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
895 Operator
= (BOOLEAN
) (MapValue
== Iterator
->ValueList
[Index
]);
901 PushBool (&StackPtr
, Operator
);
906 if (Iterator
->Operand
== EFI_IFR_NOT_OP
) {
911 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
912 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
913 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
914 if (MapBuffer
!= NULL
) {
916 MapValue
= *MapBuffer
;
918 MapValue
= (UINT8
) *MapBuffer
;
921 FreePool (MapBuffer
);
924 if (MapBuffer2
!= NULL
) {
926 MapValue2
= *MapBuffer2
;
928 MapValue2
= (UINT8
) *MapBuffer2
;
931 FreePool (MapBuffer2
);
935 switch (Iterator
->Operand
) {
936 case EFI_IFR_EQ_ID_VAL_OP
:
938 // If Not - flip the results
941 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->Value
);
943 Operator
= (BOOLEAN
) (MapValue
== Iterator
->Value
);
946 PushBool (&StackPtr
, Operator
);
950 // In the case of external variable values, we must read the variable which is
951 // named by the human readable version of the OpCode->VariableId and the guid of the formset
953 case EFI_IFR_EQ_VAR_VAL_OP
:
954 UnicodeValueToString (
957 (UINTN
) Iterator
->QuestionId1
,
958 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
963 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
965 Status
= BooleanVariableWorker (
973 if (!EFI_ERROR (Status
)) {
974 if (SizeOfVariable
== 1) {
975 CopyMem (&MapValue
, VariableData
, 1);
977 CopyMem (&MapValue
, VariableData
, 2);
980 // If Not - flip the results
983 PushBool (&StackPtr
, (BOOLEAN
)!(MapValue
== Iterator
->Value
));
985 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
990 case EFI_IFR_EQ_ID_ID_OP
:
992 // If Not - flip the results
995 Operator
= (BOOLEAN
)!(MapValue
== MapValue2
);
997 Operator
= (BOOLEAN
) (MapValue
== MapValue2
);
1000 PushBool (&StackPtr
, Operator
);
1003 case EFI_IFR_EQ_ID_LIST_OP
:
1004 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
1006 // If Not - flip the results
1009 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->ValueList
[Index
]);
1011 Operator
= (BOOLEAN
) (MapValue
== Iterator
->ValueList
[Index
]);
1014 // If We are trying to make sure that MapValue != Item[x], keep looking through
1015 // the list to make sure we don't equal any other items
1017 if (Operator
&& NotOperator
) {
1021 // If MapValue == Item, then we have succeeded (first found is good enough)
1028 PushBool (&StackPtr
, Operator
);
1035 Operator
= PopBool (&StackPtr
);
1036 Operator2
= PopBool (&StackPtr
);
1037 PushBool (&StackPtr
, (BOOLEAN
) (Operator
&& Operator2
));
1042 if (Iterator
->Operand
== EFI_IFR_NOT_OP
) {
1047 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
1048 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
1049 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
1050 if (MapBuffer
!= NULL
) {
1052 MapValue
= *MapBuffer
;
1054 MapValue
= (UINT8
) *MapBuffer
;
1057 FreePool (MapBuffer
);
1060 if (MapBuffer2
!= NULL
) {
1062 MapValue2
= *MapBuffer2
;
1064 MapValue2
= (UINT8
) *MapBuffer2
;
1067 FreePool (MapBuffer2
);
1071 switch (Iterator
->Operand
) {
1072 case EFI_IFR_EQ_ID_VAL_OP
:
1074 // If Not - flip the results
1077 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->Value
);
1079 Operator
= (BOOLEAN
) (MapValue
== Iterator
->Value
);
1082 PushBool (&StackPtr
, Operator
);
1086 // In the case of external variable values, we must read the variable which is
1087 // named by the human readable version of the OpCode->VariableId and the guid of the formset
1089 case EFI_IFR_EQ_VAR_VAL_OP
:
1090 UnicodeValueToString (
1093 (UINTN
) Iterator
->QuestionId1
,
1094 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
1099 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
1101 Status
= BooleanVariableWorker (
1109 if (!EFI_ERROR (Status
)) {
1110 if (SizeOfVariable
== 1) {
1111 CopyMem (&MapValue
, VariableData
, 1);
1113 CopyMem (&MapValue
, VariableData
, 2);
1116 // If Not - flip the results
1119 PushBool (&StackPtr
, (BOOLEAN
)!(MapValue
== Iterator
->Value
));
1121 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
1126 case EFI_IFR_EQ_ID_ID_OP
:
1128 // If Not - flip the results
1131 Operator
= (BOOLEAN
)!(MapValue
== MapValue2
);
1133 Operator
= (BOOLEAN
) (MapValue
== MapValue2
);
1136 PushBool (&StackPtr
, Operator
);
1139 case EFI_IFR_EQ_ID_LIST_OP
:
1140 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
1142 // If Not - flip the results
1145 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->ValueList
[Index
]);
1147 Operator
= (BOOLEAN
) (MapValue
== Iterator
->ValueList
[Index
]);
1150 // If We are trying to make sure that MapValue != Item[x], keep looking through
1151 // the list to make sure we don't equal any other items
1153 if (Operator
&& NotOperator
) {
1157 // If MapValue == Item, then we have succeeded (first found is good enough)
1164 PushBool (&StackPtr
, Operator
);
1171 Operator
= PopBool (&StackPtr
);
1172 Operator2
= PopBool (&StackPtr
);
1173 PushBool (&StackPtr
, (BOOLEAN
) (Operator
|| Operator2
));
1176 case EFI_IFR_NOT_OP
:
1178 // To check whether Ifr is legacy. Once every boolean expression.
1180 if (IsLegacy
== 0) {
1181 IsLegacy
= PredicateIfrType (Iterator
);
1183 if (IsLegacy
== 0x2) {
1184 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
1189 // I don't need to set the NotOperator (I know that I have to NOT this in this case
1193 if (Iterator
->Operand
== EFI_IFR_OR_OP
) {
1198 if (Iterator
->Operand
== EFI_IFR_AND_OP
) {
1203 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
1204 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
1205 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
1206 if (MapBuffer
!= NULL
) {
1208 MapValue
= *MapBuffer
;
1210 MapValue
= (UINT8
) *MapBuffer
;
1213 FreePool (MapBuffer
);
1216 if (MapBuffer2
!= NULL
) {
1218 MapValue2
= *MapBuffer2
;
1220 MapValue2
= (UINT8
) *MapBuffer2
;
1223 FreePool (MapBuffer2
);
1227 switch (Iterator
->Operand
) {
1228 case EFI_IFR_EQ_ID_VAL_OP
:
1229 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->Value
);
1230 PushBool (&StackPtr
, Operator
);
1234 // In the case of external variable values, we must read the variable which is
1235 // named by the human readable version of the OpCode->VariableId and the guid of the formset
1237 case EFI_IFR_EQ_VAR_VAL_OP
:
1238 UnicodeValueToString (
1241 (UINTN
) Iterator
->QuestionId1
,
1242 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
1247 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
1249 Status
= BooleanVariableWorker (
1257 if (!EFI_ERROR (Status
)) {
1258 if (SizeOfVariable
== 1) {
1259 CopyMem (&MapValue
, VariableData
, 1);
1261 CopyMem (&MapValue
, VariableData
, 2);
1264 PushBool (&StackPtr
, (BOOLEAN
)!(MapValue
== Iterator
->Value
));
1268 case EFI_IFR_EQ_ID_ID_OP
:
1269 Operator
= (BOOLEAN
)!(MapValue
== MapValue2
);
1270 PushBool (&StackPtr
, Operator
);
1273 case EFI_IFR_EQ_ID_LIST_OP
:
1274 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
1275 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->ValueList
[Index
]);
1281 PushBool (&StackPtr
, Operator
);
1288 Operator
= PopBool (&StackPtr
);
1289 Operator2
= PopBool (&StackPtr
);
1292 PushBool (&StackPtr
, (BOOLEAN
) (Operator
|| Operator2
));
1296 PushBool (&StackPtr
, (BOOLEAN
) (Operator
&& Operator2
));
1299 if (!OrOperator
&& !AndOperator
) {
1300 PushBool (&StackPtr
, Operator
);
1304 case EFI_IFR_TRUE_OP
:
1306 // To check whether Ifr is legacy. Once every boolean expression.
1308 if (IsLegacy
== 0) {
1309 IsLegacy
= PredicateIfrType (Iterator
);
1311 if (IsLegacy
== 0x2) {
1312 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
1317 case EFI_IFR_FALSE_OP
:
1319 // To check whether Ifr is legacy. Once every boolean expression.
1321 if (IsLegacy
== 0) {
1322 IsLegacy
= PredicateIfrType (Iterator
);
1324 if (IsLegacy
== 0x2) {
1325 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
1330 case EFI_IFR_END_IF_OP
:
1331 Operator
= PopBool (&StackPtr
);
1333 // If there is an error, return, otherwise keep looking - there might
1334 // be another test that causes an error
1337 if (Complex
&& CosmeticConsistency
) {
1344 // If not doing a global consistency check, the endif is the REAL terminator of this operation
1345 // This is used for grayout/suppress operations. InconsistentIf is a global operation so the EndIf is
1346 // not the end-all be-all of terminators.
1356 // Must have hit a non-consistency related op-code after a suppress/grayout
1358 if (ArtificialEnd
) {
1359 ArtificialEnd
= FALSE
;
1360 Operator
= PopBool (&StackPtr
);