blob: ba805560ef7fac0963d406ec97ed579aa1cef5f3 [file] [log] [blame]
qhuang8c60a0612008-10-31 04:41:33 +00001/** @file
2Parser for IFR binary encoding.
3
ydong10b18e7052011-05-31 00:59:15 +00004Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
hhtiane5eed7d2010-04-24 09:33:45 +00005This program and the accompanying materials
qhuang8c60a0612008-10-31 04:41:33 +00006are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution. The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13**/
14
15#include "Setup.h"
qhuang8c60a0612008-10-31 04:41:33 +000016
17UINT16 mStatementIndex;
18UINT16 mExpressionOpCodeIndex;
19
20BOOLEAN mInScopeSubtitle;
21BOOLEAN mInScopeSuppress;
22BOOLEAN mInScopeGrayOut;
lgao40a1147e2009-04-22 03:18:37 +000023BOOLEAN mInScopeDisable;
qhuang8c60a0612008-10-31 04:41:33 +000024FORM_EXPRESSION *mSuppressExpression;
25FORM_EXPRESSION *mGrayOutExpression;
lgao40a1147e2009-04-22 03:18:37 +000026FORM_EXPRESSION *mDisableExpression;
qhuang8c60a0612008-10-31 04:41:33 +000027
qhuang8c60a0612008-10-31 04:41:33 +000028/**
29 Initialize Statement header members.
30
31 @param OpCodeData Pointer of the raw OpCode data.
32 @param FormSet Pointer of the current FormSe.
33 @param Form Pointer of the current Form.
34
35 @return The Statement.
36
37**/
38FORM_BROWSER_STATEMENT *
39CreateStatement (
40 IN UINT8 *OpCodeData,
41 IN OUT FORM_BROWSER_FORMSET *FormSet,
42 IN OUT FORM_BROWSER_FORM *Form
43 )
44{
45 FORM_BROWSER_STATEMENT *Statement;
46 EFI_IFR_STATEMENT_HEADER *StatementHdr;
47
48 if (Form == NULL) {
49 //
50 // We are currently not in a Form Scope, so just skip this Statement
51 //
52 return NULL;
53 }
54
55 Statement = &FormSet->StatementBuffer[mStatementIndex];
56 mStatementIndex++;
57
58 InitializeListHead (&Statement->DefaultListHead);
59 InitializeListHead (&Statement->OptionListHead);
60 InitializeListHead (&Statement->InconsistentListHead);
61 InitializeListHead (&Statement->NoSubmitListHead);
62
63 Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;
64
65 Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
66
67 StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
68 CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
69 CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));
70
71 if (mInScopeSuppress) {
72 Statement->SuppressExpression = mSuppressExpression;
73 }
74
75 if (mInScopeGrayOut) {
76 Statement->GrayOutExpression = mGrayOutExpression;
77 }
78
lgao40a1147e2009-04-22 03:18:37 +000079
80 if (mInScopeDisable) {
81 Statement->DisableExpression = mDisableExpression;
82 }
83
qhuang8c60a0612008-10-31 04:41:33 +000084 Statement->InSubtitle = mInScopeSubtitle;
85
86 //
87 // Insert this Statement into current Form
88 //
89 InsertTailList (&Form->StatementListHead, &Statement->Link);
90
91 return Statement;
92}
93
qwang127064c0a2008-11-19 13:36:34 +000094/**
95 Convert a numeric value to a Unicode String and insert it to String Package.
96 This string is used as the Unicode Name for the EFI Variable. This is to support
97 the deprecated vareqval opcode.
xdu28b0fc5c2009-10-26 03:05:16 +000098
qwang127064c0a2008-11-19 13:36:34 +000099 @param FormSet The FormSet.
100 @param Statement The numeric question whose VarStoreInfo.VarName is the
101 numeric value which is used to produce the Unicode Name
102 for the EFI Variable.
xdu28b0fc5c2009-10-26 03:05:16 +0000103
qwang127064c0a2008-11-19 13:36:34 +0000104 If the Statement is NULL, the ASSERT.
105 If the opcode is not Numeric, then ASSERT.
xdu28b0fc5c2009-10-26 03:05:16 +0000106
qwang127064c0a2008-11-19 13:36:34 +0000107 @retval EFI_SUCCESS The funtion always succeeds.
108**/
qhuang8c60a0612008-10-31 04:41:33 +0000109EFI_STATUS
110UpdateCheckBoxStringToken (
111 IN CONST FORM_BROWSER_FORMSET *FormSet,
112 IN FORM_BROWSER_STATEMENT *Statement
113 )
114{
115 CHAR16 Str[MAXIMUM_VALUE_CHARACTERS];
116 EFI_STRING_ID Id;
qhuang8c60a0612008-10-31 04:41:33 +0000117
118 ASSERT (Statement != NULL);
119 ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP);
xdu28b0fc5c2009-10-26 03:05:16 +0000120
qhuang8c60a0612008-10-31 04:41:33 +0000121 UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);
qhuang8c60a0612008-10-31 04:41:33 +0000122
rsun3cb7d01c2009-04-14 10:47:19 +0000123 Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL);
124 if (Id == 0) {
125 return EFI_OUT_OF_RESOURCES;
qhuang8c60a0612008-10-31 04:41:33 +0000126 }
127
128 Statement->VarStoreInfo.VarName = Id;
xdu28b0fc5c2009-10-26 03:05:16 +0000129
qhuang8c60a0612008-10-31 04:41:33 +0000130 return EFI_SUCCESS;
131}
132
qwang127064c0a2008-11-19 13:36:34 +0000133/**
134 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
xdu28b0fc5c2009-10-26 03:05:16 +0000135
qwang127064c0a2008-11-19 13:36:34 +0000136 @param OpCodeData The current opcode.
xdu28b0fc5c2009-10-26 03:05:16 +0000137
qwang127064c0a2008-11-19 13:36:34 +0000138 @retval TRUE Yes.
139 @retval FALSE No.
140**/
qhuang8c60a0612008-10-31 04:41:33 +0000141BOOLEAN
142IsNextOpCodeGuidedVarEqName (
xdu28b0fc5c2009-10-26 03:05:16 +0000143 IN UINT8 *OpCodeData
qhuang8c60a0612008-10-31 04:41:33 +0000144 )
145{
146 //
147 // Get next opcode
148 //
149 OpCodeData += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
150 if (*OpCodeData == EFI_IFR_GUID_OP) {
lgao45c526732009-02-23 15:18:48 +0000151 if (CompareGuid (&gEfiIfrFrameworkGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
qhuang8c60a0612008-10-31 04:41:33 +0000152 //
xdu28b0fc5c2009-10-26 03:05:16 +0000153 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
qhuang8c60a0612008-10-31 04:41:33 +0000154 //
155 if ((((EFI_IFR_GUID_VAREQNAME *) OpCodeData)->ExtendOpCode) == EFI_IFR_EXTEND_OP_VAREQNAME) {
156 return TRUE;
157 }
158 }
159 }
160
161 return FALSE;
162}
163
164/**
165 Initialize Question's members.
166
167 @param OpCodeData Pointer of the raw OpCode data.
168 @param FormSet Pointer of the current FormSet.
169 @param Form Pointer of the current Form.
170
171 @return The Question.
172
173**/
174FORM_BROWSER_STATEMENT *
175CreateQuestion (
176 IN UINT8 *OpCodeData,
177 IN OUT FORM_BROWSER_FORMSET *FormSet,
178 IN OUT FORM_BROWSER_FORM *Form
179 )
180{
181 FORM_BROWSER_STATEMENT *Statement;
182 EFI_IFR_QUESTION_HEADER *QuestionHdr;
183 LIST_ENTRY *Link;
184 FORMSET_STORAGE *Storage;
185 NAME_VALUE_NODE *NameValueNode;
186 EFI_STATUS Status;
187
188 Statement = CreateStatement (OpCodeData, FormSet, Form);
189 if (Statement == NULL) {
190 return NULL;
191 }
192
193 QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
194 CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));
195 CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));
196 CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));
197
198 Statement->QuestionFlags = QuestionHdr->Flags;
199
200 if (Statement->VarStoreId == 0) {
201 //
202 // VarStoreId of zero indicates no variable storage
203 //
204 return Statement;
205 }
206
207 //
208 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
209 // Framework Compatibility
210 //
lgao4f806dd22009-02-25 09:04:47 +0000211 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
qhuang8c60a0612008-10-31 04:41:33 +0000212 if ((*OpCodeData == EFI_IFR_NUMERIC_OP) && IsNextOpCodeGuidedVarEqName (OpCodeData)) {
213 Status = UpdateCheckBoxStringToken (FormSet, Statement);
214 if (EFI_ERROR (Status)) {
215 return NULL;
216 }
217 }
218 }
219
220 //
221 // Find Storage for this Question
222 //
223 Link = GetFirstNode (&FormSet->StorageListHead);
224 while (!IsNull (&FormSet->StorageListHead, Link)) {
225 Storage = FORMSET_STORAGE_FROM_LINK (Link);
226
227 if (Storage->VarStoreId == Statement->VarStoreId) {
228 Statement->Storage = Storage;
229 break;
230 }
231
232 Link = GetNextNode (&FormSet->StorageListHead, Link);
233 }
234 ASSERT (Statement->Storage != NULL);
235
236 //
237 // Initialilze varname for Name/Value or EFI Variable
238 //
239 if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||
240 (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
241 Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);
242 ASSERT (Statement->VariableName != NULL);
243
244 if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
245 //
246 // Insert to Name/Value varstore list
247 //
248 NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));
249 ASSERT (NameValueNode != NULL);
250 NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;
251 NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);
252 ASSERT (NameValueNode->Name != NULL);
253 NameValueNode->Value = AllocateZeroPool (0x10);
254 ASSERT (NameValueNode->Value != NULL);
255 NameValueNode->EditValue = AllocateZeroPool (0x10);
256 ASSERT (NameValueNode->EditValue != NULL);
257
258 InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);
259 }
260 }
261
262 return Statement;
263}
264
265
266/**
267 Allocate a FORM_EXPRESSION node.
268
269 @param Form The Form associated with this Expression
270
271 @return Pointer to a FORM_EXPRESSION data structure.
272
273**/
274FORM_EXPRESSION *
275CreateExpression (
276 IN OUT FORM_BROWSER_FORM *Form
277 )
278{
279 FORM_EXPRESSION *Expression;
280
281 Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
jji41ac628e2009-01-19 07:58:58 +0000282 ASSERT (Expression != NULL);
qhuang8c60a0612008-10-31 04:41:33 +0000283 Expression->Signature = FORM_EXPRESSION_SIGNATURE;
284 InitializeListHead (&Expression->OpCodeListHead);
285
286 return Expression;
287}
288
289
290/**
291 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
292
293 @param FormSet Pointer of the current FormSet
294
295 @return Pointer to a FORMSET_STORAGE data structure.
296
297**/
298FORMSET_STORAGE *
299CreateStorage (
300 IN FORM_BROWSER_FORMSET *FormSet
301 )
302{
303 FORMSET_STORAGE *Storage;
304
305 Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));
jji41ac628e2009-01-19 07:58:58 +0000306 ASSERT (Storage != NULL);
qhuang8c60a0612008-10-31 04:41:33 +0000307 Storage->Signature = FORMSET_STORAGE_SIGNATURE;
308 InitializeListHead (&Storage->NameValueListHead);
309 InsertTailList (&FormSet->StorageListHead, &Storage->Link);
310
311 return Storage;
312}
313
314
315/**
316 Create ConfigHdr string for a storage.
317
318 @param FormSet Pointer of the current FormSet
319 @param Storage Pointer of the storage
320
321 @retval EFI_SUCCESS Initialize ConfigHdr success
322
323**/
324EFI_STATUS
325InitializeConfigHdr (
326 IN FORM_BROWSER_FORMSET *FormSet,
327 IN OUT FORMSET_STORAGE *Storage
328 )
329{
qhuang8c60a0612008-10-31 04:41:33 +0000330 CHAR16 *Name;
xdu28b0fc5c2009-10-26 03:05:16 +0000331
qhuang8c60a0612008-10-31 04:41:33 +0000332 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {
333 Name = Storage->Name;
334 } else {
335 Name = NULL;
336 }
xdu28b0fc5c2009-10-26 03:05:16 +0000337
lgao47e3bccc2009-04-13 06:05:15 +0000338 Storage->ConfigHdr = HiiConstructConfigHdr (
339 &Storage->Guid,
340 Name,
341 FormSet->DriverHandle
342 );
xdu28b0fc5c2009-10-26 03:05:16 +0000343
lgao47e3bccc2009-04-13 06:05:15 +0000344 if (Storage->ConfigHdr == NULL) {
345 return EFI_NOT_FOUND;
qhuang8c60a0612008-10-31 04:41:33 +0000346 }
347
lgao47e3bccc2009-04-13 06:05:15 +0000348 Storage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);
qhuang8c60a0612008-10-31 04:41:33 +0000349 Storage->SpareStrLen = 0;
350
351 return EFI_SUCCESS;
352}
353
354
355/**
356 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
357
358 @param FormSet Pointer of the current FormSet.
359 @param Question The Question to be initialized.
ydong10b18e7052011-05-31 00:59:15 +0000360 @param Form Pointer of the current form.
qhuang8c60a0612008-10-31 04:41:33 +0000361
362 @retval EFI_SUCCESS Function success.
363 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
364
365**/
366EFI_STATUS
367InitializeRequestElement (
368 IN OUT FORM_BROWSER_FORMSET *FormSet,
ydong10b18e7052011-05-31 00:59:15 +0000369 IN OUT FORM_BROWSER_STATEMENT *Question,
370 IN OUT FORM_BROWSER_FORM *Form
qhuang8c60a0612008-10-31 04:41:33 +0000371 )
372{
373 FORMSET_STORAGE *Storage;
374 UINTN StrLen;
375 UINTN StringSize;
376 CHAR16 *NewStr;
377 CHAR16 RequestElement[30];
ydong10b18e7052011-05-31 00:59:15 +0000378 LIST_ENTRY *Link;
379 BOOLEAN Find;
380 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
qhuang8c60a0612008-10-31 04:41:33 +0000381
382 Storage = Question->Storage;
383 if (Storage == NULL) {
384 return EFI_INVALID_PARAMETER;
385 }
386
387 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
388 //
389 // <ConfigRequest> is unnecessary for EFI variable storage,
390 // GetVariable()/SetVariable() will be used to retrieve/save values
391 //
392 return EFI_SUCCESS;
393 }
394
395 //
396 // Prepare <RequestElement>
397 //
398 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {
399 StrLen = UnicodeSPrint (
400 RequestElement,
401 30 * sizeof (CHAR16),
402 L"&OFFSET=%x&WIDTH=%x",
403 Question->VarStoreInfo.VarOffset,
404 Question->StorageWidth
405 );
406 Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);
407 } else {
408 StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);
409 }
410
411 if ((Question->Operand == EFI_IFR_PASSWORD_OP) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {
412 //
413 // Password with CALLBACK flag is stored in encoded format,
414 // so don't need to append it to <ConfigRequest>
415 //
416 return EFI_SUCCESS;
417 }
418
419 //
420 // Append <RequestElement> to <ConfigRequest>
421 //
422 if (StrLen > Storage->SpareStrLen) {
423 //
424 // Old String buffer is not sufficient for RequestElement, allocate a new one
425 //
426 StringSize = (Storage->ConfigRequest != NULL) ? StrSize (Storage->ConfigRequest) : sizeof (CHAR16);
427 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));
jji41ac628e2009-01-19 07:58:58 +0000428 ASSERT (NewStr != NULL);
qhuang8c60a0612008-10-31 04:41:33 +0000429 if (Storage->ConfigRequest != NULL) {
430 CopyMem (NewStr, Storage->ConfigRequest, StringSize);
qwang12f4113e12008-11-21 06:59:58 +0000431 FreePool (Storage->ConfigRequest);
qhuang8c60a0612008-10-31 04:41:33 +0000432 }
433 Storage->ConfigRequest = NewStr;
434 Storage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
435 }
436
437 StrCat (Storage->ConfigRequest, RequestElement);
438 Storage->ElementCount++;
439 Storage->SpareStrLen -= StrLen;
440
ydong10b18e7052011-05-31 00:59:15 +0000441 //
442 // Update the Config Request info saved in the form.
443 //
444 ConfigInfo = NULL;
445 Find = FALSE;
446 Link = GetFirstNode (&Form->ConfigRequestHead);
447 while (!IsNull (&Form->ConfigRequestHead, Link)) {
448 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
449
450 if (ConfigInfo != NULL && ConfigInfo->Storage->VarStoreId == Storage->VarStoreId) {
451 Find = TRUE;
452 break;
453 }
454
455 Link = GetNextNode (&Form->ConfigRequestHead, Link);
456 }
457
458 if (!Find) {
459 ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST));
ydong100194d262011-06-13 05:20:23 +0000460 ASSERT (ConfigInfo != NULL);
ydong10b18e7052011-05-31 00:59:15 +0000461 ConfigInfo->Signature = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE;
462 ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);
463 ConfigInfo->SpareStrLen = 0;
464 ConfigInfo->Storage = Storage;
465 InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link);
466 }
467
468 //
469 // Append <RequestElement> to <ConfigRequest>
470 //
471 if (StrLen > ConfigInfo->SpareStrLen) {
472 //
473 // Old String buffer is not sufficient for RequestElement, allocate a new one
474 //
475 StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);
476 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));
477 ASSERT (NewStr != NULL);
478 if (ConfigInfo->ConfigRequest != NULL) {
479 CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);
480 FreePool (ConfigInfo->ConfigRequest);
481 }
482 ConfigInfo->ConfigRequest = NewStr;
483 ConfigInfo->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
484 }
485
486 StrCat (ConfigInfo->ConfigRequest, RequestElement);
487 ConfigInfo->ElementCount++;
488 ConfigInfo->SpareStrLen -= StrLen;
qhuang8c60a0612008-10-31 04:41:33 +0000489 return EFI_SUCCESS;
490}
491
492
493/**
494 Free resources of a Expression.
495
496 @param FormSet Pointer of the Expression
497
498**/
499VOID
500DestroyExpression (
501 IN FORM_EXPRESSION *Expression
502 )
503{
504 LIST_ENTRY *Link;
505 EXPRESSION_OPCODE *OpCode;
lgao425737122010-02-25 10:10:59 +0000506 LIST_ENTRY *SubExpressionLink;
507 FORM_EXPRESSION *SubExpression;
qhuang8c60a0612008-10-31 04:41:33 +0000508
509 while (!IsListEmpty (&Expression->OpCodeListHead)) {
510 Link = GetFirstNode (&Expression->OpCodeListHead);
511 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);
512 RemoveEntryList (&OpCode->Link);
513
514 if (OpCode->ValueList != NULL) {
515 FreePool (OpCode->ValueList);
516 }
lgao425737122010-02-25 10:10:59 +0000517
518 if (OpCode->ValueName != NULL) {
519 FreePool (OpCode->ValueName);
520 }
521
522 if (OpCode->MapExpressionList.ForwardLink != NULL) {
523 while (!IsListEmpty (&OpCode->MapExpressionList)) {
524 SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);
525 SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);
526 RemoveEntryList(&SubExpression->Link);
527 DestroyExpression (SubExpression);
528 }
529 }
qhuang8c60a0612008-10-31 04:41:33 +0000530 }
531
532 //
533 // Free this Expression
534 //
qwang12f4113e12008-11-21 06:59:58 +0000535 FreePool (Expression);
qhuang8c60a0612008-10-31 04:41:33 +0000536}
537
538
539/**
540 Free resources of a storage.
541
542 @param Storage Pointer of the storage
543
544**/
545VOID
546DestroyStorage (
547 IN FORMSET_STORAGE *Storage
548 )
549{
550 LIST_ENTRY *Link;
551 NAME_VALUE_NODE *NameValueNode;
552
553 if (Storage == NULL) {
554 return;
555 }
556
557 if (Storage->Name != NULL) {
558 FreePool (Storage->Name);
559 }
560 if (Storage->Buffer != NULL) {
561 FreePool (Storage->Buffer);
562 }
563 if (Storage->EditBuffer != NULL) {
564 FreePool (Storage->EditBuffer);
565 }
566
567 while (!IsListEmpty (&Storage->NameValueListHead)) {
568 Link = GetFirstNode (&Storage->NameValueListHead);
569 NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);
570 RemoveEntryList (&NameValueNode->Link);
571
572 if (NameValueNode->Name != NULL) {
573 FreePool (NameValueNode->Name);
574 }
575 if (NameValueNode->Value != NULL) {
576 FreePool (NameValueNode->Value);
577 }
578 if (NameValueNode->EditValue != NULL) {
579 FreePool (NameValueNode->EditValue);
580 }
581 FreePool (NameValueNode);
582 }
583
584 if (Storage->ConfigHdr != NULL) {
585 FreePool (Storage->ConfigHdr);
586 }
587 if (Storage->ConfigRequest != NULL) {
588 FreePool (Storage->ConfigRequest);
589 }
590
591 FreePool (Storage);
592}
593
594
595/**
596 Free resources of a Statement.
597
ydong10e2100bf2010-12-23 06:47:50 +0000598 @param FormSet Pointer of the FormSet
qhuang8c60a0612008-10-31 04:41:33 +0000599 @param Statement Pointer of the Statement
600
601**/
602VOID
603DestroyStatement (
ydong10e2100bf2010-12-23 06:47:50 +0000604 IN FORM_BROWSER_FORMSET *FormSet,
qhuang8c60a0612008-10-31 04:41:33 +0000605 IN OUT FORM_BROWSER_STATEMENT *Statement
606 )
607{
608 LIST_ENTRY *Link;
609 QUESTION_DEFAULT *Default;
610 QUESTION_OPTION *Option;
611 FORM_EXPRESSION *Expression;
612
613 //
614 // Free Default value List
615 //
616 while (!IsListEmpty (&Statement->DefaultListHead)) {
617 Link = GetFirstNode (&Statement->DefaultListHead);
618 Default = QUESTION_DEFAULT_FROM_LINK (Link);
619 RemoveEntryList (&Default->Link);
620
qwang12f4113e12008-11-21 06:59:58 +0000621 FreePool (Default);
qhuang8c60a0612008-10-31 04:41:33 +0000622 }
623
624 //
625 // Free Options List
626 //
627 while (!IsListEmpty (&Statement->OptionListHead)) {
628 Link = GetFirstNode (&Statement->OptionListHead);
629 Option = QUESTION_OPTION_FROM_LINK (Link);
630 RemoveEntryList (&Option->Link);
631
qwang12f4113e12008-11-21 06:59:58 +0000632 FreePool (Option);
qhuang8c60a0612008-10-31 04:41:33 +0000633 }
634
635 //
636 // Free Inconsistent List
637 //
638 while (!IsListEmpty (&Statement->InconsistentListHead)) {
639 Link = GetFirstNode (&Statement->InconsistentListHead);
640 Expression = FORM_EXPRESSION_FROM_LINK (Link);
641 RemoveEntryList (&Expression->Link);
642
643 DestroyExpression (Expression);
644 }
645
646 //
647 // Free NoSubmit List
648 //
649 while (!IsListEmpty (&Statement->NoSubmitListHead)) {
650 Link = GetFirstNode (&Statement->NoSubmitListHead);
651 Expression = FORM_EXPRESSION_FROM_LINK (Link);
652 RemoveEntryList (&Expression->Link);
653
654 DestroyExpression (Expression);
655 }
656
657 if (Statement->VariableName != NULL) {
658 FreePool (Statement->VariableName);
659 }
660 if (Statement->BlockName != NULL) {
661 FreePool (Statement->BlockName);
662 }
lgao4b86b4132010-02-22 06:30:41 +0000663 if (Statement->BufferValue != NULL) {
664 FreePool (Statement->BufferValue);
665 }
ydong10e2100bf2010-12-23 06:47:50 +0000666 if (Statement->Operand == EFI_IFR_STRING_OP || Statement->Operand == EFI_IFR_PASSWORD_OP) {
667 DeleteString(Statement->HiiValue.Value.string, FormSet->HiiHandle);
668 }
qhuang8c60a0612008-10-31 04:41:33 +0000669}
670
671
672/**
673 Free resources of a Form.
674
ydong10e2100bf2010-12-23 06:47:50 +0000675 @param FormSet Pointer of the FormSet
qhuang8c60a0612008-10-31 04:41:33 +0000676 @param Form Pointer of the Form.
677
678**/
679VOID
680DestroyForm (
ydong10e2100bf2010-12-23 06:47:50 +0000681 IN FORM_BROWSER_FORMSET *FormSet,
682 IN OUT FORM_BROWSER_FORM *Form
qhuang8c60a0612008-10-31 04:41:33 +0000683 )
684{
685 LIST_ENTRY *Link;
686 FORM_EXPRESSION *Expression;
687 FORM_BROWSER_STATEMENT *Statement;
ydong10b18e7052011-05-31 00:59:15 +0000688 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
qhuang8c60a0612008-10-31 04:41:33 +0000689
690 //
691 // Free Form Expressions
692 //
693 while (!IsListEmpty (&Form->ExpressionListHead)) {
694 Link = GetFirstNode (&Form->ExpressionListHead);
695 Expression = FORM_EXPRESSION_FROM_LINK (Link);
696 RemoveEntryList (&Expression->Link);
697
698 DestroyExpression (Expression);
699 }
700
701 //
702 // Free Statements/Questions
703 //
704 while (!IsListEmpty (&Form->StatementListHead)) {
705 Link = GetFirstNode (&Form->StatementListHead);
706 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
707 RemoveEntryList (&Statement->Link);
708
ydong10e2100bf2010-12-23 06:47:50 +0000709 DestroyStatement (FormSet, Statement);
qhuang8c60a0612008-10-31 04:41:33 +0000710 }
711
712 //
ydong10b18e7052011-05-31 00:59:15 +0000713 // Free ConfigRequest string.
714 //
715 while (!IsListEmpty (&Form->ConfigRequestHead)) {
716 Link = GetFirstNode (&Form->ConfigRequestHead);
717 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
718 RemoveEntryList (&ConfigInfo->Link);
719
720 FreePool (ConfigInfo->ConfigRequest);
721 FreePool (ConfigInfo);
722 }
723
724 //
qhuang8c60a0612008-10-31 04:41:33 +0000725 // Free this Form
726 //
qwang12f4113e12008-11-21 06:59:58 +0000727 FreePool (Form);
qhuang8c60a0612008-10-31 04:41:33 +0000728}
729
730
731/**
732 Free resources allocated for a FormSet.
733
734 @param FormSet Pointer of the FormSet
735
736**/
737VOID
738DestroyFormSet (
739 IN OUT FORM_BROWSER_FORMSET *FormSet
740 )
741{
742 LIST_ENTRY *Link;
743 FORMSET_STORAGE *Storage;
744 FORMSET_DEFAULTSTORE *DefaultStore;
lgao40c66bc72009-11-12 01:16:12 +0000745 FORM_EXPRESSION *Expression;
qhuang8c60a0612008-10-31 04:41:33 +0000746 FORM_BROWSER_FORM *Form;
747
xdu24c8358c2009-11-13 05:40:21 +0000748 if (FormSet->IfrBinaryData == NULL) {
749 //
750 // Uninitialized FormSet
751 //
752 FreePool (FormSet);
753 return;
754 }
755
qhuang8c60a0612008-10-31 04:41:33 +0000756 //
757 // Free IFR binary buffer
758 //
759 FreePool (FormSet->IfrBinaryData);
760
761 //
762 // Free FormSet Storage
763 //
764 if (FormSet->StorageListHead.ForwardLink != NULL) {
765 while (!IsListEmpty (&FormSet->StorageListHead)) {
766 Link = GetFirstNode (&FormSet->StorageListHead);
767 Storage = FORMSET_STORAGE_FROM_LINK (Link);
768 RemoveEntryList (&Storage->Link);
769
770 DestroyStorage (Storage);
771 }
772 }
773
774 //
775 // Free FormSet Default Store
776 //
777 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
778 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
779 Link = GetFirstNode (&FormSet->DefaultStoreListHead);
780 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);
781 RemoveEntryList (&DefaultStore->Link);
782
qwang12f4113e12008-11-21 06:59:58 +0000783 FreePool (DefaultStore);
qhuang8c60a0612008-10-31 04:41:33 +0000784 }
785 }
786
787 //
lgao40c66bc72009-11-12 01:16:12 +0000788 // Free Formset Expressions
789 //
790 while (!IsListEmpty (&FormSet->ExpressionListHead)) {
791 Link = GetFirstNode (&FormSet->ExpressionListHead);
792 Expression = FORM_EXPRESSION_FROM_LINK (Link);
793 RemoveEntryList (&Expression->Link);
794
795 DestroyExpression (Expression);
796 }
797
798 //
qhuang8c60a0612008-10-31 04:41:33 +0000799 // Free Forms
800 //
801 if (FormSet->FormListHead.ForwardLink != NULL) {
802 while (!IsListEmpty (&FormSet->FormListHead)) {
803 Link = GetFirstNode (&FormSet->FormListHead);
804 Form = FORM_BROWSER_FORM_FROM_LINK (Link);
805 RemoveEntryList (&Form->Link);
806
ydong10e2100bf2010-12-23 06:47:50 +0000807 DestroyForm (FormSet, Form);
qhuang8c60a0612008-10-31 04:41:33 +0000808 }
809 }
810
811 if (FormSet->StatementBuffer != NULL) {
812 FreePool (FormSet->StatementBuffer);
813 }
814 if (FormSet->ExpressionBuffer != NULL) {
815 FreePool (FormSet->ExpressionBuffer);
816 }
817
818 FreePool (FormSet);
819}
820
821
822/**
823 Tell whether this Operand is an Expression OpCode or not
824
825 @param Operand Operand of an IFR OpCode.
826
827 @retval TRUE This is an Expression OpCode.
828 @retval FALSE Not an Expression OpCode.
829
830**/
831BOOLEAN
832IsExpressionOpCode (
833 IN UINT8 Operand
834 )
835{
836 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||
lgao425737122010-02-25 10:10:59 +0000837 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) ||
838 ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||
qhuang8c60a0612008-10-31 04:41:33 +0000839 (Operand == EFI_IFR_CATENATE_OP) ||
840 (Operand == EFI_IFR_TO_LOWER_OP) ||
841 (Operand == EFI_IFR_TO_UPPER_OP) ||
lgao425737122010-02-25 10:10:59 +0000842 (Operand == EFI_IFR_MAP_OP) ||
rsun3cbf73e52009-11-26 09:26:42 +0000843 (Operand == EFI_IFR_VERSION_OP) ||
844 (Operand == EFI_IFR_SECURITY_OP)) {
qhuang8c60a0612008-10-31 04:41:33 +0000845 return TRUE;
846 } else {
847 return FALSE;
848 }
849}
850
851
852/**
853 Calculate number of Statemens(Questions) and Expression OpCodes.
854
855 @param FormSet The FormSet to be counted.
856 @param NumberOfStatement Number of Statemens(Questions)
857 @param NumberOfExpression Number of Expression OpCodes
858
859**/
860VOID
861CountOpCodes (
862 IN FORM_BROWSER_FORMSET *FormSet,
863 IN OUT UINT16 *NumberOfStatement,
864 IN OUT UINT16 *NumberOfExpression
865 )
866{
867 UINT16 StatementCount;
868 UINT16 ExpressionCount;
869 UINT8 *OpCodeData;
870 UINTN Offset;
871 UINTN OpCodeLen;
872
873 Offset = 0;
874 StatementCount = 0;
875 ExpressionCount = 0;
876
877 while (Offset < FormSet->IfrBinaryLength) {
878 OpCodeData = FormSet->IfrBinaryData + Offset;
879 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
880 Offset += OpCodeLen;
881
882 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {
883 ExpressionCount++;
884 } else {
885 StatementCount++;
886 }
887 }
888
889 *NumberOfStatement = StatementCount;
890 *NumberOfExpression = ExpressionCount;
891}
892
893
894
895/**
896 Parse opcodes in the formset IFR binary.
897
898 @param FormSet Pointer of the FormSet data structure.
899
900 @retval EFI_SUCCESS Opcode parse success.
901 @retval Other Opcode parse fail.
902
903**/
904EFI_STATUS
905ParseOpCodes (
906 IN FORM_BROWSER_FORMSET *FormSet
907 )
908{
909 EFI_STATUS Status;
910 UINT16 Index;
911 FORM_BROWSER_FORM *CurrentForm;
912 FORM_BROWSER_STATEMENT *CurrentStatement;
913 EXPRESSION_OPCODE *ExpressionOpCode;
914 FORM_EXPRESSION *CurrentExpression;
915 UINT8 Operand;
916 UINT8 Scope;
917 UINTN OpCodeOffset;
918 UINTN OpCodeLength;
919 UINT8 *OpCodeData;
920 UINT8 ScopeOpCode;
921 FORMSET_STORAGE *Storage;
922 FORMSET_DEFAULTSTORE *DefaultStore;
923 QUESTION_DEFAULT *CurrentDefault;
924 QUESTION_OPTION *CurrentOption;
xdu2d02847d2009-10-26 03:03:47 +0000925 UINT8 Width;
qhuang8c60a0612008-10-31 04:41:33 +0000926 CHAR8 *AsciiString;
927 UINT16 NumberOfStatement;
928 UINT16 NumberOfExpression;
929 EFI_IMAGE_ID *ImageId;
lgao40c66bc72009-11-12 01:16:12 +0000930 BOOLEAN SuppressForQuestion;
qhuang8c60a0612008-10-31 04:41:33 +0000931 BOOLEAN SuppressForOption;
932 BOOLEAN InScopeOptionSuppress;
933 FORM_EXPRESSION *OptionSuppressExpression;
lgao40c66bc72009-11-12 01:16:12 +0000934 BOOLEAN InScopeFormSuppress;
935 FORM_EXPRESSION *FormSuppressExpression;
qhuang8c60a0612008-10-31 04:41:33 +0000936 UINT16 DepthOfDisable;
937 BOOLEAN OpCodeDisabled;
938 BOOLEAN SingleOpCodeExpression;
939 BOOLEAN InScopeDefault;
940 EFI_HII_VALUE *Value;
lgao425737122010-02-25 10:10:59 +0000941 EFI_IFR_FORM_MAP_METHOD *MapMethod;
942 UINT8 MapScopeDepth;
943 LIST_ENTRY *Link;
944 FORMSET_STORAGE *VarStorage;
945 LIST_ENTRY *MapExpressionList;
946 EFI_VARSTORE_ID TempVarstoreId;
qhuang8c60a0612008-10-31 04:41:33 +0000947
948 mInScopeSubtitle = FALSE;
lgao40c66bc72009-11-12 01:16:12 +0000949 SuppressForQuestion = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +0000950 SuppressForOption = FALSE;
lgao40c66bc72009-11-12 01:16:12 +0000951 InScopeFormSuppress = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +0000952 mInScopeSuppress = FALSE;
953 InScopeOptionSuppress = FALSE;
954 mInScopeGrayOut = FALSE;
lgao40a1147e2009-04-22 03:18:37 +0000955 mInScopeDisable = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +0000956 DepthOfDisable = 0;
957 OpCodeDisabled = FALSE;
958 SingleOpCodeExpression = FALSE;
959 InScopeDefault = FALSE;
960 CurrentExpression = NULL;
961 CurrentDefault = NULL;
962 CurrentOption = NULL;
963 OptionSuppressExpression = NULL;
lgao40c66bc72009-11-12 01:16:12 +0000964 FormSuppressExpression = NULL;
qwang12c4105892009-02-06 06:34:43 +0000965 ImageId = NULL;
lgao425737122010-02-25 10:10:59 +0000966 MapMethod = NULL;
967 MapScopeDepth = 0;
968 Link = NULL;
969 VarStorage = NULL;
970 MapExpressionList = NULL;
971 TempVarstoreId = 0;
qhuang8c60a0612008-10-31 04:41:33 +0000972
973 //
974 // Get the number of Statements and Expressions
975 //
976 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
977
978 mStatementIndex = 0;
979 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
980 if (FormSet->StatementBuffer == NULL) {
981 return EFI_OUT_OF_RESOURCES;
982 }
983
984 mExpressionOpCodeIndex = 0;
985 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));
986 if (FormSet->ExpressionBuffer == NULL) {
987 return EFI_OUT_OF_RESOURCES;
988 }
989
990 InitializeListHead (&FormSet->StorageListHead);
991 InitializeListHead (&FormSet->DefaultStoreListHead);
992 InitializeListHead (&FormSet->FormListHead);
lgao425737122010-02-25 10:10:59 +0000993 ResetCurrentExpressionStack ();
994 ResetMapExpressionListStack ();
qhuang8c60a0612008-10-31 04:41:33 +0000995
996 CurrentForm = NULL;
997 CurrentStatement = NULL;
998
999 ResetScopeStack ();
1000
1001 OpCodeOffset = 0;
1002 while (OpCodeOffset < FormSet->IfrBinaryLength) {
1003 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;
1004
1005 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
1006 OpCodeOffset += OpCodeLength;
1007 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
1008 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;
1009
1010 //
1011 // If scope bit set, push onto scope stack
1012 //
1013 if (Scope != 0) {
1014 PushScope (Operand);
1015 }
1016
1017 if (OpCodeDisabled) {
1018 //
1019 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1020 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1021 //
1022 if (Operand == EFI_IFR_DISABLE_IF_OP) {
1023 DepthOfDisable++;
1024 } else if (Operand == EFI_IFR_END_OP) {
1025 Status = PopScope (&ScopeOpCode);
1026 if (EFI_ERROR (Status)) {
1027 return Status;
1028 }
1029
1030 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {
1031 if (DepthOfDisable == 0) {
lgao40a1147e2009-04-22 03:18:37 +00001032 mInScopeDisable = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +00001033 OpCodeDisabled = FALSE;
1034 } else {
1035 DepthOfDisable--;
1036 }
1037 }
1038 }
1039 continue;
1040 }
1041
1042 if (IsExpressionOpCode (Operand)) {
1043 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];
1044 mExpressionOpCodeIndex++;
1045
1046 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;
1047 ExpressionOpCode->Operand = Operand;
1048 Value = &ExpressionOpCode->Value;
1049
1050 switch (Operand) {
1051 case EFI_IFR_EQ_ID_VAL_OP:
1052 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1053
1054 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1055 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));
1056 break;
1057
1058 case EFI_IFR_EQ_ID_ID_OP:
1059 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));
1060 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));
1061 break;
1062
1063 case EFI_IFR_EQ_ID_LIST_OP:
qhuang82654f642009-09-21 14:15:35 +00001064 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1065 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));
1066 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);
qhuang8c60a0612008-10-31 04:41:33 +00001067 break;
1068
1069 case EFI_IFR_TO_STRING_OP:
1070 case EFI_IFR_FIND_OP:
1071 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;
1072 break;
1073
1074 case EFI_IFR_STRING_REF1_OP:
1075 Value->Type = EFI_IFR_TYPE_STRING;
1076 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));
1077 break;
1078
1079 case EFI_IFR_RULE_REF_OP:
1080 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;
1081 break;
1082
1083 case EFI_IFR_SPAN_OP:
1084 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;
1085 break;
1086
1087 case EFI_IFR_THIS_OP:
qwang12d0720b52009-01-20 01:55:11 +00001088 ASSERT (CurrentStatement != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001089 ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;
1090 break;
1091
rsun3cbf73e52009-11-26 09:26:42 +00001092 case EFI_IFR_SECURITY_OP:
1093 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));
1094 break;
1095
lgao425737122010-02-25 10:10:59 +00001096 case EFI_IFR_GET_OP:
1097 case EFI_IFR_SET_OP:
1098 CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));
1099 if (TempVarstoreId != 0) {
1100 if (FormSet->StorageListHead.ForwardLink != NULL) {
1101 Link = GetFirstNode (&FormSet->StorageListHead);
1102 while (!IsNull (&FormSet->StorageListHead, Link)) {
1103 VarStorage = FORMSET_STORAGE_FROM_LINK (Link);
1104 if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {
1105 ExpressionOpCode->VarStorage = VarStorage;
1106 break;
1107 }
1108 Link = GetNextNode (&FormSet->StorageListHead, Link);
1109 }
1110 }
1111 if (ExpressionOpCode->VarStorage == NULL) {
1112 //
1113 // VarStorage is not found.
1114 //
1115 return EFI_INVALID_PARAMETER;
1116 }
1117 }
1118 ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;
1119 switch (ExpressionOpCode->ValueType) {
1120 case EFI_IFR_TYPE_BOOLEAN:
1121 case EFI_IFR_TYPE_NUM_SIZE_8:
1122 ExpressionOpCode->ValueWidth = 1;
1123 break;
1124
1125 case EFI_IFR_TYPE_NUM_SIZE_16:
1126 case EFI_IFR_TYPE_STRING:
1127 ExpressionOpCode->ValueWidth = 2;
1128 break;
1129
1130 case EFI_IFR_TYPE_NUM_SIZE_32:
1131 ExpressionOpCode->ValueWidth = 4;
1132 break;
1133
1134 case EFI_IFR_TYPE_NUM_SIZE_64:
1135 ExpressionOpCode->ValueWidth = 8;
1136 break;
1137
1138 case EFI_IFR_TYPE_DATE:
ydong10c9325702010-09-15 07:48:11 +00001139 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE);
lgao425737122010-02-25 10:10:59 +00001140 break;
1141
1142 case EFI_IFR_TYPE_TIME:
ydong10c9325702010-09-15 07:48:11 +00001143 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);
lgao425737122010-02-25 10:10:59 +00001144 break;
1145
ydong108ca61802011-06-28 06:41:28 +00001146 case EFI_IFR_TYPE_REF:
1147 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);
1148 break;
1149
lgao425737122010-02-25 10:10:59 +00001150 case EFI_IFR_TYPE_OTHER:
1151 case EFI_IFR_TYPE_UNDEFINED:
1152 case EFI_IFR_TYPE_ACTION:
1153 case EFI_IFR_TYPE_BUFFER:
1154 default:
1155 //
1156 // Invalid value type for Get/Set opcode.
1157 //
1158 return EFI_INVALID_PARAMETER;
1159 }
1160 CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID));
1161 CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));
1162 if ((ExpressionOpCode->VarStorage != NULL) &&
1163 (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE ||
1164 ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
1165 ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);
1166 if (ExpressionOpCode->ValueName == NULL) {
1167 //
1168 // String ID is invalid.
1169 //
1170 return EFI_INVALID_PARAMETER;
1171 }
1172 }
1173 break;
1174
qhuang8c60a0612008-10-31 04:41:33 +00001175 case EFI_IFR_QUESTION_REF1_OP:
qhuang82654f642009-09-21 14:15:35 +00001176 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
qhuang8c60a0612008-10-31 04:41:33 +00001177 break;
1178
1179 case EFI_IFR_QUESTION_REF3_OP:
1180 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {
1181 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1182
1183 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {
1184 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));
1185 }
1186 }
1187 break;
1188
1189 //
1190 // constant
1191 //
1192 case EFI_IFR_TRUE_OP:
1193 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1194 Value->Value.b = TRUE;
1195 break;
1196
1197 case EFI_IFR_FALSE_OP:
1198 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1199 Value->Value.b = FALSE;
1200 break;
1201
1202 case EFI_IFR_ONE_OP:
1203 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1204 Value->Value.u8 = 1;
1205 break;
1206
1207 case EFI_IFR_ZERO_OP:
1208 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1209 Value->Value.u8 = 0;
1210 break;
1211
1212 case EFI_IFR_ONES_OP:
1213 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1214 Value->Value.u64 = 0xffffffffffffffffULL;
1215 break;
1216
1217 case EFI_IFR_UINT8_OP:
1218 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1219 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;
1220 break;
1221
1222 case EFI_IFR_UINT16_OP:
1223 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1224 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));
1225 break;
1226
1227 case EFI_IFR_UINT32_OP:
1228 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1229 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));
1230 break;
1231
1232 case EFI_IFR_UINT64_OP:
1233 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1234 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));
1235 break;
1236
1237 case EFI_IFR_UNDEFINED_OP:
xdu2d02847d2009-10-26 03:03:47 +00001238 Value->Type = EFI_IFR_TYPE_UNDEFINED;
qhuang8c60a0612008-10-31 04:41:33 +00001239 break;
1240
1241 case EFI_IFR_VERSION_OP:
1242 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1243 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;
1244 break;
1245
1246 default:
1247 break;
1248 }
lgao425737122010-02-25 10:10:59 +00001249 //
1250 // Create sub expression nested in MAP opcode
1251 //
1252 if (CurrentExpression == NULL && MapScopeDepth > 0) {
1253 CurrentExpression = CreateExpression (CurrentForm);
lgao4771ecec2010-02-27 09:04:11 +00001254 ASSERT (MapExpressionList != NULL);
lgao425737122010-02-25 10:10:59 +00001255 InsertTailList (MapExpressionList, &CurrentExpression->Link);
1256 if (Scope == 0) {
1257 SingleOpCodeExpression = TRUE;
1258 }
1259 }
xdu2f8a1c222009-10-20 03:01:10 +00001260 ASSERT (CurrentExpression != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001261 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);
lgao425737122010-02-25 10:10:59 +00001262 if (Operand == EFI_IFR_MAP_OP) {
1263 //
1264 // Store current Map Expression List.
1265 //
1266 if (MapExpressionList != NULL) {
1267 PushMapExpressionList (MapExpressionList);
1268 }
1269 //
1270 // Initialize new Map Expression List.
1271 //
1272 MapExpressionList = &ExpressionOpCode->MapExpressionList;
1273 InitializeListHead (MapExpressionList);
1274 //
1275 // Store current expression.
1276 //
1277 PushCurrentExpression (CurrentExpression);
1278 CurrentExpression = NULL;
1279 MapScopeDepth ++;
1280 } else if (SingleOpCodeExpression) {
qhuang8c60a0612008-10-31 04:41:33 +00001281 //
1282 // There are two cases to indicate the end of an Expression:
1283 // for single OpCode expression: one Expression OpCode
1284 // for expression consists of more than one OpCode: EFI_IFR_END
1285 //
1286 SingleOpCodeExpression = FALSE;
1287
lgao40a1147e2009-04-22 03:18:37 +00001288 if (mInScopeDisable && CurrentForm == NULL) {
qhuang8c60a0612008-10-31 04:41:33 +00001289 //
lgao40a1147e2009-04-22 03:18:37 +00001290 // This is DisableIf expression for Form, it should be a constant expression
qhuang8c60a0612008-10-31 04:41:33 +00001291 //
1292 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
1293 if (EFI_ERROR (Status)) {
1294 return Status;
1295 }
qwang12c4105892009-02-06 06:34:43 +00001296
qhuang8c60a0612008-10-31 04:41:33 +00001297 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
1298 return EFI_INVALID_PARAMETER;
1299 }
1300
1301 OpCodeDisabled = CurrentExpression->Result.Value.b;
1302 }
1303
1304 CurrentExpression = NULL;
1305 }
1306
1307 continue;
1308 }
1309
1310 //
1311 // Parse the Opcode
1312 //
1313 switch (Operand) {
1314
1315 case EFI_IFR_FORM_SET_OP:
1316 //
xdu2f8a1c222009-10-20 03:01:10 +00001317 // Check the formset GUID
qhuang8c60a0612008-10-31 04:41:33 +00001318 //
1319 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {
1320 return EFI_INVALID_PARAMETER;
1321 }
1322
1323 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
1324 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
lgao40a1147e2009-04-22 03:18:37 +00001325
lgao4d2285262010-02-02 01:38:00 +00001326 if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
1327 //
1328 // The formset OpCode contains ClassGuid
1329 //
1330 FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);
1331 CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));
1332 }
lgao40c66bc72009-11-12 01:16:12 +00001333
1334 InitializeListHead (&FormSet->ExpressionListHead);
qhuang8c60a0612008-10-31 04:41:33 +00001335 break;
1336
1337 case EFI_IFR_FORM_OP:
1338 //
1339 // Create a new Form for this FormSet
1340 //
1341 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
jji41ac628e2009-01-19 07:58:58 +00001342 ASSERT (CurrentForm != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001343 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1344 InitializeListHead (&CurrentForm->ExpressionListHead);
1345 InitializeListHead (&CurrentForm->StatementListHead);
ydong10b18e7052011-05-31 00:59:15 +00001346 InitializeListHead (&CurrentForm->ConfigRequestHead);
qhuang8c60a0612008-10-31 04:41:33 +00001347
lgao425737122010-02-25 10:10:59 +00001348 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
ydong10b18e7052011-05-31 00:59:15 +00001349 CurrentForm->NvUpdateRequired = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +00001350 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1351 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
1352
lgao40c66bc72009-11-12 01:16:12 +00001353 if (InScopeFormSuppress) {
1354 //
1355 // Form is inside of suppressif
1356 //
1357 CurrentForm->SuppressExpression = FormSuppressExpression;
1358 }
1359
1360 if (Scope != 0) {
1361 //
1362 // Enter scope of a Form, suppressif will be used for Question or Option
1363 //
1364 SuppressForQuestion = TRUE;
1365 }
1366
qhuang8c60a0612008-10-31 04:41:33 +00001367 //
1368 // Insert into Form list of this FormSet
1369 //
1370 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1371 break;
1372
lgao425737122010-02-25 10:10:59 +00001373 case EFI_IFR_FORM_MAP_OP:
1374 //
1375 // Create a new Form for this FormSet
1376 //
1377 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1378 ASSERT (CurrentForm != NULL);
1379 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
ydong10b18e7052011-05-31 00:59:15 +00001380 CurrentForm->NvUpdateRequired = FALSE;
lgao425737122010-02-25 10:10:59 +00001381 InitializeListHead (&CurrentForm->ExpressionListHead);
1382 InitializeListHead (&CurrentForm->StatementListHead);
ydong10b18e7052011-05-31 00:59:15 +00001383 InitializeListHead (&CurrentForm->ConfigRequestHead);
lgao425737122010-02-25 10:10:59 +00001384 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1385
1386 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1387 //
1388 // FormMap Form must contain at least one Map Method.
1389 //
1390 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {
1391 return EFI_INVALID_PARAMETER;
1392 }
1393 //
1394 // Try to find the standard form map method.
1395 //
1396 while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {
1397 if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {
1398 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1399 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1400 break;
1401 }
1402 MapMethod ++;
1403 }
1404 //
1405 // If the standard form map method is not found, the first map method title will be used.
1406 //
1407 if (CurrentForm->FormTitle == 0) {
1408 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1409 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1410 }
1411
1412 if (InScopeFormSuppress) {
1413 //
1414 // Form is inside of suppressif
1415 //
1416 CurrentForm->SuppressExpression = FormSuppressExpression;
1417 }
1418
1419 if (Scope != 0) {
1420 //
1421 // Enter scope of a Form, suppressif will be used for Question or Option
1422 //
1423 SuppressForQuestion = TRUE;
1424 }
1425
1426 //
1427 // Insert into Form list of this FormSet
1428 //
1429 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1430 break;
1431
qhuang8c60a0612008-10-31 04:41:33 +00001432 //
1433 // Storage
1434 //
1435 case EFI_IFR_VARSTORE_OP:
1436 //
1437 // Create a buffer Storage for this FormSet
1438 //
1439 Storage = CreateStorage (FormSet);
1440 Storage->Type = EFI_HII_VARSTORE_BUFFER;
1441
1442 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1443 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));
1444 CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));
1445
1446 Storage->Buffer = AllocateZeroPool (Storage->Size);
1447 Storage->EditBuffer = AllocateZeroPool (Storage->Size);
1448
1449 AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;
1450 Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);
1451 ASSERT (Storage->Name != NULL);
1452 for (Index = 0; AsciiString[Index] != 0; Index++) {
1453 Storage->Name[Index] = (CHAR16) AsciiString[Index];
1454 }
1455
1456 //
1457 // Initialize <ConfigHdr>
1458 //
1459 InitializeConfigHdr (FormSet, Storage);
1460 break;
1461
1462 case EFI_IFR_VARSTORE_NAME_VALUE_OP:
1463 //
1464 // Create a name/value Storage for this FormSet
1465 //
1466 Storage = CreateStorage (FormSet);
1467 Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;
1468
1469 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1470 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));
1471
1472 //
1473 // Initialize <ConfigHdr>
1474 //
1475 InitializeConfigHdr (FormSet, Storage);
1476 break;
1477
1478 case EFI_IFR_VARSTORE_EFI_OP:
1479 //
1480 // Create a EFI variable Storage for this FormSet
1481 //
1482 Storage = CreateStorage (FormSet);
1483 Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;
1484
1485 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1486 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));
1487 CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));
1488 break;
1489
1490 //
1491 // DefaultStore
1492 //
1493 case EFI_IFR_DEFAULTSTORE_OP:
1494 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
jji41ac628e2009-01-19 07:58:58 +00001495 ASSERT (DefaultStore != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001496 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
1497
1498 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));
1499 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
1500
1501 //
1502 // Insert to DefaultStore list of this Formset
1503 //
1504 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
1505 break;
1506
1507 //
1508 // Statements
1509 //
1510 case EFI_IFR_SUBTITLE_OP:
1511 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
qwang12bc166db2009-02-02 07:18:59 +00001512 ASSERT (CurrentStatement != NULL);
xdu28b0fc5c2009-10-26 03:05:16 +00001513
qhuang8c60a0612008-10-31 04:41:33 +00001514 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
1515
1516 if (Scope != 0) {
1517 mInScopeSubtitle = TRUE;
1518 }
1519 break;
1520
1521 case EFI_IFR_TEXT_OP:
1522 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
qwang12bc166db2009-02-02 07:18:59 +00001523 ASSERT (CurrentStatement != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001524
1525 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
1526 break;
1527
xdu2f8a1c222009-10-20 03:01:10 +00001528 case EFI_IFR_RESET_BUTTON_OP:
1529 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1530 ASSERT (CurrentStatement != NULL);
1531 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
1532 break;
1533
qhuang8c60a0612008-10-31 04:41:33 +00001534 //
1535 // Questions
1536 //
1537 case EFI_IFR_ACTION_OP:
1538 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
qwang12bc166db2009-02-02 07:18:59 +00001539 ASSERT (CurrentStatement != NULL);
xdu2d02847d2009-10-26 03:03:47 +00001540 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;
qhuang8c60a0612008-10-31 04:41:33 +00001541
1542 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
1543 //
1544 // No QuestionConfig present, so no configuration string will be processed
1545 //
1546 CurrentStatement->QuestionConfig = 0;
1547 } else {
1548 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
1549 }
1550 break;
1551
qhuang8c60a0612008-10-31 04:41:33 +00001552 case EFI_IFR_REF_OP:
1553 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001554 ASSERT (CurrentStatement != NULL);
ydong108ca61802011-06-28 06:41:28 +00001555 Value = &CurrentStatement->HiiValue;
1556 Value->Type = EFI_IFR_TYPE_REF;
1557 if (OpCodeLength >= sizeof (EFI_IFR_REF)) {
1558 CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
qhuang8c60a0612008-10-31 04:41:33 +00001559
ydong108ca61802011-06-28 06:41:28 +00001560 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
1561 CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
qhuang8c60a0612008-10-31 04:41:33 +00001562
ydong108ca61802011-06-28 06:41:28 +00001563 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
1564 CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
1565
1566 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
1567 CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1568 }
qhuang8c60a0612008-10-31 04:41:33 +00001569 }
1570 }
1571 }
ydong108ca61802011-06-28 06:41:28 +00001572 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);
1573 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001574 break;
1575
1576 case EFI_IFR_ONE_OF_OP:
1577 case EFI_IFR_NUMERIC_OP:
1578 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidy945e3ae2009-05-13 09:24:25 +00001579 ASSERT(CurrentStatement != NULL);
xdu28b0fc5c2009-10-26 03:05:16 +00001580
qhuang8c60a0612008-10-31 04:41:33 +00001581 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
1582 Value = &CurrentStatement->HiiValue;
1583
1584 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
1585 case EFI_IFR_NUMERIC_SIZE_1:
1586 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
1587 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
1588 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
ydong10cd7bfc22010-09-16 04:51:25 +00001589 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);
qhuang8c60a0612008-10-31 04:41:33 +00001590 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1591 break;
1592
1593 case EFI_IFR_NUMERIC_SIZE_2:
1594 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
1595 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
1596 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));
ydong10cd7bfc22010-09-16 04:51:25 +00001597 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);
qhuang8c60a0612008-10-31 04:41:33 +00001598 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1599 break;
1600
1601 case EFI_IFR_NUMERIC_SIZE_4:
1602 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
1603 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
1604 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));
ydong10cd7bfc22010-09-16 04:51:25 +00001605 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);
qhuang8c60a0612008-10-31 04:41:33 +00001606 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1607 break;
1608
1609 case EFI_IFR_NUMERIC_SIZE_8:
1610 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
1611 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
1612 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));
ydong10cd7bfc22010-09-16 04:51:25 +00001613 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);
qhuang8c60a0612008-10-31 04:41:33 +00001614 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1615 break;
1616
1617 default:
1618 break;
1619 }
1620
ydong10b18e7052011-05-31 00:59:15 +00001621 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001622
1623 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {
1624 SuppressForOption = TRUE;
1625 }
1626 break;
1627
1628 case EFI_IFR_ORDERED_LIST_OP:
1629 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001630 ASSERT(CurrentStatement != NULL);
xdu28b0fc5c2009-10-26 03:05:16 +00001631
qhuang8c60a0612008-10-31 04:41:33 +00001632 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;
1633 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;
qhuang8c60a0612008-10-31 04:41:33 +00001634
xdu2d02847d2009-10-26 03:03:47 +00001635 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;
lgao4b86b4132010-02-22 06:30:41 +00001636 CurrentStatement->BufferValue = NULL;
qhuang8c60a0612008-10-31 04:41:33 +00001637
1638 if (Scope != 0) {
1639 SuppressForOption = TRUE;
1640 }
1641 break;
1642
1643 case EFI_IFR_CHECKBOX_OP:
1644 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001645 ASSERT(CurrentStatement != NULL);
xdu28b0fc5c2009-10-26 03:05:16 +00001646
qhuang8c60a0612008-10-31 04:41:33 +00001647 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;
ydong10cd7bfc22010-09-16 04:51:25 +00001648 CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);
qhuang8c60a0612008-10-31 04:41:33 +00001649 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
1650
ydong10b18e7052011-05-31 00:59:15 +00001651 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001652
1653 break;
1654
1655 case EFI_IFR_STRING_OP:
1656 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001657 ASSERT (CurrentStatement != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001658 //
1659 // MinSize is the minimum number of characters that can be accepted for this opcode,
1660 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1661 // The characters are stored as Unicode, so the storage width should multiply 2.
1662 //
1663 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;
1664 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;
1665 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
1666 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;
1667
1668 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1669 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));
ydong10e2100bf2010-12-23 06:47:50 +00001670 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
qhuang8c60a0612008-10-31 04:41:33 +00001671
ydong10b18e7052011-05-31 00:59:15 +00001672 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001673 break;
1674
1675 case EFI_IFR_PASSWORD_OP:
1676 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001677 ASSERT (CurrentStatement != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001678 //
1679 // MinSize is the minimum number of characters that can be accepted for this opcode,
1680 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1681 // The characters are stored as Unicode, so the storage width should multiply 2.
1682 //
1683 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));
1684 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));
1685 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
1686
1687 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1688 CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));
ydong10e2100bf2010-12-23 06:47:50 +00001689 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
qhuang8c60a0612008-10-31 04:41:33 +00001690
ydong10b18e7052011-05-31 00:59:15 +00001691 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001692 break;
1693
1694 case EFI_IFR_DATE_OP:
1695 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001696 ASSERT(CurrentStatement != NULL);
xdu28b0fc5c2009-10-26 03:05:16 +00001697
qhuang8c60a0612008-10-31 04:41:33 +00001698 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;
1699 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
1700
1701 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {
ydong10cd7bfc22010-09-16 04:51:25 +00001702 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);
qhuang8c60a0612008-10-31 04:41:33 +00001703
ydong10b18e7052011-05-31 00:59:15 +00001704 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001705 } else {
1706 //
1707 // Don't assign storage for RTC type of date/time
1708 //
1709 CurrentStatement->Storage = NULL;
1710 CurrentStatement->StorageWidth = 0;
1711 }
1712 break;
1713
1714 case EFI_IFR_TIME_OP:
1715 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001716 ASSERT(CurrentStatement != NULL);
xdu28b0fc5c2009-10-26 03:05:16 +00001717
qhuang8c60a0612008-10-31 04:41:33 +00001718 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;
1719 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
1720
1721 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {
ydong105ec56d12011-05-17 01:27:05 +00001722 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);
qhuang8c60a0612008-10-31 04:41:33 +00001723
ydong10b18e7052011-05-31 00:59:15 +00001724 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001725 } else {
1726 //
1727 // Don't assign storage for RTC type of date/time
1728 //
1729 CurrentStatement->Storage = NULL;
1730 CurrentStatement->StorageWidth = 0;
1731 }
1732 break;
1733
1734 //
1735 // Default
1736 //
1737 case EFI_IFR_DEFAULT_OP:
1738 //
1739 // EFI_IFR_DEFAULT appear in scope of a Question,
1740 // It creates a default value for the current question.
1741 // A Question may have more than one Default value which have different default types.
1742 //
1743 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
jji41ac628e2009-01-19 07:58:58 +00001744 ASSERT (CurrentDefault != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001745 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
1746
1747 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
1748 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
1749 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
1750 ExtendValueToU64 (&CurrentDefault->Value);
1751
1752 //
1753 // Insert to Default Value list of current Question
1754 //
1755 InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);
1756
1757 if (Scope != 0) {
1758 InScopeDefault = TRUE;
1759 }
1760 break;
1761
1762 //
1763 // Option
1764 //
1765 case EFI_IFR_ONE_OF_OPTION_OP:
1766 //
1767 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1768 // It create a selection for use in current Question.
1769 //
1770 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
jji41ac628e2009-01-19 07:58:58 +00001771 ASSERT (CurrentOption != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001772 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
1773
1774 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
1775 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
1776 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
1777 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));
1778 ExtendValueToU64 (&CurrentOption->Value);
1779
1780 if (InScopeOptionSuppress) {
1781 CurrentOption->SuppressExpression = OptionSuppressExpression;
1782 }
1783
1784 //
1785 // Insert to Option list of current Question
1786 //
1787 InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);
xdu2d02847d2009-10-26 03:03:47 +00001788
1789 //
1790 // Now we know the Storage width of nested Ordered List
1791 //
xdu21b2bf3c2010-02-05 06:13:18 +00001792 ASSERT (CurrentStatement != NULL);
xdu2d02847d2009-10-26 03:03:47 +00001793 if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) {
1794 Width = 1;
1795 switch (CurrentOption->Value.Type) {
1796 case EFI_IFR_TYPE_NUM_SIZE_8:
1797 Width = 1;
1798 break;
1799
1800 case EFI_IFR_TYPE_NUM_SIZE_16:
1801 Width = 2;
1802 break;
1803
1804 case EFI_IFR_TYPE_NUM_SIZE_32:
1805 Width = 4;
1806 break;
1807
1808 case EFI_IFR_TYPE_NUM_SIZE_64:
1809 Width = 8;
1810 break;
1811
1812 default:
1813 //
1814 // Invalid type for Ordered List
1815 //
1816 break;
1817 }
1818
1819 CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);
1820 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
1821 CurrentStatement->ValueType = CurrentOption->Value.Type;
1822
ydong10b18e7052011-05-31 00:59:15 +00001823 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
xdu2d02847d2009-10-26 03:03:47 +00001824 }
qhuang8c60a0612008-10-31 04:41:33 +00001825 break;
1826
1827 //
1828 // Conditional
1829 //
1830 case EFI_IFR_NO_SUBMIT_IF_OP:
1831 case EFI_IFR_INCONSISTENT_IF_OP:
1832 //
1833 // Create an Expression node
1834 //
1835 CurrentExpression = CreateExpression (CurrentForm);
1836 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));
1837
1838 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {
1839 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;
1840 InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);
1841 } else {
1842 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;
1843 InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);
1844 }
lgao40c66bc72009-11-12 01:16:12 +00001845
1846 //
1847 // Take a look at next OpCode to see whether current expression consists
1848 // of single OpCode
1849 //
1850 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1851 SingleOpCodeExpression = TRUE;
1852 }
qhuang8c60a0612008-10-31 04:41:33 +00001853 break;
1854
1855 case EFI_IFR_SUPPRESS_IF_OP:
1856 //
1857 // Question and Option will appear in scope of this OpCode
1858 //
1859 CurrentExpression = CreateExpression (CurrentForm);
1860 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;
lgao40c66bc72009-11-12 01:16:12 +00001861
1862 if (CurrentForm == NULL) {
1863 InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);
1864 } else {
1865 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1866 }
qhuang8c60a0612008-10-31 04:41:33 +00001867
1868 if (SuppressForOption) {
1869 InScopeOptionSuppress = TRUE;
1870 OptionSuppressExpression = CurrentExpression;
lgao40c66bc72009-11-12 01:16:12 +00001871 } else if (SuppressForQuestion) {
qhuang8c60a0612008-10-31 04:41:33 +00001872 mInScopeSuppress = TRUE;
1873 mSuppressExpression = CurrentExpression;
lgao40c66bc72009-11-12 01:16:12 +00001874 } else {
1875 InScopeFormSuppress = TRUE;
1876 FormSuppressExpression = CurrentExpression;
1877 }
1878
1879 //
1880 // Take a look at next OpCode to see whether current expression consists
1881 // of single OpCode
1882 //
1883 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1884 SingleOpCodeExpression = TRUE;
qhuang8c60a0612008-10-31 04:41:33 +00001885 }
1886 break;
1887
1888 case EFI_IFR_GRAY_OUT_IF_OP:
1889 //
1890 // Questions will appear in scope of this OpCode
1891 //
1892 CurrentExpression = CreateExpression (CurrentForm);
1893 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;
1894 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1895
1896 mInScopeGrayOut = TRUE;
1897 mGrayOutExpression = CurrentExpression;
lgao40c66bc72009-11-12 01:16:12 +00001898
1899 //
1900 // Take a look at next OpCode to see whether current expression consists
1901 // of single OpCode
1902 //
1903 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1904 SingleOpCodeExpression = TRUE;
1905 }
qhuang8c60a0612008-10-31 04:41:33 +00001906 break;
1907
1908 case EFI_IFR_DISABLE_IF_OP:
1909 //
1910 // The DisableIf expression should only rely on constant, so it could be
1911 // evaluated at initialization and it will not be queued
1912 //
1913 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
jji41ac628e2009-01-19 07:58:58 +00001914 ASSERT (CurrentExpression != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001915 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;
1916 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;
1917 InitializeListHead (&CurrentExpression->OpCodeListHead);
1918
lgao40a1147e2009-04-22 03:18:37 +00001919 if (CurrentForm != NULL) {
1920 //
1921 // This is DisableIf for Question, enqueue it to Form expression list
1922 //
1923 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1924 }
1925
1926 mDisableExpression = CurrentExpression;
1927 mInScopeDisable = TRUE;
1928 OpCodeDisabled = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +00001929
1930 //
1931 // Take a look at next OpCode to see whether current expression consists
1932 // of single OpCode
1933 //
1934 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1935 SingleOpCodeExpression = TRUE;
1936 }
1937 break;
1938
1939 //
1940 // Expression
1941 //
1942 case EFI_IFR_VALUE_OP:
1943 CurrentExpression = CreateExpression (CurrentForm);
1944 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;
1945 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1946
1947 if (InScopeDefault) {
1948 //
1949 // Used for default (EFI_IFR_DEFAULT)
1950 //
1951 CurrentDefault->ValueExpression = CurrentExpression;
1952 } else {
1953 //
1954 // If used for a question, then the question will be read-only
1955 //
qwang12bc166db2009-02-02 07:18:59 +00001956 //
1957 // Make sure CurrentStatement is not NULL.
1958 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1959 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1960 //
1961 ASSERT (CurrentStatement != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001962 CurrentStatement->ValueExpression = CurrentExpression;
1963 }
lgao40c66bc72009-11-12 01:16:12 +00001964
1965 //
1966 // Take a look at next OpCode to see whether current expression consists
1967 // of single OpCode
1968 //
1969 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1970 SingleOpCodeExpression = TRUE;
1971 }
qhuang8c60a0612008-10-31 04:41:33 +00001972 break;
1973
1974 case EFI_IFR_RULE_OP:
1975 CurrentExpression = CreateExpression (CurrentForm);
1976 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;
1977
1978 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;
1979 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
lgao40c66bc72009-11-12 01:16:12 +00001980
1981 //
1982 // Take a look at next OpCode to see whether current expression consists
1983 // of single OpCode
1984 //
1985 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
1986 SingleOpCodeExpression = TRUE;
1987 }
qhuang8c60a0612008-10-31 04:41:33 +00001988 break;
1989
lgao425737122010-02-25 10:10:59 +00001990 case EFI_IFR_READ_OP:
1991 CurrentExpression = CreateExpression (CurrentForm);
1992 CurrentExpression->Type = EFI_HII_EXPRESSION_READ;
1993 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
1994
1995 //
1996 // Make sure CurrentStatement is not NULL.
1997 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
1998 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
1999 //
2000 ASSERT (CurrentStatement != NULL);
2001 CurrentStatement->ReadExpression = CurrentExpression;
2002
2003 //
2004 // Take a look at next OpCode to see whether current expression consists
2005 // of single OpCode
2006 //
2007 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2008 SingleOpCodeExpression = TRUE;
2009 }
2010 break;
2011
2012 case EFI_IFR_WRITE_OP:
2013 CurrentExpression = CreateExpression (CurrentForm);
2014 CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;
2015 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2016
2017 //
2018 // Make sure CurrentStatement is not NULL.
2019 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2020 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2021 //
2022 ASSERT (CurrentStatement != NULL);
2023 CurrentStatement->WriteExpression = CurrentExpression;
2024
2025 //
2026 // Take a look at next OpCode to see whether current expression consists
2027 // of single OpCode
2028 //
2029 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2030 SingleOpCodeExpression = TRUE;
2031 }
2032 break;
2033
qhuang8c60a0612008-10-31 04:41:33 +00002034 //
2035 // Image
2036 //
2037 case EFI_IFR_IMAGE_OP:
2038 //
2039 // Get ScopeOpcode from top of stack
2040 //
2041 PopScope (&ScopeOpCode);
2042 PushScope (ScopeOpCode);
2043
2044 switch (ScopeOpCode) {
2045 case EFI_IFR_FORM_SET_OP:
2046 ImageId = &FormSet->ImageId;
2047 break;
2048
2049 case EFI_IFR_FORM_OP:
lgao425737122010-02-25 10:10:59 +00002050 case EFI_IFR_FORM_MAP_OP:
qwang12d0720b52009-01-20 01:55:11 +00002051 ASSERT (CurrentForm != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00002052 ImageId = &CurrentForm->ImageId;
2053 break;
2054
2055 case EFI_IFR_ONE_OF_OPTION_OP:
2056 ImageId = &CurrentOption->ImageId;
2057 break;
2058
2059 default:
qwang12bc166db2009-02-02 07:18:59 +00002060 //
2061 // Make sure CurrentStatement is not NULL.
2062 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2063 // file is wrongly generated by tools such as VFR Compiler.
2064 //
2065 ASSERT (CurrentStatement != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00002066 ImageId = &CurrentStatement->ImageId;
2067 break;
2068 }
2069
qwang12c4105892009-02-06 06:34:43 +00002070 ASSERT (ImageId != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00002071 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
2072 break;
2073
2074 //
2075 // Refresh
2076 //
2077 case EFI_IFR_REFRESH_OP:
qwang12c4105892009-02-06 06:34:43 +00002078 ASSERT (CurrentStatement != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00002079 CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;
2080 break;
2081
2082 //
ydong10211cc6e2011-06-08 08:09:47 +00002083 // Refresh guid.
2084 //
2085 case EFI_IFR_REFRESH_ID_OP:
2086 ASSERT (CurrentStatement != NULL);
2087 CopyMem (&CurrentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));
2088 break;
2089
2090 //
ydong10b00964a2011-06-08 07:27:39 +00002091 // Modal tag
2092 //
2093 case EFI_IFR_MODAL_TAG_OP:
2094 ASSERT (CurrentForm != NULL);
2095 CurrentForm->ModalForm = TRUE;
2096 break;
2097
2098 //
qhuang8c60a0612008-10-31 04:41:33 +00002099 // Vendor specific
2100 //
2101 case EFI_IFR_GUID_OP:
lgao45c526732009-02-23 15:18:48 +00002102 if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
qhuang8c60a0612008-10-31 04:41:33 +00002103 //
2104 // Tiano specific GUIDed opcodes
2105 //
2106 switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {
2107 case EFI_IFR_EXTEND_OP_LABEL:
2108 //
2109 // just ignore label
2110 //
2111 break;
2112
2113 case EFI_IFR_EXTEND_OP_BANNER:
lgao40a1147e2009-04-22 03:18:37 +00002114 //
lgao4b9e388d2009-04-22 07:30:52 +00002115 // By SubClass to get Banner Data from Front Page
lgao40a1147e2009-04-22 03:18:37 +00002116 //
qhuang8c60a0612008-10-31 04:41:33 +00002117 if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {
2118 CopyMem (
lgao40a1147e2009-04-22 03:18:37 +00002119 &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][
qhuang8c60a0612008-10-31 04:41:33 +00002120 ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],
2121 &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,
2122 sizeof (EFI_STRING_ID)
2123 );
2124 }
2125 break;
2126
2127 case EFI_IFR_EXTEND_OP_CLASS:
2128 CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));
2129 break;
2130
2131 case EFI_IFR_EXTEND_OP_SUBCLASS:
2132 CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));
2133 break;
2134
2135 default:
2136 break;
2137 }
2138 }
2139
2140 break;
2141
2142 //
2143 // Scope End
2144 //
2145 case EFI_IFR_END_OP:
2146 Status = PopScope (&ScopeOpCode);
2147 if (EFI_ERROR (Status)) {
2148 ResetScopeStack ();
2149 return Status;
2150 }
2151
2152 switch (ScopeOpCode) {
2153 case EFI_IFR_FORM_SET_OP:
2154 //
2155 // End of FormSet, update FormSet IFR binary length
2156 // to stop parsing substantial OpCodes
2157 //
2158 FormSet->IfrBinaryLength = OpCodeOffset;
2159 break;
2160
2161 case EFI_IFR_FORM_OP:
lgao425737122010-02-25 10:10:59 +00002162 case EFI_IFR_FORM_MAP_OP:
qhuang8c60a0612008-10-31 04:41:33 +00002163 //
2164 // End of Form
2165 //
2166 CurrentForm = NULL;
lgao40c66bc72009-11-12 01:16:12 +00002167 SuppressForQuestion = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +00002168 break;
2169
2170 case EFI_IFR_ONE_OF_OPTION_OP:
2171 //
2172 // End of Option
2173 //
2174 CurrentOption = NULL;
2175 break;
2176
2177 case EFI_IFR_SUBTITLE_OP:
2178 mInScopeSubtitle = FALSE;
2179 break;
2180
2181 case EFI_IFR_NO_SUBMIT_IF_OP:
2182 case EFI_IFR_INCONSISTENT_IF_OP:
2183 //
2184 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2185 //
2186 break;
2187
2188 case EFI_IFR_SUPPRESS_IF_OP:
2189 if (SuppressForOption) {
2190 InScopeOptionSuppress = FALSE;
lgao40c66bc72009-11-12 01:16:12 +00002191 } else if (SuppressForQuestion) {
qhuang8c60a0612008-10-31 04:41:33 +00002192 mInScopeSuppress = FALSE;
lgao40c66bc72009-11-12 01:16:12 +00002193 } else {
2194 InScopeFormSuppress = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +00002195 }
2196 break;
2197
2198 case EFI_IFR_GRAY_OUT_IF_OP:
2199 mInScopeGrayOut = FALSE;
2200 break;
2201
2202 case EFI_IFR_DISABLE_IF_OP:
lgao40a1147e2009-04-22 03:18:37 +00002203 mInScopeDisable = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +00002204 OpCodeDisabled = FALSE;
2205 break;
2206
2207 case EFI_IFR_ONE_OF_OP:
2208 case EFI_IFR_ORDERED_LIST_OP:
2209 SuppressForOption = FALSE;
2210 break;
2211
2212 case EFI_IFR_DEFAULT_OP:
2213 InScopeDefault = FALSE;
2214 break;
2215
lgao425737122010-02-25 10:10:59 +00002216 case EFI_IFR_MAP_OP:
2217 //
2218 // Get current Map Expression List.
2219 //
2220 Status = PopMapExpressionList ((VOID **) &MapExpressionList);
2221 if (Status == EFI_ACCESS_DENIED) {
2222 MapExpressionList = NULL;
2223 }
2224 //
2225 // Get current expression.
2226 //
2227 Status = PopCurrentExpression ((VOID **) &CurrentExpression);
2228 ASSERT_EFI_ERROR (Status);
lgao4771ecec2010-02-27 09:04:11 +00002229 ASSERT (MapScopeDepth > 0);
lgao425737122010-02-25 10:10:59 +00002230 MapScopeDepth --;
2231 break;
2232
qhuang8c60a0612008-10-31 04:41:33 +00002233 default:
2234 if (IsExpressionOpCode (ScopeOpCode)) {
lgao40a1147e2009-04-22 03:18:37 +00002235 if (mInScopeDisable && CurrentForm == NULL) {
qhuang8c60a0612008-10-31 04:41:33 +00002236 //
lgao40a1147e2009-04-22 03:18:37 +00002237 // This is DisableIf expression for Form, it should be a constant expression
qhuang8c60a0612008-10-31 04:41:33 +00002238 //
xdu2f8a1c222009-10-20 03:01:10 +00002239 ASSERT (CurrentExpression != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00002240 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
2241 if (EFI_ERROR (Status)) {
2242 return Status;
2243 }
qwang12a935a0d2009-02-10 09:40:27 +00002244
qhuang8c60a0612008-10-31 04:41:33 +00002245 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
2246 return EFI_INVALID_PARAMETER;
2247 }
2248
2249 OpCodeDisabled = CurrentExpression->Result.Value.b;
2250 //
lgao425737122010-02-25 10:10:59 +00002251 // DisableIf Expression is only used once and not queued, free it
qhuang8c60a0612008-10-31 04:41:33 +00002252 //
2253 DestroyExpression (CurrentExpression);
2254 }
2255
2256 //
2257 // End of current Expression
2258 //
2259 CurrentExpression = NULL;
2260 }
2261 break;
2262 }
2263 break;
2264
2265 default:
2266 break;
2267 }
2268 }
2269
2270 return EFI_SUCCESS;
2271}