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