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
28 // Global stack used to evaluate boolean expresions
30 BOOLEAN
*mBooleanEvaluationStack
= (BOOLEAN
) 0;
31 BOOLEAN
*mBooleanEvaluationStackEnd
= (BOOLEAN
) 0;
36 IN OUT BOOLEAN
**Stack
,
37 IN UINTN StackSizeInBoolean
43 Grow size of the boolean stack
47 Stack - Old stack on the way in and new stack on the way out
49 StackSizeInBoolean - New size of the stack
59 NewStack
= AllocatePool (StackSizeInBoolean
* sizeof (BOOLEAN
));
60 ASSERT (NewStack
!= NULL
);
64 // Copy to Old Stack to the New Stack
68 mBooleanEvaluationStack
,
69 (mBooleanEvaluationStackEnd
- mBooleanEvaluationStack
) * sizeof (BOOLEAN
)
73 // Make the Stack pointer point to the old data in the new stack
75 *Stack
= NewStack
+ (*Stack
- mBooleanEvaluationStack
);
80 FreePool (mBooleanEvaluationStack
);
83 mBooleanEvaluationStack
= NewStack
;
84 mBooleanEvaluationStackEnd
= NewStack
+ StackSizeInBoolean
;
89 InitializeBooleanEvaluator (
96 Allocate a global stack for boolean processing.
111 GrowBooleanStack (&NullStack
, 0x1000);
117 IN OUT BOOLEAN
**Stack
,
118 IN BOOLEAN BoolResult
124 Push an element onto the Boolean Stack
128 Stack - Current stack location.
129 BoolResult - BOOLEAN to push.
137 CopyMem (*Stack
, &BoolResult
, sizeof (BOOLEAN
));
140 if (*Stack
>= mBooleanEvaluationStackEnd
) {
142 // If we run out of stack space make a new one that is 2X as big. Copy
143 // the old data into the new stack and update Stack to point to the old
144 // data in the new stack.
148 (mBooleanEvaluationStackEnd
- mBooleanEvaluationStack
) * sizeof (BOOLEAN
) * 2
156 IN OUT BOOLEAN
**Stack
162 Pop an element from the Boolean stack.
166 Stack - Current stack location
170 Top of the BOOLEAN stack.
177 CopyMem (&ReturnValue
, *Stack
, sizeof (BOOLEAN
));
183 GrowBooleanExpression (
184 IN EFI_INCONSISTENCY_DATA
*InconsistentTags
,
185 OUT VOID
**BooleanExpression
,
186 IN OUT UINTN
*BooleanExpressionLength
189 UINT8
*NewExpression
;
191 NewExpression
= AllocatePool (*BooleanExpressionLength
+ sizeof (EFI_INCONSISTENCY_DATA
));
192 ASSERT (NewExpression
!= NULL
);
194 if (*BooleanExpression
!= NULL
) {
196 // Copy Old buffer to the New buffer
198 CopyMem (NewExpression
, *BooleanExpression
, *BooleanExpressionLength
);
200 CopyMem (&NewExpression
[*BooleanExpressionLength
], InconsistentTags
, sizeof (EFI_INCONSISTENCY_DATA
));
203 // Free The Old buffer
205 FreePool (*BooleanExpression
);
208 // Copy data into new buffer
210 CopyMem (NewExpression
, InconsistentTags
, sizeof (EFI_INCONSISTENCY_DATA
));
213 *BooleanExpressionLength
= *BooleanExpressionLength
+ sizeof (EFI_INCONSISTENCY_DATA
);
214 *BooleanExpression
= (VOID
*) NewExpression
;
220 CreateBooleanExpression (
221 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
225 OUT VOID
**BooleanExpression
,
226 OUT UINTN
*BooleanExpressionLength
239 EFI_INCONSISTENCY_DATA
*InconsistentTags
;
240 EFI_INCONSISTENCY_DATA FakeInconsistentTags
;
242 InconsistentTags
= FileFormTags
->InconsistentTags
;
245 // Did we run into a question that contains the Id we are looking for?
247 for (Count
= 0; InconsistentTags
->Operand
!= 0xFF; Count
++) {
250 // Reserve INVALID_OFFSET_VALUE - 1 for TURE and FALSE, because we need to treat them as well
251 // as ideqid etc. but they have no coresponding id, so we reserve this value.
253 if (InconsistentTags
->QuestionId1
== Id
||
254 InconsistentTags
->QuestionId1
== INVALID_OFFSET_VALUE
- 1) {
256 // If !Complex - means evaluate a single if/endif expression
260 // If the ConsistencyId does not match the expression we are looking for
261 // skip to the next consistency database entry
263 if (InconsistentTags
->ConsistencyId
!= Value
) {
268 // We need to rewind to the beginning of the Inconsistent expression
271 (InconsistentTags
->Operand
!= EFI_IFR_INCONSISTENT_IF_OP
) &&
272 (InconsistentTags
->Operand
!= EFI_IFR_GRAYOUT_IF_OP
) &&
273 (InconsistentTags
->Operand
!= EFI_IFR_SUPPRESS_IF_OP
);
275 InconsistentTags
= InconsistentTags
->Previous
;
278 // Store the consistency check expression, ensure the next for loop starts at the op-code afterwards
280 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
281 InconsistentTags
= InconsistentTags
->Next
;
284 // Keep growing until we hit the End expression op-code or we hit the beginning of another
285 // consistency check like grayout/suppress
288 InconsistentTags
->Operand
!= EFI_IFR_END_IF_OP
&&
289 InconsistentTags
->Operand
!= EFI_IFR_GRAYOUT_IF_OP
&&
290 InconsistentTags
->Operand
!= EFI_IFR_SUPPRESS_IF_OP
;
292 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
293 InconsistentTags
= InconsistentTags
->Next
;
296 // Store the EndExpression Op-code
298 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
302 if (InconsistentTags
->Next
!= NULL
) {
304 // Skip to next entry
306 InconsistentTags
= InconsistentTags
->Next
;
310 FakeInconsistentTags
.Operand
= 0;
313 // Add one last expression which will signify we have definitely hit the end
315 GrowBooleanExpression (&FakeInconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
320 BooleanVariableWorker (
321 IN CHAR16
*VariableName
,
322 IN EFI_VARIABLE_DEFINITION
*VariableDefinition
,
323 IN BOOLEAN
*StackPtr
,
324 IN OUT UINTN
*SizeOfVariable
,
325 IN OUT VOID
**VariableData
340 Status
= gRT
->GetVariable (
342 &VariableDefinition
->Guid
,
348 if (EFI_ERROR (Status
)) {
350 if (Status
== EFI_BUFFER_TOO_SMALL
) {
351 *VariableData
= AllocatePool (*SizeOfVariable
);
352 ASSERT (*VariableData
!= NULL
);
354 Status
= gRT
->GetVariable (
356 &VariableDefinition
->Guid
,
363 if (Status
== EFI_NOT_FOUND
) {
365 // This is a serious flaw, we must have some standard result if a variable
366 // is not found. Our default behavior must either be return a TRUE or FALSE
367 // since there is nothing else we can really do. Therefore, my crystal ball
368 // says I will return a FALSE
370 PushBool (&StackPtr
, FALSE
);
380 IN EFI_INCONSISTENCY_DATA
*Iterator
385 This routine is for the purpose of predicate whether the Ifr is generated by a VfrCompiler greater than or equal to 1.88 or
386 less than 1.88 which is legacy.
389 Iterator - The pointer to inconsistency tags
393 0x2 - If IFR is not legacy
395 0x1 - If IFR is legacy
400 // legacy Ifr cover the states:
402 // Operand Opcode Operand
404 // while Operand means ideqval, TRUE, or other what can be evaluated to True or False,
405 // and Opcode means AND or OR.
407 if (Iterator
->Operand
== EFI_IFR_NOT_OP
||
408 Iterator
->Operand
== 0) {
410 } else if (Iterator
->Operand
== EFI_IFR_EQ_VAR_VAL_OP
||
411 Iterator
->Operand
== EFI_IFR_EQ_ID_VAL_OP
||
412 Iterator
->Operand
== EFI_IFR_EQ_ID_ID_OP
||
413 Iterator
->Operand
== EFI_IFR_EQ_ID_LIST_OP
) {
415 if (Iterator
->Operand
== EFI_IFR_AND_OP
||
416 Iterator
->Operand
== EFI_IFR_OR_OP
) {
428 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
430 IN OUT EFI_INCONSISTENCY_DATA
**PIterator
,
431 IN OUT BOOLEAN
**StackPtr
436 PostOrderEvaluate is used for Ifr generated by VfrCompiler greater than or equal to 1.88,
437 which generate Operand Operand Opcode type Ifr.
438 PostOrderEvaluete only evaluate boolean expression part, not suppressif/grayoutif. TRUE,
439 FALSE, >=, >, (, ) are supported.
443 FileFormTags - The pointer to the tags of the form
445 Width - Width of Operand, recognized every iteration
447 PIterator - The pointer to inconsistency tags
449 StackPtr - The pointer to the evaluation stack
453 TRUE - If value is valid
455 FALSE - If value is not valid
465 UINTN SizeOfVariable
;
466 CHAR16 VariableName
[MAXIMUM_VALUE_CHARACTERS
];
468 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
482 if ((*PIterator
)->Operand
== 0) {
486 Width
= (*PIterator
)->Width
;
489 // Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.
491 if ((*PIterator
)->QuestionId1
!= INVALID_OFFSET_VALUE
&&
492 (*PIterator
)->QuestionId1
!= INVALID_OFFSET_VALUE
- 1) {
493 ExtractNvValue (FileFormTags
, (*PIterator
)->VariableNumber
, Width
, (*PIterator
)->QuestionId1
, (VOID
**) &MapBuffer
);
494 ExtractNvValue (FileFormTags
, (*PIterator
)->VariableNumber2
, Width
, (*PIterator
)->QuestionId2
, (VOID
**) &MapBuffer2
);
495 if (MapBuffer
!= NULL
) {
497 MapValue
= *MapBuffer
;
499 MapValue
= (UINT8
) *MapBuffer
;
502 FreePool (MapBuffer
);
505 if (MapBuffer2
!= NULL
) {
507 MapValue2
= *MapBuffer2
;
509 MapValue2
= (UINT8
) *MapBuffer2
;
512 FreePool (MapBuffer2
);
516 switch ((*PIterator
)->Operand
) {
517 case EFI_IFR_EQ_VAR_VAL_OP
:
518 UnicodeValueToString (
521 (UINTN
) (*PIterator
)->QuestionId1
,
522 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
527 ExtractRequestedNvMap (FileFormTags
, (*PIterator
)->VariableNumber
, &VariableDefinition
);
529 Status
= BooleanVariableWorker (
537 if (!EFI_ERROR (Status
)) {
538 if (SizeOfVariable
== 1) {
539 CopyMem (&MapValue
, VariableData
, 1);
541 CopyMem (&MapValue
, VariableData
, 2);
545 // Do operation after knowing the compare operator.
547 MapValue2
= (*PIterator
)->Value
;
549 if ((*PIterator
)->Operand
== EFI_IFR_GT_OP
) {
550 PushValue
= (BOOLEAN
) (MapValue
> MapValue2
);
551 } else if ((*PIterator
)->Operand
== EFI_IFR_GE_OP
) {
552 PushValue
= (BOOLEAN
) (MapValue
>= MapValue2
);
555 PushValue
= (BOOLEAN
) (MapValue
== MapValue2
);
557 PushBool (StackPtr
, PushValue
);
562 case EFI_IFR_EQ_ID_VAL_OP
:
564 // Do operation after knowing the compare operator.
566 MapValue2
= (*PIterator
)->Value
;
568 if ((*PIterator
)->Operand
== EFI_IFR_GT_OP
) {
569 PushValue
= (BOOLEAN
) (MapValue
> MapValue2
);
570 } else if ((*PIterator
)->Operand
== EFI_IFR_GE_OP
) {
571 PushValue
= (BOOLEAN
) (MapValue
>= MapValue2
);
574 PushValue
= (BOOLEAN
) (MapValue
== MapValue2
);
576 PushBool (StackPtr
, PushValue
);
579 case EFI_IFR_EQ_ID_ID_OP
:
581 // Do operation after knowing the compare operator.
584 if ((*PIterator
)->Operand
== EFI_IFR_GT_OP
) {
585 PushValue
= (BOOLEAN
) (MapValue
> MapValue2
);
586 } else if ((*PIterator
)->Operand
== EFI_IFR_GE_OP
) {
587 PushValue
= (BOOLEAN
) (MapValue
>= MapValue2
);
590 PushValue
= (BOOLEAN
) (MapValue
== MapValue2
);
592 PushBool (StackPtr
, PushValue
);
595 case EFI_IFR_EQ_ID_LIST_OP
:
596 for (Index
= 0; Index
< (*PIterator
)->ListLength
; Index
++) {
597 Operator
= (BOOLEAN
) (MapValue
== (*PIterator
)->ValueList
[Index
]);
603 PushBool (StackPtr
, Operator
);
606 case EFI_IFR_TRUE_OP
:
607 PushBool (StackPtr
, TRUE
);
610 case EFI_IFR_FALSE_OP
:
611 PushBool (StackPtr
, FALSE
);
615 Operator
= PopBool (StackPtr
);
616 Operator2
= PopBool (StackPtr
);
617 PushBool (StackPtr
, (BOOLEAN
) (Operator
&& Operator2
));
620 Operator
= PopBool (StackPtr
);
621 Operator2
= PopBool (StackPtr
);
622 PushBool (StackPtr
, (BOOLEAN
) (Operator
|| Operator2
));
625 Operator
= PopBool (StackPtr
);
626 PushBool (StackPtr
, (BOOLEAN
) (!Operator
));
629 case EFI_IFR_SUPPRESS_IF_OP
:
630 case EFI_IFR_GRAYOUT_IF_OP
:
631 case EFI_IFR_INCONSISTENT_IF_OP
:
634 // Return to the previous tag if runs out of boolean expression.
648 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
660 TRUE - If value is valid
662 FALSE - If value is not valid
667 EFI_INCONSISTENCY_DATA
*Iterator
;
671 VOID
*BooleanExpression
;
672 UINTN BooleanExpressionLength
;
676 BOOLEAN ArtificialEnd
;
681 UINTN SizeOfVariable
;
682 CHAR16 VariableName
[MAXIMUM_VALUE_CHARACTERS
];
687 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
688 BOOLEAN CosmeticConsistency
;
692 BooleanExpressionLength
= 0;
693 BooleanExpression
= NULL
;
695 ArtificialEnd
= FALSE
;
696 CosmeticConsistency
= TRUE
;
700 if (Tag
->StorageWidth
== 1) {
705 CreateBooleanExpression (FileFormTags
, Value
, Id
, Complex
, &BooleanExpression
, &BooleanExpressionLength
);
707 if (mBooleanEvaluationStack
== 0) {
708 InitializeBooleanEvaluator ();
711 if (BooleanExpression
== NULL
) {
715 StackPtr
= mBooleanEvaluationStack
;
716 Iterator
= BooleanExpression
;
727 if (Iterator
->Operand
== 0) {
732 // Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.
734 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
&&
735 Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
-1) {
736 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
737 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
738 if (MapBuffer
!= NULL
) {
740 MapValue
= *MapBuffer
;
742 MapValue
= (UINT8
) *MapBuffer
;
745 FreePool (MapBuffer
);
748 if (MapBuffer2
!= NULL
) {
750 MapValue2
= *MapBuffer2
;
752 MapValue2
= (UINT8
) *MapBuffer2
;
755 FreePool (MapBuffer2
);
759 switch (Iterator
->Operand
) {
760 case EFI_IFR_SUPPRESS_IF_OP
:
762 // Must have hit a suppress followed by a grayout or vice-versa
765 ArtificialEnd
= FALSE
;
766 Operator
= PopBool (&StackPtr
);
768 Tag
->Suppress
= TRUE
;
774 ArtificialEnd
= TRUE
;
775 *PopUp
= Iterator
->Popup
;
778 case EFI_IFR_GRAYOUT_IF_OP
:
780 // Must have hit a suppress followed by a grayout or vice-versa
783 ArtificialEnd
= FALSE
;
784 Operator
= PopBool (&StackPtr
);
792 ArtificialEnd
= TRUE
;
793 *PopUp
= Iterator
->Popup
;
796 case EFI_IFR_INCONSISTENT_IF_OP
:
797 CosmeticConsistency
= FALSE
;
798 *PopUp
= Iterator
->Popup
;
802 // In the case of external variable values, we must read the variable which is
803 // named by the human readable version of the OpCode->VariableId and the guid of the formset
805 case EFI_IFR_EQ_VAR_VAL_OP
:
807 // To check whether Ifr is legacy. Once every boolean expression.
810 IsLegacy
= PredicateIfrType (Iterator
);
812 if (IsLegacy
== 0x2) {
813 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
817 UnicodeValueToString (
820 (UINTN
) Iterator
->QuestionId1
,
821 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
826 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
828 Status
= BooleanVariableWorker (
836 if (!EFI_ERROR (Status
)) {
837 if (SizeOfVariable
== 1) {
838 CopyMem (&MapValue
, VariableData
, 1);
840 CopyMem (&MapValue
, VariableData
, 2);
843 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
848 case EFI_IFR_EQ_ID_VAL_OP
:
850 // To check whether Ifr is legacy. Once every boolean expression.
853 IsLegacy
= PredicateIfrType (Iterator
);
855 if (IsLegacy
== 0x2) {
856 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
860 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
863 case EFI_IFR_EQ_ID_ID_OP
:
865 // To check whether Ifr is legacy. Once every boolean expression.
868 IsLegacy
= PredicateIfrType (Iterator
);
870 if (IsLegacy
== 0x2) {
871 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
875 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== MapValue2
));
878 case EFI_IFR_EQ_ID_LIST_OP
:
880 // To check whether Ifr is legacy. Once every boolean expression.
883 IsLegacy
= PredicateIfrType (Iterator
);
885 if (IsLegacy
== 0x2) {
886 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
890 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
891 Operator
= (BOOLEAN
) (MapValue
== Iterator
->ValueList
[Index
]);
897 PushBool (&StackPtr
, Operator
);
902 if (Iterator
->Operand
== EFI_IFR_NOT_OP
) {
907 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
908 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
909 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
910 if (MapBuffer
!= NULL
) {
912 MapValue
= *MapBuffer
;
914 MapValue
= (UINT8
) *MapBuffer
;
917 FreePool (MapBuffer
);
920 if (MapBuffer2
!= NULL
) {
922 MapValue2
= *MapBuffer2
;
924 MapValue2
= (UINT8
) *MapBuffer2
;
927 FreePool (MapBuffer2
);
931 switch (Iterator
->Operand
) {
932 case EFI_IFR_EQ_ID_VAL_OP
:
934 // If Not - flip the results
937 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->Value
);
939 Operator
= (BOOLEAN
) (MapValue
== Iterator
->Value
);
942 PushBool (&StackPtr
, Operator
);
946 // In the case of external variable values, we must read the variable which is
947 // named by the human readable version of the OpCode->VariableId and the guid of the formset
949 case EFI_IFR_EQ_VAR_VAL_OP
:
950 UnicodeValueToString (
953 (UINTN
) Iterator
->QuestionId1
,
954 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
959 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
961 Status
= BooleanVariableWorker (
969 if (!EFI_ERROR (Status
)) {
970 if (SizeOfVariable
== 1) {
971 CopyMem (&MapValue
, VariableData
, 1);
973 CopyMem (&MapValue
, VariableData
, 2);
976 // If Not - flip the results
979 PushBool (&StackPtr
, (BOOLEAN
)!(MapValue
== Iterator
->Value
));
981 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
986 case EFI_IFR_EQ_ID_ID_OP
:
988 // If Not - flip the results
991 Operator
= (BOOLEAN
)!(MapValue
== MapValue2
);
993 Operator
= (BOOLEAN
) (MapValue
== MapValue2
);
996 PushBool (&StackPtr
, Operator
);
999 case EFI_IFR_EQ_ID_LIST_OP
:
1000 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
1002 // If Not - flip the results
1005 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->ValueList
[Index
]);
1007 Operator
= (BOOLEAN
) (MapValue
== Iterator
->ValueList
[Index
]);
1010 // If We are trying to make sure that MapValue != Item[x], keep looking through
1011 // the list to make sure we don't equal any other items
1013 if (Operator
&& NotOperator
) {
1017 // If MapValue == Item, then we have succeeded (first found is good enough)
1024 PushBool (&StackPtr
, Operator
);
1031 Operator
= PopBool (&StackPtr
);
1032 Operator2
= PopBool (&StackPtr
);
1033 PushBool (&StackPtr
, (BOOLEAN
) (Operator
&& Operator2
));
1038 if (Iterator
->Operand
== EFI_IFR_NOT_OP
) {
1043 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
1044 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
1045 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
1046 if (MapBuffer
!= NULL
) {
1048 MapValue
= *MapBuffer
;
1050 MapValue
= (UINT8
) *MapBuffer
;
1053 FreePool (MapBuffer
);
1056 if (MapBuffer2
!= NULL
) {
1058 MapValue2
= *MapBuffer2
;
1060 MapValue2
= (UINT8
) *MapBuffer2
;
1063 FreePool (MapBuffer2
);
1067 switch (Iterator
->Operand
) {
1068 case EFI_IFR_EQ_ID_VAL_OP
:
1070 // If Not - flip the results
1073 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->Value
);
1075 Operator
= (BOOLEAN
) (MapValue
== Iterator
->Value
);
1078 PushBool (&StackPtr
, Operator
);
1082 // In the case of external variable values, we must read the variable which is
1083 // named by the human readable version of the OpCode->VariableId and the guid of the formset
1085 case EFI_IFR_EQ_VAR_VAL_OP
:
1086 UnicodeValueToString (
1089 (UINTN
) Iterator
->QuestionId1
,
1090 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
1095 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
1097 Status
= BooleanVariableWorker (
1105 if (!EFI_ERROR (Status
)) {
1106 if (SizeOfVariable
== 1) {
1107 CopyMem (&MapValue
, VariableData
, 1);
1109 CopyMem (&MapValue
, VariableData
, 2);
1112 // If Not - flip the results
1115 PushBool (&StackPtr
, (BOOLEAN
)!(MapValue
== Iterator
->Value
));
1117 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
1122 case EFI_IFR_EQ_ID_ID_OP
:
1124 // If Not - flip the results
1127 Operator
= (BOOLEAN
)!(MapValue
== MapValue2
);
1129 Operator
= (BOOLEAN
) (MapValue
== MapValue2
);
1132 PushBool (&StackPtr
, Operator
);
1135 case EFI_IFR_EQ_ID_LIST_OP
:
1136 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
1138 // If Not - flip the results
1141 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->ValueList
[Index
]);
1143 Operator
= (BOOLEAN
) (MapValue
== Iterator
->ValueList
[Index
]);
1146 // If We are trying to make sure that MapValue != Item[x], keep looking through
1147 // the list to make sure we don't equal any other items
1149 if (Operator
&& NotOperator
) {
1153 // If MapValue == Item, then we have succeeded (first found is good enough)
1160 PushBool (&StackPtr
, Operator
);
1167 Operator
= PopBool (&StackPtr
);
1168 Operator2
= PopBool (&StackPtr
);
1169 PushBool (&StackPtr
, (BOOLEAN
) (Operator
|| Operator2
));
1172 case EFI_IFR_NOT_OP
:
1174 // To check whether Ifr is legacy. Once every boolean expression.
1176 if (IsLegacy
== 0) {
1177 IsLegacy
= PredicateIfrType (Iterator
);
1179 if (IsLegacy
== 0x2) {
1180 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
1185 // I don't need to set the NotOperator (I know that I have to NOT this in this case
1189 if (Iterator
->Operand
== EFI_IFR_OR_OP
) {
1194 if (Iterator
->Operand
== EFI_IFR_AND_OP
) {
1199 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
1200 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
1201 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
1202 if (MapBuffer
!= NULL
) {
1204 MapValue
= *MapBuffer
;
1206 MapValue
= (UINT8
) *MapBuffer
;
1209 FreePool (MapBuffer
);
1212 if (MapBuffer2
!= NULL
) {
1214 MapValue2
= *MapBuffer2
;
1216 MapValue2
= (UINT8
) *MapBuffer2
;
1219 FreePool (MapBuffer2
);
1223 switch (Iterator
->Operand
) {
1224 case EFI_IFR_EQ_ID_VAL_OP
:
1225 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->Value
);
1226 PushBool (&StackPtr
, Operator
);
1230 // In the case of external variable values, we must read the variable which is
1231 // named by the human readable version of the OpCode->VariableId and the guid of the formset
1233 case EFI_IFR_EQ_VAR_VAL_OP
:
1234 UnicodeValueToString (
1237 (UINTN
) Iterator
->QuestionId1
,
1238 (sizeof (VariableName
) / sizeof (VariableName
[0])) - 1
1243 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
1245 Status
= BooleanVariableWorker (
1253 if (!EFI_ERROR (Status
)) {
1254 if (SizeOfVariable
== 1) {
1255 CopyMem (&MapValue
, VariableData
, 1);
1257 CopyMem (&MapValue
, VariableData
, 2);
1260 PushBool (&StackPtr
, (BOOLEAN
)!(MapValue
== Iterator
->Value
));
1264 case EFI_IFR_EQ_ID_ID_OP
:
1265 Operator
= (BOOLEAN
)!(MapValue
== MapValue2
);
1266 PushBool (&StackPtr
, Operator
);
1269 case EFI_IFR_EQ_ID_LIST_OP
:
1270 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
1271 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->ValueList
[Index
]);
1277 PushBool (&StackPtr
, Operator
);
1284 Operator
= PopBool (&StackPtr
);
1285 Operator2
= PopBool (&StackPtr
);
1288 PushBool (&StackPtr
, (BOOLEAN
) (Operator
|| Operator2
));
1292 PushBool (&StackPtr
, (BOOLEAN
) (Operator
&& Operator2
));
1295 if (!OrOperator
&& !AndOperator
) {
1296 PushBool (&StackPtr
, Operator
);
1300 case EFI_IFR_TRUE_OP
:
1302 // To check whether Ifr is legacy. Once every boolean expression.
1304 if (IsLegacy
== 0) {
1305 IsLegacy
= PredicateIfrType (Iterator
);
1307 if (IsLegacy
== 0x2) {
1308 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
1313 case EFI_IFR_FALSE_OP
:
1315 // To check whether Ifr is legacy. Once every boolean expression.
1317 if (IsLegacy
== 0) {
1318 IsLegacy
= PredicateIfrType (Iterator
);
1320 if (IsLegacy
== 0x2) {
1321 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
1326 case EFI_IFR_END_IF_OP
:
1327 Operator
= PopBool (&StackPtr
);
1329 // If there is an error, return, otherwise keep looking - there might
1330 // be another test that causes an error
1333 if (Complex
&& CosmeticConsistency
) {
1340 // If not doing a global consistency check, the endif is the REAL terminator of this operation
1341 // This is used for grayout/suppress operations. InconsistentIf is a global operation so the EndIf is
1342 // not the end-all be-all of terminators.
1352 // Must have hit a non-consistency related op-code after a suppress/grayout
1354 if (ArtificialEnd
) {
1355 ArtificialEnd
= FALSE
;
1356 Operator
= PopBool (&StackPtr
);