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