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