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