3 Copyright (c) 2006, 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 gBS
->FreePool (mBooleanEvaluationStack
);
82 mBooleanEvaluationStack
= NewStack
;
83 mBooleanEvaluationStackEnd
= NewStack
+ StackSizeInBoolean
;
87 InitializeBooleanEvaluator (
94 Allocate a global stack for boolean processing.
109 GrowBooleanStack (&NullStack
, 0x1000);
115 IN OUT BOOLEAN
**Stack
,
116 IN BOOLEAN BoolResult
122 Push an element onto the Boolean Stack
126 Stack - Current stack location.
127 BoolResult - BOOLEAN to push.
135 CopyMem (*Stack
, &BoolResult
, sizeof (BOOLEAN
));
138 if (*Stack
>= mBooleanEvaluationStackEnd
) {
140 // If we run out of stack space make a new one that is 2X as big. Copy
141 // the old data into the new stack and update Stack to point to the old
142 // data in the new stack.
146 (mBooleanEvaluationStackEnd
- mBooleanEvaluationStack
) * sizeof (BOOLEAN
) * 2
154 IN OUT BOOLEAN
**Stack
160 Pop an element from the Boolean stack.
164 Stack - Current stack location
168 Top of the BOOLEAN stack.
175 CopyMem (&ReturnValue
, *Stack
, sizeof (BOOLEAN
));
180 GrowBooleanExpression (
181 IN EFI_INCONSISTENCY_DATA
*InconsistentTags
,
182 OUT VOID
**BooleanExpression
,
183 IN OUT UINTN
*BooleanExpressionLength
186 UINT8
*NewExpression
;
188 NewExpression
= AllocatePool (*BooleanExpressionLength
+ sizeof (EFI_INCONSISTENCY_DATA
));
189 ASSERT (NewExpression
!= NULL
);
191 if (*BooleanExpression
!= NULL
) {
193 // Copy Old buffer to the New buffer
195 CopyMem (NewExpression
, *BooleanExpression
, *BooleanExpressionLength
);
197 CopyMem (&NewExpression
[*BooleanExpressionLength
], InconsistentTags
, sizeof (EFI_INCONSISTENCY_DATA
));
200 // Free The Old buffer
202 gBS
->FreePool (*BooleanExpression
);
205 // Copy data into new buffer
207 CopyMem (NewExpression
, InconsistentTags
, sizeof (EFI_INCONSISTENCY_DATA
));
210 *BooleanExpressionLength
= *BooleanExpressionLength
+ sizeof (EFI_INCONSISTENCY_DATA
);
211 *BooleanExpression
= (VOID
*) NewExpression
;
216 CreateBooleanExpression (
217 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
221 OUT VOID
**BooleanExpression
,
222 OUT UINTN
*BooleanExpressionLength
235 EFI_INCONSISTENCY_DATA
*InconsistentTags
;
236 EFI_INCONSISTENCY_DATA FakeInconsistentTags
;
238 InconsistentTags
= FileFormTags
->InconsistentTags
;
241 // Did we run into a question that contains the Id we are looking for?
243 for (Count
= 0; InconsistentTags
->Operand
!= 0xFF; Count
++) {
246 // Reserve INVALID_OFFSET_VALUE - 1 for TURE and FALSE, because we need to treat them as well
247 // as ideqid etc. but they have no coresponding id, so we reserve this value.
249 if (InconsistentTags
->QuestionId1
== Id
||
250 InconsistentTags
->QuestionId1
== INVALID_OFFSET_VALUE
- 1) {
252 // If !Complex - means evaluate a single if/endif expression
256 // If the ConsistencyId does not match the expression we are looking for
257 // skip to the next consistency database entry
259 if (InconsistentTags
->ConsistencyId
!= Value
) {
264 // We need to rewind to the beginning of the Inconsistent expression
267 (InconsistentTags
->Operand
!= EFI_IFR_INCONSISTENT_IF_OP
) &&
268 (InconsistentTags
->Operand
!= EFI_IFR_GRAYOUT_IF_OP
) &&
269 (InconsistentTags
->Operand
!= EFI_IFR_SUPPRESS_IF_OP
);
271 InconsistentTags
= InconsistentTags
->Previous
;
274 // Store the consistency check expression, ensure the next for loop starts at the op-code afterwards
276 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
277 InconsistentTags
= InconsistentTags
->Next
;
280 // Keep growing until we hit the End expression op-code or we hit the beginning of another
281 // consistency check like grayout/suppress
284 InconsistentTags
->Operand
!= EFI_IFR_END_IF_OP
&&
285 InconsistentTags
->Operand
!= EFI_IFR_GRAYOUT_IF_OP
&&
286 InconsistentTags
->Operand
!= EFI_IFR_SUPPRESS_IF_OP
;
288 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
289 InconsistentTags
= InconsistentTags
->Next
;
292 // Store the EndExpression Op-code
294 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
298 if (InconsistentTags
->Next
!= NULL
) {
300 // Skip to next entry
302 InconsistentTags
= InconsistentTags
->Next
;
306 FakeInconsistentTags
.Operand
= 0;
309 // Add one last expression which will signify we have definitely hit the end
311 GrowBooleanExpression (&FakeInconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
315 BooleanVariableWorker (
316 IN CHAR16
*VariableName
,
317 IN EFI_VARIABLE_DEFINITION
*VariableDefinition
,
318 IN BOOLEAN
*StackPtr
,
319 IN OUT UINTN
*SizeOfVariable
,
320 IN OUT VOID
**VariableData
335 Status
= gRT
->GetVariable (
337 &VariableDefinition
->Guid
,
343 if (EFI_ERROR (Status
)) {
345 if (Status
== EFI_BUFFER_TOO_SMALL
) {
346 *VariableData
= AllocatePool (*SizeOfVariable
);
347 ASSERT (*VariableData
!= NULL
);
349 Status
= gRT
->GetVariable (
351 &VariableDefinition
->Guid
,
358 if (Status
== EFI_NOT_FOUND
) {
360 // This is a serious flaw, we must have some standard result if a variable
361 // is not found. Our default behavior must either be return a TRUE or FALSE
362 // since there is nothing else we can really do. Therefore, my crystal ball
363 // says I will return a FALSE
365 PushBool (&StackPtr
, FALSE
);
374 IN EFI_INCONSISTENCY_DATA
*Iterator
379 This routine is for the purpose of predicate whether the Ifr is generated by a VfrCompiler greater than or equal to 1.88 or
380 less than 1.88 which is legacy.
383 Iterator - The pointer to inconsistency tags
387 0x2 - If IFR is not legacy
389 0x1 - If IFR is legacy
394 // legacy Ifr cover the states:
396 // Operand Opcode Operand
398 // while Operand means ideqval, TRUE, or other what can be evaluated to True or False,
399 // and Opcode means AND or OR.
401 if (Iterator
->Operand
== EFI_IFR_NOT_OP
||
402 Iterator
->Operand
== 0) {
404 } else if (Iterator
->Operand
== EFI_IFR_EQ_VAR_VAL_OP
||
405 Iterator
->Operand
== EFI_IFR_EQ_ID_VAL_OP
||
406 Iterator
->Operand
== EFI_IFR_EQ_ID_ID_OP
||
407 Iterator
->Operand
== EFI_IFR_EQ_ID_LIST_OP
) {
409 if (Iterator
->Operand
== EFI_IFR_AND_OP
||
410 Iterator
->Operand
== EFI_IFR_OR_OP
) {
421 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
423 IN OUT EFI_INCONSISTENCY_DATA
**PIterator
,
424 IN OUT BOOLEAN
**StackPtr
429 PostOrderEvaluate is used for Ifr generated by VfrCompiler greater than or equal to 1.88,
430 which generate Operand Operand Opcode type Ifr.
431 PostOrderEvaluete only evaluate boolean expression part, not suppressif/grayoutif. TRUE,
432 FALSE, >=, >, (, ) are supported.
436 FileFormTags - The pointer to the tags of the form
438 Width - Width of Operand, recognized every iteration
440 PIterator - The pointer to inconsistency tags
442 StackPtr - The pointer to the evaluation stack
446 TRUE - If value is valid
448 FALSE - If value is not valid
458 UINTN SizeOfVariable
;
459 CHAR16 VariableName
[40];
461 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
475 if ((*PIterator
)->Operand
== 0) {
479 Width
= (*PIterator
)->Width
;
482 // Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.
484 if ((*PIterator
)->QuestionId1
!= INVALID_OFFSET_VALUE
&&
485 (*PIterator
)->QuestionId1
!= INVALID_OFFSET_VALUE
- 1) {
486 ExtractNvValue (FileFormTags
, (*PIterator
)->VariableNumber
, Width
, (*PIterator
)->QuestionId1
, (VOID
**) &MapBuffer
);
487 ExtractNvValue (FileFormTags
, (*PIterator
)->VariableNumber2
, Width
, (*PIterator
)->QuestionId2
, (VOID
**) &MapBuffer2
);
488 if (MapBuffer
!= NULL
) {
490 MapValue
= *MapBuffer
;
492 MapValue
= (UINT8
) *MapBuffer
;
495 gBS
->FreePool (MapBuffer
);
498 if (MapBuffer2
!= NULL
) {
500 MapValue2
= *MapBuffer2
;
502 MapValue2
= (UINT8
) *MapBuffer2
;
505 gBS
->FreePool (MapBuffer2
);
509 switch ((*PIterator
)->Operand
) {
510 case EFI_IFR_EQ_VAR_VAL_OP
:
511 UnicodeValueToString (
514 (UINTN
) (*PIterator
)->QuestionId1
,
515 (sizeof (VariableName
) / sizeof (VariableName
[0]))
520 ExtractRequestedNvMap (FileFormTags
, (*PIterator
)->VariableNumber
, &VariableDefinition
);
522 Status
= BooleanVariableWorker (
530 if (!EFI_ERROR (Status
)) {
531 if (SizeOfVariable
== 1) {
532 CopyMem (&MapValue
, VariableData
, 1);
534 CopyMem (&MapValue
, VariableData
, 2);
538 // Do operation after knowing the compare operator.
540 MapValue2
= (*PIterator
)->Value
;
542 if ((*PIterator
)->Operand
== EFI_IFR_GT_OP
) {
543 PushValue
= (BOOLEAN
) (MapValue
> MapValue2
);
544 } else if ((*PIterator
)->Operand
== EFI_IFR_GE_OP
) {
545 PushValue
= (BOOLEAN
) (MapValue
>= MapValue2
);
548 PushValue
= (BOOLEAN
) (MapValue
== MapValue2
);
550 PushBool (StackPtr
, PushValue
);
555 case EFI_IFR_EQ_ID_VAL_OP
:
557 // Do operation after knowing the compare operator.
559 MapValue2
= (*PIterator
)->Value
;
561 if ((*PIterator
)->Operand
== EFI_IFR_GT_OP
) {
562 PushValue
= (BOOLEAN
) (MapValue
> MapValue2
);
563 } else if ((*PIterator
)->Operand
== EFI_IFR_GE_OP
) {
564 PushValue
= (BOOLEAN
) (MapValue
>= MapValue2
);
567 PushValue
= (BOOLEAN
) (MapValue
== MapValue2
);
569 PushBool (StackPtr
, PushValue
);
572 case EFI_IFR_EQ_ID_ID_OP
:
574 // Do operation after knowing the compare operator.
577 if ((*PIterator
)->Operand
== EFI_IFR_GT_OP
) {
578 PushValue
= (BOOLEAN
) (MapValue
> MapValue2
);
579 } else if ((*PIterator
)->Operand
== EFI_IFR_GE_OP
) {
580 PushValue
= (BOOLEAN
) (MapValue
>= MapValue2
);
583 PushValue
= (BOOLEAN
) (MapValue
== MapValue2
);
585 PushBool (StackPtr
, PushValue
);
588 case EFI_IFR_EQ_ID_LIST_OP
:
589 for (Index
= 0; Index
< (*PIterator
)->ListLength
; Index
++) {
590 Operator
= (BOOLEAN
) (MapValue
== (*PIterator
)->ValueList
[Index
]);
596 PushBool (StackPtr
, Operator
);
599 case EFI_IFR_TRUE_OP
:
600 PushBool (StackPtr
, TRUE
);
603 case EFI_IFR_FALSE_OP
:
604 PushBool (StackPtr
, FALSE
);
608 Operator
= PopBool (StackPtr
);
609 Operator2
= PopBool (StackPtr
);
610 PushBool (StackPtr
, (BOOLEAN
) (Operator
&& Operator2
));
613 Operator
= PopBool (StackPtr
);
614 Operator2
= PopBool (StackPtr
);
615 PushBool (StackPtr
, (BOOLEAN
) (Operator
|| Operator2
));
618 Operator
= PopBool (StackPtr
);
619 PushBool (StackPtr
, !Operator
);
622 case EFI_IFR_SUPPRESS_IF_OP
:
623 case EFI_IFR_GRAYOUT_IF_OP
:
624 case EFI_IFR_INCONSISTENT_IF_OP
:
627 // Return to the previous tag if runs out of boolean expression.
641 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
653 TRUE - If value is valid
655 FALSE - If value is not valid
660 EFI_INCONSISTENCY_DATA
*Iterator
;
664 VOID
*BooleanExpression
;
665 UINTN BooleanExpressionLength
;
669 BOOLEAN ArtificialEnd
;
674 UINTN SizeOfVariable
;
675 CHAR16 VariableName
[40];
680 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
681 BOOLEAN CosmeticConsistency
;
685 BooleanExpressionLength
= 0;
686 BooleanExpression
= NULL
;
688 ArtificialEnd
= FALSE
;
689 CosmeticConsistency
= TRUE
;
693 if (Tag
->StorageWidth
== 1) {
698 CreateBooleanExpression (FileFormTags
, Value
, Id
, Complex
, &BooleanExpression
, &BooleanExpressionLength
);
700 if (mBooleanEvaluationStack
== 0) {
701 InitializeBooleanEvaluator ();
704 if (BooleanExpression
== NULL
) {
708 StackPtr
= mBooleanEvaluationStack
;
709 Iterator
= BooleanExpression
;
720 if (Iterator
->Operand
== 0) {
725 // Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.
727 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
&&
728 Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
-1) {
729 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
730 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
731 if (MapBuffer
!= NULL
) {
733 MapValue
= *MapBuffer
;
735 MapValue
= (UINT8
) *MapBuffer
;
738 gBS
->FreePool (MapBuffer
);
741 if (MapBuffer2
!= NULL
) {
743 MapValue2
= *MapBuffer2
;
745 MapValue2
= (UINT8
) *MapBuffer2
;
748 gBS
->FreePool (MapBuffer2
);
752 switch (Iterator
->Operand
) {
753 case EFI_IFR_SUPPRESS_IF_OP
:
755 // Must have hit a suppress followed by a grayout or vice-versa
758 ArtificialEnd
= FALSE
;
759 Operator
= PopBool (&StackPtr
);
761 Tag
->Suppress
= TRUE
;
767 ArtificialEnd
= TRUE
;
768 *PopUp
= Iterator
->Popup
;
771 case EFI_IFR_GRAYOUT_IF_OP
:
773 // Must have hit a suppress followed by a grayout or vice-versa
776 ArtificialEnd
= FALSE
;
777 Operator
= PopBool (&StackPtr
);
785 ArtificialEnd
= TRUE
;
786 *PopUp
= Iterator
->Popup
;
789 case EFI_IFR_INCONSISTENT_IF_OP
:
790 CosmeticConsistency
= FALSE
;
791 *PopUp
= Iterator
->Popup
;
795 // In the case of external variable values, we must read the variable which is
796 // named by the human readable version of the OpCode->VariableId and the guid of the formset
798 case EFI_IFR_EQ_VAR_VAL_OP
:
800 // To check whether Ifr is legacy. Once every boolean expression.
803 IsLegacy
= PredicateIfrType (Iterator
);
805 if (IsLegacy
== 0x2) {
806 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
810 UnicodeValueToString (
813 (UINTN
) Iterator
->QuestionId1
,
814 (sizeof (VariableName
) / sizeof (VariableName
[0]))
819 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
821 Status
= BooleanVariableWorker (
829 if (!EFI_ERROR (Status
)) {
830 if (SizeOfVariable
== 1) {
831 CopyMem (&MapValue
, VariableData
, 1);
833 CopyMem (&MapValue
, VariableData
, 2);
836 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
841 case EFI_IFR_EQ_ID_VAL_OP
:
843 // To check whether Ifr is legacy. Once every boolean expression.
846 IsLegacy
= PredicateIfrType (Iterator
);
848 if (IsLegacy
== 0x2) {
849 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
853 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
856 case EFI_IFR_EQ_ID_ID_OP
:
858 // To check whether Ifr is legacy. Once every boolean expression.
861 IsLegacy
= PredicateIfrType (Iterator
);
863 if (IsLegacy
== 0x2) {
864 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
868 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== MapValue2
));
871 case EFI_IFR_EQ_ID_LIST_OP
:
873 // To check whether Ifr is legacy. Once every boolean expression.
876 IsLegacy
= PredicateIfrType (Iterator
);
878 if (IsLegacy
== 0x2) {
879 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
883 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
884 Operator
= (BOOLEAN
) (MapValue
== Iterator
->ValueList
[Index
]);
890 PushBool (&StackPtr
, Operator
);
895 if (Iterator
->Operand
== EFI_IFR_NOT_OP
) {
900 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
901 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
902 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
903 if (MapBuffer
!= NULL
) {
905 MapValue
= *MapBuffer
;
907 MapValue
= (UINT8
) *MapBuffer
;
910 gBS
->FreePool (MapBuffer
);
913 if (MapBuffer2
!= NULL
) {
915 MapValue2
= *MapBuffer2
;
917 MapValue2
= (UINT8
) *MapBuffer2
;
920 gBS
->FreePool (MapBuffer2
);
924 switch (Iterator
->Operand
) {
925 case EFI_IFR_EQ_ID_VAL_OP
:
927 // If Not - flip the results
930 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->Value
);
932 Operator
= (BOOLEAN
) (MapValue
== Iterator
->Value
);
935 PushBool (&StackPtr
, Operator
);
939 // In the case of external variable values, we must read the variable which is
940 // named by the human readable version of the OpCode->VariableId and the guid of the formset
942 case EFI_IFR_EQ_VAR_VAL_OP
:
943 UnicodeValueToString (
946 (UINTN
) Iterator
->QuestionId1
,
947 (sizeof (VariableName
) / sizeof (VariableName
[0]))
952 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
954 Status
= BooleanVariableWorker (
962 if (!EFI_ERROR (Status
)) {
963 if (SizeOfVariable
== 1) {
964 CopyMem (&MapValue
, VariableData
, 1);
966 CopyMem (&MapValue
, VariableData
, 2);
969 // If Not - flip the results
972 PushBool (&StackPtr
, (BOOLEAN
)!(MapValue
== Iterator
->Value
));
974 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
979 case EFI_IFR_EQ_ID_ID_OP
:
981 // If Not - flip the results
984 Operator
= (BOOLEAN
)!(MapValue
== MapValue2
);
986 Operator
= (BOOLEAN
) (MapValue
== MapValue2
);
989 PushBool (&StackPtr
, Operator
);
992 case EFI_IFR_EQ_ID_LIST_OP
:
993 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
995 // If Not - flip the results
998 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->ValueList
[Index
]);
1000 Operator
= (BOOLEAN
) (MapValue
== Iterator
->ValueList
[Index
]);
1003 // If We are trying to make sure that MapValue != Item[x], keep looking through
1004 // the list to make sure we don't equal any other items
1006 if (Operator
&& NotOperator
) {
1010 // If MapValue == Item, then we have succeeded (first found is good enough)
1017 PushBool (&StackPtr
, Operator
);
1024 Operator
= PopBool (&StackPtr
);
1025 Operator2
= PopBool (&StackPtr
);
1026 PushBool (&StackPtr
, (BOOLEAN
) (Operator
&& Operator2
));
1031 if (Iterator
->Operand
== EFI_IFR_NOT_OP
) {
1036 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
1037 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
1038 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
1039 if (MapBuffer
!= NULL
) {
1041 MapValue
= *MapBuffer
;
1043 MapValue
= (UINT8
) *MapBuffer
;
1046 gBS
->FreePool (MapBuffer
);
1049 if (MapBuffer2
!= NULL
) {
1051 MapValue2
= *MapBuffer2
;
1053 MapValue2
= (UINT8
) *MapBuffer2
;
1056 gBS
->FreePool (MapBuffer2
);
1060 switch (Iterator
->Operand
) {
1061 case EFI_IFR_EQ_ID_VAL_OP
:
1063 // If Not - flip the results
1066 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->Value
);
1068 Operator
= (BOOLEAN
) (MapValue
== Iterator
->Value
);
1071 PushBool (&StackPtr
, Operator
);
1075 // In the case of external variable values, we must read the variable which is
1076 // named by the human readable version of the OpCode->VariableId and the guid of the formset
1078 case EFI_IFR_EQ_VAR_VAL_OP
:
1079 UnicodeValueToString (
1082 (UINTN
) Iterator
->QuestionId1
,
1083 (sizeof (VariableName
) / sizeof (VariableName
[0]))
1088 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
1090 Status
= BooleanVariableWorker (
1098 if (!EFI_ERROR (Status
)) {
1099 if (SizeOfVariable
== 1) {
1100 CopyMem (&MapValue
, VariableData
, 1);
1102 CopyMem (&MapValue
, VariableData
, 2);
1105 // If Not - flip the results
1108 PushBool (&StackPtr
, (BOOLEAN
)!(MapValue
== Iterator
->Value
));
1110 PushBool (&StackPtr
, (BOOLEAN
) (MapValue
== Iterator
->Value
));
1115 case EFI_IFR_EQ_ID_ID_OP
:
1117 // If Not - flip the results
1120 Operator
= (BOOLEAN
)!(MapValue
== MapValue2
);
1122 Operator
= (BOOLEAN
) (MapValue
== MapValue2
);
1125 PushBool (&StackPtr
, Operator
);
1128 case EFI_IFR_EQ_ID_LIST_OP
:
1129 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
1131 // If Not - flip the results
1134 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->ValueList
[Index
]);
1136 Operator
= (BOOLEAN
) (MapValue
== Iterator
->ValueList
[Index
]);
1139 // If We are trying to make sure that MapValue != Item[x], keep looking through
1140 // the list to make sure we don't equal any other items
1142 if (Operator
&& NotOperator
) {
1146 // If MapValue == Item, then we have succeeded (first found is good enough)
1153 PushBool (&StackPtr
, Operator
);
1160 Operator
= PopBool (&StackPtr
);
1161 Operator2
= PopBool (&StackPtr
);
1162 PushBool (&StackPtr
, (BOOLEAN
) (Operator
|| Operator2
));
1165 case EFI_IFR_NOT_OP
:
1167 // To check whether Ifr is legacy. Once every boolean expression.
1169 if (IsLegacy
== 0) {
1170 IsLegacy
= PredicateIfrType (Iterator
);
1172 if (IsLegacy
== 0x2) {
1173 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
1178 // I don't need to set the NotOperator (I know that I have to NOT this in this case
1182 if (Iterator
->Operand
== EFI_IFR_OR_OP
) {
1187 if (Iterator
->Operand
== EFI_IFR_AND_OP
) {
1192 if (Iterator
->QuestionId1
!= INVALID_OFFSET_VALUE
) {
1193 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber
, Width
, Iterator
->QuestionId1
, (VOID
**) &MapBuffer
);
1194 ExtractNvValue (FileFormTags
, Iterator
->VariableNumber2
, Width
, Iterator
->QuestionId2
, (VOID
**) &MapBuffer2
);
1195 if (MapBuffer
!= NULL
) {
1197 MapValue
= *MapBuffer
;
1199 MapValue
= (UINT8
) *MapBuffer
;
1202 gBS
->FreePool (MapBuffer
);
1205 if (MapBuffer2
!= NULL
) {
1207 MapValue2
= *MapBuffer2
;
1209 MapValue2
= (UINT8
) *MapBuffer2
;
1212 gBS
->FreePool (MapBuffer2
);
1216 switch (Iterator
->Operand
) {
1217 case EFI_IFR_EQ_ID_VAL_OP
:
1218 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->Value
);
1219 PushBool (&StackPtr
, Operator
);
1223 // In the case of external variable values, we must read the variable which is
1224 // named by the human readable version of the OpCode->VariableId and the guid of the formset
1226 case EFI_IFR_EQ_VAR_VAL_OP
:
1227 UnicodeValueToString (
1230 (UINTN
) Iterator
->QuestionId1
,
1231 (sizeof (VariableName
) / sizeof (VariableName
[0]))
1236 ExtractRequestedNvMap (FileFormTags
, Iterator
->VariableNumber
, &VariableDefinition
);
1238 Status
= BooleanVariableWorker (
1246 if (!EFI_ERROR (Status
)) {
1247 if (SizeOfVariable
== 1) {
1248 CopyMem (&MapValue
, VariableData
, 1);
1250 CopyMem (&MapValue
, VariableData
, 2);
1253 PushBool (&StackPtr
, (BOOLEAN
)!(MapValue
== Iterator
->Value
));
1257 case EFI_IFR_EQ_ID_ID_OP
:
1258 Operator
= (BOOLEAN
)!(MapValue
== MapValue2
);
1259 PushBool (&StackPtr
, Operator
);
1262 case EFI_IFR_EQ_ID_LIST_OP
:
1263 for (Index
= 0; Index
< Iterator
->ListLength
; Index
++) {
1264 Operator
= (BOOLEAN
)!(MapValue
== Iterator
->ValueList
[Index
]);
1270 PushBool (&StackPtr
, Operator
);
1277 Operator
= PopBool (&StackPtr
);
1278 Operator2
= PopBool (&StackPtr
);
1281 PushBool (&StackPtr
, (BOOLEAN
) (Operator
|| Operator2
));
1285 PushBool (&StackPtr
, (BOOLEAN
) (Operator
&& Operator2
));
1288 if (!OrOperator
&& !AndOperator
) {
1289 PushBool (&StackPtr
, Operator
);
1293 case EFI_IFR_TRUE_OP
:
1295 // To check whether Ifr is legacy. Once every boolean expression.
1297 if (IsLegacy
== 0) {
1298 IsLegacy
= PredicateIfrType (Iterator
);
1300 if (IsLegacy
== 0x2) {
1301 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
1306 case EFI_IFR_FALSE_OP
:
1308 // To check whether Ifr is legacy. Once every boolean expression.
1310 if (IsLegacy
== 0) {
1311 IsLegacy
= PredicateIfrType (Iterator
);
1313 if (IsLegacy
== 0x2) {
1314 PostOrderEvaluate (FileFormTags
, Width
, &Iterator
, &StackPtr
);
1319 case EFI_IFR_END_IF_OP
:
1320 Operator
= PopBool (&StackPtr
);
1322 // If there is an error, return, otherwise keep looking - there might
1323 // be another test that causes an error
1326 if (Complex
&& CosmeticConsistency
) {
1333 // If not doing a global consistency check, the endif is the REAL terminator of this operation
1334 // This is used for grayout/suppress operations. InconsistentIf is a global operation so the EndIf is
1335 // not the end-all be-all of terminators.
1345 // Must have hit a non-consistency related op-code after a suppress/grayout
1347 if (ArtificialEnd
) {
1348 ArtificialEnd
= FALSE
;
1349 Operator
= PopBool (&StackPtr
);