]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
2cd666fc707180a3c73f5660479939451ddaeef8
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / IfrParse.c
1 /** @file
2 Parser for IFR binary encoding.
3
4 Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
5 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 #include "Setup.h"
16
17 UINT16 mStatementIndex;
18 UINT16 mExpressionOpCodeIndex;
19
20 BOOLEAN mInScopeSubtitle;
21 /**
22 Initialize Statement header members.
23
24 @param OpCodeData Pointer of the raw OpCode data.
25 @param FormSet Pointer of the current FormSe.
26 @param Form Pointer of the current Form.
27
28 @return The Statement.
29
30 **/
31 FORM_BROWSER_STATEMENT *
32 CreateStatement (
33 IN UINT8 *OpCodeData,
34 IN OUT FORM_BROWSER_FORMSET *FormSet,
35 IN OUT FORM_BROWSER_FORM *Form
36 )
37 {
38 FORM_BROWSER_STATEMENT *Statement;
39 EFI_IFR_STATEMENT_HEADER *StatementHdr;
40 INTN ConditionalExprCount;
41
42 if (Form == NULL) {
43 //
44 // We are currently not in a Form Scope, so just skip this Statement
45 //
46 return NULL;
47 }
48
49 Statement = &FormSet->StatementBuffer[mStatementIndex];
50 mStatementIndex++;
51
52 InitializeListHead (&Statement->DefaultListHead);
53 InitializeListHead (&Statement->OptionListHead);
54 InitializeListHead (&Statement->InconsistentListHead);
55 InitializeListHead (&Statement->NoSubmitListHead);
56
57 Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;
58
59 Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
60
61 StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
62 CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
63 CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));
64
65 ConditionalExprCount = GetConditionalExpressionCount(ExpressStatement);
66 if (ConditionalExprCount > 0) {
67 //
68 // Form is inside of suppressif
69 //
70
71 Statement->Expression = (FORM_EXPRESSION_LIST *) AllocatePool(
72 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
73 ASSERT (Statement->Expression != NULL);
74 Statement->Expression->Count = (UINTN) ConditionalExprCount;
75 Statement->Expression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
76 CopyMem (Statement->Expression->Expression, GetConditionalExpressionList(ExpressStatement), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
77 }
78
79 Statement->InSubtitle = mInScopeSubtitle;
80
81 //
82 // Insert this Statement into current Form
83 //
84 InsertTailList (&Form->StatementListHead, &Statement->Link);
85
86 return Statement;
87 }
88
89 /**
90 Convert a numeric value to a Unicode String and insert it to String Package.
91 This string is used as the Unicode Name for the EFI Variable. This is to support
92 the deprecated vareqval opcode.
93
94 @param FormSet The FormSet.
95 @param Statement The numeric question whose VarStoreInfo.VarName is the
96 numeric value which is used to produce the Unicode Name
97 for the EFI Variable.
98
99 If the Statement is NULL, the ASSERT.
100 If the opcode is not Numeric, then ASSERT.
101
102 @retval EFI_SUCCESS The funtion always succeeds.
103 **/
104 EFI_STATUS
105 UpdateCheckBoxStringToken (
106 IN CONST FORM_BROWSER_FORMSET *FormSet,
107 IN FORM_BROWSER_STATEMENT *Statement
108 )
109 {
110 CHAR16 Str[MAXIMUM_VALUE_CHARACTERS];
111 EFI_STRING_ID Id;
112
113 ASSERT (Statement != NULL);
114 ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP);
115
116 UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);
117
118 Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL);
119 if (Id == 0) {
120 return EFI_OUT_OF_RESOURCES;
121 }
122
123 Statement->VarStoreInfo.VarName = Id;
124
125 return EFI_SUCCESS;
126 }
127
128 /**
129 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
130
131 @param OpCodeData The current opcode.
132
133 @retval TRUE Yes.
134 @retval FALSE No.
135 **/
136 BOOLEAN
137 IsNextOpCodeGuidedVarEqName (
138 IN UINT8 *OpCodeData
139 )
140 {
141 //
142 // Get next opcode
143 //
144 OpCodeData += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
145 if (*OpCodeData == EFI_IFR_GUID_OP) {
146 if (CompareGuid (&gEfiIfrFrameworkGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
147 //
148 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
149 //
150 if ((((EFI_IFR_GUID_VAREQNAME *) OpCodeData)->ExtendOpCode) == EFI_IFR_EXTEND_OP_VAREQNAME) {
151 return TRUE;
152 }
153 }
154 }
155
156 return FALSE;
157 }
158
159 /**
160 Initialize Question's members.
161
162 @param OpCodeData Pointer of the raw OpCode data.
163 @param FormSet Pointer of the current FormSet.
164 @param Form Pointer of the current Form.
165
166 @return The Question.
167
168 **/
169 FORM_BROWSER_STATEMENT *
170 CreateQuestion (
171 IN UINT8 *OpCodeData,
172 IN OUT FORM_BROWSER_FORMSET *FormSet,
173 IN OUT FORM_BROWSER_FORM *Form
174 )
175 {
176 FORM_BROWSER_STATEMENT *Statement;
177 EFI_IFR_QUESTION_HEADER *QuestionHdr;
178 LIST_ENTRY *Link;
179 FORMSET_STORAGE *Storage;
180 NAME_VALUE_NODE *NameValueNode;
181 EFI_STATUS Status;
182
183 Statement = CreateStatement (OpCodeData, FormSet, Form);
184 if (Statement == NULL) {
185 return NULL;
186 }
187
188 QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
189 CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));
190 CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));
191 CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));
192
193 Statement->QuestionFlags = QuestionHdr->Flags;
194
195 if (Statement->VarStoreId == 0) {
196 //
197 // VarStoreId of zero indicates no variable storage
198 //
199 return Statement;
200 }
201
202 //
203 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
204 // Framework Compatibility
205 //
206 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
207 if ((*OpCodeData == EFI_IFR_NUMERIC_OP) && IsNextOpCodeGuidedVarEqName (OpCodeData)) {
208 Status = UpdateCheckBoxStringToken (FormSet, Statement);
209 if (EFI_ERROR (Status)) {
210 return NULL;
211 }
212 }
213 }
214
215 //
216 // Find Storage for this Question
217 //
218 Link = GetFirstNode (&FormSet->StorageListHead);
219 while (!IsNull (&FormSet->StorageListHead, Link)) {
220 Storage = FORMSET_STORAGE_FROM_LINK (Link);
221
222 if (Storage->VarStoreId == Statement->VarStoreId) {
223 Statement->Storage = Storage;
224 break;
225 }
226
227 Link = GetNextNode (&FormSet->StorageListHead, Link);
228 }
229 ASSERT (Statement->Storage != NULL);
230
231 //
232 // Initialilze varname for Name/Value or EFI Variable
233 //
234 if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||
235 (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
236 Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);
237 ASSERT (Statement->VariableName != NULL);
238
239 if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
240 //
241 // Insert to Name/Value varstore list
242 //
243 NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));
244 ASSERT (NameValueNode != NULL);
245 NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;
246 NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);
247 ASSERT (NameValueNode->Name != NULL);
248 NameValueNode->Value = AllocateZeroPool (0x10);
249 ASSERT (NameValueNode->Value != NULL);
250 NameValueNode->EditValue = AllocateZeroPool (0x10);
251 ASSERT (NameValueNode->EditValue != NULL);
252
253 InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);
254 }
255 }
256
257 return Statement;
258 }
259
260
261 /**
262 Allocate a FORM_EXPRESSION node.
263
264 @param Form The Form associated with this Expression
265
266 @return Pointer to a FORM_EXPRESSION data structure.
267
268 **/
269 FORM_EXPRESSION *
270 CreateExpression (
271 IN OUT FORM_BROWSER_FORM *Form
272 )
273 {
274 FORM_EXPRESSION *Expression;
275
276 Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
277 ASSERT (Expression != NULL);
278 Expression->Signature = FORM_EXPRESSION_SIGNATURE;
279 InitializeListHead (&Expression->OpCodeListHead);
280
281 return Expression;
282 }
283
284
285 /**
286 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
287
288 @param FormSet Pointer of the current FormSet
289
290 @return Pointer to a FORMSET_STORAGE data structure.
291
292 **/
293 FORMSET_STORAGE *
294 CreateStorage (
295 IN FORM_BROWSER_FORMSET *FormSet
296 )
297 {
298 FORMSET_STORAGE *Storage;
299
300 Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));
301 ASSERT (Storage != NULL);
302 Storage->Signature = FORMSET_STORAGE_SIGNATURE;
303 InitializeListHead (&Storage->NameValueListHead);
304 InsertTailList (&FormSet->StorageListHead, &Storage->Link);
305
306 return Storage;
307 }
308
309
310 /**
311 Create ConfigHdr string for a storage.
312
313 @param FormSet Pointer of the current FormSet
314 @param Storage Pointer of the storage
315
316 @retval EFI_SUCCESS Initialize ConfigHdr success
317
318 **/
319 EFI_STATUS
320 InitializeConfigHdr (
321 IN FORM_BROWSER_FORMSET *FormSet,
322 IN OUT FORMSET_STORAGE *Storage
323 )
324 {
325 CHAR16 *Name;
326
327 if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
328 Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
329 Name = Storage->Name;
330 } else {
331 Name = NULL;
332 }
333
334 Storage->ConfigHdr = HiiConstructConfigHdr (
335 &Storage->Guid,
336 Name,
337 FormSet->DriverHandle
338 );
339
340 if (Storage->ConfigHdr == NULL) {
341 return EFI_NOT_FOUND;
342 }
343
344 Storage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);
345 Storage->SpareStrLen = 0;
346
347 return EFI_SUCCESS;
348 }
349
350
351 /**
352 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
353
354 @param FormSet Pointer of the current FormSet.
355 @param Question The Question to be initialized.
356 @param Form Pointer of the current form.
357
358 @retval EFI_SUCCESS Function success.
359 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
360
361 **/
362 EFI_STATUS
363 InitializeRequestElement (
364 IN OUT FORM_BROWSER_FORMSET *FormSet,
365 IN OUT FORM_BROWSER_STATEMENT *Question,
366 IN OUT FORM_BROWSER_FORM *Form
367 )
368 {
369 FORMSET_STORAGE *Storage;
370 UINTN StrLen;
371 UINTN StringSize;
372 CHAR16 *NewStr;
373 CHAR16 RequestElement[30];
374 LIST_ENTRY *Link;
375 BOOLEAN Find;
376 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
377
378 Storage = Question->Storage;
379 if (Storage == NULL) {
380 return EFI_INVALID_PARAMETER;
381 }
382
383 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
384 //
385 // <ConfigRequest> is unnecessary for EFI variable storage,
386 // GetVariable()/SetVariable() will be used to retrieve/save values
387 //
388 return EFI_SUCCESS;
389 }
390
391 //
392 // Prepare <RequestElement>
393 //
394 if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
395 Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
396 StrLen = UnicodeSPrint (
397 RequestElement,
398 30 * sizeof (CHAR16),
399 L"&OFFSET=%x&WIDTH=%x",
400 Question->VarStoreInfo.VarOffset,
401 Question->StorageWidth
402 );
403 Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);
404 } else {
405 StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);
406 }
407
408 if ((Question->Operand == EFI_IFR_PASSWORD_OP) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {
409 //
410 // Password with CALLBACK flag is stored in encoded format,
411 // so don't need to append it to <ConfigRequest>
412 //
413 return EFI_SUCCESS;
414 }
415
416 //
417 // Append <RequestElement> to <ConfigRequest>
418 //
419 if (StrLen > Storage->SpareStrLen) {
420 //
421 // Old String buffer is not sufficient for RequestElement, allocate a new one
422 //
423 StringSize = (Storage->ConfigRequest != NULL) ? StrSize (Storage->ConfigRequest) : sizeof (CHAR16);
424 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));
425 ASSERT (NewStr != NULL);
426 if (Storage->ConfigRequest != NULL) {
427 CopyMem (NewStr, Storage->ConfigRequest, StringSize);
428 FreePool (Storage->ConfigRequest);
429 }
430 Storage->ConfigRequest = NewStr;
431 Storage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
432 }
433
434 StrCat (Storage->ConfigRequest, RequestElement);
435 Storage->ElementCount++;
436 Storage->SpareStrLen -= StrLen;
437
438 //
439 // Update the Config Request info saved in the form.
440 //
441 ConfigInfo = NULL;
442 Find = FALSE;
443 Link = GetFirstNode (&Form->ConfigRequestHead);
444 while (!IsNull (&Form->ConfigRequestHead, Link)) {
445 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
446
447 if (ConfigInfo != NULL && ConfigInfo->Storage->VarStoreId == Storage->VarStoreId) {
448 Find = TRUE;
449 break;
450 }
451
452 Link = GetNextNode (&Form->ConfigRequestHead, Link);
453 }
454
455 if (!Find) {
456 ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST));
457 ASSERT (ConfigInfo != NULL);
458 ConfigInfo->Signature = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE;
459 ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);
460 ConfigInfo->SpareStrLen = 0;
461 ConfigInfo->Storage = Storage;
462 InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link);
463 }
464
465 //
466 // Append <RequestElement> to <ConfigRequest>
467 //
468 if (StrLen > ConfigInfo->SpareStrLen) {
469 //
470 // Old String buffer is not sufficient for RequestElement, allocate a new one
471 //
472 StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);
473 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));
474 ASSERT (NewStr != NULL);
475 if (ConfigInfo->ConfigRequest != NULL) {
476 CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);
477 FreePool (ConfigInfo->ConfigRequest);
478 }
479 ConfigInfo->ConfigRequest = NewStr;
480 ConfigInfo->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
481 }
482
483 StrCat (ConfigInfo->ConfigRequest, RequestElement);
484 ConfigInfo->ElementCount++;
485 ConfigInfo->SpareStrLen -= StrLen;
486 return EFI_SUCCESS;
487 }
488
489
490 /**
491 Free resources of a Expression.
492
493 @param FormSet Pointer of the Expression
494
495 **/
496 VOID
497 DestroyExpression (
498 IN FORM_EXPRESSION *Expression
499 )
500 {
501 LIST_ENTRY *Link;
502 EXPRESSION_OPCODE *OpCode;
503 LIST_ENTRY *SubExpressionLink;
504 FORM_EXPRESSION *SubExpression;
505
506 while (!IsListEmpty (&Expression->OpCodeListHead)) {
507 Link = GetFirstNode (&Expression->OpCodeListHead);
508 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);
509 RemoveEntryList (&OpCode->Link);
510
511 if (OpCode->ValueList != NULL) {
512 FreePool (OpCode->ValueList);
513 }
514
515 if (OpCode->ValueName != NULL) {
516 FreePool (OpCode->ValueName);
517 }
518
519 if (OpCode->MapExpressionList.ForwardLink != NULL) {
520 while (!IsListEmpty (&OpCode->MapExpressionList)) {
521 SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);
522 SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);
523 RemoveEntryList(&SubExpression->Link);
524 DestroyExpression (SubExpression);
525 }
526 }
527 }
528
529 //
530 // Free this Expression
531 //
532 FreePool (Expression);
533 }
534
535
536 /**
537 Free resources of a storage.
538
539 @param Storage Pointer of the storage
540
541 **/
542 VOID
543 DestroyStorage (
544 IN FORMSET_STORAGE *Storage
545 )
546 {
547 LIST_ENTRY *Link;
548 NAME_VALUE_NODE *NameValueNode;
549
550 if (Storage == NULL) {
551 return;
552 }
553
554 if (Storage->Name != NULL) {
555 FreePool (Storage->Name);
556 }
557 if (Storage->Buffer != NULL) {
558 FreePool (Storage->Buffer);
559 }
560 if (Storage->EditBuffer != NULL) {
561 FreePool (Storage->EditBuffer);
562 }
563
564 while (!IsListEmpty (&Storage->NameValueListHead)) {
565 Link = GetFirstNode (&Storage->NameValueListHead);
566 NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);
567 RemoveEntryList (&NameValueNode->Link);
568
569 if (NameValueNode->Name != NULL) {
570 FreePool (NameValueNode->Name);
571 }
572 if (NameValueNode->Value != NULL) {
573 FreePool (NameValueNode->Value);
574 }
575 if (NameValueNode->EditValue != NULL) {
576 FreePool (NameValueNode->EditValue);
577 }
578 FreePool (NameValueNode);
579 }
580
581 if (Storage->ConfigHdr != NULL) {
582 FreePool (Storage->ConfigHdr);
583 }
584 if (Storage->ConfigRequest != NULL) {
585 FreePool (Storage->ConfigRequest);
586 }
587
588 FreePool (Storage);
589 }
590
591
592 /**
593 Free resources of a Statement.
594
595 @param FormSet Pointer of the FormSet
596 @param Statement Pointer of the Statement
597
598 **/
599 VOID
600 DestroyStatement (
601 IN FORM_BROWSER_FORMSET *FormSet,
602 IN OUT FORM_BROWSER_STATEMENT *Statement
603 )
604 {
605 LIST_ENTRY *Link;
606 QUESTION_DEFAULT *Default;
607 QUESTION_OPTION *Option;
608 FORM_EXPRESSION *Expression;
609
610 //
611 // Free Default value List
612 //
613 while (!IsListEmpty (&Statement->DefaultListHead)) {
614 Link = GetFirstNode (&Statement->DefaultListHead);
615 Default = QUESTION_DEFAULT_FROM_LINK (Link);
616 RemoveEntryList (&Default->Link);
617
618 FreePool (Default);
619 }
620
621 //
622 // Free Options List
623 //
624 while (!IsListEmpty (&Statement->OptionListHead)) {
625 Link = GetFirstNode (&Statement->OptionListHead);
626 Option = QUESTION_OPTION_FROM_LINK (Link);
627 if (Option->SuppressExpression != NULL) {
628 FreePool (Option->SuppressExpression);
629 }
630 RemoveEntryList (&Option->Link);
631
632 FreePool (Option);
633 }
634
635 //
636 // Free Inconsistent List
637 //
638 while (!IsListEmpty (&Statement->InconsistentListHead)) {
639 Link = GetFirstNode (&Statement->InconsistentListHead);
640 Expression = FORM_EXPRESSION_FROM_LINK (Link);
641 RemoveEntryList (&Expression->Link);
642
643 DestroyExpression (Expression);
644 }
645
646 //
647 // Free NoSubmit List
648 //
649 while (!IsListEmpty (&Statement->NoSubmitListHead)) {
650 Link = GetFirstNode (&Statement->NoSubmitListHead);
651 Expression = FORM_EXPRESSION_FROM_LINK (Link);
652 RemoveEntryList (&Expression->Link);
653
654 DestroyExpression (Expression);
655 }
656
657 if (Statement->Expression != NULL) {
658 FreePool (Statement->Expression);
659 }
660
661 if (Statement->VariableName != NULL) {
662 FreePool (Statement->VariableName);
663 }
664 if (Statement->BlockName != NULL) {
665 FreePool (Statement->BlockName);
666 }
667 if (Statement->BufferValue != NULL) {
668 FreePool (Statement->BufferValue);
669 }
670 if (Statement->Operand == EFI_IFR_STRING_OP || Statement->Operand == EFI_IFR_PASSWORD_OP) {
671 DeleteString(Statement->HiiValue.Value.string, FormSet->HiiHandle);
672 }
673 }
674
675
676 /**
677 Free resources of a Form.
678
679 @param FormSet Pointer of the FormSet
680 @param Form Pointer of the Form.
681
682 **/
683 VOID
684 DestroyForm (
685 IN FORM_BROWSER_FORMSET *FormSet,
686 IN OUT FORM_BROWSER_FORM *Form
687 )
688 {
689 LIST_ENTRY *Link;
690 FORM_EXPRESSION *Expression;
691 FORM_BROWSER_STATEMENT *Statement;
692 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
693
694 //
695 // Free Form Expressions
696 //
697 while (!IsListEmpty (&Form->ExpressionListHead)) {
698 Link = GetFirstNode (&Form->ExpressionListHead);
699 Expression = FORM_EXPRESSION_FROM_LINK (Link);
700 RemoveEntryList (&Expression->Link);
701
702 DestroyExpression (Expression);
703 }
704
705 //
706 // Free Statements/Questions
707 //
708 while (!IsListEmpty (&Form->StatementListHead)) {
709 Link = GetFirstNode (&Form->StatementListHead);
710 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
711 RemoveEntryList (&Statement->Link);
712
713 DestroyStatement (FormSet, Statement);
714 }
715
716 //
717 // Free ConfigRequest string.
718 //
719 while (!IsListEmpty (&Form->ConfigRequestHead)) {
720 Link = GetFirstNode (&Form->ConfigRequestHead);
721 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
722 RemoveEntryList (&ConfigInfo->Link);
723
724 FreePool (ConfigInfo->ConfigRequest);
725 FreePool (ConfigInfo);
726 }
727
728 if (Form->SuppressExpression != NULL) {
729 FreePool (Form->SuppressExpression);
730 }
731
732 //
733 // Free this Form
734 //
735 FreePool (Form);
736 }
737
738
739 /**
740 Free resources allocated for a FormSet.
741
742 @param FormSet Pointer of the FormSet
743
744 **/
745 VOID
746 DestroyFormSet (
747 IN OUT FORM_BROWSER_FORMSET *FormSet
748 )
749 {
750 LIST_ENTRY *Link;
751 FORMSET_STORAGE *Storage;
752 FORMSET_DEFAULTSTORE *DefaultStore;
753 FORM_EXPRESSION *Expression;
754 FORM_BROWSER_FORM *Form;
755
756 if (FormSet->IfrBinaryData == NULL) {
757 //
758 // Uninitialized FormSet
759 //
760 FreePool (FormSet);
761 return;
762 }
763
764 //
765 // Free IFR binary buffer
766 //
767 FreePool (FormSet->IfrBinaryData);
768
769 //
770 // Free FormSet Storage
771 //
772 if (FormSet->StorageListHead.ForwardLink != NULL) {
773 while (!IsListEmpty (&FormSet->StorageListHead)) {
774 Link = GetFirstNode (&FormSet->StorageListHead);
775 Storage = FORMSET_STORAGE_FROM_LINK (Link);
776 RemoveEntryList (&Storage->Link);
777
778 DestroyStorage (Storage);
779 }
780 }
781
782 //
783 // Free FormSet Default Store
784 //
785 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
786 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
787 Link = GetFirstNode (&FormSet->DefaultStoreListHead);
788 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);
789 RemoveEntryList (&DefaultStore->Link);
790
791 FreePool (DefaultStore);
792 }
793 }
794
795 //
796 // Free Formset Expressions
797 //
798 while (!IsListEmpty (&FormSet->ExpressionListHead)) {
799 Link = GetFirstNode (&FormSet->ExpressionListHead);
800 Expression = FORM_EXPRESSION_FROM_LINK (Link);
801 RemoveEntryList (&Expression->Link);
802
803 DestroyExpression (Expression);
804 }
805
806 //
807 // Free Forms
808 //
809 if (FormSet->FormListHead.ForwardLink != NULL) {
810 while (!IsListEmpty (&FormSet->FormListHead)) {
811 Link = GetFirstNode (&FormSet->FormListHead);
812 Form = FORM_BROWSER_FORM_FROM_LINK (Link);
813 RemoveEntryList (&Form->Link);
814
815 DestroyForm (FormSet, Form);
816 }
817 }
818
819 if (FormSet->StatementBuffer != NULL) {
820 FreePool (FormSet->StatementBuffer);
821 }
822 if (FormSet->ExpressionBuffer != NULL) {
823 FreePool (FormSet->ExpressionBuffer);
824 }
825
826 FreePool (FormSet);
827 }
828
829
830 /**
831 Tell whether this Operand is an Expression OpCode or not
832
833 @param Operand Operand of an IFR OpCode.
834
835 @retval TRUE This is an Expression OpCode.
836 @retval FALSE Not an Expression OpCode.
837
838 **/
839 BOOLEAN
840 IsExpressionOpCode (
841 IN UINT8 Operand
842 )
843 {
844 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||
845 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) ||
846 ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||
847 (Operand == EFI_IFR_CATENATE_OP) ||
848 (Operand == EFI_IFR_TO_LOWER_OP) ||
849 (Operand == EFI_IFR_TO_UPPER_OP) ||
850 (Operand == EFI_IFR_MAP_OP) ||
851 (Operand == EFI_IFR_VERSION_OP) ||
852 (Operand == EFI_IFR_SECURITY_OP)) {
853 return TRUE;
854 } else {
855 return FALSE;
856 }
857 }
858
859
860 /**
861 Calculate number of Statemens(Questions) and Expression OpCodes.
862
863 @param FormSet The FormSet to be counted.
864 @param NumberOfStatement Number of Statemens(Questions)
865 @param NumberOfExpression Number of Expression OpCodes
866
867 **/
868 VOID
869 CountOpCodes (
870 IN FORM_BROWSER_FORMSET *FormSet,
871 IN OUT UINT16 *NumberOfStatement,
872 IN OUT UINT16 *NumberOfExpression
873 )
874 {
875 UINT16 StatementCount;
876 UINT16 ExpressionCount;
877 UINT8 *OpCodeData;
878 UINTN Offset;
879 UINTN OpCodeLen;
880
881 Offset = 0;
882 StatementCount = 0;
883 ExpressionCount = 0;
884
885 while (Offset < FormSet->IfrBinaryLength) {
886 OpCodeData = FormSet->IfrBinaryData + Offset;
887 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
888 Offset += OpCodeLen;
889
890 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {
891 ExpressionCount++;
892 } else {
893 StatementCount++;
894 }
895 }
896
897 *NumberOfStatement = StatementCount;
898 *NumberOfExpression = ExpressionCount;
899 }
900
901
902
903 /**
904 Parse opcodes in the formset IFR binary.
905
906 @param FormSet Pointer of the FormSet data structure.
907
908 @retval EFI_SUCCESS Opcode parse success.
909 @retval Other Opcode parse fail.
910
911 **/
912 EFI_STATUS
913 ParseOpCodes (
914 IN FORM_BROWSER_FORMSET *FormSet
915 )
916 {
917 EFI_STATUS Status;
918 UINT16 Index;
919 FORM_BROWSER_FORM *CurrentForm;
920 FORM_BROWSER_STATEMENT *CurrentStatement;
921 EXPRESSION_OPCODE *ExpressionOpCode;
922 FORM_EXPRESSION *CurrentExpression;
923 UINT8 Operand;
924 UINT8 Scope;
925 UINTN OpCodeOffset;
926 UINTN OpCodeLength;
927 UINT8 *OpCodeData;
928 UINT8 ScopeOpCode;
929 FORMSET_STORAGE *Storage;
930 FORMSET_DEFAULTSTORE *DefaultStore;
931 QUESTION_DEFAULT *CurrentDefault;
932 QUESTION_OPTION *CurrentOption;
933 UINT8 Width;
934 CHAR8 *AsciiString;
935 UINT16 NumberOfStatement;
936 UINT16 NumberOfExpression;
937 EFI_IMAGE_ID *ImageId;
938 BOOLEAN SuppressForQuestion;
939 BOOLEAN SuppressForOption;
940 UINT16 DepthOfDisable;
941 BOOLEAN OpCodeDisabled;
942 BOOLEAN SingleOpCodeExpression;
943 BOOLEAN InScopeDefault;
944 EFI_HII_VALUE *Value;
945 EFI_IFR_FORM_MAP_METHOD *MapMethod;
946 UINT8 MapScopeDepth;
947 LIST_ENTRY *Link;
948 FORMSET_STORAGE *VarStorage;
949 LIST_ENTRY *MapExpressionList;
950 EFI_VARSTORE_ID TempVarstoreId;
951 BOOLEAN InScopeDisable;
952 INTN ConditionalExprCount;
953
954 mInScopeSubtitle = FALSE;
955 SuppressForQuestion = FALSE;
956 SuppressForOption = FALSE;
957 InScopeDisable = FALSE;
958 DepthOfDisable = 0;
959 OpCodeDisabled = FALSE;
960 SingleOpCodeExpression = FALSE;
961 InScopeDefault = FALSE;
962 CurrentExpression = NULL;
963 CurrentDefault = NULL;
964 CurrentOption = NULL;
965 ImageId = NULL;
966 MapMethod = NULL;
967 MapScopeDepth = 0;
968 Link = NULL;
969 VarStorage = NULL;
970 MapExpressionList = NULL;
971 TempVarstoreId = 0;
972 ConditionalExprCount = 0;
973
974 //
975 // Get the number of Statements and Expressions
976 //
977 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
978
979 mStatementIndex = 0;
980 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
981 if (FormSet->StatementBuffer == NULL) {
982 return EFI_OUT_OF_RESOURCES;
983 }
984
985 mExpressionOpCodeIndex = 0;
986 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));
987 if (FormSet->ExpressionBuffer == NULL) {
988 return EFI_OUT_OF_RESOURCES;
989 }
990
991 InitializeListHead (&FormSet->StorageListHead);
992 InitializeListHead (&FormSet->DefaultStoreListHead);
993 InitializeListHead (&FormSet->FormListHead);
994 InitializeListHead (&FormSet->ExpressionListHead);
995 ResetCurrentExpressionStack ();
996 ResetMapExpressionListStack ();
997
998 CurrentForm = NULL;
999 CurrentStatement = NULL;
1000
1001 ResetScopeStack ();
1002
1003 OpCodeOffset = 0;
1004 while (OpCodeOffset < FormSet->IfrBinaryLength) {
1005 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;
1006
1007 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
1008 OpCodeOffset += OpCodeLength;
1009 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
1010 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;
1011
1012 //
1013 // If scope bit set, push onto scope stack
1014 //
1015 if (Scope != 0) {
1016 PushScope (Operand);
1017 }
1018
1019 if (OpCodeDisabled) {
1020 //
1021 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1022 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1023 //
1024 if (Operand == EFI_IFR_DISABLE_IF_OP) {
1025 DepthOfDisable++;
1026 } else if (Operand == EFI_IFR_END_OP) {
1027 Status = PopScope (&ScopeOpCode);
1028 if (EFI_ERROR (Status)) {
1029 return Status;
1030 }
1031
1032 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {
1033 if (DepthOfDisable == 0) {
1034 InScopeDisable = FALSE;
1035 OpCodeDisabled = FALSE;
1036 } else {
1037 DepthOfDisable--;
1038 }
1039 }
1040 }
1041 continue;
1042 }
1043
1044 if (IsExpressionOpCode (Operand)) {
1045 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];
1046 mExpressionOpCodeIndex++;
1047
1048 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;
1049 ExpressionOpCode->Operand = Operand;
1050 Value = &ExpressionOpCode->Value;
1051
1052 switch (Operand) {
1053 case EFI_IFR_EQ_ID_VAL_OP:
1054 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1055
1056 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1057 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));
1058 break;
1059
1060 case EFI_IFR_EQ_ID_ID_OP:
1061 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));
1062 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));
1063 break;
1064
1065 case EFI_IFR_EQ_ID_VAL_LIST_OP:
1066 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1067 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));
1068 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);
1069 break;
1070
1071 case EFI_IFR_TO_STRING_OP:
1072 case EFI_IFR_FIND_OP:
1073 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;
1074 break;
1075
1076 case EFI_IFR_STRING_REF1_OP:
1077 Value->Type = EFI_IFR_TYPE_STRING;
1078 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));
1079 break;
1080
1081 case EFI_IFR_RULE_REF_OP:
1082 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;
1083 break;
1084
1085 case EFI_IFR_SPAN_OP:
1086 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;
1087 break;
1088
1089 case EFI_IFR_THIS_OP:
1090 ASSERT (CurrentStatement != NULL);
1091 ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;
1092 break;
1093
1094 case EFI_IFR_SECURITY_OP:
1095 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));
1096 break;
1097
1098 case EFI_IFR_GET_OP:
1099 case EFI_IFR_SET_OP:
1100 CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));
1101 if (TempVarstoreId != 0) {
1102 if (FormSet->StorageListHead.ForwardLink != NULL) {
1103 Link = GetFirstNode (&FormSet->StorageListHead);
1104 while (!IsNull (&FormSet->StorageListHead, Link)) {
1105 VarStorage = FORMSET_STORAGE_FROM_LINK (Link);
1106 if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {
1107 ExpressionOpCode->VarStorage = VarStorage;
1108 break;
1109 }
1110 Link = GetNextNode (&FormSet->StorageListHead, Link);
1111 }
1112 }
1113 if (ExpressionOpCode->VarStorage == NULL) {
1114 //
1115 // VarStorage is not found.
1116 //
1117 return EFI_INVALID_PARAMETER;
1118 }
1119 }
1120 ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;
1121 switch (ExpressionOpCode->ValueType) {
1122 case EFI_IFR_TYPE_BOOLEAN:
1123 case EFI_IFR_TYPE_NUM_SIZE_8:
1124 ExpressionOpCode->ValueWidth = 1;
1125 break;
1126
1127 case EFI_IFR_TYPE_NUM_SIZE_16:
1128 case EFI_IFR_TYPE_STRING:
1129 ExpressionOpCode->ValueWidth = 2;
1130 break;
1131
1132 case EFI_IFR_TYPE_NUM_SIZE_32:
1133 ExpressionOpCode->ValueWidth = 4;
1134 break;
1135
1136 case EFI_IFR_TYPE_NUM_SIZE_64:
1137 ExpressionOpCode->ValueWidth = 8;
1138 break;
1139
1140 case EFI_IFR_TYPE_DATE:
1141 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE);
1142 break;
1143
1144 case EFI_IFR_TYPE_TIME:
1145 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);
1146 break;
1147
1148 case EFI_IFR_TYPE_REF:
1149 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);
1150 break;
1151
1152 case EFI_IFR_TYPE_OTHER:
1153 case EFI_IFR_TYPE_UNDEFINED:
1154 case EFI_IFR_TYPE_ACTION:
1155 case EFI_IFR_TYPE_BUFFER:
1156 default:
1157 //
1158 // Invalid value type for Get/Set opcode.
1159 //
1160 return EFI_INVALID_PARAMETER;
1161 }
1162 CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID));
1163 CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));
1164 if ((ExpressionOpCode->VarStorage != NULL) &&
1165 (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE ||
1166 ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
1167 ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);
1168 if (ExpressionOpCode->ValueName == NULL) {
1169 //
1170 // String ID is invalid.
1171 //
1172 return EFI_INVALID_PARAMETER;
1173 }
1174 }
1175 break;
1176
1177 case EFI_IFR_QUESTION_REF1_OP:
1178 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1179 break;
1180
1181 case EFI_IFR_QUESTION_REF3_OP:
1182 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {
1183 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1184
1185 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {
1186 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));
1187 }
1188 }
1189 break;
1190
1191 //
1192 // constant
1193 //
1194 case EFI_IFR_TRUE_OP:
1195 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1196 Value->Value.b = TRUE;
1197 break;
1198
1199 case EFI_IFR_FALSE_OP:
1200 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1201 Value->Value.b = FALSE;
1202 break;
1203
1204 case EFI_IFR_ONE_OP:
1205 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1206 Value->Value.u8 = 1;
1207 break;
1208
1209 case EFI_IFR_ZERO_OP:
1210 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1211 Value->Value.u8 = 0;
1212 break;
1213
1214 case EFI_IFR_ONES_OP:
1215 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1216 Value->Value.u64 = 0xffffffffffffffffULL;
1217 break;
1218
1219 case EFI_IFR_UINT8_OP:
1220 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1221 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;
1222 break;
1223
1224 case EFI_IFR_UINT16_OP:
1225 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1226 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));
1227 break;
1228
1229 case EFI_IFR_UINT32_OP:
1230 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1231 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));
1232 break;
1233
1234 case EFI_IFR_UINT64_OP:
1235 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1236 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));
1237 break;
1238
1239 case EFI_IFR_UNDEFINED_OP:
1240 Value->Type = EFI_IFR_TYPE_UNDEFINED;
1241 break;
1242
1243 case EFI_IFR_VERSION_OP:
1244 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1245 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;
1246 break;
1247
1248 default:
1249 break;
1250 }
1251 //
1252 // Create sub expression nested in MAP opcode
1253 //
1254 if (CurrentExpression == NULL && MapScopeDepth > 0) {
1255 CurrentExpression = CreateExpression (CurrentForm);
1256 ASSERT (MapExpressionList != NULL);
1257 InsertTailList (MapExpressionList, &CurrentExpression->Link);
1258 if (Scope == 0) {
1259 SingleOpCodeExpression = TRUE;
1260 }
1261 }
1262 ASSERT (CurrentExpression != NULL);
1263 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);
1264 if (Operand == EFI_IFR_MAP_OP) {
1265 //
1266 // Store current Map Expression List.
1267 //
1268 if (MapExpressionList != NULL) {
1269 PushMapExpressionList (MapExpressionList);
1270 }
1271 //
1272 // Initialize new Map Expression List.
1273 //
1274 MapExpressionList = &ExpressionOpCode->MapExpressionList;
1275 InitializeListHead (MapExpressionList);
1276 //
1277 // Store current expression.
1278 //
1279 PushCurrentExpression (CurrentExpression);
1280 CurrentExpression = NULL;
1281 MapScopeDepth ++;
1282 } else if (SingleOpCodeExpression) {
1283 //
1284 // There are two cases to indicate the end of an Expression:
1285 // for single OpCode expression: one Expression OpCode
1286 // for expression consists of more than one OpCode: EFI_IFR_END
1287 //
1288 SingleOpCodeExpression = FALSE;
1289
1290 if (InScopeDisable && CurrentForm == NULL) {
1291 //
1292 // This is DisableIf expression for Form, it should be a constant expression
1293 //
1294 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
1295 if (EFI_ERROR (Status)) {
1296 return Status;
1297 }
1298
1299 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
1300 return EFI_INVALID_PARAMETER;
1301 }
1302
1303 OpCodeDisabled = CurrentExpression->Result.Value.b;
1304 }
1305
1306 CurrentExpression = NULL;
1307 }
1308
1309 continue;
1310 }
1311
1312 //
1313 // Parse the Opcode
1314 //
1315 switch (Operand) {
1316
1317 case EFI_IFR_FORM_SET_OP:
1318 //
1319 // Check the formset GUID
1320 //
1321 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {
1322 return EFI_INVALID_PARAMETER;
1323 }
1324
1325 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
1326 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
1327
1328 if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
1329 //
1330 // The formset OpCode contains ClassGuid
1331 //
1332 FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);
1333 CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));
1334 }
1335 break;
1336
1337 case EFI_IFR_FORM_OP:
1338 //
1339 // Create a new Form for this FormSet
1340 //
1341 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1342 ASSERT (CurrentForm != NULL);
1343 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1344 InitializeListHead (&CurrentForm->ExpressionListHead);
1345 InitializeListHead (&CurrentForm->StatementListHead);
1346 InitializeListHead (&CurrentForm->ConfigRequestHead);
1347
1348 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1349 CurrentForm->NvUpdateRequired = FALSE;
1350 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1351 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
1352
1353 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
1354 if ( ConditionalExprCount > 0) {
1355 //
1356 // Form is inside of suppressif
1357 //
1358 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1359 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1360 ASSERT (CurrentForm->SuppressExpression != NULL);
1361 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1362 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1363 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
1364 }
1365
1366 if (Scope != 0) {
1367 //
1368 // Enter scope of a Form, suppressif will be used for Question or Option
1369 //
1370 SuppressForQuestion = TRUE;
1371 }
1372
1373 //
1374 // Insert into Form list of this FormSet
1375 //
1376 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1377 break;
1378
1379 case EFI_IFR_FORM_MAP_OP:
1380 //
1381 // Create a new Form for this FormSet
1382 //
1383 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1384 ASSERT (CurrentForm != NULL);
1385 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1386 CurrentForm->NvUpdateRequired = FALSE;
1387 InitializeListHead (&CurrentForm->ExpressionListHead);
1388 InitializeListHead (&CurrentForm->StatementListHead);
1389 InitializeListHead (&CurrentForm->ConfigRequestHead);
1390 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1391
1392 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1393 //
1394 // FormMap Form must contain at least one Map Method.
1395 //
1396 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {
1397 return EFI_INVALID_PARAMETER;
1398 }
1399 //
1400 // Try to find the standard form map method.
1401 //
1402 while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {
1403 if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {
1404 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1405 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1406 break;
1407 }
1408 MapMethod ++;
1409 }
1410 //
1411 // If the standard form map method is not found, the first map method title will be used.
1412 //
1413 if (CurrentForm->FormTitle == 0) {
1414 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1415 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1416 }
1417
1418 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
1419 if ( ConditionalExprCount > 0) {
1420 //
1421 // Form is inside of suppressif
1422 //
1423 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1424 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1425 ASSERT (CurrentForm->SuppressExpression != NULL);
1426 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1427 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1428 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
1429 }
1430
1431 if (Scope != 0) {
1432 //
1433 // Enter scope of a Form, suppressif will be used for Question or Option
1434 //
1435 SuppressForQuestion = TRUE;
1436 }
1437
1438 //
1439 // Insert into Form list of this FormSet
1440 //
1441 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1442 break;
1443
1444 //
1445 // Storage
1446 //
1447 case EFI_IFR_VARSTORE_OP:
1448 //
1449 // Create a buffer Storage for this FormSet
1450 //
1451 Storage = CreateStorage (FormSet);
1452 Storage->Type = EFI_HII_VARSTORE_BUFFER;
1453
1454 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1455 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));
1456 CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));
1457
1458 Storage->Buffer = AllocateZeroPool (Storage->Size);
1459 Storage->EditBuffer = AllocateZeroPool (Storage->Size);
1460
1461 AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;
1462 Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);
1463 ASSERT (Storage->Name != NULL);
1464 for (Index = 0; AsciiString[Index] != 0; Index++) {
1465 Storage->Name[Index] = (CHAR16) AsciiString[Index];
1466 }
1467
1468 //
1469 // Initialize <ConfigHdr>
1470 //
1471 InitializeConfigHdr (FormSet, Storage);
1472 break;
1473
1474 case EFI_IFR_VARSTORE_NAME_VALUE_OP:
1475 //
1476 // Create a name/value Storage for this FormSet
1477 //
1478 Storage = CreateStorage (FormSet);
1479 Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;
1480
1481 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1482 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));
1483
1484 //
1485 // Initialize <ConfigHdr>
1486 //
1487 InitializeConfigHdr (FormSet, Storage);
1488 break;
1489
1490 case EFI_IFR_VARSTORE_EFI_OP:
1491 //
1492 // Create a EFI variable Storage for this FormSet
1493 //
1494 Storage = CreateStorage (FormSet);
1495
1496 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1497 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));
1498 CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));
1499 CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Size, sizeof (UINT16));
1500
1501 if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) {
1502 Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;
1503 break;
1504 }
1505
1506 Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER;
1507 Storage->Buffer = AllocateZeroPool (Storage->Size);
1508 Storage->EditBuffer = AllocateZeroPool (Storage->Size);
1509
1510 AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Name;
1511 Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);
1512 ASSERT (Storage->Name != NULL);
1513 for (Index = 0; AsciiString[Index] != 0; Index++) {
1514 Storage->Name[Index] = (CHAR16) AsciiString[Index];
1515 }
1516
1517 //
1518 // Initialize <ConfigHdr>
1519 //
1520 InitializeConfigHdr (FormSet, Storage);
1521 break;
1522
1523 //
1524 // DefaultStore
1525 //
1526 case EFI_IFR_DEFAULTSTORE_OP:
1527 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
1528 ASSERT (DefaultStore != NULL);
1529 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
1530
1531 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));
1532 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
1533
1534 //
1535 // Insert to DefaultStore list of this Formset
1536 //
1537 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
1538 break;
1539
1540 //
1541 // Statements
1542 //
1543 case EFI_IFR_SUBTITLE_OP:
1544 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1545 ASSERT (CurrentStatement != NULL);
1546
1547 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
1548
1549 if (Scope != 0) {
1550 mInScopeSubtitle = TRUE;
1551 }
1552 break;
1553
1554 case EFI_IFR_TEXT_OP:
1555 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1556 ASSERT (CurrentStatement != NULL);
1557
1558 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
1559 break;
1560
1561 case EFI_IFR_RESET_BUTTON_OP:
1562 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1563 ASSERT (CurrentStatement != NULL);
1564 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
1565 break;
1566
1567 //
1568 // Questions
1569 //
1570 case EFI_IFR_ACTION_OP:
1571 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1572 ASSERT (CurrentStatement != NULL);
1573 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;
1574
1575 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
1576 //
1577 // No QuestionConfig present, so no configuration string will be processed
1578 //
1579 CurrentStatement->QuestionConfig = 0;
1580 } else {
1581 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
1582 }
1583 break;
1584
1585 case EFI_IFR_REF_OP:
1586 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1587 ASSERT (CurrentStatement != NULL);
1588 Value = &CurrentStatement->HiiValue;
1589 Value->Type = EFI_IFR_TYPE_REF;
1590 if (OpCodeLength >= sizeof (EFI_IFR_REF)) {
1591 CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
1592
1593 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
1594 CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1595
1596 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
1597 CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
1598
1599 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
1600 CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1601 }
1602 }
1603 }
1604 }
1605 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);
1606 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1607 break;
1608
1609 case EFI_IFR_ONE_OF_OP:
1610 case EFI_IFR_NUMERIC_OP:
1611 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1612 ASSERT(CurrentStatement != NULL);
1613
1614 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
1615 Value = &CurrentStatement->HiiValue;
1616
1617 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
1618 case EFI_IFR_NUMERIC_SIZE_1:
1619 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
1620 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
1621 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
1622 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);
1623 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1624 break;
1625
1626 case EFI_IFR_NUMERIC_SIZE_2:
1627 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
1628 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
1629 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));
1630 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);
1631 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1632 break;
1633
1634 case EFI_IFR_NUMERIC_SIZE_4:
1635 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
1636 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
1637 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));
1638 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);
1639 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1640 break;
1641
1642 case EFI_IFR_NUMERIC_SIZE_8:
1643 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
1644 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
1645 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));
1646 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);
1647 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1648 break;
1649
1650 default:
1651 break;
1652 }
1653
1654 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1655
1656 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {
1657 SuppressForOption = TRUE;
1658 }
1659 break;
1660
1661 case EFI_IFR_ORDERED_LIST_OP:
1662 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1663 ASSERT(CurrentStatement != NULL);
1664
1665 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;
1666 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;
1667
1668 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;
1669 CurrentStatement->BufferValue = NULL;
1670
1671 if (Scope != 0) {
1672 SuppressForOption = TRUE;
1673 }
1674 break;
1675
1676 case EFI_IFR_CHECKBOX_OP:
1677 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1678 ASSERT(CurrentStatement != NULL);
1679
1680 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;
1681 CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);
1682 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
1683
1684 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1685
1686 break;
1687
1688 case EFI_IFR_STRING_OP:
1689 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1690 ASSERT (CurrentStatement != NULL);
1691 //
1692 // MinSize is the minimum number of characters that can be accepted for this opcode,
1693 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1694 // The characters are stored as Unicode, so the storage width should multiply 2.
1695 //
1696 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;
1697 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;
1698 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
1699 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;
1700
1701 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1702 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));
1703 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
1704
1705 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1706 break;
1707
1708 case EFI_IFR_PASSWORD_OP:
1709 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1710 ASSERT (CurrentStatement != NULL);
1711 //
1712 // MinSize is the minimum number of characters that can be accepted for this opcode,
1713 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1714 // The characters are stored as Unicode, so the storage width should multiply 2.
1715 //
1716 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));
1717 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));
1718 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
1719
1720 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1721 CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));
1722 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
1723
1724 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1725 break;
1726
1727 case EFI_IFR_DATE_OP:
1728 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1729 ASSERT(CurrentStatement != NULL);
1730
1731 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;
1732 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
1733
1734 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {
1735 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);
1736
1737 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1738 } else {
1739 //
1740 // Don't assign storage for RTC type of date/time
1741 //
1742 CurrentStatement->Storage = NULL;
1743 CurrentStatement->StorageWidth = 0;
1744 }
1745 break;
1746
1747 case EFI_IFR_TIME_OP:
1748 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1749 ASSERT(CurrentStatement != NULL);
1750
1751 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;
1752 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
1753
1754 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {
1755 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);
1756
1757 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1758 } else {
1759 //
1760 // Don't assign storage for RTC type of date/time
1761 //
1762 CurrentStatement->Storage = NULL;
1763 CurrentStatement->StorageWidth = 0;
1764 }
1765 break;
1766
1767 //
1768 // Default
1769 //
1770 case EFI_IFR_DEFAULT_OP:
1771 //
1772 // EFI_IFR_DEFAULT appear in scope of a Question,
1773 // It creates a default value for the current question.
1774 // A Question may have more than one Default value which have different default types.
1775 //
1776 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
1777 ASSERT (CurrentDefault != NULL);
1778 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
1779
1780 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
1781 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
1782 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
1783 ExtendValueToU64 (&CurrentDefault->Value);
1784
1785 //
1786 // Insert to Default Value list of current Question
1787 //
1788 InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);
1789
1790 if (Scope != 0) {
1791 InScopeDefault = TRUE;
1792 }
1793 break;
1794
1795 //
1796 // Option
1797 //
1798 case EFI_IFR_ONE_OF_OPTION_OP:
1799 //
1800 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1801 // It create a selection for use in current Question.
1802 //
1803 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
1804 ASSERT (CurrentOption != NULL);
1805 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
1806
1807 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
1808 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
1809 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
1810 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
1811 ExtendValueToU64 (&CurrentOption->Value);
1812
1813 ConditionalExprCount = GetConditionalExpressionCount(ExpressOption);
1814 if ( ConditionalExprCount > 0) {
1815 //
1816 // Form is inside of suppressif
1817 //
1818 CurrentOption->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1819 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1820 ASSERT (CurrentOption->SuppressExpression != NULL);
1821 CurrentOption->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1822 CurrentOption->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1823 CopyMem (CurrentOption->SuppressExpression->Expression, GetConditionalExpressionList(ExpressOption), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
1824 }
1825
1826 //
1827 // Insert to Option list of current Question
1828 //
1829 InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);
1830
1831 //
1832 // Now we know the Storage width of nested Ordered List
1833 //
1834 ASSERT (CurrentStatement != NULL);
1835 if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) {
1836 Width = 1;
1837 switch (CurrentOption->Value.Type) {
1838 case EFI_IFR_TYPE_NUM_SIZE_8:
1839 Width = 1;
1840 break;
1841
1842 case EFI_IFR_TYPE_NUM_SIZE_16:
1843 Width = 2;
1844 break;
1845
1846 case EFI_IFR_TYPE_NUM_SIZE_32:
1847 Width = 4;
1848 break;
1849
1850 case EFI_IFR_TYPE_NUM_SIZE_64:
1851 Width = 8;
1852 break;
1853
1854 default:
1855 //
1856 // Invalid type for Ordered List
1857 //
1858 break;
1859 }
1860
1861 CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);
1862 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
1863 CurrentStatement->ValueType = CurrentOption->Value.Type;
1864 if (CurrentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {
1865 CurrentStatement->HiiValue.Buffer = CurrentStatement->BufferValue;
1866 CurrentStatement->HiiValue.BufferLen = CurrentStatement->StorageWidth;
1867 }
1868
1869 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1870 }
1871 break;
1872
1873 //
1874 // Conditional
1875 //
1876 case EFI_IFR_NO_SUBMIT_IF_OP:
1877 case EFI_IFR_INCONSISTENT_IF_OP:
1878 //
1879 // Create an Expression node
1880 //
1881 CurrentExpression = CreateExpression (CurrentForm);
1882 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));
1883
1884 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {
1885 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;
1886 InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);
1887 } else {
1888 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;
1889 InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);
1890 }
1891
1892 //
1893 // Take a look at next OpCode to see whether current expression consists
1894 // of single OpCode
1895 //
1896 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1897 SingleOpCodeExpression = TRUE;
1898 }
1899 break;
1900
1901 case EFI_IFR_SUPPRESS_IF_OP:
1902 //
1903 // Question and Option will appear in scope of this OpCode
1904 //
1905 CurrentExpression = CreateExpression (CurrentForm);
1906 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;
1907
1908 if (CurrentForm == NULL) {
1909 InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);
1910 } else {
1911 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1912 }
1913
1914 if (SuppressForOption) {
1915 PushConditionalExpression(CurrentExpression, ExpressOption);
1916 } else if (SuppressForQuestion) {
1917 PushConditionalExpression(CurrentExpression, ExpressStatement);
1918 } else {
1919 PushConditionalExpression(CurrentExpression, ExpressForm);
1920 }
1921
1922 //
1923 // Take a look at next OpCode to see whether current expression consists
1924 // of single OpCode
1925 //
1926 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1927 SingleOpCodeExpression = TRUE;
1928 }
1929 break;
1930
1931 case EFI_IFR_GRAY_OUT_IF_OP:
1932 //
1933 // Questions will appear in scope of this OpCode
1934 //
1935 CurrentExpression = CreateExpression (CurrentForm);
1936 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;
1937 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1938 PushConditionalExpression(CurrentExpression, ExpressStatement);
1939
1940 //
1941 // Take a look at next OpCode to see whether current expression consists
1942 // of single OpCode
1943 //
1944 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1945 SingleOpCodeExpression = TRUE;
1946 }
1947 break;
1948
1949 case EFI_IFR_DISABLE_IF_OP:
1950 //
1951 // The DisableIf expression should only rely on constant, so it could be
1952 // evaluated at initialization and it will not be queued
1953 //
1954 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
1955 ASSERT (CurrentExpression != NULL);
1956 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;
1957 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;
1958 InitializeListHead (&CurrentExpression->OpCodeListHead);
1959
1960 if (CurrentForm != NULL) {
1961 //
1962 // This is DisableIf for Question, enqueue it to Form expression list
1963 //
1964 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1965 PushConditionalExpression(CurrentExpression, ExpressStatement);
1966 }
1967
1968 OpCodeDisabled = FALSE;
1969 InScopeDisable = TRUE;
1970 //
1971 // Take a look at next OpCode to see whether current expression consists
1972 // of single OpCode
1973 //
1974 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1975 SingleOpCodeExpression = TRUE;
1976 }
1977 break;
1978
1979 //
1980 // Expression
1981 //
1982 case EFI_IFR_VALUE_OP:
1983 CurrentExpression = CreateExpression (CurrentForm);
1984 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;
1985 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1986
1987 if (InScopeDefault) {
1988 //
1989 // Used for default (EFI_IFR_DEFAULT)
1990 //
1991 CurrentDefault->ValueExpression = CurrentExpression;
1992 } else {
1993 //
1994 // If used for a question, then the question will be read-only
1995 //
1996 //
1997 // Make sure CurrentStatement is not NULL.
1998 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1999 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2000 //
2001 ASSERT (CurrentStatement != NULL);
2002 CurrentStatement->ValueExpression = CurrentExpression;
2003 }
2004
2005 //
2006 // Take a look at next OpCode to see whether current expression consists
2007 // of single OpCode
2008 //
2009 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2010 SingleOpCodeExpression = TRUE;
2011 }
2012 break;
2013
2014 case EFI_IFR_RULE_OP:
2015 CurrentExpression = CreateExpression (CurrentForm);
2016 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;
2017
2018 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;
2019 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2020
2021 //
2022 // Take a look at next OpCode to see whether current expression consists
2023 // of single OpCode
2024 //
2025 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2026 SingleOpCodeExpression = TRUE;
2027 }
2028 break;
2029
2030 case EFI_IFR_READ_OP:
2031 CurrentExpression = CreateExpression (CurrentForm);
2032 CurrentExpression->Type = EFI_HII_EXPRESSION_READ;
2033 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2034
2035 //
2036 // Make sure CurrentStatement is not NULL.
2037 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2038 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2039 //
2040 ASSERT (CurrentStatement != NULL);
2041 CurrentStatement->ReadExpression = CurrentExpression;
2042
2043 //
2044 // Take a look at next OpCode to see whether current expression consists
2045 // of single OpCode
2046 //
2047 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2048 SingleOpCodeExpression = TRUE;
2049 }
2050 break;
2051
2052 case EFI_IFR_WRITE_OP:
2053 CurrentExpression = CreateExpression (CurrentForm);
2054 CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;
2055 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2056
2057 //
2058 // Make sure CurrentStatement is not NULL.
2059 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2060 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2061 //
2062 ASSERT (CurrentStatement != NULL);
2063 CurrentStatement->WriteExpression = CurrentExpression;
2064
2065 //
2066 // Take a look at next OpCode to see whether current expression consists
2067 // of single OpCode
2068 //
2069 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2070 SingleOpCodeExpression = TRUE;
2071 }
2072 break;
2073
2074 //
2075 // Image
2076 //
2077 case EFI_IFR_IMAGE_OP:
2078 //
2079 // Get ScopeOpcode from top of stack
2080 //
2081 PopScope (&ScopeOpCode);
2082 PushScope (ScopeOpCode);
2083
2084 switch (ScopeOpCode) {
2085 case EFI_IFR_FORM_SET_OP:
2086 ImageId = &FormSet->ImageId;
2087 break;
2088
2089 case EFI_IFR_FORM_OP:
2090 case EFI_IFR_FORM_MAP_OP:
2091 ASSERT (CurrentForm != NULL);
2092 ImageId = &CurrentForm->ImageId;
2093 break;
2094
2095 case EFI_IFR_ONE_OF_OPTION_OP:
2096 ImageId = &CurrentOption->ImageId;
2097 break;
2098
2099 default:
2100 //
2101 // Make sure CurrentStatement is not NULL.
2102 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2103 // file is wrongly generated by tools such as VFR Compiler.
2104 //
2105 ASSERT (CurrentStatement != NULL);
2106 ImageId = &CurrentStatement->ImageId;
2107 break;
2108 }
2109
2110 ASSERT (ImageId != NULL);
2111 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
2112 break;
2113
2114 //
2115 // Refresh
2116 //
2117 case EFI_IFR_REFRESH_OP:
2118 ASSERT (CurrentStatement != NULL);
2119 CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;
2120 break;
2121
2122 //
2123 // Refresh guid.
2124 //
2125 case EFI_IFR_REFRESH_ID_OP:
2126 ASSERT (CurrentStatement != NULL);
2127 CopyMem (&CurrentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));
2128 break;
2129
2130 //
2131 // Modal tag
2132 //
2133 case EFI_IFR_MODAL_TAG_OP:
2134 ASSERT (CurrentForm != NULL);
2135 CurrentForm->ModalForm = TRUE;
2136 break;
2137
2138 //
2139 // Lock tag, used by form and statement.
2140 //
2141 case EFI_IFR_LOCKED_OP:
2142 //
2143 // Get ScopeOpcode from top of stack
2144 //
2145 PopScope (&ScopeOpCode);
2146 PushScope (ScopeOpCode);
2147 switch (ScopeOpCode) {
2148 case EFI_IFR_FORM_OP:
2149 case EFI_IFR_FORM_MAP_OP:
2150 ASSERT (CurrentForm != NULL);
2151 CurrentForm->Locked = TRUE;
2152 break;
2153
2154 default:
2155 ASSERT (CurrentStatement != NULL);
2156 CurrentStatement->Locked = TRUE;
2157 }
2158 break;
2159
2160 //
2161 // Vendor specific
2162 //
2163 case EFI_IFR_GUID_OP:
2164 if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
2165 //
2166 // Tiano specific GUIDed opcodes
2167 //
2168 switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {
2169 case EFI_IFR_EXTEND_OP_LABEL:
2170 //
2171 // just ignore label
2172 //
2173 break;
2174
2175 case EFI_IFR_EXTEND_OP_BANNER:
2176 //
2177 // By SubClass to get Banner Data from Front Page
2178 //
2179 if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {
2180 CopyMem (
2181 &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][
2182 ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],
2183 &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,
2184 sizeof (EFI_STRING_ID)
2185 );
2186 }
2187 break;
2188
2189 case EFI_IFR_EXTEND_OP_CLASS:
2190 CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));
2191 break;
2192
2193 case EFI_IFR_EXTEND_OP_SUBCLASS:
2194 CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));
2195 break;
2196
2197 default:
2198 break;
2199 }
2200 }
2201
2202 break;
2203
2204 //
2205 // Scope End
2206 //
2207 case EFI_IFR_END_OP:
2208 Status = PopScope (&ScopeOpCode);
2209 if (EFI_ERROR (Status)) {
2210 ResetScopeStack ();
2211 return Status;
2212 }
2213
2214 switch (ScopeOpCode) {
2215 case EFI_IFR_FORM_SET_OP:
2216 //
2217 // End of FormSet, update FormSet IFR binary length
2218 // to stop parsing substantial OpCodes
2219 //
2220 FormSet->IfrBinaryLength = OpCodeOffset;
2221 break;
2222
2223 case EFI_IFR_FORM_OP:
2224 case EFI_IFR_FORM_MAP_OP:
2225 //
2226 // End of Form
2227 //
2228 CurrentForm = NULL;
2229 SuppressForQuestion = FALSE;
2230 break;
2231
2232 case EFI_IFR_ONE_OF_OPTION_OP:
2233 //
2234 // End of Option
2235 //
2236 CurrentOption = NULL;
2237 break;
2238
2239 case EFI_IFR_SUBTITLE_OP:
2240 mInScopeSubtitle = FALSE;
2241 break;
2242
2243 case EFI_IFR_NO_SUBMIT_IF_OP:
2244 case EFI_IFR_INCONSISTENT_IF_OP:
2245 //
2246 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2247 //
2248 break;
2249
2250 case EFI_IFR_SUPPRESS_IF_OP:
2251 if (SuppressForOption) {
2252 PopConditionalExpression(ExpressOption);
2253 } else if (SuppressForQuestion) {
2254 PopConditionalExpression(ExpressStatement);
2255 } else {
2256 PopConditionalExpression(ExpressForm);
2257 }
2258 break;
2259
2260 case EFI_IFR_GRAY_OUT_IF_OP:
2261 PopConditionalExpression(ExpressStatement);
2262 break;
2263
2264 case EFI_IFR_DISABLE_IF_OP:
2265 if (CurrentForm != NULL) {
2266 PopConditionalExpression(ExpressStatement);
2267 }
2268 InScopeDisable = FALSE;
2269 OpCodeDisabled = FALSE;
2270 break;
2271
2272 case EFI_IFR_ONE_OF_OP:
2273 case EFI_IFR_ORDERED_LIST_OP:
2274 SuppressForOption = FALSE;
2275 break;
2276
2277 case EFI_IFR_DEFAULT_OP:
2278 InScopeDefault = FALSE;
2279 break;
2280
2281 case EFI_IFR_MAP_OP:
2282 //
2283 // Get current Map Expression List.
2284 //
2285 Status = PopMapExpressionList ((VOID **) &MapExpressionList);
2286 if (Status == EFI_ACCESS_DENIED) {
2287 MapExpressionList = NULL;
2288 }
2289 //
2290 // Get current expression.
2291 //
2292 Status = PopCurrentExpression ((VOID **) &CurrentExpression);
2293 ASSERT_EFI_ERROR (Status);
2294 ASSERT (MapScopeDepth > 0);
2295 MapScopeDepth --;
2296 break;
2297
2298 default:
2299 if (IsExpressionOpCode (ScopeOpCode)) {
2300 if (InScopeDisable && CurrentForm == NULL) {
2301 //
2302 // This is DisableIf expression for Form, it should be a constant expression
2303 //
2304 ASSERT (CurrentExpression != NULL);
2305 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
2306 if (EFI_ERROR (Status)) {
2307 return Status;
2308 }
2309
2310 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
2311 return EFI_INVALID_PARAMETER;
2312 }
2313
2314 OpCodeDisabled = CurrentExpression->Result.Value.b;
2315 //
2316 // DisableIf Expression is only used once and not queued, free it
2317 //
2318 DestroyExpression (CurrentExpression);
2319 }
2320
2321 //
2322 // End of current Expression
2323 //
2324 CurrentExpression = NULL;
2325 }
2326 break;
2327 }
2328 break;
2329
2330 default:
2331 break;
2332 }
2333 }
2334
2335 return EFI_SUCCESS;
2336 }