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