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