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