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