]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/SetupBrowserDxe/Boolean.c
Change the function name.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / SetupBrowserDxe / Boolean.c
1 /**@file
2
3
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
9
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.
12
13 **/
14
15
16
17 #include "Setup.h"
18 #include "Ui.h"
19
20 //
21 // Global stack used to evaluate boolean expresions
22 //
23 BOOLEAN *mBooleanEvaluationStack = (BOOLEAN) 0;
24 BOOLEAN *mBooleanEvaluationStackEnd = (BOOLEAN) 0;
25
26 STATIC
27 VOID
28 GrowBooleanStack (
29 IN OUT BOOLEAN **Stack,
30 IN UINTN StackSizeInBoolean
31 )
32 /*++
33
34 Routine Description:
35
36 Grow size of the boolean stack
37
38 Arguments:
39
40 Stack - Old stack on the way in and new stack on the way out
41
42 StackSizeInBoolean - New size of the stack
43
44 Returns:
45
46 NONE
47
48 --*/
49 {
50 BOOLEAN *NewStack;
51
52 NewStack = AllocatePool (StackSizeInBoolean * sizeof (BOOLEAN));
53 ASSERT (NewStack != NULL);
54
55 if (*Stack != NULL) {
56 //
57 // Copy to Old Stack to the New Stack
58 //
59 CopyMem (
60 NewStack,
61 mBooleanEvaluationStack,
62 (mBooleanEvaluationStackEnd - mBooleanEvaluationStack) * sizeof (BOOLEAN)
63 );
64
65 //
66 // Make the Stack pointer point to the old data in the new stack
67 //
68 *Stack = NewStack + (*Stack - mBooleanEvaluationStack);
69
70 //
71 // Free The Old Stack
72 //
73 FreePool (mBooleanEvaluationStack);
74 }
75
76 mBooleanEvaluationStack = NewStack;
77 mBooleanEvaluationStackEnd = NewStack + StackSizeInBoolean;
78 }
79
80 STATIC
81 VOID
82 InitializeBooleanEvaluator (
83 VOID
84 )
85 /*++
86
87 Routine Description:
88
89 Allocate a global stack for boolean processing.
90
91 Arguments:
92
93 NONE
94
95 Returns:
96
97 NONE
98
99 --*/
100 {
101 BOOLEAN *NullStack;
102
103 NullStack = NULL;
104 GrowBooleanStack (&NullStack, 0x1000);
105 }
106
107 STATIC
108 VOID
109 PushBool (
110 IN OUT BOOLEAN **Stack,
111 IN BOOLEAN BoolResult
112 )
113 /*++
114
115 Routine Description:
116
117 Push an element onto the Boolean Stack
118
119 Arguments:
120
121 Stack - Current stack location.
122 BoolResult - BOOLEAN to push.
123
124 Returns:
125
126 None.
127
128 --*/
129 {
130 CopyMem (*Stack, &BoolResult, sizeof (BOOLEAN));
131 *Stack += 1;
132
133 if (*Stack >= mBooleanEvaluationStackEnd) {
134 //
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.
138 //
139 GrowBooleanStack (
140 Stack,
141 (mBooleanEvaluationStackEnd - mBooleanEvaluationStack) * sizeof (BOOLEAN) * 2
142 );
143 }
144 }
145
146 STATIC
147 BOOLEAN
148 PopBool (
149 IN OUT BOOLEAN **Stack
150 )
151 /*++
152
153 Routine Description:
154
155 Pop an element from the Boolean stack.
156
157 Arguments:
158
159 Stack - Current stack location
160
161 Returns:
162
163 Top of the BOOLEAN stack.
164
165 --*/
166 {
167 BOOLEAN ReturnValue;
168
169 *Stack -= 1;
170 CopyMem (&ReturnValue, *Stack, sizeof (BOOLEAN));
171 return ReturnValue;
172 }
173
174 STATIC
175 EFI_STATUS
176 GrowBooleanExpression (
177 IN EFI_INCONSISTENCY_DATA *InconsistentTags,
178 OUT VOID **BooleanExpression,
179 IN OUT UINTN *BooleanExpressionLength
180 )
181 {
182 UINT8 *NewExpression;
183
184 NewExpression = AllocatePool (*BooleanExpressionLength + sizeof (EFI_INCONSISTENCY_DATA));
185 ASSERT (NewExpression != NULL);
186
187 if (*BooleanExpression != NULL) {
188 //
189 // Copy Old buffer to the New buffer
190 //
191 CopyMem (NewExpression, *BooleanExpression, *BooleanExpressionLength);
192
193 CopyMem (&NewExpression[*BooleanExpressionLength], InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));
194
195 //
196 // Free The Old buffer
197 //
198 FreePool (*BooleanExpression);
199 } else {
200 //
201 // Copy data into new buffer
202 //
203 CopyMem (NewExpression, InconsistentTags, sizeof (EFI_INCONSISTENCY_DATA));
204 }
205
206 *BooleanExpressionLength = *BooleanExpressionLength + sizeof (EFI_INCONSISTENCY_DATA);
207 *BooleanExpression = (VOID *) NewExpression;
208 return EFI_SUCCESS;
209 }
210
211 STATIC
212 VOID
213 CreateBooleanExpression (
214 IN EFI_FILE_FORM_TAGS *FileFormTags,
215 IN UINT16 Value,
216 IN UINT16 Id,
217 IN BOOLEAN Complex,
218 OUT VOID **BooleanExpression,
219 OUT UINTN *BooleanExpressionLength
220 )
221 /*++
222
223 Routine Description:
224
225 Arguments:
226
227 Returns:
228
229 --*/
230 {
231 UINTN Count;
232 EFI_INCONSISTENCY_DATA *InconsistentTags;
233 EFI_INCONSISTENCY_DATA FakeInconsistentTags;
234
235 InconsistentTags = FileFormTags->InconsistentTags;
236
237 //
238 // Did we run into a question that contains the Id we are looking for?
239 //
240 for (Count = 0; InconsistentTags->Operand != 0xFF; Count++) {
241
242 //
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.
245 //
246 if (InconsistentTags->QuestionId1 == Id ||
247 InconsistentTags->QuestionId1 == INVALID_OFFSET_VALUE - 1) {
248 //
249 // If !Complex - means evaluate a single if/endif expression
250 //
251 if (!Complex) {
252 //
253 // If the ConsistencyId does not match the expression we are looking for
254 // skip to the next consistency database entry
255 //
256 if (InconsistentTags->ConsistencyId != Value) {
257 goto NextEntry;
258 }
259 }
260 //
261 // We need to rewind to the beginning of the Inconsistent expression
262 //
263 for (;
264 (InconsistentTags->Operand != EFI_IFR_INCONSISTENT_IF_OP) &&
265 (InconsistentTags->Operand != EFI_IFR_GRAYOUT_IF_OP) &&
266 (InconsistentTags->Operand != EFI_IFR_SUPPRESS_IF_OP);
267 ) {
268 InconsistentTags = InconsistentTags->Previous;
269 }
270 //
271 // Store the consistency check expression, ensure the next for loop starts at the op-code afterwards
272 //
273 GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);
274 InconsistentTags = InconsistentTags->Next;
275
276 //
277 // Keep growing until we hit the End expression op-code or we hit the beginning of another
278 // consistency check like grayout/suppress
279 //
280 for (;
281 InconsistentTags->Operand != EFI_IFR_END_IF_OP &&
282 InconsistentTags->Operand != EFI_IFR_GRAYOUT_IF_OP &&
283 InconsistentTags->Operand != EFI_IFR_SUPPRESS_IF_OP;
284 ) {
285 GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);
286 InconsistentTags = InconsistentTags->Next;
287 }
288 //
289 // Store the EndExpression Op-code
290 //
291 GrowBooleanExpression (InconsistentTags, BooleanExpression, BooleanExpressionLength);
292 }
293
294 NextEntry:
295 if (InconsistentTags->Next != NULL) {
296 //
297 // Skip to next entry
298 //
299 InconsistentTags = InconsistentTags->Next;
300 }
301 }
302
303 FakeInconsistentTags.Operand = 0;
304
305 //
306 // Add one last expression which will signify we have definitely hit the end
307 //
308 GrowBooleanExpression (&FakeInconsistentTags, BooleanExpression, BooleanExpressionLength);
309 }
310
311 STATIC
312 EFI_STATUS
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
319 )
320 /*++
321
322 Routine Description:
323
324
325 Arguments:
326
327 Returns:
328
329 --*/
330 {
331 EFI_STATUS Status;
332
333 Status = gRT->GetVariable (
334 VariableName,
335 &VariableDefinition->Guid,
336 NULL,
337 SizeOfVariable,
338 *VariableData
339 );
340
341 if (EFI_ERROR (Status)) {
342
343 if (Status == EFI_BUFFER_TOO_SMALL) {
344 *VariableData = AllocatePool (*SizeOfVariable);
345 ASSERT (*VariableData != NULL);
346
347 Status = gRT->GetVariable (
348 VariableName,
349 &VariableDefinition->Guid,
350 NULL,
351 SizeOfVariable,
352 *VariableData
353 );
354 }
355
356 if (Status == EFI_NOT_FOUND) {
357 //
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
362 //
363 PushBool (&StackPtr, FALSE);
364 }
365 }
366
367 return Status;
368 }
369
370 STATIC
371 UINT8
372 PredicateIfrType (
373 IN EFI_INCONSISTENCY_DATA *Iterator
374 )
375 /*++
376
377 Routine Description:
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.
380
381 Arguments:
382 Iterator - The pointer to inconsistency tags
383
384 Returns:
385
386 0x2 - If IFR is not legacy
387
388 0x1 - If IFR is legacy
389
390 --*/
391 {
392 //
393 // legacy Ifr cover the states:
394 // Not ...
395 // Operand Opcode Operand
396 //
397 // while Operand means ideqval, TRUE, or other what can be evaluated to True or False,
398 // and Opcode means AND or OR.
399 //
400 if (Iterator->Operand == EFI_IFR_NOT_OP ||
401 Iterator->Operand == 0) {
402 return 0x1;
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) {
407 Iterator++;
408 if (Iterator->Operand == EFI_IFR_AND_OP ||
409 Iterator->Operand == EFI_IFR_OR_OP) {
410 Iterator--;
411 return 0x1;
412 }
413 Iterator--;
414 }
415 return 0x2;
416 }
417
418 STATIC
419 VOID
420 PostOrderEvaluate (
421 IN EFI_FILE_FORM_TAGS *FileFormTags,
422 IN UINT16 Width,
423 IN OUT EFI_INCONSISTENCY_DATA **PIterator,
424 IN OUT BOOLEAN **StackPtr
425 )
426 /*++
427
428 Routine Description:
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.
433
434 Arguments:
435
436 FileFormTags - The pointer to the tags of the form
437
438 Width - Width of Operand, recognized every iteration
439
440 PIterator - The pointer to inconsistency tags
441
442 StackPtr - The pointer to the evaluation stack
443
444 Returns:
445
446 TRUE - If value is valid
447
448 FALSE - If value is not valid
449
450 --*/
451 {
452 BOOLEAN Operator;
453 BOOLEAN Operator2;
454 UINT16 *MapBuffer;
455 UINT16 *MapBuffer2;
456 UINT16 MapValue;
457 UINT16 MapValue2;
458 UINTN SizeOfVariable;
459 CHAR16 VariableName[MAXIMUM_VALUE_CHARACTERS];
460 VOID *VariableData;
461 EFI_VARIABLE_DEFINITION *VariableDefinition;
462 EFI_STATUS Status;
463 UINTN Index;
464 BOOLEAN PushValue;
465
466 Operator = FALSE;
467 Operator2 = FALSE;
468 MapBuffer = NULL;
469 MapBuffer2 = NULL;
470 MapValue = 0;
471 MapValue2 = 0;
472 VariableData = NULL;
473
474 while (TRUE) {
475 if ((*PIterator)->Operand == 0) {
476 return;
477 }
478
479 Width = (*PIterator)->Width;
480
481 //
482 // Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.
483 //
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) {
489 if (Width == 2) {
490 MapValue = *MapBuffer;
491 } else {
492 MapValue = (UINT8) *MapBuffer;
493 }
494
495 FreePool (MapBuffer);
496 }
497
498 if (MapBuffer2 != NULL) {
499 if (Width == 2) {
500 MapValue2 = *MapBuffer2;
501 } else {
502 MapValue2 = (UINT8) *MapBuffer2;
503 }
504
505 FreePool (MapBuffer2);
506 }
507 }
508
509 switch ((*PIterator)->Operand) {
510 case EFI_IFR_EQ_VAR_VAL_OP:
511 UnicodeValueToString (
512 VariableName,
513 FALSE,
514 (UINTN) (*PIterator)->QuestionId1,
515 (sizeof (VariableName) / sizeof (VariableName[0])) - 1
516 );
517
518 SizeOfVariable = 0;
519
520 ExtractRequestedNvMap (FileFormTags, (*PIterator)->VariableNumber, &VariableDefinition);
521
522 Status = BooleanVariableWorker (
523 VariableName,
524 VariableDefinition,
525 *StackPtr,
526 &SizeOfVariable,
527 &VariableData
528 );
529
530 if (!EFI_ERROR (Status)) {
531 if (SizeOfVariable == 1) {
532 CopyMem (&MapValue, VariableData, 1);
533 } else {
534 CopyMem (&MapValue, VariableData, 2);
535 }
536
537 //
538 // Do operation after knowing the compare operator.
539 //
540 MapValue2 = (*PIterator)->Value;
541 (*PIterator)++;
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);
546 } else {
547 (*PIterator)--;
548 PushValue = (BOOLEAN) (MapValue == MapValue2);
549 }
550 PushBool (StackPtr, PushValue);
551 }
552
553 break;
554
555 case EFI_IFR_EQ_ID_VAL_OP:
556 //
557 // Do operation after knowing the compare operator.
558 //
559 MapValue2 = (*PIterator)->Value;
560 (*PIterator)++;
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);
565 } else {
566 (*PIterator)--;
567 PushValue = (BOOLEAN) (MapValue == MapValue2);
568 }
569 PushBool (StackPtr, PushValue);
570 break;
571
572 case EFI_IFR_EQ_ID_ID_OP:
573 //
574 // Do operation after knowing the compare operator.
575 //
576 (*PIterator)++;
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);
581 } else {
582 (*PIterator)--;
583 PushValue = (BOOLEAN) (MapValue == MapValue2);
584 }
585 PushBool (StackPtr, PushValue);
586 break;
587
588 case EFI_IFR_EQ_ID_LIST_OP:
589 for (Index = 0; Index < (*PIterator)->ListLength; Index++) {
590 Operator = (BOOLEAN) (MapValue == (*PIterator)->ValueList[Index]);
591 if (Operator) {
592 break;
593 }
594 }
595
596 PushBool (StackPtr, Operator);
597 break;
598
599 case EFI_IFR_TRUE_OP:
600 PushBool (StackPtr, TRUE);
601 break;
602
603 case EFI_IFR_FALSE_OP:
604 PushBool (StackPtr, FALSE);
605 break;
606
607 case EFI_IFR_AND_OP:
608 Operator = PopBool (StackPtr);
609 Operator2 = PopBool (StackPtr);
610 PushBool (StackPtr, (BOOLEAN) (Operator && Operator2));
611 break;
612 case EFI_IFR_OR_OP:
613 Operator = PopBool (StackPtr);
614 Operator2 = PopBool (StackPtr);
615 PushBool (StackPtr, (BOOLEAN) (Operator || Operator2));
616 break;
617 case EFI_IFR_NOT_OP:
618 Operator = PopBool (StackPtr);
619 PushBool (StackPtr, (BOOLEAN) (!Operator));
620 break;
621
622 case EFI_IFR_SUPPRESS_IF_OP:
623 case EFI_IFR_GRAYOUT_IF_OP:
624 case EFI_IFR_INCONSISTENT_IF_OP:
625 default:
626 //
627 // Return to the previous tag if runs out of boolean expression.
628 //
629 (*PIterator)--;
630 return;
631 }
632 (*PIterator)++;
633 }
634 }
635
636 BOOLEAN
637 ValueIsNotValid (
638 IN BOOLEAN Complex,
639 IN UINT16 Value,
640 IN EFI_TAG *Tag,
641 IN EFI_FILE_FORM_TAGS *FileFormTags,
642 IN STRING_REF *PopUp
643 )
644 /*++
645
646 Routine Description:
647
648
649 Arguments:
650
651 Returns:
652
653 TRUE - If value is valid
654
655 FALSE - If value is not valid
656
657 --*/
658 {
659 BOOLEAN *StackPtr;
660 EFI_INCONSISTENCY_DATA *Iterator;
661 BOOLEAN Operator;
662 BOOLEAN Operator2;
663 UINTN Index;
664 VOID *BooleanExpression;
665 UINTN BooleanExpressionLength;
666 BOOLEAN NotOperator;
667 BOOLEAN OrOperator;
668 BOOLEAN AndOperator;
669 BOOLEAN ArtificialEnd;
670 UINT16 *MapBuffer;
671 UINT16 *MapBuffer2;
672 UINT16 MapValue;
673 UINT16 MapValue2;
674 UINTN SizeOfVariable;
675 CHAR16 VariableName[MAXIMUM_VALUE_CHARACTERS];
676 VOID *VariableData;
677 EFI_STATUS Status;
678 UINT16 Id;
679 UINT16 Width;
680 EFI_VARIABLE_DEFINITION *VariableDefinition;
681 BOOLEAN CosmeticConsistency;
682 UINT8 IsLegacy;
683
684 VariableData = NULL;
685 BooleanExpressionLength = 0;
686 BooleanExpression = NULL;
687 Operator = FALSE;
688 ArtificialEnd = FALSE;
689 CosmeticConsistency = TRUE;
690 IsLegacy = 0;
691
692 Id = Tag->Id;
693 if (Tag->StorageWidth == 1) {
694 Width = 1;
695 } else {
696 Width = 2;
697 }
698 CreateBooleanExpression (FileFormTags, Value, Id, Complex, &BooleanExpression, &BooleanExpressionLength);
699
700 if (mBooleanEvaluationStack == 0) {
701 InitializeBooleanEvaluator ();
702 }
703
704 if (BooleanExpression == NULL) {
705 return FALSE;
706 }
707
708 StackPtr = mBooleanEvaluationStack;
709 Iterator = BooleanExpression;
710 MapBuffer = NULL;
711 MapBuffer2 = NULL;
712 MapValue = 0;
713 MapValue2 = 0;
714
715 while (TRUE) {
716 NotOperator = FALSE;
717 OrOperator = FALSE;
718 AndOperator = FALSE;
719
720 if (Iterator->Operand == 0) {
721 return Operator;
722 }
723
724 //
725 // Because INVALID_OFFSET_VALUE - 1 is reserved for TRUE or FALSE, omit them.
726 //
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) {
732 if (Width == 2) {
733 MapValue = *MapBuffer;
734 } else {
735 MapValue = (UINT8) *MapBuffer;
736 }
737
738 FreePool (MapBuffer);
739 }
740
741 if (MapBuffer2 != NULL) {
742 if (Width == 2) {
743 MapValue2 = *MapBuffer2;
744 } else {
745 MapValue2 = (UINT8) *MapBuffer2;
746 }
747
748 FreePool (MapBuffer2);
749 }
750 }
751
752 switch (Iterator->Operand) {
753 case EFI_IFR_SUPPRESS_IF_OP:
754 //
755 // Must have hit a suppress followed by a grayout or vice-versa
756 //
757 if (ArtificialEnd) {
758 ArtificialEnd = FALSE;
759 Operator = PopBool (&StackPtr);
760 if (Operator) {
761 Tag->Suppress = TRUE;
762 }
763
764 return Operator;
765 }
766
767 ArtificialEnd = TRUE;
768 *PopUp = Iterator->Popup;
769 break;
770
771 case EFI_IFR_GRAYOUT_IF_OP:
772 //
773 // Must have hit a suppress followed by a grayout or vice-versa
774 //
775 if (ArtificialEnd) {
776 ArtificialEnd = FALSE;
777 Operator = PopBool (&StackPtr);
778 if (Operator) {
779 Tag->GrayOut = TRUE;
780 }
781
782 return Operator;
783 }
784
785 ArtificialEnd = TRUE;
786 *PopUp = Iterator->Popup;
787 break;
788
789 case EFI_IFR_INCONSISTENT_IF_OP:
790 CosmeticConsistency = FALSE;
791 *PopUp = Iterator->Popup;
792 break;
793
794 //
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
797 //
798 case EFI_IFR_EQ_VAR_VAL_OP:
799 //
800 // To check whether Ifr is legacy. Once every boolean expression.
801 //
802 if (IsLegacy == 0) {
803 IsLegacy = PredicateIfrType (Iterator);
804 }
805 if (IsLegacy == 0x2) {
806 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
807 break;
808 }
809
810 UnicodeValueToString (
811 VariableName,
812 FALSE,
813 (UINTN) Iterator->QuestionId1,
814 (sizeof (VariableName) / sizeof (VariableName[0])) - 1
815 );
816
817 SizeOfVariable = 0;
818
819 ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);
820
821 Status = BooleanVariableWorker (
822 VariableName,
823 VariableDefinition,
824 StackPtr,
825 &SizeOfVariable,
826 &VariableData
827 );
828
829 if (!EFI_ERROR (Status)) {
830 if (SizeOfVariable == 1) {
831 CopyMem (&MapValue, VariableData, 1);
832 } else {
833 CopyMem (&MapValue, VariableData, 2);
834 }
835
836 PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));
837 }
838
839 break;
840
841 case EFI_IFR_EQ_ID_VAL_OP:
842 //
843 // To check whether Ifr is legacy. Once every boolean expression.
844 //
845 if (IsLegacy == 0) {
846 IsLegacy = PredicateIfrType (Iterator);
847 }
848 if (IsLegacy == 0x2) {
849 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
850 break;
851 }
852
853 PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));
854 break;
855
856 case EFI_IFR_EQ_ID_ID_OP:
857 //
858 // To check whether Ifr is legacy. Once every boolean expression.
859 //
860 if (IsLegacy == 0) {
861 IsLegacy = PredicateIfrType (Iterator);
862 }
863 if (IsLegacy == 0x2) {
864 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
865 break;
866 }
867
868 PushBool (&StackPtr, (BOOLEAN) (MapValue == MapValue2));
869 break;
870
871 case EFI_IFR_EQ_ID_LIST_OP:
872 //
873 // To check whether Ifr is legacy. Once every boolean expression.
874 //
875 if (IsLegacy == 0) {
876 IsLegacy = PredicateIfrType (Iterator);
877 }
878 if (IsLegacy == 0x2) {
879 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
880 break;
881 }
882
883 for (Index = 0; Index < Iterator->ListLength; Index++) {
884 Operator = (BOOLEAN) (MapValue == Iterator->ValueList[Index]);
885 if (Operator) {
886 break;
887 }
888 }
889
890 PushBool (&StackPtr, Operator);
891 break;
892
893 case EFI_IFR_AND_OP:
894 Iterator++;
895 if (Iterator->Operand == EFI_IFR_NOT_OP) {
896 NotOperator = TRUE;
897 Iterator++;
898 }
899
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) {
904 if (Width == 2) {
905 MapValue = *MapBuffer;
906 } else {
907 MapValue = (UINT8) *MapBuffer;
908 }
909
910 FreePool (MapBuffer);
911 }
912
913 if (MapBuffer2 != NULL) {
914 if (Width == 2) {
915 MapValue2 = *MapBuffer2;
916 } else {
917 MapValue2 = (UINT8) *MapBuffer2;
918 }
919
920 FreePool (MapBuffer2);
921 }
922 }
923
924 switch (Iterator->Operand) {
925 case EFI_IFR_EQ_ID_VAL_OP:
926 //
927 // If Not - flip the results
928 //
929 if (NotOperator) {
930 Operator = (BOOLEAN)!(MapValue == Iterator->Value);
931 } else {
932 Operator = (BOOLEAN) (MapValue == Iterator->Value);
933 }
934
935 PushBool (&StackPtr, Operator);
936 break;
937
938 //
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
941 //
942 case EFI_IFR_EQ_VAR_VAL_OP:
943 UnicodeValueToString (
944 VariableName,
945 FALSE,
946 (UINTN) Iterator->QuestionId1,
947 (sizeof (VariableName) / sizeof (VariableName[0])) - 1
948 );
949
950 SizeOfVariable = 0;
951
952 ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);
953
954 Status = BooleanVariableWorker (
955 VariableName,
956 VariableDefinition,
957 StackPtr,
958 &SizeOfVariable,
959 &VariableData
960 );
961
962 if (!EFI_ERROR (Status)) {
963 if (SizeOfVariable == 1) {
964 CopyMem (&MapValue, VariableData, 1);
965 } else {
966 CopyMem (&MapValue, VariableData, 2);
967 }
968 //
969 // If Not - flip the results
970 //
971 if (NotOperator) {
972 PushBool (&StackPtr, (BOOLEAN)!(MapValue == Iterator->Value));
973 } else {
974 PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));
975 }
976 }
977 break;
978
979 case EFI_IFR_EQ_ID_ID_OP:
980 //
981 // If Not - flip the results
982 //
983 if (NotOperator) {
984 Operator = (BOOLEAN)!(MapValue == MapValue2);
985 } else {
986 Operator = (BOOLEAN) (MapValue == MapValue2);
987 }
988
989 PushBool (&StackPtr, Operator);
990 break;
991
992 case EFI_IFR_EQ_ID_LIST_OP:
993 for (Index = 0; Index < Iterator->ListLength; Index++) {
994 //
995 // If Not - flip the results
996 //
997 if (NotOperator) {
998 Operator = (BOOLEAN)!(MapValue == Iterator->ValueList[Index]);
999 } else {
1000 Operator = (BOOLEAN) (MapValue == Iterator->ValueList[Index]);
1001 }
1002 //
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
1005 //
1006 if (Operator && NotOperator) {
1007 continue;
1008 }
1009 //
1010 // If MapValue == Item, then we have succeeded (first found is good enough)
1011 //
1012 if (Operator) {
1013 break;
1014 }
1015 }
1016
1017 PushBool (&StackPtr, Operator);
1018 break;
1019
1020 default:
1021 return FALSE;
1022 }
1023
1024 Operator = PopBool (&StackPtr);
1025 Operator2 = PopBool (&StackPtr);
1026 PushBool (&StackPtr, (BOOLEAN) (Operator && Operator2));
1027 break;
1028
1029 case EFI_IFR_OR_OP:
1030 Iterator++;
1031 if (Iterator->Operand == EFI_IFR_NOT_OP) {
1032 NotOperator = TRUE;
1033 Iterator++;
1034 }
1035
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) {
1040 if (Width == 2) {
1041 MapValue = *MapBuffer;
1042 } else {
1043 MapValue = (UINT8) *MapBuffer;
1044 }
1045
1046 FreePool (MapBuffer);
1047 }
1048
1049 if (MapBuffer2 != NULL) {
1050 if (Width == 2) {
1051 MapValue2 = *MapBuffer2;
1052 } else {
1053 MapValue2 = (UINT8) *MapBuffer2;
1054 }
1055
1056 FreePool (MapBuffer2);
1057 }
1058 }
1059
1060 switch (Iterator->Operand) {
1061 case EFI_IFR_EQ_ID_VAL_OP:
1062 //
1063 // If Not - flip the results
1064 //
1065 if (NotOperator) {
1066 Operator = (BOOLEAN)!(MapValue == Iterator->Value);
1067 } else {
1068 Operator = (BOOLEAN) (MapValue == Iterator->Value);
1069 }
1070
1071 PushBool (&StackPtr, Operator);
1072 break;
1073
1074 //
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
1077 //
1078 case EFI_IFR_EQ_VAR_VAL_OP:
1079 UnicodeValueToString (
1080 VariableName,
1081 FALSE,
1082 (UINTN) Iterator->QuestionId1,
1083 (sizeof (VariableName) / sizeof (VariableName[0])) - 1
1084 );
1085
1086 SizeOfVariable = 0;
1087
1088 ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);
1089
1090 Status = BooleanVariableWorker (
1091 VariableName,
1092 VariableDefinition,
1093 StackPtr,
1094 &SizeOfVariable,
1095 &VariableData
1096 );
1097
1098 if (!EFI_ERROR (Status)) {
1099 if (SizeOfVariable == 1) {
1100 CopyMem (&MapValue, VariableData, 1);
1101 } else {
1102 CopyMem (&MapValue, VariableData, 2);
1103 }
1104 //
1105 // If Not - flip the results
1106 //
1107 if (NotOperator) {
1108 PushBool (&StackPtr, (BOOLEAN)!(MapValue == Iterator->Value));
1109 } else {
1110 PushBool (&StackPtr, (BOOLEAN) (MapValue == Iterator->Value));
1111 }
1112 }
1113 break;
1114
1115 case EFI_IFR_EQ_ID_ID_OP:
1116 //
1117 // If Not - flip the results
1118 //
1119 if (NotOperator) {
1120 Operator = (BOOLEAN)!(MapValue == MapValue2);
1121 } else {
1122 Operator = (BOOLEAN) (MapValue == MapValue2);
1123 }
1124
1125 PushBool (&StackPtr, Operator);
1126 break;
1127
1128 case EFI_IFR_EQ_ID_LIST_OP:
1129 for (Index = 0; Index < Iterator->ListLength; Index++) {
1130 //
1131 // If Not - flip the results
1132 //
1133 if (NotOperator) {
1134 Operator = (BOOLEAN)!(MapValue == Iterator->ValueList[Index]);
1135 } else {
1136 Operator = (BOOLEAN) (MapValue == Iterator->ValueList[Index]);
1137 }
1138 //
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
1141 //
1142 if (Operator && NotOperator) {
1143 continue;
1144 }
1145 //
1146 // If MapValue == Item, then we have succeeded (first found is good enough)
1147 //
1148 if (Operator) {
1149 break;
1150 }
1151 }
1152
1153 PushBool (&StackPtr, Operator);
1154 break;
1155
1156 default:
1157 return FALSE;
1158 }
1159
1160 Operator = PopBool (&StackPtr);
1161 Operator2 = PopBool (&StackPtr);
1162 PushBool (&StackPtr, (BOOLEAN) (Operator || Operator2));
1163 break;
1164
1165 case EFI_IFR_NOT_OP:
1166 //
1167 // To check whether Ifr is legacy. Once every boolean expression.
1168 //
1169 if (IsLegacy == 0) {
1170 IsLegacy = PredicateIfrType (Iterator);
1171 }
1172 if (IsLegacy == 0x2) {
1173 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
1174 break;
1175 }
1176
1177 //
1178 // I don't need to set the NotOperator (I know that I have to NOT this in this case
1179 //
1180 Iterator++;
1181
1182 if (Iterator->Operand == EFI_IFR_OR_OP) {
1183 OrOperator = TRUE;
1184 Iterator++;
1185 }
1186
1187 if (Iterator->Operand == EFI_IFR_AND_OP) {
1188 AndOperator = TRUE;
1189 Iterator++;
1190 }
1191
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) {
1196 if (Width == 2) {
1197 MapValue = *MapBuffer;
1198 } else {
1199 MapValue = (UINT8) *MapBuffer;
1200 }
1201
1202 FreePool (MapBuffer);
1203 }
1204
1205 if (MapBuffer2 != NULL) {
1206 if (Width == 2) {
1207 MapValue2 = *MapBuffer2;
1208 } else {
1209 MapValue2 = (UINT8) *MapBuffer2;
1210 }
1211
1212 FreePool (MapBuffer2);
1213 }
1214 }
1215
1216 switch (Iterator->Operand) {
1217 case EFI_IFR_EQ_ID_VAL_OP:
1218 Operator = (BOOLEAN)!(MapValue == Iterator->Value);
1219 PushBool (&StackPtr, Operator);
1220 break;
1221
1222 //
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
1225 //
1226 case EFI_IFR_EQ_VAR_VAL_OP:
1227 UnicodeValueToString (
1228 VariableName,
1229 FALSE,
1230 (UINTN) Iterator->QuestionId1,
1231 (sizeof (VariableName) / sizeof (VariableName[0])) - 1
1232 );
1233
1234 SizeOfVariable = 0;
1235
1236 ExtractRequestedNvMap (FileFormTags, Iterator->VariableNumber, &VariableDefinition);
1237
1238 Status = BooleanVariableWorker (
1239 VariableName,
1240 VariableDefinition,
1241 StackPtr,
1242 &SizeOfVariable,
1243 &VariableData
1244 );
1245
1246 if (!EFI_ERROR (Status)) {
1247 if (SizeOfVariable == 1) {
1248 CopyMem (&MapValue, VariableData, 1);
1249 } else {
1250 CopyMem (&MapValue, VariableData, 2);
1251 }
1252
1253 PushBool (&StackPtr, (BOOLEAN)!(MapValue == Iterator->Value));
1254 }
1255 break;
1256
1257 case EFI_IFR_EQ_ID_ID_OP:
1258 Operator = (BOOLEAN)!(MapValue == MapValue2);
1259 PushBool (&StackPtr, Operator);
1260 break;
1261
1262 case EFI_IFR_EQ_ID_LIST_OP:
1263 for (Index = 0; Index < Iterator->ListLength; Index++) {
1264 Operator = (BOOLEAN)!(MapValue == Iterator->ValueList[Index]);
1265 if (Operator) {
1266 continue;
1267 }
1268 }
1269
1270 PushBool (&StackPtr, Operator);
1271 break;
1272
1273 default:
1274 return FALSE;
1275 }
1276
1277 Operator = PopBool (&StackPtr);
1278 Operator2 = PopBool (&StackPtr);
1279
1280 if (OrOperator) {
1281 PushBool (&StackPtr, (BOOLEAN) (Operator || Operator2));
1282 }
1283
1284 if (AndOperator) {
1285 PushBool (&StackPtr, (BOOLEAN) (Operator && Operator2));
1286 }
1287
1288 if (!OrOperator && !AndOperator) {
1289 PushBool (&StackPtr, Operator);
1290 }
1291 break;
1292
1293 case EFI_IFR_TRUE_OP:
1294 //
1295 // To check whether Ifr is legacy. Once every boolean expression.
1296 //
1297 if (IsLegacy == 0) {
1298 IsLegacy = PredicateIfrType (Iterator);
1299 }
1300 if (IsLegacy == 0x2) {
1301 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
1302 break;
1303 }
1304 break;
1305
1306 case EFI_IFR_FALSE_OP:
1307 //
1308 // To check whether Ifr is legacy. Once every boolean expression.
1309 //
1310 if (IsLegacy == 0) {
1311 IsLegacy = PredicateIfrType (Iterator);
1312 }
1313 if (IsLegacy == 0x2) {
1314 PostOrderEvaluate (FileFormTags, Width, &Iterator, &StackPtr);
1315 break;
1316 }
1317 break;
1318
1319 case EFI_IFR_END_IF_OP:
1320 Operator = PopBool (&StackPtr);
1321 //
1322 // If there is an error, return, otherwise keep looking - there might
1323 // be another test that causes an error
1324 //
1325 if (Operator) {
1326 if (Complex && CosmeticConsistency) {
1327 return EFI_SUCCESS;
1328 } else {
1329 return Operator;
1330 }
1331 } else {
1332 //
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.
1336 //
1337 if (!Complex) {
1338 return Operator;
1339 }
1340 break;
1341 }
1342
1343 default:
1344 //
1345 // Must have hit a non-consistency related op-code after a suppress/grayout
1346 //
1347 if (ArtificialEnd) {
1348 ArtificialEnd = FALSE;
1349 Operator = PopBool (&StackPtr);
1350 return Operator;
1351 }
1352
1353 goto Done;
1354 }
1355
1356 Iterator++;
1357 }
1358
1359 Done:
1360 return FALSE;
1361 }