]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/UefiIfrParser.c
EdkCompatibilityPkg: Fix the typo in the comment
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / UefiIfrParser.c
1 /** @file
2 Parser for IFR binary encoding.
3
4 Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "HiiDatabase.h"
16
17 #include "UefiIfrParserExpression.h"
18
19 UINT16 mStatementIndex;
20
21 BOOLEAN mInScopeSubtitle;
22 BOOLEAN mInScopeSuppress;
23 BOOLEAN mInScopeGrayOut;
24
25 EFI_GUID mFrameworkHiiCompatibilityGuid = EFI_IFR_FRAMEWORK_GUID;
26 extern EFI_GUID mTianoHiiIfrGuid;
27
28 /**
29 Find the question's OneOfOptionMap list in FormSet
30 based on the input question Id.
31
32 @param FormSet FormSet context.
33 @param QuestionId Unique ID to specicy the question in FormSet.
34
35 @return the found OneOfOptionMap list. If not found, NULL will return.
36 **/
37 LIST_ENTRY *
38 GetOneOfOptionMapEntryListHead (
39 IN CONST FORM_BROWSER_FORMSET *FormSet,
40 IN UINT16 QuestionId
41 )
42 {
43 LIST_ENTRY *Link;
44 ONE_OF_OPTION_MAP *Map;
45
46 Link = GetFirstNode (&FormSet->OneOfOptionMapListHead);
47
48 while (!IsNull (&FormSet->OneOfOptionMapListHead, Link)) {
49 Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);
50 if (QuestionId == Map->QuestionId) {
51 return &Map->OneOfOptionMapEntryListHead;
52 }
53 Link = GetNextNode (&FormSet->OneOfOptionMapListHead, Link);
54 }
55
56 return NULL;
57 }
58
59 /**
60 Free OneOfOption map list.
61
62 @param OneOfOptionMapListHead Pointer to list header of OneOfOptionMap list.
63
64 **/
65 VOID
66 DestoryOneOfOptionMap (
67 IN LIST_ENTRY *OneOfOptionMapListHead
68 )
69 {
70 ONE_OF_OPTION_MAP *Map;
71 ONE_OF_OPTION_MAP_ENTRY *MapEntry;
72 LIST_ENTRY *Link;
73 LIST_ENTRY *Link2;
74
75 while (!IsListEmpty (OneOfOptionMapListHead)) {
76 Link = GetFirstNode (OneOfOptionMapListHead);
77
78 Map = ONE_OF_OPTION_MAP_FROM_LINK (Link);
79
80 while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) {
81 Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead);
82
83 MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link2);
84
85 RemoveEntryList (Link2);
86
87 FreePool (MapEntry);
88 }
89
90 RemoveEntryList (Link);
91 FreePool (Map);
92 }
93 }
94
95
96 /**
97 Initialize Statement header members.
98
99 @param OpCodeData Pointer of the raw OpCode data.
100 @param FormSet Pointer of the current FormSet.
101 @param Form Pointer of the current Form.
102
103 @return The Statement.
104
105 **/
106 FORM_BROWSER_STATEMENT *
107 CreateStatement (
108 IN UINT8 *OpCodeData,
109 IN OUT FORM_BROWSER_FORMSET *FormSet,
110 IN OUT FORM_BROWSER_FORM *Form
111 )
112 {
113 FORM_BROWSER_STATEMENT *Statement;
114 EFI_IFR_STATEMENT_HEADER *StatementHdr;
115
116 if (Form == NULL) {
117 //
118 // We are currently not in a Form Scope, so just skip this Statement
119 //
120 return NULL;
121 }
122
123 Statement = &FormSet->StatementBuffer[mStatementIndex];
124 mStatementIndex++;
125
126 InitializeListHead (&Statement->DefaultListHead);
127 InitializeListHead (&Statement->OptionListHead);
128
129 Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;
130
131 Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
132
133 StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
134 CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
135 CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));
136
137 Statement->InSubtitle = mInScopeSubtitle;
138
139 //
140 // Insert this Statement into current Form
141 //
142 InsertTailList (&Form->StatementListHead, &Statement->Link);
143
144 return Statement;
145 }
146
147 /**
148 Initialize Question's members.
149
150 @param OpCodeData Pointer of the raw OpCode data.
151 @param FormSet Pointer of the current FormSet.
152 @param Form Pointer of the current Form.
153
154 @return The Question.
155
156 **/
157 FORM_BROWSER_STATEMENT *
158 CreateQuestion (
159 IN UINT8 *OpCodeData,
160 IN OUT FORM_BROWSER_FORMSET *FormSet,
161 IN OUT FORM_BROWSER_FORM *Form
162 )
163 {
164 FORM_BROWSER_STATEMENT *Statement;
165 EFI_IFR_QUESTION_HEADER *QuestionHdr;
166 LIST_ENTRY *Link;
167 FORMSET_STORAGE *Storage;
168
169 Statement = CreateStatement (OpCodeData, FormSet, Form);
170 if (Statement == NULL) {
171 return NULL;
172 }
173
174 QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
175 CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));
176 CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));
177 CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));
178
179 if (FormSet->MaxQuestionId < QuestionHdr->QuestionId) {
180 FormSet->MaxQuestionId = QuestionHdr->QuestionId;
181 }
182
183 Statement->QuestionFlags = QuestionHdr->Flags;
184
185 if (Statement->VarStoreId == 0) {
186 //
187 // VarStoreId of zero indicates no variable storage
188 //
189 return Statement;
190 }
191
192 //
193 // Find Storage for this Question
194 //
195 Link = GetFirstNode (&FormSet->StorageListHead);
196 while (!IsNull (&FormSet->StorageListHead, Link)) {
197 Storage = FORMSET_STORAGE_FROM_LINK (Link);
198
199 if (Storage->VarStoreId == Statement->VarStoreId) {
200 Statement->Storage = Storage;
201 break;
202 }
203
204 Link = GetNextNode (&FormSet->StorageListHead, Link);
205 }
206 ASSERT (Statement->Storage != NULL);
207
208 return Statement;
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 **/
219 FORMSET_STORAGE *
220 CreateStorage (
221 IN FORM_BROWSER_FORMSET *FormSet
222 )
223 {
224 FORMSET_STORAGE *Storage;
225
226 Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));
227 ASSERT (Storage != NULL);
228 Storage->Signature = FORMSET_STORAGE_SIGNATURE;
229 InsertTailList (&FormSet->StorageListHead, &Storage->Link);
230
231 return Storage;
232 }
233
234 /**
235 Free resources of a storage
236
237 @param Storage Pointer of the storage
238
239 @return None.
240
241 **/
242 VOID
243 DestroyStorage (
244 IN FORMSET_STORAGE *Storage
245 )
246 {
247 if (Storage == NULL) {
248 return;
249 }
250
251 if (Storage->Name!= NULL) {
252 FreePool (Storage->Name);
253 }
254
255 FreePool (Storage);
256 }
257
258
259 /**
260 Free resources of a Statement
261
262 @param Statement Pointer of the Statement
263
264 @return None.
265
266 **/
267 VOID
268 DestroyStatement (
269 IN OUT FORM_BROWSER_STATEMENT *Statement
270 )
271 {
272 LIST_ENTRY *Link;
273 QUESTION_DEFAULT *Default;
274 QUESTION_OPTION *Option;
275
276 //
277 // Free Default value List
278 //
279 while (!IsListEmpty (&Statement->DefaultListHead)) {
280 Link = GetFirstNode (&Statement->DefaultListHead);
281 Default = QUESTION_DEFAULT_FROM_LINK (Link);
282 RemoveEntryList (&Default->Link);
283
284 gBS->FreePool (Default);
285 }
286
287 //
288 // Free Options List
289 //
290 while (!IsListEmpty (&Statement->OptionListHead)) {
291 Link = GetFirstNode (&Statement->OptionListHead);
292 Option = QUESTION_OPTION_FROM_LINK (Link);
293 RemoveEntryList (&Option->Link);
294
295 gBS->FreePool (Option);
296 }
297
298 }
299
300
301
302 /**
303 Free resources of a Form
304
305 @param Form Pointer of the Form
306
307 @return None.
308
309 **/
310 VOID
311 DestroyForm (
312 IN OUT FORM_BROWSER_FORM *Form
313 )
314 {
315 LIST_ENTRY *Link;
316 FORM_BROWSER_STATEMENT *Statement;
317
318 //
319 // Free Statements/Questions
320 //
321 while (!IsListEmpty (&Form->StatementListHead)) {
322 Link = GetFirstNode (&Form->StatementListHead);
323 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
324 RemoveEntryList (&Statement->Link);
325
326 DestroyStatement (Statement);
327 }
328
329 //
330 // Free this Form
331 //
332 gBS->FreePool (Form);
333 }
334
335
336 /**
337 Free resources allocated for a FormSet
338
339 @param FormSet Pointer of the FormSet
340
341 @return None.
342
343 **/
344 VOID
345 DestroyFormSet (
346 IN OUT FORM_BROWSER_FORMSET *FormSet
347 )
348 {
349 LIST_ENTRY *Link;
350 FORMSET_STORAGE *Storage;
351 FORMSET_DEFAULTSTORE *DefaultStore;
352 FORM_BROWSER_FORM *Form;
353
354 //
355 // Free IFR binary buffer
356 //
357 FreePool (FormSet->IfrBinaryData);
358
359 //
360 // Free FormSet Storage
361 //
362 if (FormSet->StorageListHead.ForwardLink != NULL) {
363 while (!IsListEmpty (&FormSet->StorageListHead)) {
364 Link = GetFirstNode (&FormSet->StorageListHead);
365 Storage = FORMSET_STORAGE_FROM_LINK (Link);
366 RemoveEntryList (&Storage->Link);
367
368 DestroyStorage (Storage);
369 }
370 }
371
372 //
373 // Free FormSet Default Store
374 //
375 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
376 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
377 Link = GetFirstNode (&FormSet->DefaultStoreListHead);
378 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);
379 RemoveEntryList (&DefaultStore->Link);
380
381 gBS->FreePool (DefaultStore);
382 }
383 }
384
385 //
386 // Free Forms
387 //
388 if (FormSet->FormListHead.ForwardLink != NULL) {
389 while (!IsListEmpty (&FormSet->FormListHead)) {
390 Link = GetFirstNode (&FormSet->FormListHead);
391 Form = FORM_BROWSER_FORM_FROM_LINK (Link);
392 RemoveEntryList (&Form->Link);
393
394 DestroyForm (Form);
395 }
396 }
397
398 if (FormSet->StatementBuffer != NULL) {
399 FreePool (FormSet->StatementBuffer);
400 }
401
402 DestoryOneOfOptionMap (&FormSet->OneOfOptionMapListHead);
403
404 if (FormSet->OriginalDefaultVarStoreName != NULL) {
405 FreePool (FormSet->OriginalDefaultVarStoreName);
406 }
407
408 FreePool (FormSet);
409 }
410
411
412 /**
413 Tell whether this Operand is an Expression OpCode or not
414
415 @param Operand Operand of an IFR OpCode.
416
417 @retval TRUE This is an Expression OpCode.
418 @retval FALSE Not an Expression OpCode.
419
420 **/
421 BOOLEAN
422 IsExpressionOpCode (
423 IN UINT8 Operand
424 )
425 {
426 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||
427 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) ||
428 ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||
429 (Operand == EFI_IFR_CATENATE_OP) ||
430 (Operand == EFI_IFR_TO_LOWER_OP) ||
431 (Operand == EFI_IFR_TO_UPPER_OP) ||
432 (Operand == EFI_IFR_MAP_OP) ||
433 (Operand == EFI_IFR_VERSION_OP) ||
434 (Operand == EFI_IFR_SECURITY_OP)) {
435 return TRUE;
436 } else {
437 return FALSE;
438 }
439 }
440
441
442 /**
443 Calculate number of Statemens(Questions) and Expression OpCodes.
444
445 @param FormSet The FormSet to be counted.
446 @param NumberOfStatement Number of Statemens(Questions)
447 @param NumberOfExpression Number of Expression OpCodes
448
449 @return None.
450
451 **/
452 VOID
453 CountOpCodes (
454 IN FORM_BROWSER_FORMSET *FormSet,
455 IN OUT UINT16 *NumberOfStatement,
456 IN OUT UINT16 *NumberOfExpression
457 )
458 {
459 UINT16 StatementCount;
460 UINT16 ExpressionCount;
461 UINT8 *OpCodeData;
462 UINTN Offset;
463 UINTN OpCodeLen;
464
465 Offset = 0;
466 StatementCount = 0;
467 ExpressionCount = 0;
468
469 while (Offset < FormSet->IfrBinaryLength) {
470 OpCodeData = FormSet->IfrBinaryData + Offset;
471 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
472 Offset += OpCodeLen;
473
474 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {
475 ExpressionCount++;
476 } else {
477 StatementCount++;
478 }
479 }
480
481 *NumberOfStatement = StatementCount;
482 *NumberOfExpression = ExpressionCount;
483 }
484
485
486 /**
487 Parse opcodes in the formset IFR binary.
488
489 @param FormSet Pointer of the FormSet data structure.
490
491 @retval EFI_SUCCESS Opcode parse success.
492 @retval Other Opcode parse fail.
493
494 **/
495 EFI_STATUS
496 ParseOpCodes (
497 IN FORM_BROWSER_FORMSET *FormSet
498 )
499 {
500 EFI_STATUS Status;
501 UINT16 Index;
502 FORM_BROWSER_FORM *CurrentForm;
503 FORM_BROWSER_STATEMENT *CurrentStatement;
504 UINT8 Operand;
505 UINT8 Scope;
506 UINTN OpCodeOffset;
507 UINTN OpCodeLength;
508 UINT8 *OpCodeData;
509 UINT8 ScopeOpCode;
510 FORMSET_STORAGE *Storage;
511 FORMSET_DEFAULTSTORE *DefaultStore;
512 QUESTION_DEFAULT *CurrentDefault;
513 QUESTION_OPTION *CurrentOption;
514 CHAR8 *AsciiString;
515 UINT16 NumberOfStatement;
516 UINT16 NumberOfExpression;
517 EFI_IMAGE_ID *ImageId;
518 EFI_HII_VALUE *Value;
519 LIST_ENTRY *OneOfOptinMapEntryListHead;
520 EFI_IFR_GUID_OPTIONKEY *OptionMap;
521 ONE_OF_OPTION_MAP *OneOfOptionMap;
522 ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;
523 UINT8 OneOfType;
524 EFI_IFR_ONE_OF *OneOfOpcode;
525 HII_THUNK_CONTEXT *ThunkContext;
526 EFI_IFR_FORM_MAP_METHOD *MapMethod;
527
528 mInScopeSubtitle = FALSE;
529 mInScopeSuppress = FALSE;
530 mInScopeGrayOut = FALSE;
531 CurrentDefault = NULL;
532 CurrentOption = NULL;
533 MapMethod = NULL;
534 ThunkContext = UefiHiiHandleToThunkContext ((CONST HII_THUNK_PRIVATE_DATA*) mHiiThunkPrivateData, FormSet->HiiHandle);
535
536 //
537 // Set to a invalid value.
538 //
539 OneOfType = (UINT8) -1;
540
541 //
542 // Get the number of Statements and Expressions
543 //
544 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
545 FormSet->NumberOfStatement = NumberOfStatement;
546
547 mStatementIndex = 0;
548 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
549 if (FormSet->StatementBuffer == NULL) {
550 return EFI_OUT_OF_RESOURCES;
551 }
552
553 InitializeListHead (&FormSet->StorageListHead);
554 InitializeListHead (&FormSet->DefaultStoreListHead);
555 InitializeListHead (&FormSet->FormListHead);
556 InitializeListHead (&FormSet->OneOfOptionMapListHead);
557
558 CurrentForm = NULL;
559 CurrentStatement = NULL;
560
561 ResetScopeStack ();
562
563 OpCodeOffset = 0;
564 while (OpCodeOffset < FormSet->IfrBinaryLength) {
565 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;
566
567 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
568 OpCodeOffset += OpCodeLength;
569 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
570 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;
571
572 //
573 // If scope bit set, push onto scope stack
574 //
575 if (Scope != 0) {
576 PushScope (Operand);
577 }
578
579 if (IsExpressionOpCode (Operand)) {
580 continue;
581 }
582
583 //
584 // Parse the Opcode
585 //
586 switch (Operand) {
587
588 case EFI_IFR_FORM_SET_OP:
589 //
590 // check the formset GUID
591 //
592 if (!CompareGuid ((EFI_GUID *)(VOID *)&FormSet->Guid, (EFI_GUID *)(VOID *)&((EFI_IFR_FORM_SET *) OpCodeData)->Guid)) {
593 return EFI_INVALID_PARAMETER;
594 }
595
596 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
597 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
598 break;
599
600 case EFI_IFR_FORM_OP:
601 //
602 // Create a new Form for this FormSet
603 //
604 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
605 ASSERT (CurrentForm != NULL);
606 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
607
608 InitializeListHead (&CurrentForm->StatementListHead);
609
610 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
611 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
612
613 //
614 // Insert into Form list of this FormSet
615 //
616 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
617 break;
618
619 case EFI_IFR_FORM_MAP_OP:
620 //
621 // Create a new Form Map for this FormSet
622 //
623 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
624 ASSERT (CurrentForm != NULL);
625 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
626
627 InitializeListHead (&CurrentForm->StatementListHead);
628
629 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
630 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
631
632 //
633 // FormMap Form must contain at least one Map Method.
634 //
635 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {
636 return EFI_INVALID_PARAMETER;
637 }
638
639 //
640 // Try to find the standard form map method.
641 //
642 while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {
643 if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {
644 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
645 break;
646 }
647 MapMethod ++;
648 }
649 //
650 // If the standard form map method is not found, the first map method title will be used.
651 //
652 if (CurrentForm->FormTitle == 0) {
653 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
654 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
655 }
656
657 //
658 // Insert into Form list of this FormSet
659 //
660 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
661 break;
662
663 //
664 // Storage
665 //
666 case EFI_IFR_VARSTORE_OP:
667 //
668 // Create a buffer Storage for this FormSet
669 //
670 Storage = CreateStorage (FormSet);
671 Storage->Type = EFI_HII_VARSTORE_BUFFER;
672
673 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
674 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));
675 CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));
676
677 AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;
678 Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);
679 ASSERT (Storage->Name != NULL);
680 for (Index = 0; AsciiString[Index] != 0; Index++) {
681 Storage->Name[Index] = (CHAR16) AsciiString[Index];
682 }
683
684 break;
685
686 case EFI_IFR_VARSTORE_NAME_VALUE_OP:
687 //
688 // Framework IFR doesn't support Name/Value VarStore opcode
689 //
690 if (ThunkContext != NULL && ThunkContext->ByFrameworkHiiNewPack) {
691 ASSERT (FALSE);
692 }
693
694 //
695 // Create a name/value Storage for this FormSet
696 //
697 Storage = CreateStorage (FormSet);
698 Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;
699
700 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
701 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));
702
703 break;
704
705 case EFI_IFR_VARSTORE_EFI_OP:
706 //
707 // Create a EFI variable Storage for this FormSet
708 //
709 Storage = CreateStorage (FormSet);
710 Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;
711
712 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
713 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));
714 CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));
715 break;
716
717 //
718 // DefaultStore
719 //
720 case EFI_IFR_DEFAULTSTORE_OP:
721 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
722 ASSERT (DefaultStore != NULL);
723 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
724
725 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));
726 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
727
728 //
729 // Insert to DefaultStore list of this Formset
730 //
731 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
732 break;
733
734 //
735 // Statements
736 //
737 case EFI_IFR_SUBTITLE_OP:
738 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
739 ASSERT (CurrentStatement != NULL);
740 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
741
742 if (Scope != 0) {
743 mInScopeSubtitle = TRUE;
744 }
745 break;
746
747 case EFI_IFR_TEXT_OP:
748 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
749 ASSERT (CurrentStatement != NULL);
750
751 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
752 break;
753
754 //
755 // Questions
756 //
757 case EFI_IFR_ACTION_OP:
758 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
759 ASSERT (CurrentStatement != NULL);
760
761 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
762 //
763 // No QuestionConfig present, so no configuration string will be processed
764 //
765 CurrentStatement->QuestionConfig = 0;
766 } else {
767 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
768 }
769 break;
770
771 case EFI_IFR_RESET_BUTTON_OP:
772 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
773 ASSERT (CurrentStatement != NULL);
774 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
775 break;
776
777 case EFI_IFR_REF_OP:
778 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
779 ASSERT (CurrentStatement != NULL);
780
781 CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
782 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
783 CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
784
785 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
786 CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
787
788 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
789 CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
790 }
791 }
792 }
793 break;
794
795 case EFI_IFR_ONE_OF_OP:
796 case EFI_IFR_NUMERIC_OP:
797 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
798 ASSERT (CurrentStatement != NULL);
799
800 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
801 Value = &CurrentStatement->HiiValue;
802
803 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
804 case EFI_IFR_NUMERIC_SIZE_1:
805 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
806 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
807 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
808 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);
809 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
810 break;
811
812 case EFI_IFR_NUMERIC_SIZE_2:
813 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
814 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
815 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));
816 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);
817 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
818 break;
819
820 case EFI_IFR_NUMERIC_SIZE_4:
821 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
822 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
823 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));
824 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);
825 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
826 break;
827
828 case EFI_IFR_NUMERIC_SIZE_8:
829 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
830 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
831 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));
832 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);
833 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
834 break;
835
836 default:
837 break;
838 }
839
840 if (Operand == EFI_IFR_ONE_OF_OP) {
841 OneOfOpcode = (EFI_IFR_ONE_OF *) OpCodeData;
842 OneOfType = (UINT8) (OneOfOpcode->Flags & EFI_IFR_NUMERIC_SIZE);
843 }
844 break;
845
846 case EFI_IFR_ORDERED_LIST_OP:
847 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
848 ASSERT (CurrentStatement != NULL);
849
850 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;
851 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;
852 CurrentStatement->StorageWidth = (UINT16)(CurrentStatement->MaxContainers * sizeof (UINT8));
853
854 //
855 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver
856 // has to use FormBrowser2.Callback() to retrieve the uncommited data for
857 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).
858 //
859 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_OTHER;
860 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
861
862 break;
863
864 case EFI_IFR_CHECKBOX_OP:
865 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
866 ASSERT (CurrentStatement != NULL);
867
868 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;
869 CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);
870 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
871
872 break;
873
874 case EFI_IFR_STRING_OP:
875 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
876 ASSERT (CurrentStatement != NULL);
877
878 //
879 // MinSize is the minimum number of characters that can be accepted for this opcode,
880 // MaxSize is the maximum number of characters that can be accepted for this opcode.
881 // The characters are stored as Unicode, so the storage width should multiply 2.
882 //
883 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;
884 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;
885 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));
886 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;
887
888 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
889 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
890
891 break;
892
893 case EFI_IFR_PASSWORD_OP:
894 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
895 ASSERT (CurrentStatement != NULL);
896
897 //
898 // MinSize is the minimum number of characters that can be accepted for this opcode,
899 // MaxSize is the maximum number of characters that can be accepted for this opcode.
900 // The characters are stored as Unicode, so the storage width should multiply 2.
901 //
902 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));
903 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));
904 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));
905
906 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
907 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
908
909 break;
910
911 case EFI_IFR_DATE_OP:
912 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
913 ASSERT (CurrentStatement != NULL);
914
915 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;
916 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
917
918 break;
919
920 case EFI_IFR_TIME_OP:
921 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
922 ASSERT (CurrentStatement != NULL);
923
924 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;
925 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
926
927 break;
928
929 //
930 // Default
931 //
932 case EFI_IFR_DEFAULT_OP:
933 //
934 // EFI_IFR_DEFAULT appear in scope of a Question,
935 // It creates a default value for the current question.
936 // A Question may have more than one Default value which have different default types.
937 //
938 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
939 ASSERT (CurrentDefault != NULL);
940 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
941
942 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
943 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
944 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
945 ExtendValueToU64 (&CurrentDefault->Value);
946
947 //
948 // Insert to Default Value list of current Question
949 //
950 InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);
951
952 break;
953
954 //
955 // Option
956 //
957 case EFI_IFR_ONE_OF_OPTION_OP:
958 //
959 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
960 // It create a selection for use in current Question.
961 //
962 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
963 ASSERT (CurrentOption != NULL);
964 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
965
966 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
967 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
968 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
969 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
970 ExtendValueToU64 (&CurrentOption->Value);
971
972 //
973 // Insert to Option list of current Question
974 //
975 InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);
976 break;
977
978 //
979 // Conditional
980 //
981 case EFI_IFR_NO_SUBMIT_IF_OP:
982 case EFI_IFR_INCONSISTENT_IF_OP:
983 break;
984
985 case EFI_IFR_SUPPRESS_IF_OP:
986 break;
987
988 case EFI_IFR_GRAY_OUT_IF_OP:
989 break;
990
991 case EFI_IFR_DISABLE_IF_OP:
992 //
993 // Framework IFR doesn't support DisableIf opcode
994 //
995 if (ThunkContext != NULL && ThunkContext->ByFrameworkHiiNewPack) {
996 ASSERT (FALSE);
997 }
998
999 //
1000 // Expression
1001 //
1002 case EFI_IFR_VALUE_OP:
1003 case EFI_IFR_READ_OP:
1004 case EFI_IFR_WRITE_OP:
1005 break;
1006
1007 case EFI_IFR_RULE_OP:
1008 break;
1009
1010 //
1011 // Image
1012 //
1013 case EFI_IFR_IMAGE_OP:
1014 //
1015 // Get ScopeOpcode from top of stack
1016 //
1017 PopScope (&ScopeOpCode);
1018 PushScope (ScopeOpCode);
1019
1020 switch (ScopeOpCode) {
1021 case EFI_IFR_FORM_SET_OP:
1022 ImageId = &FormSet->ImageId;
1023 break;
1024
1025 case EFI_IFR_FORM_OP:
1026 case EFI_IFR_FORM_MAP_OP:
1027 ASSERT (CurrentForm != NULL);
1028 ImageId = &CurrentForm->ImageId;
1029 break;
1030
1031 case EFI_IFR_ONE_OF_OPTION_OP:
1032 ASSERT (CurrentOption != NULL);
1033 ImageId = &CurrentOption->ImageId;
1034 break;
1035
1036 default:
1037 //
1038 // Make sure CurrentStatement is not NULL.
1039 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1040 // file is wrongly generated by tools such as VFR Compiler.
1041 //
1042 ASSERT (CurrentStatement != NULL);
1043 ImageId = &CurrentStatement->ImageId;
1044 break;
1045 }
1046
1047 ASSERT (ImageId != NULL);
1048 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
1049 break;
1050
1051 //
1052 // Refresh
1053 //
1054 case EFI_IFR_REFRESH_OP:
1055 ASSERT (CurrentStatement != NULL);
1056 CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;
1057 break;
1058
1059 //
1060 // Vendor specific
1061 //
1062 case EFI_IFR_GUID_OP:
1063 OptionMap = (EFI_IFR_GUID_OPTIONKEY *) OpCodeData;
1064
1065 if (CompareGuid (&mTianoHiiIfrGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
1066 //
1067 // Tiano specific GUIDed opcodes
1068 //
1069 switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {
1070 case EFI_IFR_EXTEND_OP_LABEL:
1071 //
1072 // just ignore label
1073 //
1074 break;
1075
1076
1077 case EFI_IFR_EXTEND_OP_CLASS:
1078 CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));
1079 break;
1080
1081 case EFI_IFR_EXTEND_OP_SUBCLASS:
1082 CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));
1083 break;
1084
1085 default:
1086 break;
1087 }
1088 } else if (CompareGuid ((EFI_GUID *)(VOID *)&OptionMap->Guid, &mFrameworkHiiCompatibilityGuid)) {
1089 if (OptionMap->ExtendOpCode == EFI_IFR_EXTEND_OP_OPTIONKEY) {
1090 OneOfOptinMapEntryListHead = GetOneOfOptionMapEntryListHead (FormSet, OptionMap->QuestionId);
1091 if (OneOfOptinMapEntryListHead == NULL) {
1092 OneOfOptionMap = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP));
1093 ASSERT (OneOfOptionMap != NULL);
1094
1095 OneOfOptionMap->Signature = ONE_OF_OPTION_MAP_SIGNATURE;
1096 OneOfOptionMap->QuestionId = OptionMap->QuestionId;
1097
1098 //
1099 // Make sure OneOfType is initialized.
1100 //
1101 ASSERT (OneOfType != (UINT8) -1);
1102 OneOfOptionMap->ValueType = OneOfType;
1103 InitializeListHead (&OneOfOptionMap->OneOfOptionMapEntryListHead);
1104 OneOfOptinMapEntryListHead = &OneOfOptionMap->OneOfOptionMapEntryListHead;
1105 InsertTailList (&FormSet->OneOfOptionMapListHead, &OneOfOptionMap->Link);
1106 }
1107 OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY));
1108 ASSERT (OneOfOptionMapEntry != NULL);
1109
1110 OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE;
1111 OneOfOptionMapEntry->FwKey = OptionMap->KeyValue;
1112 CopyMem (&OneOfOptionMapEntry->Value, &OptionMap->OptionValue, sizeof (EFI_IFR_TYPE_VALUE));
1113
1114 InsertTailList (OneOfOptinMapEntryListHead, &OneOfOptionMapEntry->Link);
1115 }
1116 }
1117 break;
1118
1119 //
1120 // Scope End
1121 //
1122 case EFI_IFR_END_OP:
1123 Status = PopScope (&ScopeOpCode);
1124 if (EFI_ERROR (Status)) {
1125 ResetScopeStack ();
1126 return Status;
1127 }
1128
1129 switch (ScopeOpCode) {
1130 case EFI_IFR_FORM_SET_OP:
1131 //
1132 // End of FormSet, update FormSet IFR binary length
1133 // to stop parsing substantial OpCodes
1134 //
1135 FormSet->IfrBinaryLength = OpCodeOffset;
1136 break;
1137
1138 case EFI_IFR_FORM_OP:
1139 case EFI_IFR_FORM_MAP_OP:
1140 //
1141 // End of Form
1142 //
1143 CurrentForm = NULL;
1144 break;
1145
1146 case EFI_IFR_ONE_OF_OPTION_OP:
1147 //
1148 // End of Option
1149 //
1150 CurrentOption = NULL;
1151 break;
1152
1153 case EFI_IFR_SUBTITLE_OP:
1154 mInScopeSubtitle = FALSE;
1155 break;
1156
1157 case EFI_IFR_NO_SUBMIT_IF_OP:
1158 case EFI_IFR_INCONSISTENT_IF_OP:
1159 //
1160 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1161 //
1162 break;
1163
1164 case EFI_IFR_GRAY_OUT_IF_OP:
1165 mInScopeGrayOut = FALSE;
1166 break;
1167
1168 default:
1169 if (IsExpressionOpCode (ScopeOpCode)) {
1170 }
1171 break;
1172 }
1173 break;
1174
1175 default:
1176 break;
1177 }
1178 }
1179
1180 return EFI_SUCCESS;
1181 }
1182
1183
1184
1185