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