]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
Fix a bug to handle case that SendForm() is called with an invalid FormSetGuid.
[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
4c8358c7 658 if (FormSet->IfrBinaryData == NULL) {\r
659 //\r
660 // Uninitialized FormSet\r
661 //\r
662 FreePool (FormSet);\r
663 return;\r
664 }\r
665\r
c60a0616 666 //\r
667 // Free IFR binary buffer\r
668 //\r
669 FreePool (FormSet->IfrBinaryData);\r
670\r
671 //\r
672 // Free FormSet Storage\r
673 //\r
674 if (FormSet->StorageListHead.ForwardLink != NULL) {\r
675 while (!IsListEmpty (&FormSet->StorageListHead)) {\r
676 Link = GetFirstNode (&FormSet->StorageListHead);\r
677 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
678 RemoveEntryList (&Storage->Link);\r
679\r
680 DestroyStorage (Storage);\r
681 }\r
682 }\r
683\r
684 //\r
685 // Free FormSet Default Store\r
686 //\r
687 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {\r
688 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
689 Link = GetFirstNode (&FormSet->DefaultStoreListHead);\r
690 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);\r
691 RemoveEntryList (&DefaultStore->Link);\r
692\r
f4113e1f 693 FreePool (DefaultStore);\r
c60a0616 694 }\r
695 }\r
696\r
0c66bc76
LG
697 //\r
698 // Free Formset Expressions\r
699 //\r
700 while (!IsListEmpty (&FormSet->ExpressionListHead)) {\r
701 Link = GetFirstNode (&FormSet->ExpressionListHead);\r
702 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
703 RemoveEntryList (&Expression->Link);\r
704\r
705 DestroyExpression (Expression);\r
706 }\r
707\r
c60a0616 708 //\r
709 // Free Forms\r
710 //\r
711 if (FormSet->FormListHead.ForwardLink != NULL) {\r
712 while (!IsListEmpty (&FormSet->FormListHead)) {\r
713 Link = GetFirstNode (&FormSet->FormListHead);\r
714 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
715 RemoveEntryList (&Form->Link);\r
716\r
717 DestroyForm (Form);\r
718 }\r
719 }\r
720\r
721 if (FormSet->StatementBuffer != NULL) {\r
722 FreePool (FormSet->StatementBuffer);\r
723 }\r
724 if (FormSet->ExpressionBuffer != NULL) {\r
725 FreePool (FormSet->ExpressionBuffer);\r
726 }\r
727\r
728 FreePool (FormSet);\r
729}\r
730\r
731\r
732/**\r
733 Tell whether this Operand is an Expression OpCode or not\r
734\r
735 @param Operand Operand of an IFR OpCode.\r
736\r
737 @retval TRUE This is an Expression OpCode.\r
738 @retval FALSE Not an Expression OpCode.\r
739\r
740**/\r
741BOOLEAN\r
742IsExpressionOpCode (\r
743 IN UINT8 Operand\r
744 )\r
745{\r
746 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||\r
747 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
748 (Operand == EFI_IFR_CATENATE_OP) ||\r
749 (Operand == EFI_IFR_TO_LOWER_OP) ||\r
750 (Operand == EFI_IFR_TO_UPPER_OP) ||\r
751 (Operand == EFI_IFR_VERSION_OP)\r
752 ) {\r
753 return TRUE;\r
754 } else {\r
755 return FALSE;\r
756 }\r
757}\r
758\r
759\r
760/**\r
761 Calculate number of Statemens(Questions) and Expression OpCodes.\r
762\r
763 @param FormSet The FormSet to be counted.\r
764 @param NumberOfStatement Number of Statemens(Questions)\r
765 @param NumberOfExpression Number of Expression OpCodes\r
766\r
767**/\r
768VOID\r
769CountOpCodes (\r
770 IN FORM_BROWSER_FORMSET *FormSet,\r
771 IN OUT UINT16 *NumberOfStatement,\r
772 IN OUT UINT16 *NumberOfExpression\r
773 )\r
774{\r
775 UINT16 StatementCount;\r
776 UINT16 ExpressionCount;\r
777 UINT8 *OpCodeData;\r
778 UINTN Offset;\r
779 UINTN OpCodeLen;\r
780\r
781 Offset = 0;\r
782 StatementCount = 0;\r
783 ExpressionCount = 0;\r
784\r
785 while (Offset < FormSet->IfrBinaryLength) {\r
786 OpCodeData = FormSet->IfrBinaryData + Offset;\r
787 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
788 Offset += OpCodeLen;\r
789\r
790 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {\r
791 ExpressionCount++;\r
792 } else {\r
793 StatementCount++;\r
794 }\r
795 }\r
796\r
797 *NumberOfStatement = StatementCount;\r
798 *NumberOfExpression = ExpressionCount;\r
799}\r
800\r
801\r
802\r
803/**\r
804 Parse opcodes in the formset IFR binary.\r
805\r
806 @param FormSet Pointer of the FormSet data structure.\r
807\r
808 @retval EFI_SUCCESS Opcode parse success.\r
809 @retval Other Opcode parse fail.\r
810\r
811**/\r
812EFI_STATUS\r
813ParseOpCodes (\r
814 IN FORM_BROWSER_FORMSET *FormSet\r
815 )\r
816{\r
817 EFI_STATUS Status;\r
818 UINT16 Index;\r
819 FORM_BROWSER_FORM *CurrentForm;\r
820 FORM_BROWSER_STATEMENT *CurrentStatement;\r
821 EXPRESSION_OPCODE *ExpressionOpCode;\r
822 FORM_EXPRESSION *CurrentExpression;\r
823 UINT8 Operand;\r
824 UINT8 Scope;\r
825 UINTN OpCodeOffset;\r
826 UINTN OpCodeLength;\r
827 UINT8 *OpCodeData;\r
828 UINT8 ScopeOpCode;\r
829 FORMSET_STORAGE *Storage;\r
830 FORMSET_DEFAULTSTORE *DefaultStore;\r
831 QUESTION_DEFAULT *CurrentDefault;\r
832 QUESTION_OPTION *CurrentOption;\r
d02847d3 833 UINT8 Width;\r
c60a0616 834 CHAR8 *AsciiString;\r
835 UINT16 NumberOfStatement;\r
836 UINT16 NumberOfExpression;\r
837 EFI_IMAGE_ID *ImageId;\r
0c66bc76 838 BOOLEAN SuppressForQuestion;\r
c60a0616 839 BOOLEAN SuppressForOption;\r
840 BOOLEAN InScopeOptionSuppress;\r
841 FORM_EXPRESSION *OptionSuppressExpression;\r
0c66bc76
LG
842 BOOLEAN InScopeFormSuppress;\r
843 FORM_EXPRESSION *FormSuppressExpression;\r
c60a0616 844 UINT16 DepthOfDisable;\r
845 BOOLEAN OpCodeDisabled;\r
846 BOOLEAN SingleOpCodeExpression;\r
847 BOOLEAN InScopeDefault;\r
848 EFI_HII_VALUE *Value;\r
849\r
850 mInScopeSubtitle = FALSE;\r
0c66bc76 851 SuppressForQuestion = FALSE;\r
c60a0616 852 SuppressForOption = FALSE;\r
0c66bc76 853 InScopeFormSuppress = FALSE;\r
c60a0616 854 mInScopeSuppress = FALSE;\r
855 InScopeOptionSuppress = FALSE;\r
856 mInScopeGrayOut = FALSE;\r
0a1147ed 857 mInScopeDisable = FALSE;\r
c60a0616 858 DepthOfDisable = 0;\r
859 OpCodeDisabled = FALSE;\r
860 SingleOpCodeExpression = FALSE;\r
861 InScopeDefault = FALSE;\r
862 CurrentExpression = NULL;\r
863 CurrentDefault = NULL;\r
864 CurrentOption = NULL;\r
865 OptionSuppressExpression = NULL;\r
0c66bc76 866 FormSuppressExpression = NULL;\r
c410589e 867 ImageId = NULL;\r
c60a0616 868\r
869 //\r
870 // Get the number of Statements and Expressions\r
871 //\r
872 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r
873\r
874 mStatementIndex = 0;\r
875 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r
876 if (FormSet->StatementBuffer == NULL) {\r
877 return EFI_OUT_OF_RESOURCES;\r
878 }\r
879\r
880 mExpressionOpCodeIndex = 0;\r
881 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));\r
882 if (FormSet->ExpressionBuffer == NULL) {\r
883 return EFI_OUT_OF_RESOURCES;\r
884 }\r
885\r
886 InitializeListHead (&FormSet->StorageListHead);\r
887 InitializeListHead (&FormSet->DefaultStoreListHead);\r
888 InitializeListHead (&FormSet->FormListHead);\r
889\r
890 CurrentForm = NULL;\r
891 CurrentStatement = NULL;\r
892\r
893 ResetScopeStack ();\r
894\r
895 OpCodeOffset = 0;\r
896 while (OpCodeOffset < FormSet->IfrBinaryLength) {\r
897 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;\r
898\r
899 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
900 OpCodeOffset += OpCodeLength;\r
901 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
902 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;\r
903\r
904 //\r
905 // If scope bit set, push onto scope stack\r
906 //\r
907 if (Scope != 0) {\r
908 PushScope (Operand);\r
909 }\r
910\r
911 if (OpCodeDisabled) {\r
912 //\r
913 // DisableIf Expression is evaluated to be TRUE, try to find its end.\r
914 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END\r
915 //\r
916 if (Operand == EFI_IFR_DISABLE_IF_OP) {\r
917 DepthOfDisable++;\r
918 } else if (Operand == EFI_IFR_END_OP) {\r
919 Status = PopScope (&ScopeOpCode);\r
920 if (EFI_ERROR (Status)) {\r
921 return Status;\r
922 }\r
923\r
924 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {\r
925 if (DepthOfDisable == 0) {\r
0a1147ed 926 mInScopeDisable = FALSE;\r
c60a0616 927 OpCodeDisabled = FALSE;\r
928 } else {\r
929 DepthOfDisable--;\r
930 }\r
931 }\r
932 }\r
933 continue;\r
934 }\r
935\r
936 if (IsExpressionOpCode (Operand)) {\r
937 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];\r
938 mExpressionOpCodeIndex++;\r
939\r
940 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;\r
941 ExpressionOpCode->Operand = Operand;\r
942 Value = &ExpressionOpCode->Value;\r
943\r
944 switch (Operand) {\r
945 case EFI_IFR_EQ_ID_VAL_OP:\r
946 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
947\r
948 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
949 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));\r
950 break;\r
951\r
952 case EFI_IFR_EQ_ID_ID_OP:\r
953 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));\r
954 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));\r
955 break;\r
956\r
957 case EFI_IFR_EQ_ID_LIST_OP:\r
2654f642 958 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
959 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r
960 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);\r
c60a0616 961 break;\r
962\r
963 case EFI_IFR_TO_STRING_OP:\r
964 case EFI_IFR_FIND_OP:\r
965 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;\r
966 break;\r
967\r
968 case EFI_IFR_STRING_REF1_OP:\r
969 Value->Type = EFI_IFR_TYPE_STRING;\r
970 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));\r
971 break;\r
972\r
973 case EFI_IFR_RULE_REF_OP:\r
974 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;\r
975 break;\r
976\r
977 case EFI_IFR_SPAN_OP:\r
978 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;\r
979 break;\r
980\r
981 case EFI_IFR_THIS_OP:\r
d0720b57 982 ASSERT (CurrentStatement != NULL);\r
c60a0616 983 ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;\r
984 break;\r
985\r
986 case EFI_IFR_QUESTION_REF1_OP:\r
2654f642 987 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
c60a0616 988 break;\r
989\r
990 case EFI_IFR_QUESTION_REF3_OP:\r
991 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {\r
992 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
993\r
994 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {\r
995 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
996 }\r
997 }\r
998 break;\r
999\r
1000 //\r
1001 // constant\r
1002 //\r
1003 case EFI_IFR_TRUE_OP:\r
1004 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
1005 Value->Value.b = TRUE;\r
1006 break;\r
1007\r
1008 case EFI_IFR_FALSE_OP:\r
1009 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
1010 Value->Value.b = FALSE;\r
1011 break;\r
1012\r
1013 case EFI_IFR_ONE_OP:\r
1014 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1015 Value->Value.u8 = 1;\r
1016 break;\r
1017\r
1018 case EFI_IFR_ZERO_OP:\r
1019 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1020 Value->Value.u8 = 0;\r
1021 break;\r
1022\r
1023 case EFI_IFR_ONES_OP:\r
1024 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1025 Value->Value.u64 = 0xffffffffffffffffULL;\r
1026 break;\r
1027\r
1028 case EFI_IFR_UINT8_OP:\r
1029 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1030 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;\r
1031 break;\r
1032\r
1033 case EFI_IFR_UINT16_OP:\r
1034 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1035 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));\r
1036 break;\r
1037\r
1038 case EFI_IFR_UINT32_OP:\r
1039 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1040 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));\r
1041 break;\r
1042\r
1043 case EFI_IFR_UINT64_OP:\r
1044 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1045 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));\r
1046 break;\r
1047\r
1048 case EFI_IFR_UNDEFINED_OP:\r
d02847d3 1049 Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
c60a0616 1050 break;\r
1051\r
1052 case EFI_IFR_VERSION_OP:\r
1053 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1054 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;\r
1055 break;\r
1056\r
1057 default:\r
1058 break;\r
1059 }\r
1060\r
f8a1c229 1061 ASSERT (CurrentExpression != NULL);\r
c60a0616 1062 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r
1063\r
1064 if (SingleOpCodeExpression) {\r
1065 //\r
1066 // There are two cases to indicate the end of an Expression:\r
1067 // for single OpCode expression: one Expression OpCode\r
1068 // for expression consists of more than one OpCode: EFI_IFR_END\r
1069 //\r
1070 SingleOpCodeExpression = FALSE;\r
1071\r
0a1147ed 1072 if (mInScopeDisable && CurrentForm == NULL) {\r
c60a0616 1073 //\r
0a1147ed 1074 // This is DisableIf expression for Form, it should be a constant expression\r
c60a0616 1075 //\r
1076 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
1077 if (EFI_ERROR (Status)) {\r
1078 return Status;\r
1079 }\r
c410589e 1080\r
c60a0616 1081 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
1082 return EFI_INVALID_PARAMETER;\r
1083 }\r
1084\r
1085 OpCodeDisabled = CurrentExpression->Result.Value.b;\r
1086 }\r
1087\r
1088 CurrentExpression = NULL;\r
1089 }\r
1090\r
1091 continue;\r
1092 }\r
1093\r
1094 //\r
1095 // Parse the Opcode\r
1096 //\r
1097 switch (Operand) {\r
1098\r
1099 case EFI_IFR_FORM_SET_OP:\r
1100 //\r
f8a1c229 1101 // Check the formset GUID\r
c60a0616 1102 //\r
1103 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {\r
1104 return EFI_INVALID_PARAMETER;\r
1105 }\r
1106\r
1107 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
1108 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
0a1147ed
LG
1109\r
1110 //\r
1111 // The formset OpCode contains ClassGuid\r
1112 //\r
7da73676 1113 FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
0a1147ed 1114 CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));\r
0c66bc76
LG
1115\r
1116 InitializeListHead (&FormSet->ExpressionListHead);\r
c60a0616 1117 break;\r
1118\r
1119 case EFI_IFR_FORM_OP:\r
1120 //\r
1121 // Create a new Form for this FormSet\r
1122 //\r
1123 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
1ac628ee 1124 ASSERT (CurrentForm != NULL);\r
c60a0616 1125 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
1126 InitializeListHead (&CurrentForm->ExpressionListHead);\r
1127 InitializeListHead (&CurrentForm->StatementListHead);\r
1128\r
1129 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
1130 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
1131\r
0c66bc76
LG
1132 if (InScopeFormSuppress) {\r
1133 //\r
1134 // Form is inside of suppressif\r
1135 //\r
1136 CurrentForm->SuppressExpression = FormSuppressExpression;\r
1137 }\r
1138\r
1139 if (Scope != 0) {\r
1140 //\r
1141 // Enter scope of a Form, suppressif will be used for Question or Option\r
1142 //\r
1143 SuppressForQuestion = TRUE;\r
1144 }\r
1145\r
c60a0616 1146 //\r
1147 // Insert into Form list of this FormSet\r
1148 //\r
1149 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1150 break;\r
1151\r
1152 //\r
1153 // Storage\r
1154 //\r
1155 case EFI_IFR_VARSTORE_OP:\r
1156 //\r
1157 // Create a buffer Storage for this FormSet\r
1158 //\r
1159 Storage = CreateStorage (FormSet);\r
1160 Storage->Type = EFI_HII_VARSTORE_BUFFER;\r
1161\r
1162 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1163 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1164 CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));\r
1165\r
1166 Storage->Buffer = AllocateZeroPool (Storage->Size);\r
1167 Storage->EditBuffer = AllocateZeroPool (Storage->Size);\r
1168\r
1169 AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r
1170 Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);\r
1171 ASSERT (Storage->Name != NULL);\r
1172 for (Index = 0; AsciiString[Index] != 0; Index++) {\r
1173 Storage->Name[Index] = (CHAR16) AsciiString[Index];\r
1174 }\r
1175\r
1176 //\r
1177 // Initialize <ConfigHdr>\r
1178 //\r
1179 InitializeConfigHdr (FormSet, Storage);\r
1180 break;\r
1181\r
1182 case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
1183 //\r
1184 // Create a name/value Storage for this FormSet\r
1185 //\r
1186 Storage = CreateStorage (FormSet);\r
1187 Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
1188\r
1189 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1190 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1191\r
1192 //\r
1193 // Initialize <ConfigHdr>\r
1194 //\r
1195 InitializeConfigHdr (FormSet, Storage);\r
1196 break;\r
1197\r
1198 case EFI_IFR_VARSTORE_EFI_OP:\r
1199 //\r
1200 // Create a EFI variable Storage for this FormSet\r
1201 //\r
1202 Storage = CreateStorage (FormSet);\r
1203 Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;\r
1204\r
1205 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1206 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1207 CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));\r
1208 break;\r
1209\r
1210 //\r
1211 // DefaultStore\r
1212 //\r
1213 case EFI_IFR_DEFAULTSTORE_OP:\r
1214 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
1ac628ee 1215 ASSERT (DefaultStore != NULL);\r
c60a0616 1216 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
1217\r
1218 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1219 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
1220\r
1221 //\r
1222 // Insert to DefaultStore list of this Formset\r
1223 //\r
1224 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
1225 break;\r
1226\r
1227 //\r
1228 // Statements\r
1229 //\r
1230 case EFI_IFR_SUBTITLE_OP:\r
1231 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
bc166db3 1232 ASSERT (CurrentStatement != NULL);\r
8b0fc5c1 1233\r
c60a0616 1234 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
1235\r
1236 if (Scope != 0) {\r
1237 mInScopeSubtitle = TRUE;\r
1238 }\r
1239 break;\r
1240\r
1241 case EFI_IFR_TEXT_OP:\r
1242 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
bc166db3 1243 ASSERT (CurrentStatement != NULL);\r
c60a0616 1244\r
1245 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
1246 break;\r
1247\r
f8a1c229 1248 case EFI_IFR_RESET_BUTTON_OP:\r
1249 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1250 ASSERT (CurrentStatement != NULL);\r
1251 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
1252 break;\r
1253\r
c60a0616 1254 //\r
1255 // Questions\r
1256 //\r
1257 case EFI_IFR_ACTION_OP:\r
1258 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
bc166db3 1259 ASSERT (CurrentStatement != NULL);\r
d02847d3 1260 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;\r
c60a0616 1261\r
1262 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
1263 //\r
1264 // No QuestionConfig present, so no configuration string will be processed\r
1265 //\r
1266 CurrentStatement->QuestionConfig = 0;\r
1267 } else {\r
1268 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));\r
1269 }\r
1270 break;\r
1271\r
c60a0616 1272 case EFI_IFR_REF_OP:\r
1273 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1274 ASSERT (CurrentStatement != NULL);\r
d02847d3 1275 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_UNDEFINED;\r
c60a0616 1276 CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
1277 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
1278 CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
1279\r
1280 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
1281 CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
1282\r
1283 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
1284 CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
1285 }\r
1286 }\r
1287 }\r
1288 break;\r
1289\r
1290 case EFI_IFR_ONE_OF_OP:\r
1291 case EFI_IFR_NUMERIC_OP:\r
1292 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
945e3aed 1293 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1294\r
c60a0616 1295 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
1296 Value = &CurrentStatement->HiiValue;\r
1297\r
1298 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
1299 case EFI_IFR_NUMERIC_SIZE_1:\r
1300 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
1301 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
1302 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
1303 CurrentStatement->StorageWidth = sizeof (UINT8);\r
1304 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1305 break;\r
1306\r
1307 case EFI_IFR_NUMERIC_SIZE_2:\r
1308 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
1309 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
1310 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));\r
1311 CurrentStatement->StorageWidth = sizeof (UINT16);\r
1312 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1313 break;\r
1314\r
1315 case EFI_IFR_NUMERIC_SIZE_4:\r
1316 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
1317 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
1318 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));\r
1319 CurrentStatement->StorageWidth = sizeof (UINT32);\r
1320 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1321 break;\r
1322\r
1323 case EFI_IFR_NUMERIC_SIZE_8:\r
1324 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
1325 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
1326 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));\r
1327 CurrentStatement->StorageWidth = sizeof (UINT64);\r
1328 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1329 break;\r
1330\r
1331 default:\r
1332 break;\r
1333 }\r
1334\r
1335 InitializeRequestElement (FormSet, CurrentStatement);\r
1336\r
1337 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {\r
1338 SuppressForOption = TRUE;\r
1339 }\r
1340 break;\r
1341\r
1342 case EFI_IFR_ORDERED_LIST_OP:\r
1343 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1344 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1345\r
c60a0616 1346 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
1347 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
c60a0616 1348\r
d02847d3 1349 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;\r
c60a0616 1350\r
1351 if (Scope != 0) {\r
1352 SuppressForOption = TRUE;\r
1353 }\r
1354 break;\r
1355\r
1356 case EFI_IFR_CHECKBOX_OP:\r
1357 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1358 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1359\r
c60a0616 1360 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
1361 CurrentStatement->StorageWidth = sizeof (BOOLEAN);\r
1362 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
1363\r
1364 InitializeRequestElement (FormSet, CurrentStatement);\r
1365\r
1366 break;\r
1367\r
1368 case EFI_IFR_STRING_OP:\r
1369 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1370 ASSERT (CurrentStatement != NULL);\r
c60a0616 1371 //\r
1372 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1373 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1374 // The characters are stored as Unicode, so the storage width should multiply 2.\r
1375 //\r
1376 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;\r
1377 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;\r
1378 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
1379 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;\r
1380\r
1381 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1382 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));\r
1383\r
1384 InitializeRequestElement (FormSet, CurrentStatement);\r
1385 break;\r
1386\r
1387 case EFI_IFR_PASSWORD_OP:\r
1388 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1389 ASSERT (CurrentStatement != NULL);\r
c60a0616 1390 //\r
1391 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1392 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1393 // The characters are stored as Unicode, so the storage width should multiply 2.\r
1394 //\r
1395 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));\r
1396 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));\r
1397 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
1398\r
1399 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1400 CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));\r
1401\r
1402 InitializeRequestElement (FormSet, CurrentStatement);\r
1403 break;\r
1404\r
1405 case EFI_IFR_DATE_OP:\r
1406 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1407 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1408\r
c60a0616 1409 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
1410 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
1411\r
1412 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
1413 CurrentStatement->StorageWidth = sizeof (EFI_HII_DATE);\r
1414\r
1415 InitializeRequestElement (FormSet, CurrentStatement);\r
1416 } else {\r
1417 //\r
1418 // Don't assign storage for RTC type of date/time\r
1419 //\r
1420 CurrentStatement->Storage = NULL;\r
1421 CurrentStatement->StorageWidth = 0;\r
1422 }\r
1423 break;\r
1424\r
1425 case EFI_IFR_TIME_OP:\r
1426 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1427 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1428\r
c60a0616 1429 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
1430 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
1431\r
1432 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
1433 CurrentStatement->StorageWidth = sizeof (EFI_IFR_TIME);\r
1434\r
1435 InitializeRequestElement (FormSet, CurrentStatement);\r
1436 } else {\r
1437 //\r
1438 // Don't assign storage for RTC type of date/time\r
1439 //\r
1440 CurrentStatement->Storage = NULL;\r
1441 CurrentStatement->StorageWidth = 0;\r
1442 }\r
1443 break;\r
1444\r
1445 //\r
1446 // Default\r
1447 //\r
1448 case EFI_IFR_DEFAULT_OP:\r
1449 //\r
1450 // EFI_IFR_DEFAULT appear in scope of a Question,\r
1451 // It creates a default value for the current question.\r
1452 // A Question may have more than one Default value which have different default types.\r
1453 //\r
1454 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
1ac628ee 1455 ASSERT (CurrentDefault != NULL);\r
c60a0616 1456 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
1457\r
1458 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
1459 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1460 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1461 ExtendValueToU64 (&CurrentDefault->Value);\r
1462\r
1463 //\r
1464 // Insert to Default Value list of current Question\r
1465 //\r
1466 InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r
1467\r
1468 if (Scope != 0) {\r
1469 InScopeDefault = TRUE;\r
1470 }\r
1471 break;\r
1472\r
1473 //\r
1474 // Option\r
1475 //\r
1476 case EFI_IFR_ONE_OF_OPTION_OP:\r
1477 //\r
1478 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
1479 // It create a selection for use in current Question.\r
1480 //\r
1481 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
1ac628ee 1482 ASSERT (CurrentOption != NULL);\r
c60a0616 1483 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
1484\r
1485 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
1486 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
1487 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));\r
1488 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1489 ExtendValueToU64 (&CurrentOption->Value);\r
1490\r
1491 if (InScopeOptionSuppress) {\r
1492 CurrentOption->SuppressExpression = OptionSuppressExpression;\r
1493 }\r
1494\r
1495 //\r
1496 // Insert to Option list of current Question\r
1497 //\r
1498 InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);\r
d02847d3 1499\r
1500 //\r
1501 // Now we know the Storage width of nested Ordered List\r
1502 //\r
1503 if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) {\r
1504 Width = 1;\r
1505 switch (CurrentOption->Value.Type) {\r
1506 case EFI_IFR_TYPE_NUM_SIZE_8:\r
1507 Width = 1;\r
1508 break;\r
1509\r
1510 case EFI_IFR_TYPE_NUM_SIZE_16:\r
1511 Width = 2;\r
1512 break;\r
1513\r
1514 case EFI_IFR_TYPE_NUM_SIZE_32:\r
1515 Width = 4;\r
1516 break;\r
1517\r
1518 case EFI_IFR_TYPE_NUM_SIZE_64:\r
1519 Width = 8;\r
1520 break;\r
1521\r
1522 default:\r
1523 //\r
1524 // Invalid type for Ordered List\r
1525 //\r
1526 break;\r
1527 }\r
1528\r
1529 CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);\r
1530 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
1531 CurrentStatement->ValueType = CurrentOption->Value.Type;\r
1532\r
1533 InitializeRequestElement (FormSet, CurrentStatement);\r
1534 }\r
c60a0616 1535 break;\r
1536\r
1537 //\r
1538 // Conditional\r
1539 //\r
1540 case EFI_IFR_NO_SUBMIT_IF_OP:\r
1541 case EFI_IFR_INCONSISTENT_IF_OP:\r
1542 //\r
1543 // Create an Expression node\r
1544 //\r
1545 CurrentExpression = CreateExpression (CurrentForm);\r
1546 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r
1547\r
1548 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r
1549 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r
1550 InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
1551 } else {\r
1552 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
1553 InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);\r
1554 }\r
0c66bc76
LG
1555\r
1556 //\r
1557 // Take a look at next OpCode to see whether current expression consists\r
1558 // of single OpCode\r
1559 //\r
1560 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1561 SingleOpCodeExpression = TRUE;\r
1562 }\r
c60a0616 1563 break;\r
1564\r
1565 case EFI_IFR_SUPPRESS_IF_OP:\r
1566 //\r
1567 // Question and Option will appear in scope of this OpCode\r
1568 //\r
1569 CurrentExpression = CreateExpression (CurrentForm);\r
1570 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
0c66bc76
LG
1571\r
1572 if (CurrentForm == NULL) {\r
1573 InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);\r
1574 } else {\r
1575 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1576 }\r
c60a0616 1577\r
1578 if (SuppressForOption) {\r
1579 InScopeOptionSuppress = TRUE;\r
1580 OptionSuppressExpression = CurrentExpression;\r
0c66bc76 1581 } else if (SuppressForQuestion) {\r
c60a0616 1582 mInScopeSuppress = TRUE;\r
1583 mSuppressExpression = CurrentExpression;\r
0c66bc76
LG
1584 } else {\r
1585 InScopeFormSuppress = TRUE;\r
1586 FormSuppressExpression = CurrentExpression;\r
1587 }\r
1588\r
1589 //\r
1590 // Take a look at next OpCode to see whether current expression consists\r
1591 // of single OpCode\r
1592 //\r
1593 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1594 SingleOpCodeExpression = TRUE;\r
c60a0616 1595 }\r
1596 break;\r
1597\r
1598 case EFI_IFR_GRAY_OUT_IF_OP:\r
1599 //\r
1600 // Questions will appear in scope of this OpCode\r
1601 //\r
1602 CurrentExpression = CreateExpression (CurrentForm);\r
1603 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r
1604 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1605\r
1606 mInScopeGrayOut = TRUE;\r
1607 mGrayOutExpression = CurrentExpression;\r
0c66bc76
LG
1608\r
1609 //\r
1610 // Take a look at next OpCode to see whether current expression consists\r
1611 // of single OpCode\r
1612 //\r
1613 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1614 SingleOpCodeExpression = TRUE;\r
1615 }\r
c60a0616 1616 break;\r
1617\r
1618 case EFI_IFR_DISABLE_IF_OP:\r
1619 //\r
1620 // The DisableIf expression should only rely on constant, so it could be\r
1621 // evaluated at initialization and it will not be queued\r
1622 //\r
1623 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
1ac628ee 1624 ASSERT (CurrentExpression != NULL);\r
c60a0616 1625 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;\r
1626 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r
1627 InitializeListHead (&CurrentExpression->OpCodeListHead);\r
1628\r
0a1147ed
LG
1629 if (CurrentForm != NULL) {\r
1630 //\r
1631 // This is DisableIf for Question, enqueue it to Form expression list\r
1632 //\r
1633 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1634 }\r
1635\r
1636 mDisableExpression = CurrentExpression;\r
1637 mInScopeDisable = TRUE;\r
1638 OpCodeDisabled = FALSE;\r
c60a0616 1639\r
1640 //\r
1641 // Take a look at next OpCode to see whether current expression consists\r
1642 // of single OpCode\r
1643 //\r
1644 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1645 SingleOpCodeExpression = TRUE;\r
1646 }\r
1647 break;\r
1648\r
1649 //\r
1650 // Expression\r
1651 //\r
1652 case EFI_IFR_VALUE_OP:\r
1653 CurrentExpression = CreateExpression (CurrentForm);\r
1654 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r
1655 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1656\r
1657 if (InScopeDefault) {\r
1658 //\r
1659 // Used for default (EFI_IFR_DEFAULT)\r
1660 //\r
1661 CurrentDefault->ValueExpression = CurrentExpression;\r
1662 } else {\r
1663 //\r
1664 // If used for a question, then the question will be read-only\r
1665 //\r
bc166db3 1666 //\r
1667 // Make sure CurrentStatement is not NULL.\r
1668 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1669 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
1670 //\r
1671 ASSERT (CurrentStatement != NULL);\r
c60a0616 1672 CurrentStatement->ValueExpression = CurrentExpression;\r
1673 }\r
0c66bc76
LG
1674\r
1675 //\r
1676 // Take a look at next OpCode to see whether current expression consists\r
1677 // of single OpCode\r
1678 //\r
1679 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1680 SingleOpCodeExpression = TRUE;\r
1681 }\r
c60a0616 1682 break;\r
1683\r
1684 case EFI_IFR_RULE_OP:\r
1685 CurrentExpression = CreateExpression (CurrentForm);\r
1686 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r
1687\r
1688 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
1689 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
0c66bc76
LG
1690\r
1691 //\r
1692 // Take a look at next OpCode to see whether current expression consists\r
1693 // of single OpCode\r
1694 //\r
1695 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1696 SingleOpCodeExpression = TRUE;\r
1697 }\r
c60a0616 1698 break;\r
1699\r
1700 //\r
1701 // Image\r
1702 //\r
1703 case EFI_IFR_IMAGE_OP:\r
1704 //\r
1705 // Get ScopeOpcode from top of stack\r
1706 //\r
1707 PopScope (&ScopeOpCode);\r
1708 PushScope (ScopeOpCode);\r
1709\r
1710 switch (ScopeOpCode) {\r
1711 case EFI_IFR_FORM_SET_OP:\r
1712 ImageId = &FormSet->ImageId;\r
1713 break;\r
1714\r
1715 case EFI_IFR_FORM_OP:\r
d0720b57 1716 ASSERT (CurrentForm != NULL);\r
c60a0616 1717 ImageId = &CurrentForm->ImageId;\r
1718 break;\r
1719\r
1720 case EFI_IFR_ONE_OF_OPTION_OP:\r
1721 ImageId = &CurrentOption->ImageId;\r
1722 break;\r
1723\r
1724 default:\r
bc166db3 1725 //\r
1726 // Make sure CurrentStatement is not NULL.\r
1727 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1728 // file is wrongly generated by tools such as VFR Compiler.\r
1729 //\r
1730 ASSERT (CurrentStatement != NULL);\r
c60a0616 1731 ImageId = &CurrentStatement->ImageId;\r
1732 break;\r
1733 }\r
1734\r
c410589e 1735 ASSERT (ImageId != NULL);\r
c60a0616 1736 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));\r
1737 break;\r
1738\r
1739 //\r
1740 // Refresh\r
1741 //\r
1742 case EFI_IFR_REFRESH_OP:\r
c410589e 1743 ASSERT (CurrentStatement != NULL);\r
c60a0616 1744 CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
1745 break;\r
1746\r
1747 //\r
1748 // Vendor specific\r
1749 //\r
1750 case EFI_IFR_GUID_OP:\r
5c526736 1751 if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
c60a0616 1752 //\r
1753 // Tiano specific GUIDed opcodes\r
1754 //\r
1755 switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {\r
1756 case EFI_IFR_EXTEND_OP_LABEL:\r
1757 //\r
1758 // just ignore label\r
1759 //\r
1760 break;\r
1761\r
1762 case EFI_IFR_EXTEND_OP_BANNER:\r
0a1147ed 1763 //\r
b9e388d2 1764 // By SubClass to get Banner Data from Front Page\r
0a1147ed 1765 //\r
c60a0616 1766 if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
1767 CopyMem (\r
0a1147ed 1768 &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
c60a0616 1769 ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],\r
1770 &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,\r
1771 sizeof (EFI_STRING_ID)\r
1772 );\r
1773 }\r
1774 break;\r
1775\r
1776 case EFI_IFR_EXTEND_OP_CLASS:\r
1777 CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));\r
1778 break;\r
1779\r
1780 case EFI_IFR_EXTEND_OP_SUBCLASS:\r
1781 CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));\r
1782 break;\r
1783\r
1784 default:\r
1785 break;\r
1786 }\r
1787 }\r
1788\r
1789 break;\r
1790\r
1791 //\r
1792 // Scope End\r
1793 //\r
1794 case EFI_IFR_END_OP:\r
1795 Status = PopScope (&ScopeOpCode);\r
1796 if (EFI_ERROR (Status)) {\r
1797 ResetScopeStack ();\r
1798 return Status;\r
1799 }\r
1800\r
1801 switch (ScopeOpCode) {\r
1802 case EFI_IFR_FORM_SET_OP:\r
1803 //\r
1804 // End of FormSet, update FormSet IFR binary length\r
1805 // to stop parsing substantial OpCodes\r
1806 //\r
1807 FormSet->IfrBinaryLength = OpCodeOffset;\r
1808 break;\r
1809\r
1810 case EFI_IFR_FORM_OP:\r
1811 //\r
1812 // End of Form\r
1813 //\r
1814 CurrentForm = NULL;\r
0c66bc76 1815 SuppressForQuestion = FALSE;\r
c60a0616 1816 break;\r
1817\r
1818 case EFI_IFR_ONE_OF_OPTION_OP:\r
1819 //\r
1820 // End of Option\r
1821 //\r
1822 CurrentOption = NULL;\r
1823 break;\r
1824\r
1825 case EFI_IFR_SUBTITLE_OP:\r
1826 mInScopeSubtitle = FALSE;\r
1827 break;\r
1828\r
1829 case EFI_IFR_NO_SUBMIT_IF_OP:\r
1830 case EFI_IFR_INCONSISTENT_IF_OP:\r
1831 //\r
1832 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
1833 //\r
1834 break;\r
1835\r
1836 case EFI_IFR_SUPPRESS_IF_OP:\r
1837 if (SuppressForOption) {\r
1838 InScopeOptionSuppress = FALSE;\r
0c66bc76 1839 } else if (SuppressForQuestion) {\r
c60a0616 1840 mInScopeSuppress = FALSE;\r
0c66bc76
LG
1841 } else {\r
1842 InScopeFormSuppress = FALSE;\r
c60a0616 1843 }\r
1844 break;\r
1845\r
1846 case EFI_IFR_GRAY_OUT_IF_OP:\r
1847 mInScopeGrayOut = FALSE;\r
1848 break;\r
1849\r
1850 case EFI_IFR_DISABLE_IF_OP:\r
0a1147ed 1851 mInScopeDisable = FALSE;\r
c60a0616 1852 OpCodeDisabled = FALSE;\r
1853 break;\r
1854\r
1855 case EFI_IFR_ONE_OF_OP:\r
1856 case EFI_IFR_ORDERED_LIST_OP:\r
1857 SuppressForOption = FALSE;\r
1858 break;\r
1859\r
1860 case EFI_IFR_DEFAULT_OP:\r
1861 InScopeDefault = FALSE;\r
1862 break;\r
1863\r
1864 default:\r
1865 if (IsExpressionOpCode (ScopeOpCode)) {\r
0a1147ed 1866 if (mInScopeDisable && CurrentForm == NULL) {\r
c60a0616 1867 //\r
0a1147ed 1868 // This is DisableIf expression for Form, it should be a constant expression\r
c60a0616 1869 //\r
f8a1c229 1870 ASSERT (CurrentExpression != NULL);\r
c60a0616 1871 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
1872 if (EFI_ERROR (Status)) {\r
1873 return Status;\r
1874 }\r
a935a0d8 1875\r
c60a0616 1876 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
1877 return EFI_INVALID_PARAMETER;\r
1878 }\r
1879\r
1880 OpCodeDisabled = CurrentExpression->Result.Value.b;\r
1881 //\r
1882 // DisableIf Expression is only used once and not quequed, free it\r
1883 //\r
1884 DestroyExpression (CurrentExpression);\r
1885 }\r
1886\r
1887 //\r
1888 // End of current Expression\r
1889 //\r
1890 CurrentExpression = NULL;\r
1891 }\r
1892 break;\r
1893 }\r
1894 break;\r
1895\r
1896 default:\r
1897 break;\r
1898 }\r
1899 }\r
1900\r
1901 return EFI_SUCCESS;\r
1902}\r