]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/UefiIfrParser.c
Update code to match EDKII coding style.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / UefiIfrParser.c
1 /** @file
2 Parser for IFR binary encoding.
3
4 Copyright (c) 2008 - 2010, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "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 FormSe.
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 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
625
626 InitializeListHead (&CurrentForm->StatementListHead);
627
628 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
629 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
630
631 //
632 // FormMap Form must contain at least one Map Method.
633 //
634 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {
635 return EFI_INVALID_PARAMETER;
636 }
637
638 //
639 // Try to find the standard form map method.
640 //
641 while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {
642 if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {
643 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
644 break;
645 }
646 MapMethod ++;
647 }
648 //
649 // If the standard form map method is not found, the first map method title will be used.
650 //
651 if (CurrentForm->FormTitle == 0) {
652 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
653 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
654 }
655
656 //
657 // Insert into Form list of this FormSet
658 //
659 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
660 break;
661
662 //
663 // Storage
664 //
665 case EFI_IFR_VARSTORE_OP:
666 //
667 // Create a buffer Storage for this FormSet
668 //
669 Storage = CreateStorage (FormSet);
670 Storage->Type = EFI_HII_VARSTORE_BUFFER;
671
672 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
673 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));
674 CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));
675
676 AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;
677 Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);
678 ASSERT (Storage->Name != NULL);
679 for (Index = 0; AsciiString[Index] != 0; Index++) {
680 Storage->Name[Index] = (CHAR16) AsciiString[Index];
681 }
682
683 break;
684
685 case EFI_IFR_VARSTORE_NAME_VALUE_OP:
686 //
687 // Framework IFR doesn't support Name/Value VarStore opcode
688 //
689 if (ThunkContext != NULL && ThunkContext->ByFrameworkHiiNewPack) {
690 ASSERT (FALSE);
691 }
692
693 //
694 // Create a name/value Storage for this FormSet
695 //
696 Storage = CreateStorage (FormSet);
697 Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;
698
699 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
700 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));
701
702 break;
703
704 case EFI_IFR_VARSTORE_EFI_OP:
705 //
706 // Create a EFI variable Storage for this FormSet
707 //
708 Storage = CreateStorage (FormSet);
709 Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;
710
711 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
712 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));
713 CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));
714 break;
715
716 //
717 // DefaultStore
718 //
719 case EFI_IFR_DEFAULTSTORE_OP:
720 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
721 ASSERT (DefaultStore != NULL);
722 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
723
724 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));
725 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
726
727 //
728 // Insert to DefaultStore list of this Formset
729 //
730 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
731 break;
732
733 //
734 // Statements
735 //
736 case EFI_IFR_SUBTITLE_OP:
737 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
738 ASSERT (CurrentStatement != NULL);
739 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
740
741 if (Scope != 0) {
742 mInScopeSubtitle = TRUE;
743 }
744 break;
745
746 case EFI_IFR_TEXT_OP:
747 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
748 ASSERT (CurrentStatement != NULL);
749
750 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
751 break;
752
753 //
754 // Questions
755 //
756 case EFI_IFR_ACTION_OP:
757 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
758 ASSERT (CurrentStatement != NULL);
759
760 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
761 //
762 // No QuestionConfig present, so no configuration string will be processed
763 //
764 CurrentStatement->QuestionConfig = 0;
765 } else {
766 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
767 }
768 break;
769
770 case EFI_IFR_RESET_BUTTON_OP:
771 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
772 ASSERT (CurrentStatement != NULL);
773 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
774 break;
775
776 case EFI_IFR_REF_OP:
777 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
778 ASSERT (CurrentStatement != NULL);
779
780 CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
781 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
782 CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
783
784 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
785 CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
786
787 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
788 CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
789 }
790 }
791 }
792 break;
793
794 case EFI_IFR_ONE_OF_OP:
795 case EFI_IFR_NUMERIC_OP:
796 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
797 ASSERT (CurrentStatement != NULL);
798
799 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
800 Value = &CurrentStatement->HiiValue;
801
802 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
803 case EFI_IFR_NUMERIC_SIZE_1:
804 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
805 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
806 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
807 CurrentStatement->StorageWidth = sizeof (UINT8);
808 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
809 break;
810
811 case EFI_IFR_NUMERIC_SIZE_2:
812 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
813 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
814 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));
815 CurrentStatement->StorageWidth = sizeof (UINT16);
816 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
817 break;
818
819 case EFI_IFR_NUMERIC_SIZE_4:
820 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
821 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
822 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));
823 CurrentStatement->StorageWidth = sizeof (UINT32);
824 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
825 break;
826
827 case EFI_IFR_NUMERIC_SIZE_8:
828 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
829 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
830 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));
831 CurrentStatement->StorageWidth = sizeof (UINT64);
832 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
833 break;
834
835 default:
836 break;
837 }
838
839 if (Operand == EFI_IFR_ONE_OF_OP) {
840 OneOfOpcode = (EFI_IFR_ONE_OF *) OpCodeData;
841 OneOfType = (UINT8) (OneOfOpcode->Flags & EFI_IFR_NUMERIC_SIZE);
842 }
843 break;
844
845 case EFI_IFR_ORDERED_LIST_OP:
846 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
847 ASSERT (CurrentStatement != NULL);
848
849 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;
850 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;
851 CurrentStatement->StorageWidth = (UINT16)(CurrentStatement->MaxContainers * sizeof (UINT8));
852
853 //
854 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver
855 // has to use FormBrowser2.Callback() to retrieve the uncommited data for
856 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).
857 //
858 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_OTHER;
859 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
860
861 break;
862
863 case EFI_IFR_CHECKBOX_OP:
864 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
865 ASSERT (CurrentStatement != NULL);
866
867 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;
868 CurrentStatement->StorageWidth = sizeof (BOOLEAN);
869 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
870
871 break;
872
873 case EFI_IFR_STRING_OP:
874 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
875 ASSERT (CurrentStatement != NULL);
876
877 //
878 // MinSize is the minimum number of characters that can be accepted for this opcode,
879 // MaxSize is the maximum number of characters that can be accepted for this opcode.
880 // The characters are stored as Unicode, so the storage width should multiply 2.
881 //
882 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;
883 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;
884 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));
885 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;
886
887 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
888 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
889
890 break;
891
892 case EFI_IFR_PASSWORD_OP:
893 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
894 ASSERT (CurrentStatement != NULL);
895
896 //
897 // MinSize is the minimum number of characters that can be accepted for this opcode,
898 // MaxSize is the maximum number of characters that can be accepted for this opcode.
899 // The characters are stored as Unicode, so the storage width should multiply 2.
900 //
901 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));
902 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));
903 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));
904
905 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
906 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
907
908 break;
909
910 case EFI_IFR_DATE_OP:
911 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
912 ASSERT (CurrentStatement != NULL);
913
914 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;
915 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
916
917 break;
918
919 case EFI_IFR_TIME_OP:
920 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
921 ASSERT (CurrentStatement != NULL);
922
923 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;
924 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
925
926 break;
927
928 //
929 // Default
930 //
931 case EFI_IFR_DEFAULT_OP:
932 //
933 // EFI_IFR_DEFAULT appear in scope of a Question,
934 // It creates a default value for the current question.
935 // A Question may have more than one Default value which have different default types.
936 //
937 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
938 ASSERT (CurrentDefault != NULL);
939 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
940
941 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
942 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
943 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
944 ExtendValueToU64 (&CurrentDefault->Value);
945
946 //
947 // Insert to Default Value list of current Question
948 //
949 InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);
950
951 break;
952
953 //
954 // Option
955 //
956 case EFI_IFR_ONE_OF_OPTION_OP:
957 //
958 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
959 // It create a selection for use in current Question.
960 //
961 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
962 ASSERT (CurrentOption != NULL);
963 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
964
965 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
966 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
967 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
968 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
969 ExtendValueToU64 (&CurrentOption->Value);
970
971 //
972 // Insert to Option list of current Question
973 //
974 InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);
975 break;
976
977 //
978 // Conditional
979 //
980 case EFI_IFR_NO_SUBMIT_IF_OP:
981 case EFI_IFR_INCONSISTENT_IF_OP:
982 break;
983
984 case EFI_IFR_SUPPRESS_IF_OP:
985 break;
986
987 case EFI_IFR_GRAY_OUT_IF_OP:
988 break;
989
990 case EFI_IFR_DISABLE_IF_OP:
991 //
992 // Framework IFR doesn't support DisableIf opcode
993 //
994 if (ThunkContext != NULL && ThunkContext->ByFrameworkHiiNewPack) {
995 ASSERT (FALSE);
996 }
997
998 //
999 // Expression
1000 //
1001 case EFI_IFR_VALUE_OP:
1002 case EFI_IFR_READ_OP:
1003 case EFI_IFR_WRITE_OP:
1004 break;
1005
1006 case EFI_IFR_RULE_OP:
1007 break;
1008
1009 //
1010 // Image
1011 //
1012 case EFI_IFR_IMAGE_OP:
1013 //
1014 // Get ScopeOpcode from top of stack
1015 //
1016 PopScope (&ScopeOpCode);
1017 PushScope (ScopeOpCode);
1018
1019 switch (ScopeOpCode) {
1020 case EFI_IFR_FORM_SET_OP:
1021 ImageId = &FormSet->ImageId;
1022 break;
1023
1024 case EFI_IFR_FORM_OP:
1025 case EFI_IFR_FORM_MAP_OP:
1026 ImageId = &CurrentForm->ImageId;
1027 break;
1028
1029 case EFI_IFR_ONE_OF_OPTION_OP:
1030 ImageId = &CurrentOption->ImageId;
1031 break;
1032
1033 default:
1034 //
1035 // Make sure CurrentStatement is not NULL.
1036 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1037 // file is wrongly generated by tools such as VFR Compiler.
1038 //
1039 ASSERT (CurrentStatement != NULL);
1040 ImageId = &CurrentStatement->ImageId;
1041 break;
1042 }
1043
1044 ASSERT (ImageId != NULL);
1045 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
1046 break;
1047
1048 //
1049 // Refresh
1050 //
1051 case EFI_IFR_REFRESH_OP:
1052 ASSERT (CurrentStatement != NULL);
1053 CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;
1054 break;
1055
1056 //
1057 // Vendor specific
1058 //
1059 case EFI_IFR_GUID_OP:
1060 OptionMap = (EFI_IFR_GUID_OPTIONKEY *) OpCodeData;
1061
1062 if (CompareGuid (&mTianoHiiIfrGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
1063 //
1064 // Tiano specific GUIDed opcodes
1065 //
1066 switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {
1067 case EFI_IFR_EXTEND_OP_LABEL:
1068 //
1069 // just ignore label
1070 //
1071 break;
1072
1073
1074 case EFI_IFR_EXTEND_OP_CLASS:
1075 CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));
1076 break;
1077
1078 case EFI_IFR_EXTEND_OP_SUBCLASS:
1079 CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));
1080 break;
1081
1082 default:
1083 break;
1084 }
1085 } else if (CompareGuid ((EFI_GUID *)(VOID *)&OptionMap->Guid, &mFrameworkHiiCompatibilityGuid)) {
1086 if (OptionMap->ExtendOpCode == EFI_IFR_EXTEND_OP_OPTIONKEY) {
1087 OneOfOptinMapEntryListHead = GetOneOfOptionMapEntryListHead (FormSet, OptionMap->QuestionId);
1088 if (OneOfOptinMapEntryListHead == NULL) {
1089 OneOfOptionMap = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP));
1090 ASSERT (OneOfOptionMap != NULL);
1091
1092 OneOfOptionMap->Signature = ONE_OF_OPTION_MAP_SIGNATURE;
1093 OneOfOptionMap->QuestionId = OptionMap->QuestionId;
1094
1095 //
1096 // Make sure OneOfType is initialized.
1097 //
1098 ASSERT (OneOfType != (UINT8) -1);
1099 OneOfOptionMap->ValueType = OneOfType;
1100 InitializeListHead (&OneOfOptionMap->OneOfOptionMapEntryListHead);
1101 OneOfOptinMapEntryListHead = &OneOfOptionMap->OneOfOptionMapEntryListHead;
1102 InsertTailList (&FormSet->OneOfOptionMapListHead, &OneOfOptionMap->Link);
1103 }
1104 OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY));
1105 ASSERT (OneOfOptionMapEntry != NULL);
1106
1107 OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE;
1108 OneOfOptionMapEntry->FwKey = OptionMap->KeyValue;
1109 CopyMem (&OneOfOptionMapEntry->Value, &OptionMap->OptionValue, sizeof (EFI_IFR_TYPE_VALUE));
1110
1111 InsertTailList (OneOfOptinMapEntryListHead, &OneOfOptionMapEntry->Link);
1112 }
1113 }
1114 break;
1115
1116 //
1117 // Scope End
1118 //
1119 case EFI_IFR_END_OP:
1120 Status = PopScope (&ScopeOpCode);
1121 if (EFI_ERROR (Status)) {
1122 ResetScopeStack ();
1123 return Status;
1124 }
1125
1126 switch (ScopeOpCode) {
1127 case EFI_IFR_FORM_SET_OP:
1128 //
1129 // End of FormSet, update FormSet IFR binary length
1130 // to stop parsing substantial OpCodes
1131 //
1132 FormSet->IfrBinaryLength = OpCodeOffset;
1133 break;
1134
1135 case EFI_IFR_FORM_OP:
1136 case EFI_IFR_FORM_MAP_OP:
1137 //
1138 // End of Form
1139 //
1140 CurrentForm = NULL;
1141 break;
1142
1143 case EFI_IFR_ONE_OF_OPTION_OP:
1144 //
1145 // End of Option
1146 //
1147 CurrentOption = NULL;
1148 break;
1149
1150 case EFI_IFR_SUBTITLE_OP:
1151 mInScopeSubtitle = FALSE;
1152 break;
1153
1154 case EFI_IFR_NO_SUBMIT_IF_OP:
1155 case EFI_IFR_INCONSISTENT_IF_OP:
1156 //
1157 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
1158 //
1159 break;
1160
1161 case EFI_IFR_GRAY_OUT_IF_OP:
1162 mInScopeGrayOut = FALSE;
1163 break;
1164
1165 default:
1166 if (IsExpressionOpCode (ScopeOpCode)) {
1167 }
1168 break;
1169 }
1170 break;
1171
1172 default:
1173 break;
1174 }
1175 }
1176
1177 return EFI_SUCCESS;
1178 }
1179
1180
1181
1182