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