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