]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParser.c
Bug fixes for FrameworkHiiToUefiHiiThunk;
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / UefiIfrParser.c
1 /** @file
2 Parser for IFR binary encoding.
3
4 Copyright (c) 2008, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "UefiIfrParser.h"
16 #include "UefiIfrParserExpression.h"
17 #include "UefiIfrParserInternal.h"
18 #include "UefiIfrParserCommon.h"
19
20
21 UINT16 mStatementIndex;
22 UINT16 mExpressionOpCodeIndex;
23
24 BOOLEAN mInScopeSubtitle;
25 BOOLEAN mInScopeSuppress;
26 BOOLEAN mInScopeGrayOut;
27 FORM_EXPRESSION *mSuppressExpression;
28 FORM_EXPRESSION *mGrayOutExpression;
29
30 EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
31
32 /**
33 Initialize Statement header members.
34
35 @param OpCodeData Pointer of the raw OpCode data.
36 @param FormSet Pointer of the current FormSe.
37 @param Form Pointer of the current Form.
38
39 @return The Statement.
40
41 **/
42 FORM_BROWSER_STATEMENT *
43 CreateStatement (
44 IN UINT8 *OpCodeData,
45 IN OUT FORM_BROWSER_FORMSET *FormSet,
46 IN OUT FORM_BROWSER_FORM *Form
47 )
48 {
49 FORM_BROWSER_STATEMENT *Statement;
50 EFI_IFR_STATEMENT_HEADER *StatementHdr;
51
52 if (Form == NULL) {
53 //
54 // We are currently not in a Form Scope, so just skip this Statement
55 //
56 return NULL;
57 }
58
59 Statement = &FormSet->StatementBuffer[mStatementIndex];
60 mStatementIndex++;
61
62 InitializeListHead (&Statement->DefaultListHead);
63 InitializeListHead (&Statement->OptionListHead);
64 InitializeListHead (&Statement->InconsistentListHead);
65 InitializeListHead (&Statement->NoSubmitListHead);
66
67 Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;
68
69 Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
70
71 StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
72 CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
73 CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));
74
75 if (mInScopeSuppress) {
76 Statement->SuppressExpression = mSuppressExpression;
77 }
78
79 if (mInScopeGrayOut) {
80 Statement->GrayOutExpression = mGrayOutExpression;
81 }
82
83 Statement->InSubtitle = mInScopeSubtitle;
84
85 //
86 // Insert this Statement into current Form
87 //
88 InsertTailList (&Form->StatementListHead, &Statement->Link);
89
90 return Statement;
91 }
92
93
94 /**
95 Initialize Question's members.
96
97 @param OpCodeData Pointer of the raw OpCode data.
98 @param FormSet Pointer of the current FormSet.
99 @param Form Pointer of the current Form.
100
101 @return The Question.
102
103 **/
104 FORM_BROWSER_STATEMENT *
105 CreateQuestion (
106 IN UINT8 *OpCodeData,
107 IN OUT FORM_BROWSER_FORMSET *FormSet,
108 IN OUT FORM_BROWSER_FORM *Form
109 )
110 {
111 FORM_BROWSER_STATEMENT *Statement;
112 EFI_IFR_QUESTION_HEADER *QuestionHdr;
113 LIST_ENTRY *Link;
114 FORMSET_STORAGE *Storage;
115 NAME_VALUE_NODE *NameValueNode;
116
117 Statement = CreateStatement (OpCodeData, FormSet, Form);
118 if (Statement == NULL) {
119 return NULL;
120 }
121
122 QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
123 CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));
124 CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));
125 CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));
126
127 Statement->QuestionFlags = QuestionHdr->Flags;
128
129 if (Statement->VarStoreId == 0) {
130 //
131 // VarStoreId of zero indicates no variable storage
132 //
133 return Statement;
134 }
135
136 //
137 // Find Storage for this Question
138 //
139 Link = GetFirstNode (&FormSet->StorageListHead);
140 while (!IsNull (&FormSet->StorageListHead, Link)) {
141 Storage = FORMSET_STORAGE_FROM_LINK (Link);
142
143 if (Storage->VarStoreId == Statement->VarStoreId) {
144 Statement->Storage = Storage;
145 break;
146 }
147
148 Link = GetNextNode (&FormSet->StorageListHead, Link);
149 }
150 ASSERT (Statement->Storage != NULL);
151
152 //
153 // Initialilze varname for Name/Value or EFI Variable
154 //
155 if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||
156 (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
157 Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);
158 ASSERT (Statement->VariableName != NULL);
159
160 if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
161 //
162 // Insert to Name/Value varstore list
163 //
164 NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));
165 ASSERT (NameValueNode != NULL);
166 NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;
167 NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);
168 ASSERT (NameValueNode->Name != NULL);
169 NameValueNode->Value = AllocateZeroPool (0x10);
170 ASSERT (NameValueNode->Value != NULL);
171 NameValueNode->EditValue = AllocateZeroPool (0x10);
172 ASSERT (NameValueNode->EditValue != NULL);
173
174 InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);
175 }
176 }
177
178 return Statement;
179 }
180
181
182 /**
183 Allocate a FORM_EXPRESSION node.
184
185 @param Form The Form associated with this Expression
186
187 @return Pointer to a FORM_EXPRESSION data structure.
188
189 **/
190 FORM_EXPRESSION *
191 CreateExpression (
192 IN OUT FORM_BROWSER_FORM *Form
193 )
194 {
195 FORM_EXPRESSION *Expression;
196
197 Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
198 Expression->Signature = FORM_EXPRESSION_SIGNATURE;
199 InitializeListHead (&Expression->OpCodeListHead);
200
201 return Expression;
202 }
203
204
205 /**
206 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
207
208 @param FormSet Pointer of the current FormSet
209
210 @return Pointer to a FORMSET_STORAGE data structure.
211
212 **/
213 FORMSET_STORAGE *
214 CreateStorage (
215 IN FORM_BROWSER_FORMSET *FormSet
216 )
217 {
218 FORMSET_STORAGE *Storage;
219
220 Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));
221 Storage->Signature = FORMSET_STORAGE_SIGNATURE;
222 InitializeListHead (&Storage->NameValueListHead);
223 InsertTailList (&FormSet->StorageListHead, &Storage->Link);
224
225 return Storage;
226 }
227
228
229 /**
230 Create ConfigHdr string for a storage.
231
232 @param FormSet Pointer of the current FormSet
233 @param Storage Pointer of the storage
234
235 @retval EFI_SUCCESS Initialize ConfigHdr success
236
237 **/
238 EFI_STATUS
239 InitializeConfigHdr (
240 IN FORM_BROWSER_FORMSET *FormSet,
241 IN OUT FORMSET_STORAGE *Storage
242 )
243 {
244 EFI_STATUS Status;
245 UINTN StrBufferLen;
246 CHAR16 *Name;
247
248 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {
249 Name = Storage->Name;
250 } else {
251 Name = NULL;
252 }
253
254 StrBufferLen = 0;
255 Status = ConstructConfigHdr (
256 Storage->ConfigHdr,
257 &StrBufferLen,
258 &Storage->Guid,
259 Name,
260 FormSet->DriverHandle
261 );
262 if (Status == EFI_BUFFER_TOO_SMALL) {
263 Storage->ConfigHdr = AllocateZeroPool (StrBufferLen);
264 Status = ConstructConfigHdr (
265 Storage->ConfigHdr,
266 &StrBufferLen,
267 &Storage->Guid,
268 Name,
269 FormSet->DriverHandle
270 );
271 }
272
273 if (EFI_ERROR (Status)) {
274 return Status;
275 }
276
277 Storage->ConfigRequest = AllocateCopyPool (StrBufferLen, Storage->ConfigHdr);
278 Storage->SpareStrLen = 0;
279
280 return EFI_SUCCESS;
281 }
282
283
284 /**
285 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
286
287 @param FormSet Pointer of the current FormSet.
288 @param Question The Question to be initialized.
289
290 @retval EFI_SUCCESS Function success.
291 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
292
293 **/
294 EFI_STATUS
295 InitializeRequestElement (
296 IN OUT FORM_BROWSER_FORMSET *FormSet,
297 IN OUT FORM_BROWSER_STATEMENT *Question
298 )
299 {
300 FORMSET_STORAGE *Storage;
301 UINTN StrLen;
302 UINTN StringSize;
303 CHAR16 *NewStr;
304 CHAR16 RequestElement[30];
305
306 Storage = Question->Storage;
307 if (Storage == NULL) {
308 return EFI_INVALID_PARAMETER;
309 }
310
311 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
312 //
313 // <ConfigRequest> is unnecessary for EFI variable storage,
314 // GetVariable()/SetVariable() will be used to retrieve/save values
315 //
316 return EFI_SUCCESS;
317 }
318
319 //
320 // Prepare <RequestElement>
321 //
322 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {
323 StrLen = UnicodeSPrint (
324 RequestElement,
325 30 * sizeof (CHAR16),
326 L"&OFFSET=%x&WIDTH=%x",
327 Question->VarStoreInfo.VarOffset,
328 Question->StorageWidth
329 );
330 Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);
331 } else {
332 StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);
333 }
334
335 if ((Question->Operand == EFI_IFR_PASSWORD_OP) && (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK)) {
336 //
337 // Password with CALLBACK flag is stored in encoded format,
338 // so don't need to append it to <ConfigRequest>
339 //
340 return EFI_SUCCESS;
341 }
342
343 //
344 // Append <RequestElement> to <ConfigRequest>
345 //
346 if (StrLen > Storage->SpareStrLen) {
347 //
348 // Old String buffer is not sufficient for RequestElement, allocate a new one
349 //
350 StringSize = (Storage->ConfigRequest != NULL) ? StrSize (Storage->ConfigRequest) : sizeof (CHAR16);
351 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));
352 if (Storage->ConfigRequest != NULL) {
353 CopyMem (NewStr, Storage->ConfigRequest, StringSize);
354 gBS->FreePool (Storage->ConfigRequest);
355 }
356 Storage->ConfigRequest = NewStr;
357 Storage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
358 }
359
360 StrCat (Storage->ConfigRequest, RequestElement);
361 Storage->ElementCount++;
362 Storage->SpareStrLen -= StrLen;
363
364 return EFI_SUCCESS;
365 }
366
367
368 /**
369 Free resources of a Expression
370
371 @param FormSet Pointer of the Expression
372
373 @return None.
374
375 **/
376 VOID
377 DestroyExpression (
378 IN FORM_EXPRESSION *Expression
379 )
380 {
381 LIST_ENTRY *Link;
382 EXPRESSION_OPCODE *OpCode;
383
384 while (!IsListEmpty (&Expression->OpCodeListHead)) {
385 Link = GetFirstNode (&Expression->OpCodeListHead);
386 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);
387 RemoveEntryList (&OpCode->Link);
388
389 SafeFreePool (OpCode->ValueList);
390 }
391
392 //
393 // Free this Expression
394 //
395 gBS->FreePool (Expression);
396 }
397
398
399 /**
400 Free resources of a storage
401
402 @param Storage Pointer of the storage
403
404 @return None.
405
406 **/
407 VOID
408 DestroyStorage (
409 IN FORMSET_STORAGE *Storage
410 )
411 {
412 LIST_ENTRY *Link;
413 NAME_VALUE_NODE *NameValueNode;
414
415 if (Storage == NULL) {
416 return;
417 }
418
419 SafeFreePool (Storage->Name);
420 SafeFreePool (Storage->Buffer);
421 SafeFreePool (Storage->EditBuffer);
422
423 while (!IsListEmpty (&Storage->NameValueListHead)) {
424 Link = GetFirstNode (&Storage->NameValueListHead);
425 NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);
426 RemoveEntryList (&NameValueNode->Link);
427
428 SafeFreePool (NameValueNode->Name);
429 SafeFreePool (NameValueNode->Value);
430 SafeFreePool (NameValueNode->EditValue);
431 SafeFreePool (NameValueNode);
432 }
433
434 SafeFreePool (Storage->ConfigHdr);
435 SafeFreePool (Storage->ConfigRequest);
436
437 gBS->FreePool (Storage);
438 }
439
440
441 /**
442 Free resources of a Statement
443
444 @param Statement Pointer of the Statement
445
446 @return None.
447
448 **/
449 VOID
450 DestroyStatement (
451 IN OUT FORM_BROWSER_STATEMENT *Statement
452 )
453 {
454 LIST_ENTRY *Link;
455 QUESTION_DEFAULT *Default;
456 QUESTION_OPTION *Option;
457 FORM_EXPRESSION *Expression;
458
459 //
460 // Free Default value List
461 //
462 while (!IsListEmpty (&Statement->DefaultListHead)) {
463 Link = GetFirstNode (&Statement->DefaultListHead);
464 Default = QUESTION_DEFAULT_FROM_LINK (Link);
465 RemoveEntryList (&Default->Link);
466
467 gBS->FreePool (Default);
468 }
469
470 //
471 // Free Options List
472 //
473 while (!IsListEmpty (&Statement->OptionListHead)) {
474 Link = GetFirstNode (&Statement->OptionListHead);
475 Option = QUESTION_OPTION_FROM_LINK (Link);
476 RemoveEntryList (&Option->Link);
477
478 gBS->FreePool (Option);
479 }
480
481 //
482 // Free Inconsistent List
483 //
484 while (!IsListEmpty (&Statement->InconsistentListHead)) {
485 Link = GetFirstNode (&Statement->InconsistentListHead);
486 Expression = FORM_EXPRESSION_FROM_LINK (Link);
487 RemoveEntryList (&Expression->Link);
488
489 DestroyExpression (Expression);
490 }
491
492 //
493 // Free NoSubmit List
494 //
495 while (!IsListEmpty (&Statement->NoSubmitListHead)) {
496 Link = GetFirstNode (&Statement->NoSubmitListHead);
497 Expression = FORM_EXPRESSION_FROM_LINK (Link);
498 RemoveEntryList (&Expression->Link);
499
500 DestroyExpression (Expression);
501 }
502
503 SafeFreePool (Statement->VariableName);
504 SafeFreePool (Statement->BlockName);
505 }
506
507
508 /**
509 Free resources of a Form
510
511 @param Form Pointer of the Form
512
513 @return None.
514
515 **/
516 VOID
517 DestroyForm (
518 IN OUT FORM_BROWSER_FORM *Form
519 )
520 {
521 LIST_ENTRY *Link;
522 FORM_EXPRESSION *Expression;
523 FORM_BROWSER_STATEMENT *Statement;
524
525 //
526 // Free Form Expressions
527 //
528 while (!IsListEmpty (&Form->ExpressionListHead)) {
529 Link = GetFirstNode (&Form->ExpressionListHead);
530 Expression = FORM_EXPRESSION_FROM_LINK (Link);
531 RemoveEntryList (&Expression->Link);
532
533 DestroyExpression (Expression);
534 }
535
536 //
537 // Free Statements/Questions
538 //
539 while (!IsListEmpty (&Form->StatementListHead)) {
540 Link = GetFirstNode (&Form->StatementListHead);
541 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
542 RemoveEntryList (&Statement->Link);
543
544 DestroyStatement (Statement);
545 }
546
547 //
548 // Free this Form
549 //
550 gBS->FreePool (Form);
551 }
552
553
554 /**
555 Free resources allocated for a FormSet
556
557 @param FormSet Pointer of the FormSet
558
559 @return None.
560
561 **/
562 VOID
563 DestroyFormSet (
564 IN OUT FORM_BROWSER_FORMSET *FormSet
565 )
566 {
567 LIST_ENTRY *Link;
568 FORMSET_STORAGE *Storage;
569 FORMSET_DEFAULTSTORE *DefaultStore;
570 FORM_BROWSER_FORM *Form;
571
572 //
573 // Free IFR binary buffer
574 //
575 SafeFreePool (FormSet->IfrBinaryData);
576
577 //
578 // Free FormSet Storage
579 //
580 if (FormSet->StorageListHead.ForwardLink != NULL) {
581 while (!IsListEmpty (&FormSet->StorageListHead)) {
582 Link = GetFirstNode (&FormSet->StorageListHead);
583 Storage = FORMSET_STORAGE_FROM_LINK (Link);
584 RemoveEntryList (&Storage->Link);
585
586 DestroyStorage (Storage);
587 }
588 }
589
590 //
591 // Free FormSet Default Store
592 //
593 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
594 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
595 Link = GetFirstNode (&FormSet->DefaultStoreListHead);
596 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);
597 RemoveEntryList (&DefaultStore->Link);
598
599 gBS->FreePool (DefaultStore);
600 }
601 }
602
603 //
604 // Free Forms
605 //
606 if (FormSet->FormListHead.ForwardLink != NULL) {
607 while (!IsListEmpty (&FormSet->FormListHead)) {
608 Link = GetFirstNode (&FormSet->FormListHead);
609 Form = FORM_BROWSER_FORM_FROM_LINK (Link);
610 RemoveEntryList (&Form->Link);
611
612 DestroyForm (Form);
613 }
614 }
615
616 SafeFreePool (FormSet->StatementBuffer);
617 SafeFreePool (FormSet->ExpressionBuffer);
618
619 SafeFreePool (FormSet);
620 }
621
622
623 /**
624 Tell whether this Operand is an Expression OpCode or not
625
626 @param Operand Operand of an IFR OpCode.
627
628 @retval TRUE This is an Expression OpCode.
629 @retval FALSE Not an Expression OpCode.
630
631 **/
632 BOOLEAN
633 IsExpressionOpCode (
634 IN UINT8 Operand
635 )
636 {
637 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||
638 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||
639 (Operand == EFI_IFR_CATENATE_OP)
640 ) {
641 return TRUE;
642 } else {
643 return FALSE;
644 }
645 }
646
647
648 /**
649 Calculate number of Statemens(Questions) and Expression OpCodes.
650
651 @param FormSet The FormSet to be counted.
652 @param NumberOfStatement Number of Statemens(Questions)
653 @param NumberOfExpression Number of Expression OpCodes
654
655 @return None.
656
657 **/
658 VOID
659 CountOpCodes (
660 IN FORM_BROWSER_FORMSET *FormSet,
661 IN OUT UINT16 *NumberOfStatement,
662 IN OUT UINT16 *NumberOfExpression
663 )
664 {
665 UINT16 StatementCount;
666 UINT16 ExpressionCount;
667 UINT8 *OpCodeData;
668 UINTN Offset;
669 UINTN OpCodeLen;
670
671 Offset = 0;
672 StatementCount = 0;
673 ExpressionCount = 0;
674
675 while (Offset < FormSet->IfrBinaryLength) {
676 OpCodeData = FormSet->IfrBinaryData + Offset;
677 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
678 Offset += OpCodeLen;
679
680 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {
681 ExpressionCount++;
682 } else {
683 StatementCount++;
684 }
685 }
686
687 *NumberOfStatement = StatementCount;
688 *NumberOfExpression = ExpressionCount;
689 }
690
691
692 /**
693 Parse opcodes in the formset IFR binary.
694
695 @param FormSet Pointer of the FormSet data structure.
696
697 @retval EFI_SUCCESS Opcode parse success.
698 @retval Other Opcode parse fail.
699
700 **/
701 EFI_STATUS
702 ParseOpCodes (
703 IN FORM_BROWSER_FORMSET *FormSet
704 )
705 {
706 EFI_STATUS Status;
707 UINT16 Index;
708 FORM_BROWSER_FORM *CurrentForm;
709 FORM_BROWSER_STATEMENT *CurrentStatement;
710 EXPRESSION_OPCODE *ExpressionOpCode;
711 FORM_EXPRESSION *CurrentExpression;
712 UINT8 Operand;
713 UINT8 Scope;
714 UINTN OpCodeOffset;
715 UINTN OpCodeLength;
716 UINT8 *OpCodeData;
717 UINT8 ScopeOpCode;
718 FORMSET_STORAGE *Storage;
719 FORMSET_DEFAULTSTORE *DefaultStore;
720 QUESTION_DEFAULT *CurrentDefault;
721 QUESTION_OPTION *CurrentOption;
722 CHAR8 *AsciiString;
723 UINT16 NumberOfStatement;
724 UINT16 NumberOfExpression;
725 EFI_IMAGE_ID *ImageId;
726 BOOLEAN SuppressForOption;
727 BOOLEAN InScopeOptionSuppress;
728 FORM_EXPRESSION *OptionSuppressExpression;
729 BOOLEAN InScopeDisable;
730 UINT16 DepthOfDisable;
731 BOOLEAN OpCodeDisabled;
732 BOOLEAN SingleOpCodeExpression;
733 BOOLEAN InScopeDefault;
734 EFI_HII_VALUE *Value;
735
736 mInScopeSubtitle = FALSE;
737 SuppressForOption = FALSE;
738 mInScopeSuppress = FALSE;
739 InScopeOptionSuppress = FALSE;
740 mInScopeGrayOut = FALSE;
741 InScopeDisable = FALSE;
742 DepthOfDisable = 0;
743 OpCodeDisabled = FALSE;
744 SingleOpCodeExpression = FALSE;
745 InScopeDefault = FALSE;
746 CurrentExpression = NULL;
747 CurrentDefault = NULL;
748 CurrentOption = NULL;
749 OptionSuppressExpression = NULL;
750
751 //
752 // Get the number of Statements and Expressions
753 //
754 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
755
756 mStatementIndex = 0;
757 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
758 if (FormSet->StatementBuffer == NULL) {
759 return EFI_OUT_OF_RESOURCES;
760 }
761
762 mExpressionOpCodeIndex = 0;
763 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));
764 if (FormSet->ExpressionBuffer == NULL) {
765 return EFI_OUT_OF_RESOURCES;
766 }
767
768 InitializeListHead (&FormSet->StorageListHead);
769 InitializeListHead (&FormSet->DefaultStoreListHead);
770 InitializeListHead (&FormSet->FormListHead);
771
772 CurrentForm = NULL;
773 CurrentStatement = NULL;
774
775 ResetScopeStack ();
776
777 OpCodeOffset = 0;
778 while (OpCodeOffset < FormSet->IfrBinaryLength) {
779 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;
780
781 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
782 OpCodeOffset += OpCodeLength;
783 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
784 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;
785
786 //
787 // If scope bit set, push onto scope stack
788 //
789 if (Scope) {
790 PushScope (Operand);
791 }
792
793 if (OpCodeDisabled) {
794 //
795 // DisableIf Expression is evaluated to be TRUE, try to find its end.
796 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
797 //
798 if (Operand == EFI_IFR_DISABLE_IF_OP) {
799 DepthOfDisable++;
800 } else if (Operand == EFI_IFR_END_OP) {
801 Status = PopScope (&ScopeOpCode);
802 if (EFI_ERROR (Status)) {
803 return Status;
804 }
805
806 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {
807 if (DepthOfDisable == 0) {
808 InScopeDisable = FALSE;
809 OpCodeDisabled = FALSE;
810 } else {
811 DepthOfDisable--;
812 }
813 }
814 }
815 continue;
816 }
817
818 if (IsExpressionOpCode (Operand)) {
819 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];
820 mExpressionOpCodeIndex++;
821
822 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;
823 ExpressionOpCode->Operand = Operand;
824 Value = &ExpressionOpCode->Value;
825
826 switch (Operand) {
827 case EFI_IFR_EQ_ID_VAL_OP:
828 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
829
830 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
831 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));
832 break;
833
834 case EFI_IFR_EQ_ID_ID_OP:
835 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));
836 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));
837 break;
838
839 case EFI_IFR_EQ_ID_LIST_OP:
840 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
841 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->ListLength, sizeof (UINT16));
842 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->ValueList);
843 break;
844
845 case EFI_IFR_TO_STRING_OP:
846 case EFI_IFR_FIND_OP:
847 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;
848 break;
849
850 case EFI_IFR_STRING_REF1_OP:
851 Value->Type = EFI_IFR_TYPE_STRING;
852 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));
853 break;
854
855 case EFI_IFR_RULE_REF_OP:
856 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;
857 break;
858
859 case EFI_IFR_SPAN_OP:
860 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;
861 break;
862
863 case EFI_IFR_THIS_OP:
864 ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;
865 break;
866
867 case EFI_IFR_QUESTION_REF1_OP:
868 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
869 break;
870
871 case EFI_IFR_QUESTION_REF3_OP:
872 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {
873 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
874
875 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {
876 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));
877 }
878 }
879 break;
880
881 //
882 // constant
883 //
884 case EFI_IFR_TRUE_OP:
885 Value->Type = EFI_IFR_TYPE_BOOLEAN;
886 Value->Value.b = TRUE;
887 break;
888
889 case EFI_IFR_FALSE_OP:
890 Value->Type = EFI_IFR_TYPE_BOOLEAN;
891 Value->Value.b = FALSE;
892 break;
893
894 case EFI_IFR_ONE_OP:
895 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
896 Value->Value.u8 = 1;
897 break;
898
899 case EFI_IFR_ZERO_OP:
900 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
901 Value->Value.u8 = 0;
902 break;
903
904 case EFI_IFR_ONES_OP:
905 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
906 Value->Value.u64 = 0xffffffffffffffffULL;
907 break;
908
909 case EFI_IFR_UINT8_OP:
910 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
911 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;
912 break;
913
914 case EFI_IFR_UINT16_OP:
915 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
916 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));
917 break;
918
919 case EFI_IFR_UINT32_OP:
920 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
921 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));
922 break;
923
924 case EFI_IFR_UINT64_OP:
925 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
926 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));
927 break;
928
929 case EFI_IFR_UNDEFINED_OP:
930 Value->Type = EFI_IFR_TYPE_OTHER;
931 break;
932
933 case EFI_IFR_VERSION_OP:
934 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
935 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;
936 break;
937
938 default:
939 break;
940 }
941
942 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);
943
944 if (SingleOpCodeExpression) {
945 //
946 // There are two cases to indicate the end of an Expression:
947 // for single OpCode expression: one Expression OpCode
948 // for expression consists of more than one OpCode: EFI_IFR_END
949 //
950 SingleOpCodeExpression = FALSE;
951
952 if (InScopeDisable) {
953 //
954 // Evaluate DisableIf expression
955 //
956 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
957 if (EFI_ERROR (Status)) {
958 return Status;
959 }
960 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
961 return EFI_INVALID_PARAMETER;
962 }
963
964 OpCodeDisabled = CurrentExpression->Result.Value.b;
965 }
966
967 CurrentExpression = NULL;
968 }
969
970 continue;
971 }
972
973 //
974 // Parse the Opcode
975 //
976 switch (Operand) {
977
978 case EFI_IFR_FORM_SET_OP:
979 //
980 // check the formset GUID
981 //
982 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {
983 return EFI_INVALID_PARAMETER;
984 }
985
986 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
987 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
988 break;
989
990 case EFI_IFR_FORM_OP:
991 //
992 // Create a new Form for this FormSet
993 //
994 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
995 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
996 InitializeListHead (&CurrentForm->ExpressionListHead);
997 InitializeListHead (&CurrentForm->StatementListHead);
998
999 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1000 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
1001
1002 //
1003 // Insert into Form list of this FormSet
1004 //
1005 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1006 break;
1007
1008 //
1009 // Storage
1010 //
1011 case EFI_IFR_VARSTORE_OP:
1012 //
1013 // Create a buffer Storage for this FormSet
1014 //
1015 Storage = CreateStorage (FormSet);
1016 Storage->Type = EFI_HII_VARSTORE_BUFFER;
1017
1018 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1019 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));
1020 CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));
1021
1022 Storage->Buffer = AllocateZeroPool (Storage->Size);
1023 Storage->EditBuffer = AllocateZeroPool (Storage->Size);
1024
1025 AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;
1026 Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);
1027 ASSERT (Storage->Name != NULL);
1028 for (Index = 0; AsciiString[Index] != 0; Index++) {
1029 Storage->Name[Index] = (CHAR16) AsciiString[Index];
1030 }
1031
1032 //
1033 // Initialize <ConfigHdr>
1034 //
1035 InitializeConfigHdr (FormSet, Storage);
1036 break;
1037
1038 case EFI_IFR_VARSTORE_NAME_VALUE_OP:
1039 //
1040 // Create a name/value Storage for this FormSet
1041 //
1042 Storage = CreateStorage (FormSet);
1043 Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;
1044
1045 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1046 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));
1047
1048 //
1049 // Initialize <ConfigHdr>
1050 //
1051 InitializeConfigHdr (FormSet, Storage);
1052 break;
1053
1054 case EFI_IFR_VARSTORE_EFI_OP:
1055 //
1056 // Create a EFI variable Storage for this FormSet
1057 //
1058 Storage = CreateStorage (FormSet);
1059 Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;
1060
1061 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1062 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));
1063 CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));
1064 break;
1065
1066 //
1067 // DefaultStore
1068 //
1069 case EFI_IFR_DEFAULTSTORE_OP:
1070 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
1071 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
1072
1073 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));
1074 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
1075
1076 //
1077 // Insert to DefaultStore list of this Formset
1078 //
1079 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
1080 break;
1081
1082 //
1083 // Statements
1084 //
1085 case EFI_IFR_SUBTITLE_OP:
1086 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1087 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
1088
1089 if (Scope) {
1090 mInScopeSubtitle = TRUE;
1091 }
1092 break;
1093
1094 case EFI_IFR_TEXT_OP:
1095 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1096
1097 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
1098 break;
1099
1100 //
1101 // Questions
1102 //
1103 case EFI_IFR_ACTION_OP:
1104 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1105
1106 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
1107 //
1108 // No QuestionConfig present, so no configuration string will be processed
1109 //
1110 CurrentStatement->QuestionConfig = 0;
1111 } else {
1112 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
1113 }
1114 break;
1115
1116 case EFI_IFR_RESET_BUTTON_OP:
1117 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1118
1119 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
1120 break;
1121
1122 case EFI_IFR_REF_OP:
1123 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1124
1125 CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
1126 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
1127 CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1128
1129 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
1130 CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
1131
1132 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
1133 CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1134 }
1135 }
1136 }
1137 break;
1138
1139 case EFI_IFR_ONE_OF_OP:
1140 case EFI_IFR_NUMERIC_OP:
1141 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1142
1143 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
1144 Value = &CurrentStatement->HiiValue;
1145
1146 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
1147 case EFI_IFR_NUMERIC_SIZE_1:
1148 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
1149 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
1150 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
1151 CurrentStatement->StorageWidth = sizeof (UINT8);
1152 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1153 break;
1154
1155 case EFI_IFR_NUMERIC_SIZE_2:
1156 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
1157 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
1158 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));
1159 CurrentStatement->StorageWidth = sizeof (UINT16);
1160 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1161 break;
1162
1163 case EFI_IFR_NUMERIC_SIZE_4:
1164 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
1165 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
1166 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));
1167 CurrentStatement->StorageWidth = sizeof (UINT32);
1168 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1169 break;
1170
1171 case EFI_IFR_NUMERIC_SIZE_8:
1172 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
1173 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
1174 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));
1175 CurrentStatement->StorageWidth = sizeof (UINT64);
1176 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1177 break;
1178
1179 default:
1180 break;
1181 }
1182
1183 InitializeRequestElement (FormSet, CurrentStatement);
1184
1185 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope) {
1186 SuppressForOption = TRUE;
1187 }
1188 break;
1189
1190 case EFI_IFR_ORDERED_LIST_OP:
1191 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1192
1193 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;
1194 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;
1195 CurrentStatement->StorageWidth = (UINT16)(CurrentStatement->MaxContainers * sizeof (UINT8));
1196 InitializeRequestElement (FormSet, CurrentStatement);
1197
1198 //
1199 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver
1200 // has to use FormBrowser2.Callback() to retrieve the uncommited data for
1201 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).
1202 //
1203 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_OTHER;
1204 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
1205
1206 if (Scope) {
1207 SuppressForOption = TRUE;
1208 }
1209 break;
1210
1211 case EFI_IFR_CHECKBOX_OP:
1212 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1213
1214 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;
1215 CurrentStatement->StorageWidth = sizeof (BOOLEAN);
1216 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
1217
1218 InitializeRequestElement (FormSet, CurrentStatement);
1219 break;
1220
1221 case EFI_IFR_STRING_OP:
1222 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1223
1224 //
1225 // MinSize is the minimum number of characters that can be accepted for this opcode,
1226 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1227 // The characters are stored as Unicode, so the storage width should multiply 2.
1228 //
1229 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;
1230 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;
1231 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));
1232 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;
1233
1234 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1235 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
1236
1237 InitializeRequestElement (FormSet, CurrentStatement);
1238 break;
1239
1240 case EFI_IFR_PASSWORD_OP:
1241 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1242
1243 //
1244 // MinSize is the minimum number of characters that can be accepted for this opcode,
1245 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1246 // The characters are stored as Unicode, so the storage width should multiply 2.
1247 //
1248 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));
1249 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));
1250 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));
1251
1252 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1253 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
1254
1255 InitializeRequestElement (FormSet, CurrentStatement);
1256 break;
1257
1258 case EFI_IFR_DATE_OP:
1259 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1260
1261 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;
1262 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
1263
1264 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {
1265 CurrentStatement->StorageWidth = sizeof (EFI_HII_DATE);
1266
1267 InitializeRequestElement (FormSet, CurrentStatement);
1268 } else {
1269 //
1270 // Don't assign storage for RTC type of date/time
1271 //
1272 CurrentStatement->Storage = NULL;
1273 CurrentStatement->StorageWidth = 0;
1274 }
1275 break;
1276
1277 case EFI_IFR_TIME_OP:
1278 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1279
1280 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;
1281 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
1282
1283 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {
1284 CurrentStatement->StorageWidth = sizeof (EFI_IFR_TIME);
1285
1286 InitializeRequestElement (FormSet, CurrentStatement);
1287 } else {
1288 //
1289 // Don't assign storage for RTC type of date/time
1290 //
1291 CurrentStatement->Storage = NULL;
1292 CurrentStatement->StorageWidth = 0;
1293 }
1294 break;
1295
1296 //
1297 // Default
1298 //
1299 case EFI_IFR_DEFAULT_OP:
1300 //
1301 // EFI_IFR_DEFAULT appear in scope of a Question,
1302 // It creates a default value for the current question.
1303 // A Question may have more than one Default value which have different default types.
1304 //
1305 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
1306 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
1307
1308 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
1309 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
1310 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
1311 ExtendValueToU64 (&CurrentDefault->Value);
1312
1313 //
1314 // Insert to Default Value list of current Question
1315 //
1316 InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);
1317
1318 if (Scope) {
1319 InScopeDefault = TRUE;
1320 }
1321 break;
1322
1323 //
1324 // Option
1325 //
1326 case EFI_IFR_ONE_OF_OPTION_OP:
1327 //
1328 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1329 // It create a selection for use in current Question.
1330 //
1331 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
1332 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
1333
1334 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
1335 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
1336 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
1337 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
1338 ExtendValueToU64 (&CurrentOption->Value);
1339
1340 if (InScopeOptionSuppress) {
1341 CurrentOption->SuppressExpression = OptionSuppressExpression;
1342 }
1343
1344 //
1345 // Insert to Option list of current Question
1346 //
1347 InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);
1348 break;
1349
1350 //
1351 // Conditional
1352 //
1353 case EFI_IFR_NO_SUBMIT_IF_OP:
1354 case EFI_IFR_INCONSISTENT_IF_OP:
1355 //
1356 // Create an Expression node
1357 //
1358 CurrentExpression = CreateExpression (CurrentForm);
1359 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));
1360
1361 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {
1362 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;
1363 InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);
1364 } else {
1365 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;
1366 InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);
1367 }
1368 break;
1369
1370 case EFI_IFR_SUPPRESS_IF_OP:
1371 //
1372 // Question and Option will appear in scope of this OpCode
1373 //
1374 CurrentExpression = CreateExpression (CurrentForm);
1375 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;
1376 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1377
1378 if (SuppressForOption) {
1379 InScopeOptionSuppress = TRUE;
1380 OptionSuppressExpression = CurrentExpression;
1381 } else {
1382 mInScopeSuppress = TRUE;
1383 mSuppressExpression = CurrentExpression;
1384 }
1385 break;
1386
1387 case EFI_IFR_GRAY_OUT_IF_OP:
1388 //
1389 // Questions will appear in scope of this OpCode
1390 //
1391 CurrentExpression = CreateExpression (CurrentForm);
1392 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;
1393 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1394
1395 mInScopeGrayOut = TRUE;
1396 mGrayOutExpression = CurrentExpression;
1397 break;
1398
1399 case EFI_IFR_DISABLE_IF_OP:
1400 //
1401 // The DisableIf expression should only rely on constant, so it could be
1402 // evaluated at initialization and it will not be queued
1403 //
1404 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
1405 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;
1406 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;
1407 InitializeListHead (&CurrentExpression->OpCodeListHead);
1408
1409 InScopeDisable = TRUE;
1410 OpCodeDisabled = FALSE;
1411
1412 //
1413 // Take a look at next OpCode to see whether current expression consists
1414 // of single OpCode
1415 //
1416 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1417 SingleOpCodeExpression = TRUE;
1418 }
1419 break;
1420
1421 //
1422 // Expression
1423 //
1424 case EFI_IFR_VALUE_OP:
1425 CurrentExpression = CreateExpression (CurrentForm);
1426 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;
1427 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1428
1429 if (InScopeDefault) {
1430 //
1431 // Used for default (EFI_IFR_DEFAULT)
1432 //
1433 CurrentDefault->ValueExpression = CurrentExpression;
1434 } else {
1435 //
1436 // If used for a question, then the question will be read-only
1437 //
1438 CurrentStatement->ValueExpression = CurrentExpression;
1439 }
1440 break;
1441
1442 case EFI_IFR_RULE_OP:
1443 CurrentExpression = CreateExpression (CurrentForm);
1444 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;
1445
1446 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;
1447 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1448 break;
1449
1450 //
1451 // Image
1452 //
1453 case EFI_IFR_IMAGE_OP:
1454 //
1455 // Get ScopeOpcode from top of stack
1456 //
1457 PopScope (&ScopeOpCode);
1458 PushScope (ScopeOpCode);
1459
1460 switch (ScopeOpCode) {
1461 case EFI_IFR_FORM_SET_OP:
1462 ImageId = &FormSet->ImageId;
1463 break;
1464
1465 case EFI_IFR_FORM_OP:
1466 ImageId = &CurrentForm->ImageId;
1467 break;
1468
1469 case EFI_IFR_ONE_OF_OPTION_OP:
1470 ImageId = &CurrentOption->ImageId;
1471 break;
1472
1473 default:
1474 ImageId = &CurrentStatement->ImageId;
1475 break;
1476 }
1477
1478 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
1479 break;
1480
1481 //
1482 // Refresh
1483 //
1484 case EFI_IFR_REFRESH_OP:
1485 CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;
1486 break;
1487
1488 //
1489 // Vendor specific
1490 //
1491 case EFI_IFR_GUID_OP:
1492 if (CompareGuid (&gTianoHiiIfrGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
1493 //
1494 // Tiano specific GUIDed opcodes
1495 //
1496 switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {
1497 case EFI_IFR_EXTEND_OP_LABEL:
1498 //
1499 // just ignore label
1500 //
1501 break;
1502
1503 #if 0
1504 case EFI_IFR_EXTEND_OP_BANNER:
1505 if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {
1506 CopyMem (
1507 &BannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][
1508 ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],
1509 &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,
1510 sizeof (EFI_STRING_ID)
1511 );
1512 }
1513 break;
1514 #endif
1515
1516 case EFI_IFR_EXTEND_OP_CLASS:
1517 CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));
1518 break;
1519
1520 case EFI_IFR_EXTEND_OP_SUBCLASS:
1521 CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));
1522 break;
1523
1524 default:
1525 break;
1526 }
1527 }
1528 break;
1529
1530 //
1531 // Scope End
1532 //
1533 case EFI_IFR_END_OP:
1534 Status = PopScope (&ScopeOpCode);
1535 if (EFI_ERROR (Status)) {
1536 ResetScopeStack ();
1537 return Status;
1538 }
1539
1540 switch (ScopeOpCode) {
1541 case EFI_IFR_FORM_SET_OP:
1542 //
1543 // End of FormSet, update FormSet IFR binary length
1544 // to stop parsing substantial OpCodes
1545 //
1546 FormSet->IfrBinaryLength = OpCodeOffset;
1547 break;
1548
1549 case EFI_IFR_FORM_OP:
1550 //
1551 // End of Form
1552 //
1553 CurrentForm = NULL;
1554 break;
1555
1556 case EFI_IFR_ONE_OF_OPTION_OP:
1557 //
1558 // End of Option
1559 //
1560 CurrentOption = NULL;
1561 break;
1562
1563 case EFI_IFR_SUBTITLE_OP:
1564 mInScopeSubtitle = FALSE;
1565 break;
1566
1567 case EFI_IFR_NO_SUBMIT_IF_OP:
1568 case EFI_IFR_INCONSISTENT_IF_OP:
1569 //
1570 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1571 //
1572 break;
1573
1574 case EFI_IFR_SUPPRESS_IF_OP:
1575 if (SuppressForOption) {
1576 InScopeOptionSuppress = FALSE;
1577 } else {
1578 mInScopeSuppress = FALSE;
1579 }
1580 break;
1581
1582 case EFI_IFR_GRAY_OUT_IF_OP:
1583 mInScopeGrayOut = FALSE;
1584 break;
1585
1586 case EFI_IFR_DISABLE_IF_OP:
1587 InScopeDisable = FALSE;
1588 OpCodeDisabled = FALSE;
1589 break;
1590
1591 case EFI_IFR_ONE_OF_OP:
1592 case EFI_IFR_ORDERED_LIST_OP:
1593 SuppressForOption = FALSE;
1594 break;
1595
1596 case EFI_IFR_DEFAULT_OP:
1597 InScopeDefault = FALSE;
1598 break;
1599
1600 default:
1601 if (IsExpressionOpCode (ScopeOpCode)) {
1602 if (InScopeDisable) {
1603 //
1604 // Evaluate DisableIf expression
1605 //
1606 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
1607 if (EFI_ERROR (Status)) {
1608 return Status;
1609 }
1610 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
1611 return EFI_INVALID_PARAMETER;
1612 }
1613
1614 OpCodeDisabled = CurrentExpression->Result.Value.b;
1615 //
1616 // DisableIf Expression is only used once and not quequed, free it
1617 //
1618 DestroyExpression (CurrentExpression);
1619 }
1620
1621 //
1622 // End of current Expression
1623 //
1624 CurrentExpression = NULL;
1625 }
1626 break;
1627 }
1628 break;
1629
1630 default:
1631 break;
1632 }
1633 }
1634
1635 return EFI_SUCCESS;
1636 }
1637
1638
1639
1640