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