]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
Update structure EFI_IFR_VARSTORE_EFI to follow UEFI spec 2.3.1
[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
8ca6180f
ED
1146 case EFI_IFR_TYPE_REF:\r
1147 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);\r
1148 break;\r
1149\r
2573712e
LG
1150 case EFI_IFR_TYPE_OTHER:\r
1151 case EFI_IFR_TYPE_UNDEFINED:\r
1152 case EFI_IFR_TYPE_ACTION:\r
1153 case EFI_IFR_TYPE_BUFFER:\r
1154 default:\r
1155 //\r
1156 // Invalid value type for Get/Set opcode.\r
1157 //\r
1158 return EFI_INVALID_PARAMETER;\r
1159 }\r
1160 CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID));\r
1161 CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));\r
1162 if ((ExpressionOpCode->VarStorage != NULL) && \r
1163 (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE || \r
1164 ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
1165 ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);\r
1166 if (ExpressionOpCode->ValueName == NULL) {\r
1167 //\r
1168 // String ID is invalid.\r
1169 //\r
1170 return EFI_INVALID_PARAMETER;\r
1171 }\r
1172 }\r
1173 break;\r
1174\r
c60a0616 1175 case EFI_IFR_QUESTION_REF1_OP:\r
2654f642 1176 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
c60a0616 1177 break;\r
1178\r
1179 case EFI_IFR_QUESTION_REF3_OP:\r
1180 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {\r
1181 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
1182\r
1183 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {\r
1184 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1185 }\r
1186 }\r
1187 break;\r
1188\r
1189 //\r
1190 // constant\r
1191 //\r
1192 case EFI_IFR_TRUE_OP:\r
1193 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
1194 Value->Value.b = TRUE;\r
1195 break;\r
1196\r
1197 case EFI_IFR_FALSE_OP:\r
1198 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
1199 Value->Value.b = FALSE;\r
1200 break;\r
1201\r
1202 case EFI_IFR_ONE_OP:\r
1203 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1204 Value->Value.u8 = 1;\r
1205 break;\r
1206\r
1207 case EFI_IFR_ZERO_OP:\r
1208 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1209 Value->Value.u8 = 0;\r
1210 break;\r
1211\r
1212 case EFI_IFR_ONES_OP:\r
1213 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1214 Value->Value.u64 = 0xffffffffffffffffULL;\r
1215 break;\r
1216\r
1217 case EFI_IFR_UINT8_OP:\r
1218 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1219 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;\r
1220 break;\r
1221\r
1222 case EFI_IFR_UINT16_OP:\r
1223 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1224 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));\r
1225 break;\r
1226\r
1227 case EFI_IFR_UINT32_OP:\r
1228 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1229 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));\r
1230 break;\r
1231\r
1232 case EFI_IFR_UINT64_OP:\r
1233 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1234 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));\r
1235 break;\r
1236\r
1237 case EFI_IFR_UNDEFINED_OP:\r
d02847d3 1238 Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
c60a0616 1239 break;\r
1240\r
1241 case EFI_IFR_VERSION_OP:\r
1242 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1243 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;\r
1244 break;\r
1245\r
1246 default:\r
1247 break;\r
1248 }\r
2573712e
LG
1249 //\r
1250 // Create sub expression nested in MAP opcode\r
1251 //\r
1252 if (CurrentExpression == NULL && MapScopeDepth > 0) {\r
1253 CurrentExpression = CreateExpression (CurrentForm);\r
771ececd 1254 ASSERT (MapExpressionList != NULL);\r
2573712e
LG
1255 InsertTailList (MapExpressionList, &CurrentExpression->Link);\r
1256 if (Scope == 0) {\r
1257 SingleOpCodeExpression = TRUE;\r
1258 }\r
1259 }\r
f8a1c229 1260 ASSERT (CurrentExpression != NULL);\r
c60a0616 1261 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r
2573712e
LG
1262 if (Operand == EFI_IFR_MAP_OP) {\r
1263 //\r
1264 // Store current Map Expression List.\r
1265 //\r
1266 if (MapExpressionList != NULL) {\r
1267 PushMapExpressionList (MapExpressionList);\r
1268 }\r
1269 //\r
1270 // Initialize new Map Expression List.\r
1271 //\r
1272 MapExpressionList = &ExpressionOpCode->MapExpressionList;\r
1273 InitializeListHead (MapExpressionList);\r
1274 //\r
1275 // Store current expression.\r
1276 //\r
1277 PushCurrentExpression (CurrentExpression);\r
1278 CurrentExpression = NULL;\r
1279 MapScopeDepth ++;\r
1280 } else if (SingleOpCodeExpression) {\r
c60a0616 1281 //\r
1282 // There are two cases to indicate the end of an Expression:\r
1283 // for single OpCode expression: one Expression OpCode\r
1284 // for expression consists of more than one OpCode: EFI_IFR_END\r
1285 //\r
1286 SingleOpCodeExpression = FALSE;\r
1287\r
0a1147ed 1288 if (mInScopeDisable && CurrentForm == NULL) {\r
c60a0616 1289 //\r
0a1147ed 1290 // This is DisableIf expression for Form, it should be a constant expression\r
c60a0616 1291 //\r
1292 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
1293 if (EFI_ERROR (Status)) {\r
1294 return Status;\r
1295 }\r
c410589e 1296\r
c60a0616 1297 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
1298 return EFI_INVALID_PARAMETER;\r
1299 }\r
1300\r
1301 OpCodeDisabled = CurrentExpression->Result.Value.b;\r
1302 }\r
1303\r
1304 CurrentExpression = NULL;\r
1305 }\r
1306\r
1307 continue;\r
1308 }\r
1309\r
1310 //\r
1311 // Parse the Opcode\r
1312 //\r
1313 switch (Operand) {\r
1314\r
1315 case EFI_IFR_FORM_SET_OP:\r
1316 //\r
f8a1c229 1317 // Check the formset GUID\r
c60a0616 1318 //\r
1319 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {\r
1320 return EFI_INVALID_PARAMETER;\r
1321 }\r
1322\r
1323 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
1324 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
0a1147ed 1325\r
d228526f
LG
1326 if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {\r
1327 //\r
1328 // The formset OpCode contains ClassGuid\r
1329 //\r
1330 FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);\r
1331 CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));\r
1332 }\r
0c66bc76
LG
1333\r
1334 InitializeListHead (&FormSet->ExpressionListHead);\r
c60a0616 1335 break;\r
1336\r
1337 case EFI_IFR_FORM_OP:\r
1338 //\r
1339 // Create a new Form for this FormSet\r
1340 //\r
1341 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
1ac628ee 1342 ASSERT (CurrentForm != NULL);\r
c60a0616 1343 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
1344 InitializeListHead (&CurrentForm->ExpressionListHead);\r
1345 InitializeListHead (&CurrentForm->StatementListHead);\r
b18e7050 1346 InitializeListHead (&CurrentForm->ConfigRequestHead);\r
c60a0616 1347\r
2573712e 1348 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
b18e7050 1349 CurrentForm->NvUpdateRequired = FALSE;\r
c60a0616 1350 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
1351 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
1352\r
0c66bc76
LG
1353 if (InScopeFormSuppress) {\r
1354 //\r
1355 // Form is inside of suppressif\r
1356 //\r
1357 CurrentForm->SuppressExpression = FormSuppressExpression;\r
1358 }\r
1359\r
1360 if (Scope != 0) {\r
1361 //\r
1362 // Enter scope of a Form, suppressif will be used for Question or Option\r
1363 //\r
1364 SuppressForQuestion = TRUE;\r
1365 }\r
1366\r
c60a0616 1367 //\r
1368 // Insert into Form list of this FormSet\r
1369 //\r
1370 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1371 break;\r
1372\r
2573712e
LG
1373 case EFI_IFR_FORM_MAP_OP:\r
1374 //\r
1375 // Create a new Form for this FormSet\r
1376 //\r
1377 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
1378 ASSERT (CurrentForm != NULL);\r
1379 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
b18e7050 1380 CurrentForm->NvUpdateRequired = FALSE;\r
2573712e
LG
1381 InitializeListHead (&CurrentForm->ExpressionListHead);\r
1382 InitializeListHead (&CurrentForm->StatementListHead);\r
b18e7050 1383 InitializeListHead (&CurrentForm->ConfigRequestHead);\r
2573712e
LG
1384 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
1385\r
1386 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
1387 //\r
1388 // FormMap Form must contain at least one Map Method.\r
1389 //\r
1390 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {\r
1391 return EFI_INVALID_PARAMETER;\r
1392 }\r
1393 //\r
1394 // Try to find the standard form map method.\r
1395 //\r
1396 while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {\r
1397 if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {\r
1398 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
1399 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;\r
1400 break;\r
1401 }\r
1402 MapMethod ++;\r
1403 }\r
1404 //\r
1405 // If the standard form map method is not found, the first map method title will be used.\r
1406 //\r
1407 if (CurrentForm->FormTitle == 0) {\r
1408 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
1409 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
1410 }\r
1411\r
1412 if (InScopeFormSuppress) {\r
1413 //\r
1414 // Form is inside of suppressif\r
1415 //\r
1416 CurrentForm->SuppressExpression = FormSuppressExpression;\r
1417 }\r
1418\r
1419 if (Scope != 0) {\r
1420 //\r
1421 // Enter scope of a Form, suppressif will be used for Question or Option\r
1422 //\r
1423 SuppressForQuestion = TRUE;\r
1424 }\r
1425\r
1426 //\r
1427 // Insert into Form list of this FormSet\r
1428 //\r
1429 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1430 break;\r
1431\r
c60a0616 1432 //\r
1433 // Storage\r
1434 //\r
1435 case EFI_IFR_VARSTORE_OP:\r
1436 //\r
1437 // Create a buffer Storage for this FormSet\r
1438 //\r
1439 Storage = CreateStorage (FormSet);\r
1440 Storage->Type = EFI_HII_VARSTORE_BUFFER;\r
1441\r
1442 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1443 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1444 CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));\r
1445\r
1446 Storage->Buffer = AllocateZeroPool (Storage->Size);\r
1447 Storage->EditBuffer = AllocateZeroPool (Storage->Size);\r
1448\r
1449 AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r
1450 Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);\r
1451 ASSERT (Storage->Name != NULL);\r
1452 for (Index = 0; AsciiString[Index] != 0; Index++) {\r
1453 Storage->Name[Index] = (CHAR16) AsciiString[Index];\r
1454 }\r
1455\r
1456 //\r
1457 // Initialize <ConfigHdr>\r
1458 //\r
1459 InitializeConfigHdr (FormSet, Storage);\r
1460 break;\r
1461\r
1462 case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
1463 //\r
1464 // Create a name/value Storage for this FormSet\r
1465 //\r
1466 Storage = CreateStorage (FormSet);\r
1467 Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
1468\r
1469 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1470 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1471\r
1472 //\r
1473 // Initialize <ConfigHdr>\r
1474 //\r
1475 InitializeConfigHdr (FormSet, Storage);\r
1476 break;\r
1477\r
1478 case EFI_IFR_VARSTORE_EFI_OP:\r
1479 //\r
1480 // Create a EFI variable Storage for this FormSet\r
1481 //\r
1482 Storage = CreateStorage (FormSet);\r
1483 Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;\r
1484\r
1485 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1486 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1487 CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));\r
1488 break;\r
1489\r
1490 //\r
1491 // DefaultStore\r
1492 //\r
1493 case EFI_IFR_DEFAULTSTORE_OP:\r
1494 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
1ac628ee 1495 ASSERT (DefaultStore != NULL);\r
c60a0616 1496 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
1497\r
1498 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1499 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
1500\r
1501 //\r
1502 // Insert to DefaultStore list of this Formset\r
1503 //\r
1504 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
1505 break;\r
1506\r
1507 //\r
1508 // Statements\r
1509 //\r
1510 case EFI_IFR_SUBTITLE_OP:\r
1511 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
bc166db3 1512 ASSERT (CurrentStatement != NULL);\r
8b0fc5c1 1513\r
c60a0616 1514 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
1515\r
1516 if (Scope != 0) {\r
1517 mInScopeSubtitle = TRUE;\r
1518 }\r
1519 break;\r
1520\r
1521 case EFI_IFR_TEXT_OP:\r
1522 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
bc166db3 1523 ASSERT (CurrentStatement != NULL);\r
c60a0616 1524\r
1525 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
1526 break;\r
1527\r
f8a1c229 1528 case EFI_IFR_RESET_BUTTON_OP:\r
1529 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1530 ASSERT (CurrentStatement != NULL);\r
1531 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
1532 break;\r
1533\r
c60a0616 1534 //\r
1535 // Questions\r
1536 //\r
1537 case EFI_IFR_ACTION_OP:\r
1538 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
bc166db3 1539 ASSERT (CurrentStatement != NULL);\r
d02847d3 1540 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;\r
c60a0616 1541\r
1542 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
1543 //\r
1544 // No QuestionConfig present, so no configuration string will be processed\r
1545 //\r
1546 CurrentStatement->QuestionConfig = 0;\r
1547 } else {\r
1548 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));\r
1549 }\r
1550 break;\r
1551\r
c60a0616 1552 case EFI_IFR_REF_OP:\r
1553 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1554 ASSERT (CurrentStatement != NULL);\r
8ca6180f
ED
1555 Value = &CurrentStatement->HiiValue;\r
1556 Value->Type = EFI_IFR_TYPE_REF;\r
1557 if (OpCodeLength >= sizeof (EFI_IFR_REF)) {\r
1558 CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
c60a0616 1559\r
8ca6180f
ED
1560 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
1561 CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
c60a0616 1562\r
8ca6180f
ED
1563 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
1564 CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
1565\r
1566 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
1567 CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
1568 }\r
c60a0616 1569 }\r
1570 }\r
1571 }\r
8ca6180f
ED
1572 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF); \r
1573 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 1574 break;\r
1575\r
1576 case EFI_IFR_ONE_OF_OP:\r
1577 case EFI_IFR_NUMERIC_OP:\r
1578 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
945e3aed 1579 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1580\r
c60a0616 1581 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
1582 Value = &CurrentStatement->HiiValue;\r
1583\r
1584 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
1585 case EFI_IFR_NUMERIC_SIZE_1:\r
1586 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
1587 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
1588 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
cd7bfc2c 1589 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);\r
c60a0616 1590 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1591 break;\r
1592\r
1593 case EFI_IFR_NUMERIC_SIZE_2:\r
1594 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
1595 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
1596 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));\r
cd7bfc2c 1597 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);\r
c60a0616 1598 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1599 break;\r
1600\r
1601 case EFI_IFR_NUMERIC_SIZE_4:\r
1602 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
1603 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
1604 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));\r
cd7bfc2c 1605 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);\r
c60a0616 1606 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1607 break;\r
1608\r
1609 case EFI_IFR_NUMERIC_SIZE_8:\r
1610 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
1611 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
1612 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));\r
cd7bfc2c 1613 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);\r
c60a0616 1614 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1615 break;\r
1616\r
1617 default:\r
1618 break;\r
1619 }\r
1620\r
b18e7050 1621 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 1622\r
1623 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {\r
1624 SuppressForOption = TRUE;\r
1625 }\r
1626 break;\r
1627\r
1628 case EFI_IFR_ORDERED_LIST_OP:\r
1629 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1630 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1631\r
c60a0616 1632 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
1633 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
c60a0616 1634\r
d02847d3 1635 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;\r
b86b413a 1636 CurrentStatement->BufferValue = NULL;\r
c60a0616 1637\r
1638 if (Scope != 0) {\r
1639 SuppressForOption = TRUE;\r
1640 }\r
1641 break;\r
1642\r
1643 case EFI_IFR_CHECKBOX_OP:\r
1644 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1645 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1646\r
c60a0616 1647 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
cd7bfc2c 1648 CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);\r
c60a0616 1649 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
1650\r
b18e7050 1651 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 1652\r
1653 break;\r
1654\r
1655 case EFI_IFR_STRING_OP:\r
1656 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1657 ASSERT (CurrentStatement != NULL);\r
c60a0616 1658 //\r
1659 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1660 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1661 // The characters are stored as Unicode, so the storage width should multiply 2.\r
1662 //\r
1663 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;\r
1664 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;\r
1665 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
1666 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;\r
1667\r
1668 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1669 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));\r
e2100bfa 1670 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);\r
c60a0616 1671\r
b18e7050 1672 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 1673 break;\r
1674\r
1675 case EFI_IFR_PASSWORD_OP:\r
1676 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1677 ASSERT (CurrentStatement != NULL);\r
c60a0616 1678 //\r
1679 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1680 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1681 // The characters are stored as Unicode, so the storage width should multiply 2.\r
1682 //\r
1683 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));\r
1684 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));\r
1685 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));\r
1686\r
1687 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1688 CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));\r
e2100bfa 1689 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);\r
c60a0616 1690\r
b18e7050 1691 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 1692 break;\r
1693\r
1694 case EFI_IFR_DATE_OP:\r
1695 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1696 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1697\r
c60a0616 1698 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
1699 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
1700\r
1701 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
cd7bfc2c 1702 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);\r
c60a0616 1703\r
b18e7050 1704 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 1705 } else {\r
1706 //\r
1707 // Don't assign storage for RTC type of date/time\r
1708 //\r
1709 CurrentStatement->Storage = NULL;\r
1710 CurrentStatement->StorageWidth = 0;\r
1711 }\r
1712 break;\r
1713\r
1714 case EFI_IFR_TIME_OP:\r
1715 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
b347c1bc 1716 ASSERT(CurrentStatement != NULL);\r
8b0fc5c1 1717\r
c60a0616 1718 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
1719 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
1720\r
1721 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
5ec56d19 1722 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);\r
c60a0616 1723\r
b18e7050 1724 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
c60a0616 1725 } else {\r
1726 //\r
1727 // Don't assign storage for RTC type of date/time\r
1728 //\r
1729 CurrentStatement->Storage = NULL;\r
1730 CurrentStatement->StorageWidth = 0;\r
1731 }\r
1732 break;\r
1733\r
1734 //\r
1735 // Default\r
1736 //\r
1737 case EFI_IFR_DEFAULT_OP:\r
1738 //\r
1739 // EFI_IFR_DEFAULT appear in scope of a Question,\r
1740 // It creates a default value for the current question.\r
1741 // A Question may have more than one Default value which have different default types.\r
1742 //\r
1743 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
1ac628ee 1744 ASSERT (CurrentDefault != NULL);\r
c60a0616 1745 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
1746\r
1747 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
1748 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1749 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1750 ExtendValueToU64 (&CurrentDefault->Value);\r
1751\r
1752 //\r
1753 // Insert to Default Value list of current Question\r
1754 //\r
1755 InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r
1756\r
1757 if (Scope != 0) {\r
1758 InScopeDefault = TRUE;\r
1759 }\r
1760 break;\r
1761\r
1762 //\r
1763 // Option\r
1764 //\r
1765 case EFI_IFR_ONE_OF_OPTION_OP:\r
1766 //\r
1767 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
1768 // It create a selection for use in current Question.\r
1769 //\r
1770 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
1ac628ee 1771 ASSERT (CurrentOption != NULL);\r
c60a0616 1772 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
1773\r
1774 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
1775 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
1776 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));\r
1777 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1778 ExtendValueToU64 (&CurrentOption->Value);\r
1779\r
1780 if (InScopeOptionSuppress) {\r
1781 CurrentOption->SuppressExpression = OptionSuppressExpression;\r
1782 }\r
1783\r
1784 //\r
1785 // Insert to Option list of current Question\r
1786 //\r
1787 InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);\r
d02847d3 1788\r
1789 //\r
1790 // Now we know the Storage width of nested Ordered List\r
1791 //\r
1b2bf3ca 1792 ASSERT (CurrentStatement != NULL);\r
d02847d3 1793 if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) {\r
1794 Width = 1;\r
1795 switch (CurrentOption->Value.Type) {\r
1796 case EFI_IFR_TYPE_NUM_SIZE_8:\r
1797 Width = 1;\r
1798 break;\r
1799\r
1800 case EFI_IFR_TYPE_NUM_SIZE_16:\r
1801 Width = 2;\r
1802 break;\r
1803\r
1804 case EFI_IFR_TYPE_NUM_SIZE_32:\r
1805 Width = 4;\r
1806 break;\r
1807\r
1808 case EFI_IFR_TYPE_NUM_SIZE_64:\r
1809 Width = 8;\r
1810 break;\r
1811\r
1812 default:\r
1813 //\r
1814 // Invalid type for Ordered List\r
1815 //\r
1816 break;\r
1817 }\r
1818\r
1819 CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);\r
1820 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
1821 CurrentStatement->ValueType = CurrentOption->Value.Type;\r
1822\r
b18e7050 1823 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);\r
d02847d3 1824 }\r
c60a0616 1825 break;\r
1826\r
1827 //\r
1828 // Conditional\r
1829 //\r
1830 case EFI_IFR_NO_SUBMIT_IF_OP:\r
1831 case EFI_IFR_INCONSISTENT_IF_OP:\r
1832 //\r
1833 // Create an Expression node\r
1834 //\r
1835 CurrentExpression = CreateExpression (CurrentForm);\r
1836 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r
1837\r
1838 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r
1839 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r
1840 InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
1841 } else {\r
1842 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
1843 InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);\r
1844 }\r
0c66bc76
LG
1845\r
1846 //\r
1847 // Take a look at next OpCode to see whether current expression consists\r
1848 // of single OpCode\r
1849 //\r
1850 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1851 SingleOpCodeExpression = TRUE;\r
1852 }\r
c60a0616 1853 break;\r
1854\r
1855 case EFI_IFR_SUPPRESS_IF_OP:\r
1856 //\r
1857 // Question and Option will appear in scope of this OpCode\r
1858 //\r
1859 CurrentExpression = CreateExpression (CurrentForm);\r
1860 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
0c66bc76
LG
1861\r
1862 if (CurrentForm == NULL) {\r
1863 InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);\r
1864 } else {\r
1865 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1866 }\r
c60a0616 1867\r
1868 if (SuppressForOption) {\r
1869 InScopeOptionSuppress = TRUE;\r
1870 OptionSuppressExpression = CurrentExpression;\r
0c66bc76 1871 } else if (SuppressForQuestion) {\r
c60a0616 1872 mInScopeSuppress = TRUE;\r
1873 mSuppressExpression = CurrentExpression;\r
0c66bc76
LG
1874 } else {\r
1875 InScopeFormSuppress = TRUE;\r
1876 FormSuppressExpression = CurrentExpression;\r
1877 }\r
1878\r
1879 //\r
1880 // Take a look at next OpCode to see whether current expression consists\r
1881 // of single OpCode\r
1882 //\r
1883 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1884 SingleOpCodeExpression = TRUE;\r
c60a0616 1885 }\r
1886 break;\r
1887\r
1888 case EFI_IFR_GRAY_OUT_IF_OP:\r
1889 //\r
1890 // Questions will appear in scope of this OpCode\r
1891 //\r
1892 CurrentExpression = CreateExpression (CurrentForm);\r
1893 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r
1894 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1895\r
1896 mInScopeGrayOut = TRUE;\r
1897 mGrayOutExpression = CurrentExpression;\r
0c66bc76
LG
1898\r
1899 //\r
1900 // Take a look at next OpCode to see whether current expression consists\r
1901 // of single OpCode\r
1902 //\r
1903 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1904 SingleOpCodeExpression = TRUE;\r
1905 }\r
c60a0616 1906 break;\r
1907\r
1908 case EFI_IFR_DISABLE_IF_OP:\r
1909 //\r
1910 // The DisableIf expression should only rely on constant, so it could be\r
1911 // evaluated at initialization and it will not be queued\r
1912 //\r
1913 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
1ac628ee 1914 ASSERT (CurrentExpression != NULL);\r
c60a0616 1915 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;\r
1916 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r
1917 InitializeListHead (&CurrentExpression->OpCodeListHead);\r
1918\r
0a1147ed
LG
1919 if (CurrentForm != NULL) {\r
1920 //\r
1921 // This is DisableIf for Question, enqueue it to Form expression list\r
1922 //\r
1923 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1924 }\r
1925\r
1926 mDisableExpression = CurrentExpression;\r
1927 mInScopeDisable = TRUE;\r
1928 OpCodeDisabled = FALSE;\r
c60a0616 1929\r
1930 //\r
1931 // Take a look at next OpCode to see whether current expression consists\r
1932 // of single OpCode\r
1933 //\r
1934 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1935 SingleOpCodeExpression = TRUE;\r
1936 }\r
1937 break;\r
1938\r
1939 //\r
1940 // Expression\r
1941 //\r
1942 case EFI_IFR_VALUE_OP:\r
1943 CurrentExpression = CreateExpression (CurrentForm);\r
1944 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r
1945 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1946\r
1947 if (InScopeDefault) {\r
1948 //\r
1949 // Used for default (EFI_IFR_DEFAULT)\r
1950 //\r
1951 CurrentDefault->ValueExpression = CurrentExpression;\r
1952 } else {\r
1953 //\r
1954 // If used for a question, then the question will be read-only\r
1955 //\r
bc166db3 1956 //\r
1957 // Make sure CurrentStatement is not NULL.\r
1958 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1959 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
1960 //\r
1961 ASSERT (CurrentStatement != NULL);\r
c60a0616 1962 CurrentStatement->ValueExpression = CurrentExpression;\r
1963 }\r
0c66bc76
LG
1964\r
1965 //\r
1966 // Take a look at next OpCode to see whether current expression consists\r
1967 // of single OpCode\r
1968 //\r
1969 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1970 SingleOpCodeExpression = TRUE;\r
1971 }\r
c60a0616 1972 break;\r
1973\r
1974 case EFI_IFR_RULE_OP:\r
1975 CurrentExpression = CreateExpression (CurrentForm);\r
1976 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r
1977\r
1978 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
1979 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
0c66bc76
LG
1980\r
1981 //\r
1982 // Take a look at next OpCode to see whether current expression consists\r
1983 // of single OpCode\r
1984 //\r
1985 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1986 SingleOpCodeExpression = TRUE;\r
1987 }\r
c60a0616 1988 break;\r
1989\r
2573712e
LG
1990 case EFI_IFR_READ_OP:\r
1991 CurrentExpression = CreateExpression (CurrentForm);\r
1992 CurrentExpression->Type = EFI_HII_EXPRESSION_READ;\r
1993 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1994\r
1995 //\r
1996 // Make sure CurrentStatement is not NULL.\r
1997 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
1998 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
1999 //\r
2000 ASSERT (CurrentStatement != NULL);\r
2001 CurrentStatement->ReadExpression = CurrentExpression;\r
2002\r
2003 //\r
2004 // Take a look at next OpCode to see whether current expression consists\r
2005 // of single OpCode\r
2006 //\r
2007 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2008 SingleOpCodeExpression = TRUE;\r
2009 }\r
2010 break;\r
2011\r
2012 case EFI_IFR_WRITE_OP:\r
2013 CurrentExpression = CreateExpression (CurrentForm);\r
2014 CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;\r
2015 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
2016\r
2017 //\r
2018 // Make sure CurrentStatement is not NULL.\r
2019 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
2020 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.\r
2021 //\r
2022 ASSERT (CurrentStatement != NULL);\r
2023 CurrentStatement->WriteExpression = CurrentExpression;\r
2024\r
2025 //\r
2026 // Take a look at next OpCode to see whether current expression consists\r
2027 // of single OpCode\r
2028 //\r
2029 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
2030 SingleOpCodeExpression = TRUE;\r
2031 }\r
2032 break;\r
2033\r
c60a0616 2034 //\r
2035 // Image\r
2036 //\r
2037 case EFI_IFR_IMAGE_OP:\r
2038 //\r
2039 // Get ScopeOpcode from top of stack\r
2040 //\r
2041 PopScope (&ScopeOpCode);\r
2042 PushScope (ScopeOpCode);\r
2043\r
2044 switch (ScopeOpCode) {\r
2045 case EFI_IFR_FORM_SET_OP:\r
2046 ImageId = &FormSet->ImageId;\r
2047 break;\r
2048\r
2049 case EFI_IFR_FORM_OP:\r
2573712e 2050 case EFI_IFR_FORM_MAP_OP:\r
d0720b57 2051 ASSERT (CurrentForm != NULL);\r
c60a0616 2052 ImageId = &CurrentForm->ImageId;\r
2053 break;\r
2054\r
2055 case EFI_IFR_ONE_OF_OPTION_OP:\r
2056 ImageId = &CurrentOption->ImageId;\r
2057 break;\r
2058\r
2059 default:\r
bc166db3 2060 //\r
2061 // Make sure CurrentStatement is not NULL.\r
2062 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
2063 // file is wrongly generated by tools such as VFR Compiler.\r
2064 //\r
2065 ASSERT (CurrentStatement != NULL);\r
c60a0616 2066 ImageId = &CurrentStatement->ImageId;\r
2067 break;\r
2068 }\r
2069\r
c410589e 2070 ASSERT (ImageId != NULL);\r
c60a0616 2071 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));\r
2072 break;\r
2073\r
2074 //\r
2075 // Refresh\r
2076 //\r
2077 case EFI_IFR_REFRESH_OP:\r
c410589e 2078 ASSERT (CurrentStatement != NULL);\r
c60a0616 2079 CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
2080 break;\r
2081\r
211cc6e5
ED
2082 //\r
2083 // Refresh guid.\r
2084 //\r
2085 case EFI_IFR_REFRESH_ID_OP:\r
2086 ASSERT (CurrentStatement != NULL);\r
2087 CopyMem (&CurrentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));\r
2088 break;\r
2089\r
b00964a9
ED
2090 //\r
2091 // Modal tag\r
2092 //\r
2093 case EFI_IFR_MODAL_TAG_OP:\r
2094 ASSERT (CurrentForm != NULL);\r
2095 CurrentForm->ModalForm = TRUE;\r
2096 break;\r
2097\r
c60a0616 2098 //\r
2099 // Vendor specific\r
2100 //\r
2101 case EFI_IFR_GUID_OP:\r
5c526736 2102 if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
c60a0616 2103 //\r
2104 // Tiano specific GUIDed opcodes\r
2105 //\r
2106 switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {\r
2107 case EFI_IFR_EXTEND_OP_LABEL:\r
2108 //\r
2109 // just ignore label\r
2110 //\r
2111 break;\r
2112\r
2113 case EFI_IFR_EXTEND_OP_BANNER:\r
0a1147ed 2114 //\r
b9e388d2 2115 // By SubClass to get Banner Data from Front Page\r
0a1147ed 2116 //\r
c60a0616 2117 if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
2118 CopyMem (\r
0a1147ed 2119 &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
c60a0616 2120 ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],\r
2121 &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,\r
2122 sizeof (EFI_STRING_ID)\r
2123 );\r
2124 }\r
2125 break;\r
2126\r
2127 case EFI_IFR_EXTEND_OP_CLASS:\r
2128 CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));\r
2129 break;\r
2130\r
2131 case EFI_IFR_EXTEND_OP_SUBCLASS:\r
2132 CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));\r
2133 break;\r
2134\r
2135 default:\r
2136 break;\r
2137 }\r
2138 }\r
2139\r
2140 break;\r
2141\r
2142 //\r
2143 // Scope End\r
2144 //\r
2145 case EFI_IFR_END_OP:\r
2146 Status = PopScope (&ScopeOpCode);\r
2147 if (EFI_ERROR (Status)) {\r
2148 ResetScopeStack ();\r
2149 return Status;\r
2150 }\r
2151\r
2152 switch (ScopeOpCode) {\r
2153 case EFI_IFR_FORM_SET_OP:\r
2154 //\r
2155 // End of FormSet, update FormSet IFR binary length\r
2156 // to stop parsing substantial OpCodes\r
2157 //\r
2158 FormSet->IfrBinaryLength = OpCodeOffset;\r
2159 break;\r
2160\r
2161 case EFI_IFR_FORM_OP:\r
2573712e 2162 case EFI_IFR_FORM_MAP_OP:\r
c60a0616 2163 //\r
2164 // End of Form\r
2165 //\r
2166 CurrentForm = NULL;\r
0c66bc76 2167 SuppressForQuestion = FALSE;\r
c60a0616 2168 break;\r
2169\r
2170 case EFI_IFR_ONE_OF_OPTION_OP:\r
2171 //\r
2172 // End of Option\r
2173 //\r
2174 CurrentOption = NULL;\r
2175 break;\r
2176\r
2177 case EFI_IFR_SUBTITLE_OP:\r
2178 mInScopeSubtitle = FALSE;\r
2179 break;\r
2180\r
2181 case EFI_IFR_NO_SUBMIT_IF_OP:\r
2182 case EFI_IFR_INCONSISTENT_IF_OP:\r
2183 //\r
2184 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
2185 //\r
2186 break;\r
2187\r
2188 case EFI_IFR_SUPPRESS_IF_OP:\r
2189 if (SuppressForOption) {\r
2190 InScopeOptionSuppress = FALSE;\r
0c66bc76 2191 } else if (SuppressForQuestion) {\r
c60a0616 2192 mInScopeSuppress = FALSE;\r
0c66bc76
LG
2193 } else {\r
2194 InScopeFormSuppress = FALSE;\r
c60a0616 2195 }\r
2196 break;\r
2197\r
2198 case EFI_IFR_GRAY_OUT_IF_OP:\r
2199 mInScopeGrayOut = FALSE;\r
2200 break;\r
2201\r
2202 case EFI_IFR_DISABLE_IF_OP:\r
0a1147ed 2203 mInScopeDisable = FALSE;\r
c60a0616 2204 OpCodeDisabled = FALSE;\r
2205 break;\r
2206\r
2207 case EFI_IFR_ONE_OF_OP:\r
2208 case EFI_IFR_ORDERED_LIST_OP:\r
2209 SuppressForOption = FALSE;\r
2210 break;\r
2211\r
2212 case EFI_IFR_DEFAULT_OP:\r
2213 InScopeDefault = FALSE;\r
2214 break;\r
2215\r
2573712e
LG
2216 case EFI_IFR_MAP_OP:\r
2217 //\r
2218 // Get current Map Expression List.\r
2219 //\r
2220 Status = PopMapExpressionList ((VOID **) &MapExpressionList);\r
2221 if (Status == EFI_ACCESS_DENIED) {\r
2222 MapExpressionList = NULL;\r
2223 }\r
2224 //\r
2225 // Get current expression.\r
2226 //\r
2227 Status = PopCurrentExpression ((VOID **) &CurrentExpression);\r
2228 ASSERT_EFI_ERROR (Status);\r
771ececd 2229 ASSERT (MapScopeDepth > 0);\r
2573712e
LG
2230 MapScopeDepth --;\r
2231 break;\r
2232\r
c60a0616 2233 default:\r
2234 if (IsExpressionOpCode (ScopeOpCode)) {\r
0a1147ed 2235 if (mInScopeDisable && CurrentForm == NULL) {\r
c60a0616 2236 //\r
0a1147ed 2237 // This is DisableIf expression for Form, it should be a constant expression\r
c60a0616 2238 //\r
f8a1c229 2239 ASSERT (CurrentExpression != NULL);\r
c60a0616 2240 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
2241 if (EFI_ERROR (Status)) {\r
2242 return Status;\r
2243 }\r
a935a0d8 2244\r
c60a0616 2245 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
2246 return EFI_INVALID_PARAMETER;\r
2247 }\r
2248\r
2249 OpCodeDisabled = CurrentExpression->Result.Value.b;\r
2250 //\r
2573712e 2251 // DisableIf Expression is only used once and not queued, free it\r
c60a0616 2252 //\r
2253 DestroyExpression (CurrentExpression);\r
2254 }\r
2255\r
2256 //\r
2257 // End of current Expression\r
2258 //\r
2259 CurrentExpression = NULL;\r
2260 }\r
2261 break;\r
2262 }\r
2263 break;\r
2264\r
2265 default:\r
2266 break;\r
2267 }\r
2268 }\r
2269\r
2270 return EFI_SUCCESS;\r
2271}\r