4 Copyright (c) 2006, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 // Global stack used to evaluate boolean expresions
23 BOOLEAN
*mBooleanEvaluationStack
= (BOOLEAN
) 0;
24 BOOLEAN
*mBooleanEvaluationStackEnd
= (BOOLEAN
) 0;
29 IN OUT BOOLEAN
**Stack
,
30 IN UINTN StackSizeInBoolean
36 Grow size of the boolean stack
40 Stack - Old stack on the way in and new stack on the way out
42 StackSizeInBoolean - New size of the stack
52 NewStack
= AllocatePool (StackSizeInBoolean
* sizeof (BOOLEAN
));
53 ASSERT (NewStack
!= NULL
);
57 // Copy to Old Stack to the New Stack
61 mBooleanEvaluationStack
,
62 (mBooleanEvaluationStackEnd
- mBooleanEvaluationStack
) * sizeof (BOOLEAN
)
66 // Make the Stack pointer point to the old data in the new stack
68 *Stack
= NewStack
+ (*Stack
- mBooleanEvaluationStack
);
73 FreePool (mBooleanEvaluationStack
);
76 mBooleanEvaluationStack
= NewStack
;
77 mBooleanEvaluationStackEnd
= NewStack
+ StackSizeInBoolean
;
82 InitializeBooleanEvaluator (
89 Allocate a global stack for boolean processing.
104 GrowBooleanStack (&NullStack
, 0x1000);
110 IN OUT BOOLEAN
**Stack
,
111 IN BOOLEAN BoolResult
117 Push an element onto the Boolean Stack
121 Stack - Current stack location.
122 BoolResult - BOOLEAN to push.
130 CopyMem (*Stack
, &BoolResult
, sizeof (BOOLEAN
));
133 if (*Stack
>= mBooleanEvaluationStackEnd
) {
135 // If we run out of stack space make a new one that is 2X as big. Copy
136 // the old data into the new stack and update Stack to point to the old
137 // data in the new stack.
141 (mBooleanEvaluationStackEnd
- mBooleanEvaluationStack
) * sizeof (BOOLEAN
) * 2
149 IN OUT BOOLEAN
**Stack
155 Pop an element from the Boolean stack.
159 Stack - Current stack location
163 Top of the BOOLEAN stack.
170 CopyMem (&ReturnValue
, *Stack
, sizeof (BOOLEAN
));
176 GrowBooleanExpression (
177 IN EFI_INCONSISTENCY_DATA
*InconsistentTags
,
178 OUT VOID
**BooleanExpression
,
179 IN OUT UINTN
*BooleanExpressionLength
182 UINT8
*NewExpression
;
184 NewExpression
= AllocatePool (*BooleanExpressionLength
+ sizeof (EFI_INCONSISTENCY_DATA
));
185 ASSERT (NewExpression
!= NULL
);
187 if (*BooleanExpression
!= NULL
) {
189 // Copy Old buffer to the New buffer
191 CopyMem (NewExpression
, *BooleanExpression
, *BooleanExpressionLength
);
193 CopyMem (&NewExpression
[*BooleanExpressionLength
], InconsistentTags
, sizeof (EFI_INCONSISTENCY_DATA
));
196 // Free The Old buffer
198 FreePool (*BooleanExpression
);
201 // Copy data into new buffer
203 CopyMem (NewExpression
, InconsistentTags
, sizeof (EFI_INCONSISTENCY_DATA
));
206 *BooleanExpressionLength
= *BooleanExpressionLength
+ sizeof (EFI_INCONSISTENCY_DATA
);
207 *BooleanExpression
= (VOID
*) NewExpression
;
213 CreateBooleanExpression (
214 IN EFI_FILE_FORM_TAGS
*FileFormTags
,
218 OUT VOID
**BooleanExpression
,
219 OUT UINTN
*BooleanExpressionLength
232 EFI_INCONSISTENCY_DATA
*InconsistentTags
;
233 EFI_INCONSISTENCY_DATA FakeInconsistentTags
;
235 InconsistentTags
= FileFormTags
->InconsistentTags
;
238 // Did we run into a question that contains the Id we are looking for?
240 for (Count
= 0; InconsistentTags
->Operand
!= 0xFF; Count
++) {
243 // Reserve INVALID_OFFSET_VALUE - 1 for TURE and FALSE, because we need to treat them as well
244 // as ideqid etc. but they have no coresponding id, so we reserve this value.
246 if (InconsistentTags
->QuestionId1
== Id
||
247 InconsistentTags
->QuestionId1
== INVALID_OFFSET_VALUE
- 1) {
249 // If !Complex - means evaluate a single if/endif expression
253 // If the ConsistencyId does not match the expression we are looking for
254 // skip to the next consistency database entry
256 if (InconsistentTags
->ConsistencyId
!= Value
) {
261 // We need to rewind to the beginning of the Inconsistent expression
264 (InconsistentTags
->Operand
!= EFI_IFR_INCONSISTENT_IF_OP
) &&
265 (InconsistentTags
->Operand
!= EFI_IFR_GRAYOUT_IF_OP
) &&
266 (InconsistentTags
->Operand
!= EFI_IFR_SUPPRESS_IF_OP
);
268 InconsistentTags
= InconsistentTags
->Previous
;
271 // Store the consistency check expression, ensure the next for loop starts at the op-code afterwards
273 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
274 InconsistentTags
= InconsistentTags
->Next
;
277 // Keep growing until we hit the End expression op-code or we hit the beginning of another
278 // consistency check like grayout/suppress
281 InconsistentTags
->Operand
!= EFI_IFR_END_IF_OP
&&
282 InconsistentTags
->Operand
!= EFI_IFR_GRAYOUT_IF_OP
&&
283 InconsistentTags
->Operand
!= EFI_IFR_SUPPRESS_IF_OP
;
285 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
286 InconsistentTags
= InconsistentTags
->Next
;
289 // Store the EndExpression Op-code
291 GrowBooleanExpression (InconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
295 if (InconsistentTags
->Next
!= NULL
) {
297 // Skip to next entry
299 InconsistentTags
= InconsistentTags
->Next
;
303 FakeInconsistentTags
.Operand
= 0;
306 // Add one last expression which will signify we have definitely hit the end
308 GrowBooleanExpression (&FakeInconsistentTags
, BooleanExpression
, BooleanExpressionLength
);
313 BooleanVariableWorker (
314 IN CHAR16
*VariableName
,
315 IN EFI_VARIABLE_DEFINITION
*VariableDefinition
,
316 IN BOOLEAN
*StackPtr
,
317 IN OUT UINTN
*SizeOfVariable
,
318 IN OUT VOID
**VariableData
333 Status
= gRT
->GetVariable (
335 &VariableDefinition
->Guid
,
341 if (EFI_ERROR (Status
)) {
343 if (Status
== EFI_BUFFER_TOO_SMALL
) {
344 *VariableData
= AllocatePool (*SizeOfVariable
);
345 ASSERT (*VariableData
!= NULL
);
347 Status
= gRT
->GetVariable (
349 &VariableDefinition
->Guid
,
356 if (Status
== EFI_NOT_FOUND
) {
358 // This is a serious flaw, we must have some standard result if a variable
359 // is not found. Our default behavior must either be return a TRUE or FALSE
360 // since there is nothing else we can really do. Therefore, my crystal ball
361 // says I will return a FALSE
363 PushBool (&StackPtr
, FALSE
);
373 IN EFI_INCONSISTENCY_DATA
*Iterator
378 This routine is for the purpose of predicate whether the Ifr is generated by a VfrCompiler greater than or equal to 1.88 or
379 less than 1.88 which is legacy.
382 Iterator - The pointer to inconsistency tags
386 0x2 - If IFR is not legacy
388 0x1 - If IFR is legacy
393 // legacy Ifr cover the states:
395 // Operand Opcode Operand
397 // while Operand means ideqval, TRUE, or other what can be evaluated to True or False,
398 // and Opcode means AND or OR.
400 if (Iterator
->Operand
== EFI_IFR_NOT_OP
||
401 Iterator
->Operand
== 0) {
403 } else if (Iterator
->Operand
== EFI_IFR_EQ_VAR_VAL_OP
||
404 Iterator
->Operand
== EFI_IFR_EQ_ID_VAL_OP
||
405 Iterator
->Operand
== EFI_IFR_EQ_ID_ID_OP
||
406 Iterator
->Operand
== EFI_IFR_EQ_ID_LIST_OP
) {
408 if (Iterator
->Operand
== EFI_IFR_AND_OP
||
409 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
[MAXIMUM_VALUE_CHARACTERS
];
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 FreePool (MapBuffer
);
498 if (MapBuffer2
!= NULL
) {
500 MapValue2
= *MapBuffer2
;
502 MapValue2
= (UINT8
) *MapBuffer2
;
505 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])) - 1
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
, (BOOLEAN
) (!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
[MAXIMUM_VALUE_CHARACTERS
];
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 FreePool (MapBuffer
);
741 if (MapBuffer2
!= NULL
) {
743 MapValue2
= *MapBuffer2
;
745 MapValue2
= (UINT8
) *MapBuffer2
;
748 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])) - 1
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 FreePool (MapBuffer
);
913 if (MapBuffer2
!= NULL
) {
915 MapValue2
= *MapBuffer2
;
917 MapValue2
= (UINT8
) *MapBuffer2
;
920 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])) - 1
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 FreePool (MapBuffer
);
1049 if (MapBuffer2
!= NULL
) {
1051 MapValue2
= *MapBuffer2
;
1053 MapValue2
= (UINT8
) *MapBuffer2
;
1056 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])) - 1
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 FreePool (MapBuffer
);
1205 if (MapBuffer2
!= NULL
) {
1207 MapValue2
= *MapBuffer2
;
1209 MapValue2
= (UINT8
) *MapBuffer2
;
1212 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])) - 1
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
);