blob: ed06f1c9cd0811706a8e4ca51cd7a9ce3eb78959 [file] [log] [blame]
qhuang8c60a0612008-10-31 04:41:33 +00001/** @file
2Parser for IFR binary encoding.
3
ydong10a7f87052013-01-06 06:12:50 +00004Copyright (c) 2007 - 2013, 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;
Eric Dong7c6c0642013-08-12 02:19:56 +000019EFI_QUESTION_ID mUsedQuestionId;
ydong1094f3aae2013-04-16 10:53:22 +000020extern LIST_ENTRY gBrowserStorageList;
qhuang8c60a0612008-10-31 04:41:33 +000021/**
22 Initialize Statement header members.
23
24 @param OpCodeData Pointer of the raw OpCode data.
25 @param FormSet Pointer of the current FormSe.
26 @param Form Pointer of the current Form.
27
28 @return The Statement.
29
30**/
31FORM_BROWSER_STATEMENT *
32CreateStatement (
33 IN UINT8 *OpCodeData,
34 IN OUT FORM_BROWSER_FORMSET *FormSet,
35 IN OUT FORM_BROWSER_FORM *Form
36 )
37{
38 FORM_BROWSER_STATEMENT *Statement;
39 EFI_IFR_STATEMENT_HEADER *StatementHdr;
ydong1031585af2012-01-31 07:17:42 +000040 INTN ConditionalExprCount;
qhuang8c60a0612008-10-31 04:41:33 +000041
42 if (Form == NULL) {
43 //
Eric Dong7c6c0642013-08-12 02:19:56 +000044 // Only guid op may out side the form level.
qhuang8c60a0612008-10-31 04:41:33 +000045 //
Eric Dong7c6c0642013-08-12 02:19:56 +000046 ASSERT (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_GUID_OP);
qhuang8c60a0612008-10-31 04:41:33 +000047 }
48
49 Statement = &FormSet->StatementBuffer[mStatementIndex];
50 mStatementIndex++;
51
52 InitializeListHead (&Statement->DefaultListHead);
53 InitializeListHead (&Statement->OptionListHead);
54 InitializeListHead (&Statement->InconsistentListHead);
55 InitializeListHead (&Statement->NoSubmitListHead);
Eric Dong1c0d3062013-09-04 04:15:10 +000056 InitializeListHead (&Statement->WarningListHead);
qhuang8c60a0612008-10-31 04:41:33 +000057
58 Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;
59
60 Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
Eric Dong7c6c0642013-08-12 02:19:56 +000061 Statement->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;
qhuang8c60a0612008-10-31 04:41:33 +000062
63 StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
64 CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
65 CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));
66
ydong1031585af2012-01-31 07:17:42 +000067 ConditionalExprCount = GetConditionalExpressionCount(ExpressStatement);
68 if (ConditionalExprCount > 0) {
69 //
70 // Form is inside of suppressif
71 //
72
73 Statement->Expression = (FORM_EXPRESSION_LIST *) AllocatePool(
74 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
75 ASSERT (Statement->Expression != NULL);
76 Statement->Expression->Count = (UINTN) ConditionalExprCount;
77 Statement->Expression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
78 CopyMem (Statement->Expression->Expression, GetConditionalExpressionList(ExpressStatement), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
lgao40a1147e2009-04-22 03:18:37 +000079 }
80
qhuang8c60a0612008-10-31 04:41:33 +000081 //
82 // Insert this Statement into current Form
83 //
Eric Dong7c6c0642013-08-12 02:19:56 +000084 if (Form == NULL) {
85 InsertTailList (&FormSet->StatementListOSF, &Statement->Link);
86 } else {
87 InsertTailList (&Form->StatementListHead, &Statement->Link);
88 }
qhuang8c60a0612008-10-31 04:41:33 +000089 return Statement;
90}
91
qwang127064c0a2008-11-19 13:36:34 +000092/**
93 Convert a numeric value to a Unicode String and insert it to String Package.
94 This string is used as the Unicode Name for the EFI Variable. This is to support
95 the deprecated vareqval opcode.
xdu28b0fc5c2009-10-26 03:05:16 +000096
qwang127064c0a2008-11-19 13:36:34 +000097 @param FormSet The FormSet.
98 @param Statement The numeric question whose VarStoreInfo.VarName is the
99 numeric value which is used to produce the Unicode Name
100 for the EFI Variable.
xdu28b0fc5c2009-10-26 03:05:16 +0000101
qwang127064c0a2008-11-19 13:36:34 +0000102 If the Statement is NULL, the ASSERT.
103 If the opcode is not Numeric, then ASSERT.
xdu28b0fc5c2009-10-26 03:05:16 +0000104
qwang127064c0a2008-11-19 13:36:34 +0000105 @retval EFI_SUCCESS The funtion always succeeds.
106**/
qhuang8c60a0612008-10-31 04:41:33 +0000107EFI_STATUS
108UpdateCheckBoxStringToken (
109 IN CONST FORM_BROWSER_FORMSET *FormSet,
110 IN FORM_BROWSER_STATEMENT *Statement
111 )
112{
113 CHAR16 Str[MAXIMUM_VALUE_CHARACTERS];
114 EFI_STRING_ID Id;
qhuang8c60a0612008-10-31 04:41:33 +0000115
116 ASSERT (Statement != NULL);
117 ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP);
xdu28b0fc5c2009-10-26 03:05:16 +0000118
qhuang8c60a0612008-10-31 04:41:33 +0000119 UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);
qhuang8c60a0612008-10-31 04:41:33 +0000120
rsun3cb7d01c2009-04-14 10:47:19 +0000121 Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL);
122 if (Id == 0) {
123 return EFI_OUT_OF_RESOURCES;
qhuang8c60a0612008-10-31 04:41:33 +0000124 }
125
126 Statement->VarStoreInfo.VarName = Id;
xdu28b0fc5c2009-10-26 03:05:16 +0000127
qhuang8c60a0612008-10-31 04:41:33 +0000128 return EFI_SUCCESS;
129}
130
qwang127064c0a2008-11-19 13:36:34 +0000131/**
132 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
xdu28b0fc5c2009-10-26 03:05:16 +0000133
qwang127064c0a2008-11-19 13:36:34 +0000134 @param OpCodeData The current opcode.
xdu28b0fc5c2009-10-26 03:05:16 +0000135
qwang127064c0a2008-11-19 13:36:34 +0000136 @retval TRUE Yes.
137 @retval FALSE No.
138**/
qhuang8c60a0612008-10-31 04:41:33 +0000139BOOLEAN
140IsNextOpCodeGuidedVarEqName (
xdu28b0fc5c2009-10-26 03:05:16 +0000141 IN UINT8 *OpCodeData
qhuang8c60a0612008-10-31 04:41:33 +0000142 )
143{
144 //
145 // Get next opcode
146 //
147 OpCodeData += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
148 if (*OpCodeData == EFI_IFR_GUID_OP) {
lgao45c526732009-02-23 15:18:48 +0000149 if (CompareGuid (&gEfiIfrFrameworkGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
qhuang8c60a0612008-10-31 04:41:33 +0000150 //
xdu28b0fc5c2009-10-26 03:05:16 +0000151 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
qhuang8c60a0612008-10-31 04:41:33 +0000152 //
153 if ((((EFI_IFR_GUID_VAREQNAME *) OpCodeData)->ExtendOpCode) == EFI_IFR_EXTEND_OP_VAREQNAME) {
154 return TRUE;
155 }
156 }
157 }
158
159 return FALSE;
160}
161
162/**
163 Initialize Question's members.
164
165 @param OpCodeData Pointer of the raw OpCode data.
166 @param FormSet Pointer of the current FormSet.
167 @param Form Pointer of the current Form.
168
169 @return The Question.
170
171**/
172FORM_BROWSER_STATEMENT *
173CreateQuestion (
174 IN UINT8 *OpCodeData,
175 IN OUT FORM_BROWSER_FORMSET *FormSet,
176 IN OUT FORM_BROWSER_FORM *Form
177 )
178{
179 FORM_BROWSER_STATEMENT *Statement;
180 EFI_IFR_QUESTION_HEADER *QuestionHdr;
181 LIST_ENTRY *Link;
182 FORMSET_STORAGE *Storage;
183 NAME_VALUE_NODE *NameValueNode;
184 EFI_STATUS Status;
ydong1094f3aae2013-04-16 10:53:22 +0000185 BOOLEAN Find;
qhuang8c60a0612008-10-31 04:41:33 +0000186
187 Statement = CreateStatement (OpCodeData, FormSet, Form);
188 if (Statement == NULL) {
189 return NULL;
190 }
191
192 QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
193 CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));
194 CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));
195 CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));
196
197 Statement->QuestionFlags = QuestionHdr->Flags;
198
199 if (Statement->VarStoreId == 0) {
200 //
201 // VarStoreId of zero indicates no variable storage
202 //
203 return Statement;
204 }
205
206 //
207 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
208 // Framework Compatibility
209 //
lgao4f806dd22009-02-25 09:04:47 +0000210 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
qhuang8c60a0612008-10-31 04:41:33 +0000211 if ((*OpCodeData == EFI_IFR_NUMERIC_OP) && IsNextOpCodeGuidedVarEqName (OpCodeData)) {
212 Status = UpdateCheckBoxStringToken (FormSet, Statement);
213 if (EFI_ERROR (Status)) {
214 return NULL;
215 }
216 }
217 }
218
219 //
220 // Find Storage for this Question
221 //
222 Link = GetFirstNode (&FormSet->StorageListHead);
223 while (!IsNull (&FormSet->StorageListHead, Link)) {
224 Storage = FORMSET_STORAGE_FROM_LINK (Link);
225
226 if (Storage->VarStoreId == Statement->VarStoreId) {
ydong1094f3aae2013-04-16 10:53:22 +0000227 Statement->Storage = Storage->BrowserStorage;
qhuang8c60a0612008-10-31 04:41:33 +0000228 break;
229 }
230
231 Link = GetNextNode (&FormSet->StorageListHead, Link);
232 }
233 ASSERT (Statement->Storage != NULL);
234
235 //
236 // Initialilze varname for Name/Value or EFI Variable
237 //
238 if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||
239 (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
240 Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);
241 ASSERT (Statement->VariableName != NULL);
242
243 if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
244 //
ydong1094f3aae2013-04-16 10:53:22 +0000245 // Check whether old string node already exist.
qhuang8c60a0612008-10-31 04:41:33 +0000246 //
ydong1094f3aae2013-04-16 10:53:22 +0000247 Find = FALSE;
248 if (!IsListEmpty(&Statement->Storage->NameValueListHead)) {
249 Link = GetFirstNode (&Statement->Storage->NameValueListHead);
250 while (!IsNull (&Statement->Storage->NameValueListHead, Link)) {
251 NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);
qhuang8c60a0612008-10-31 04:41:33 +0000252
ydong1094f3aae2013-04-16 10:53:22 +0000253 if (StrCmp (Statement->VariableName, NameValueNode->Name) == 0) {
254 Find = TRUE;
255 break;
256 }
257
258 Link = GetNextNode (&Statement->Storage->NameValueListHead, Link);
259 }
260 }
261
262 if (!Find) {
263 //
264 // Insert to Name/Value varstore list
265 //
266 NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));
267 ASSERT (NameValueNode != NULL);
268 NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;
269 NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);
270 ASSERT (NameValueNode->Name != NULL);
271 NameValueNode->Value = AllocateZeroPool (0x10);
272 ASSERT (NameValueNode->Value != NULL);
273 NameValueNode->EditValue = AllocateZeroPool (0x10);
274 ASSERT (NameValueNode->EditValue != NULL);
275
276 InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);
277 }
qhuang8c60a0612008-10-31 04:41:33 +0000278 }
279 }
280
281 return Statement;
282}
283
284
285/**
286 Allocate a FORM_EXPRESSION node.
287
288 @param Form The Form associated with this Expression
289
290 @return Pointer to a FORM_EXPRESSION data structure.
291
292**/
293FORM_EXPRESSION *
294CreateExpression (
295 IN OUT FORM_BROWSER_FORM *Form
296 )
297{
298 FORM_EXPRESSION *Expression;
299
300 Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
jji41ac628e2009-01-19 07:58:58 +0000301 ASSERT (Expression != NULL);
qhuang8c60a0612008-10-31 04:41:33 +0000302 Expression->Signature = FORM_EXPRESSION_SIGNATURE;
303 InitializeListHead (&Expression->OpCodeListHead);
304
305 return Expression;
306}
307
qhuang8c60a0612008-10-31 04:41:33 +0000308/**
309 Create ConfigHdr string for a storage.
310
311 @param FormSet Pointer of the current FormSet
312 @param Storage Pointer of the storage
313
314 @retval EFI_SUCCESS Initialize ConfigHdr success
315
316**/
317EFI_STATUS
318InitializeConfigHdr (
319 IN FORM_BROWSER_FORMSET *FormSet,
ydong1094f3aae2013-04-16 10:53:22 +0000320 IN OUT BROWSER_STORAGE *Storage
qhuang8c60a0612008-10-31 04:41:33 +0000321 )
322{
qhuang8c60a0612008-10-31 04:41:33 +0000323 CHAR16 *Name;
xdu28b0fc5c2009-10-26 03:05:16 +0000324
ydong10cce62302011-07-12 07:24:36 +0000325 if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
326 Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
qhuang8c60a0612008-10-31 04:41:33 +0000327 Name = Storage->Name;
328 } else {
329 Name = NULL;
330 }
xdu28b0fc5c2009-10-26 03:05:16 +0000331
lgao47e3bccc2009-04-13 06:05:15 +0000332 Storage->ConfigHdr = HiiConstructConfigHdr (
333 &Storage->Guid,
334 Name,
335 FormSet->DriverHandle
336 );
xdu28b0fc5c2009-10-26 03:05:16 +0000337
lgao47e3bccc2009-04-13 06:05:15 +0000338 if (Storage->ConfigHdr == NULL) {
339 return EFI_NOT_FOUND;
qhuang8c60a0612008-10-31 04:41:33 +0000340 }
341
qhuang8c60a0612008-10-31 04:41:33 +0000342 return EFI_SUCCESS;
343}
344
ydong1094f3aae2013-04-16 10:53:22 +0000345/**
346 Find the global storage link base on the input storate type, name and guid.
347
Eric Dongfae73622013-11-25 02:55:45 +0000348 For EFI_HII_VARSTORE_EFI_VARIABLE and EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER,
349 same guid + name = same storage
350
351 For EFI_HII_VARSTORE_NAME_VALUE:
352 same guid + HiiHandle = same storage
353
354 For EFI_HII_VARSTORE_BUFFER:
355 same guid + name + HiiHandle = same storage
356
ydong1094f3aae2013-04-16 10:53:22 +0000357 @param StorageType Storage type.
358 @param StorageGuid Storage guid.
359 @param StorageName Storage Name.
Eric Dongfae73622013-11-25 02:55:45 +0000360 @param HiiHandle HiiHandle for this varstore.
ydong1094f3aae2013-04-16 10:53:22 +0000361
362 @return Pointer to a GLOBAL_STORAGE data structure.
363
364**/
365BROWSER_STORAGE *
366FindStorageInList (
367 IN UINT8 StorageType,
368 IN EFI_GUID *StorageGuid,
Eric Dongfae73622013-11-25 02:55:45 +0000369 IN CHAR16 *StorageName,
370 IN EFI_HII_HANDLE HiiHandle
ydong1094f3aae2013-04-16 10:53:22 +0000371 )
372{
373 LIST_ENTRY *Link;
374 BROWSER_STORAGE *BrowserStorage;
375
376 Link = GetFirstNode (&gBrowserStorageList);
377 while (!IsNull (&gBrowserStorageList, Link)) {
378 BrowserStorage = BROWSER_STORAGE_FROM_LINK (Link);
Eric Dong0f83ac32013-12-09 03:22:36 +0000379 Link = GetNextNode (&gBrowserStorageList, Link);
ydong1094f3aae2013-04-16 10:53:22 +0000380
381 if ((BrowserStorage->Type == StorageType) && CompareGuid (&BrowserStorage->Guid, StorageGuid)) {
Eric Dong0f83ac32013-12-09 03:22:36 +0000382 if (StorageType == EFI_HII_VARSTORE_NAME_VALUE) {
383 if (BrowserStorage->HiiHandle == HiiHandle) {
384 return BrowserStorage;
385 }
386
387 continue;
ydong1094f3aae2013-04-16 10:53:22 +0000388 }
389
Eric Dong0f83ac32013-12-09 03:22:36 +0000390 ASSERT (StorageName != NULL);
ydong1094f3aae2013-04-16 10:53:22 +0000391 if (StrCmp (BrowserStorage->Name, StorageName) == 0) {
Eric Dongfae73622013-11-25 02:55:45 +0000392 if (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE || StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
393 return BrowserStorage;
394 } else if (StorageType == EFI_HII_VARSTORE_BUFFER && BrowserStorage->HiiHandle == HiiHandle) {
395 return BrowserStorage;
396 }
ydong1094f3aae2013-04-16 10:53:22 +0000397 }
398 }
ydong1094f3aae2013-04-16 10:53:22 +0000399 }
400
401 return NULL;
402}
403
404/**
405 Intialize the Global Storage.
406
407 @param BrowserStorage Pointer to the global storage.
408 @param StorageType Storage type.
409 @param OpCodeData Binary data for this opcode.
410
411**/
412VOID
413IntializeBrowserStorage (
414 IN BROWSER_STORAGE *BrowserStorage,
415 IN UINT8 StorageType,
416 IN UINT8 *OpCodeData
417 )
418{
419 switch (StorageType) {
420 case EFI_HII_VARSTORE_BUFFER:
421 CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));
422 CopyMem (&BrowserStorage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));
423
424 BrowserStorage->Buffer = AllocateZeroPool (BrowserStorage->Size);
425 BrowserStorage->EditBuffer = AllocateZeroPool (BrowserStorage->Size);
426 break;
427
428 case EFI_HII_VARSTORE_EFI_VARIABLE:
429 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
430 CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));
431 CopyMem (&BrowserStorage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));
432 CopyMem (&BrowserStorage->Size, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Size, sizeof (UINT16));
433
434 if (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
435 BrowserStorage->Buffer = AllocateZeroPool (BrowserStorage->Size);
436 BrowserStorage->EditBuffer = AllocateZeroPool (BrowserStorage->Size);
437 }
438 break;
439
440 case EFI_HII_VARSTORE_NAME_VALUE:
441 CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));
442
443 InitializeListHead (&BrowserStorage->NameValueListHead);
444 break;
445
446 default:
447 break;
448 }
449}
450
451/**
452 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
453
454 @param FormSet Pointer of the current FormSet
455 @param StorageType Storage type.
456 @param OpCodeData Binary data for this opcode.
457
458 @return Pointer to a FORMSET_STORAGE data structure.
459
460**/
461FORMSET_STORAGE *
462CreateStorage (
463 IN FORM_BROWSER_FORMSET *FormSet,
464 IN UINT8 StorageType,
465 IN UINT8 *OpCodeData
466 )
467{
468 FORMSET_STORAGE *Storage;
469 CHAR16 *UnicodeString;
470 UINT16 Index;
471 BROWSER_STORAGE *BrowserStorage;
472 EFI_GUID *StorageGuid;
473 CHAR8 *StorageName;
474
475 UnicodeString = NULL;
476 StorageName = NULL;
477 switch (StorageType) {
478 case EFI_HII_VARSTORE_BUFFER:
479 StorageGuid = (EFI_GUID *) (CHAR8*) &((EFI_IFR_VARSTORE *) OpCodeData)->Guid;
480 StorageName = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;
481 break;
482
483 case EFI_HII_VARSTORE_EFI_VARIABLE:
484 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
485 StorageGuid = (EFI_GUID *) (CHAR8*) &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid;
486 StorageName = (CHAR8 *) ((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Name;
487 break;
488
489 default:
490 ASSERT (StorageType == EFI_HII_VARSTORE_NAME_VALUE);
491 StorageGuid = &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid;
492 break;
493 }
494
495 if (StorageType != EFI_HII_VARSTORE_NAME_VALUE) {
496 ASSERT (StorageName != NULL);
497
498 UnicodeString = AllocateZeroPool (AsciiStrSize (StorageName) * 2);
499 ASSERT (UnicodeString != NULL);
500 for (Index = 0; StorageName[Index] != 0; Index++) {
501 UnicodeString[Index] = (CHAR16) StorageName[Index];
502 }
503 }
504
505 Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));
506 ASSERT (Storage != NULL);
507 Storage->Signature = FORMSET_STORAGE_SIGNATURE;
508 InsertTailList (&FormSet->StorageListHead, &Storage->Link);
509
Eric Dongfae73622013-11-25 02:55:45 +0000510 BrowserStorage = FindStorageInList(StorageType, StorageGuid, UnicodeString, FormSet->HiiHandle);
ydong1094f3aae2013-04-16 10:53:22 +0000511 if (BrowserStorage == NULL) {
512 BrowserStorage = AllocateZeroPool (sizeof (BROWSER_STORAGE));
513 ASSERT (BrowserStorage != NULL);
514
515 BrowserStorage->Signature = BROWSER_STORAGE_SIGNATURE;
516 InsertTailList (&gBrowserStorageList, &BrowserStorage->Link);
517
518 IntializeBrowserStorage (BrowserStorage, StorageType, OpCodeData);
519 BrowserStorage->Type = StorageType;
520 if (StorageType != EFI_HII_VARSTORE_NAME_VALUE) {
521 BrowserStorage->Name = UnicodeString;
522 }
523
Eric Dongfae73622013-11-25 02:55:45 +0000524 BrowserStorage->HiiHandle = FormSet->HiiHandle;
ydong1094f3aae2013-04-16 10:53:22 +0000525 InitializeConfigHdr (FormSet, BrowserStorage);
Eric Dongfae73622013-11-25 02:55:45 +0000526
527 BrowserStorage->Initialized = FALSE;
ydong1094f3aae2013-04-16 10:53:22 +0000528 }
ydong1094f3aae2013-04-16 10:53:22 +0000529
530 Storage->BrowserStorage = BrowserStorage;
531 Storage->ConfigRequest = AllocateCopyPool (StrSize (BrowserStorage->ConfigHdr), BrowserStorage->ConfigHdr);
532 Storage->SpareStrLen = 0;
533
534 return Storage;
535}
qhuang8c60a0612008-10-31 04:41:33 +0000536
537/**
538 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
539
540 @param FormSet Pointer of the current FormSet.
541 @param Question The Question to be initialized.
ydong10b18e7052011-05-31 00:59:15 +0000542 @param Form Pointer of the current form.
qhuang8c60a0612008-10-31 04:41:33 +0000543
544 @retval EFI_SUCCESS Function success.
545 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
546
547**/
548EFI_STATUS
549InitializeRequestElement (
550 IN OUT FORM_BROWSER_FORMSET *FormSet,
ydong10b18e7052011-05-31 00:59:15 +0000551 IN OUT FORM_BROWSER_STATEMENT *Question,
552 IN OUT FORM_BROWSER_FORM *Form
qhuang8c60a0612008-10-31 04:41:33 +0000553 )
554{
ydong1094f3aae2013-04-16 10:53:22 +0000555 BROWSER_STORAGE *Storage;
556 FORMSET_STORAGE *FormsetStorage;
qhuang8c60a0612008-10-31 04:41:33 +0000557 UINTN StrLen;
558 UINTN StringSize;
559 CHAR16 *NewStr;
560 CHAR16 RequestElement[30];
ydong10b18e7052011-05-31 00:59:15 +0000561 LIST_ENTRY *Link;
562 BOOLEAN Find;
563 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
qhuang8c60a0612008-10-31 04:41:33 +0000564
565 Storage = Question->Storage;
566 if (Storage == NULL) {
567 return EFI_INVALID_PARAMETER;
568 }
569
570 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
571 //
572 // <ConfigRequest> is unnecessary for EFI variable storage,
573 // GetVariable()/SetVariable() will be used to retrieve/save values
574 //
575 return EFI_SUCCESS;
576 }
577
578 //
579 // Prepare <RequestElement>
580 //
ydong10cce62302011-07-12 07:24:36 +0000581 if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
582 Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
qhuang8c60a0612008-10-31 04:41:33 +0000583 StrLen = UnicodeSPrint (
584 RequestElement,
585 30 * sizeof (CHAR16),
586 L"&OFFSET=%x&WIDTH=%x",
587 Question->VarStoreInfo.VarOffset,
588 Question->StorageWidth
589 );
590 Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);
591 } else {
592 StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);
593 }
594
595 if ((Question->Operand == EFI_IFR_PASSWORD_OP) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {
596 //
597 // Password with CALLBACK flag is stored in encoded format,
598 // so don't need to append it to <ConfigRequest>
599 //
600 return EFI_SUCCESS;
601 }
602
603 //
ydong1094f3aae2013-04-16 10:53:22 +0000604 // Find Formset Storage for this Question
605 //
606 FormsetStorage = NULL;
607 Link = GetFirstNode (&FormSet->StorageListHead);
608 while (!IsNull (&FormSet->StorageListHead, Link)) {
609 FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);
610
611 if (FormsetStorage->VarStoreId == Question->VarStoreId) {
612 break;
613 }
614
615 Link = GetNextNode (&FormSet->StorageListHead, Link);
616 }
617 ASSERT (FormsetStorage != NULL);
618
619 //
qhuang8c60a0612008-10-31 04:41:33 +0000620 // Append <RequestElement> to <ConfigRequest>
621 //
ydong1094f3aae2013-04-16 10:53:22 +0000622 if (StrLen > FormsetStorage->SpareStrLen) {
qhuang8c60a0612008-10-31 04:41:33 +0000623 //
624 // Old String buffer is not sufficient for RequestElement, allocate a new one
625 //
ydong1094f3aae2013-04-16 10:53:22 +0000626 StringSize = (FormsetStorage->ConfigRequest != NULL) ? StrSize (FormsetStorage->ConfigRequest) : sizeof (CHAR16);
qhuang8c60a0612008-10-31 04:41:33 +0000627 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));
jji41ac628e2009-01-19 07:58:58 +0000628 ASSERT (NewStr != NULL);
ydong1094f3aae2013-04-16 10:53:22 +0000629 if (FormsetStorage->ConfigRequest != NULL) {
630 CopyMem (NewStr, FormsetStorage->ConfigRequest, StringSize);
631 FreePool (FormsetStorage->ConfigRequest);
qhuang8c60a0612008-10-31 04:41:33 +0000632 }
ydong1094f3aae2013-04-16 10:53:22 +0000633 FormsetStorage->ConfigRequest = NewStr;
634 FormsetStorage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
qhuang8c60a0612008-10-31 04:41:33 +0000635 }
636
ydong1094f3aae2013-04-16 10:53:22 +0000637 StrCat (FormsetStorage->ConfigRequest, RequestElement);
638 FormsetStorage->ElementCount++;
639 FormsetStorage->SpareStrLen -= StrLen;
qhuang8c60a0612008-10-31 04:41:33 +0000640
ydong10b18e7052011-05-31 00:59:15 +0000641 //
642 // Update the Config Request info saved in the form.
643 //
644 ConfigInfo = NULL;
645 Find = FALSE;
646 Link = GetFirstNode (&Form->ConfigRequestHead);
647 while (!IsNull (&Form->ConfigRequestHead, Link)) {
648 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
649
ydong1094f3aae2013-04-16 10:53:22 +0000650 if (ConfigInfo != NULL && ConfigInfo->Storage == Storage) {
ydong10b18e7052011-05-31 00:59:15 +0000651 Find = TRUE;
652 break;
653 }
654
655 Link = GetNextNode (&Form->ConfigRequestHead, Link);
656 }
657
658 if (!Find) {
659 ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST));
ydong100194d262011-06-13 05:20:23 +0000660 ASSERT (ConfigInfo != NULL);
ydong10b18e7052011-05-31 00:59:15 +0000661 ConfigInfo->Signature = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE;
662 ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);
663 ConfigInfo->SpareStrLen = 0;
664 ConfigInfo->Storage = Storage;
665 InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link);
666 }
667
668 //
669 // Append <RequestElement> to <ConfigRequest>
670 //
671 if (StrLen > ConfigInfo->SpareStrLen) {
672 //
673 // Old String buffer is not sufficient for RequestElement, allocate a new one
674 //
675 StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);
676 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));
677 ASSERT (NewStr != NULL);
678 if (ConfigInfo->ConfigRequest != NULL) {
679 CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);
680 FreePool (ConfigInfo->ConfigRequest);
681 }
682 ConfigInfo->ConfigRequest = NewStr;
683 ConfigInfo->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
684 }
685
686 StrCat (ConfigInfo->ConfigRequest, RequestElement);
687 ConfigInfo->ElementCount++;
688 ConfigInfo->SpareStrLen -= StrLen;
qhuang8c60a0612008-10-31 04:41:33 +0000689 return EFI_SUCCESS;
690}
691
692
693/**
694 Free resources of a Expression.
695
696 @param FormSet Pointer of the Expression
697
698**/
699VOID
700DestroyExpression (
701 IN FORM_EXPRESSION *Expression
702 )
703{
704 LIST_ENTRY *Link;
705 EXPRESSION_OPCODE *OpCode;
lgao425737122010-02-25 10:10:59 +0000706 LIST_ENTRY *SubExpressionLink;
707 FORM_EXPRESSION *SubExpression;
qhuang8c60a0612008-10-31 04:41:33 +0000708
709 while (!IsListEmpty (&Expression->OpCodeListHead)) {
710 Link = GetFirstNode (&Expression->OpCodeListHead);
711 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);
712 RemoveEntryList (&OpCode->Link);
713
714 if (OpCode->ValueList != NULL) {
715 FreePool (OpCode->ValueList);
716 }
lgao425737122010-02-25 10:10:59 +0000717
718 if (OpCode->ValueName != NULL) {
719 FreePool (OpCode->ValueName);
720 }
721
722 if (OpCode->MapExpressionList.ForwardLink != NULL) {
723 while (!IsListEmpty (&OpCode->MapExpressionList)) {
724 SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);
725 SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);
726 RemoveEntryList(&SubExpression->Link);
727 DestroyExpression (SubExpression);
728 }
729 }
qhuang8c60a0612008-10-31 04:41:33 +0000730 }
731
732 //
733 // Free this Expression
734 //
qwang12f4113e12008-11-21 06:59:58 +0000735 FreePool (Expression);
qhuang8c60a0612008-10-31 04:41:33 +0000736}
737
qhuang8c60a0612008-10-31 04:41:33 +0000738/**
739 Free resources of a storage.
740
741 @param Storage Pointer of the storage
742
743**/
744VOID
745DestroyStorage (
746 IN FORMSET_STORAGE *Storage
747 )
748{
qhuang8c60a0612008-10-31 04:41:33 +0000749 if (Storage == NULL) {
750 return;
751 }
752
qhuang8c60a0612008-10-31 04:41:33 +0000753 if (Storage->ConfigRequest != NULL) {
754 FreePool (Storage->ConfigRequest);
755 }
756
757 FreePool (Storage);
758}
759
760
761/**
762 Free resources of a Statement.
763
ydong10e2100bf2010-12-23 06:47:50 +0000764 @param FormSet Pointer of the FormSet
qhuang8c60a0612008-10-31 04:41:33 +0000765 @param Statement Pointer of the Statement
766
767**/
768VOID
769DestroyStatement (
ydong10e2100bf2010-12-23 06:47:50 +0000770 IN FORM_BROWSER_FORMSET *FormSet,
qhuang8c60a0612008-10-31 04:41:33 +0000771 IN OUT FORM_BROWSER_STATEMENT *Statement
772 )
773{
774 LIST_ENTRY *Link;
775 QUESTION_DEFAULT *Default;
776 QUESTION_OPTION *Option;
777 FORM_EXPRESSION *Expression;
778
779 //
780 // Free Default value List
781 //
782 while (!IsListEmpty (&Statement->DefaultListHead)) {
783 Link = GetFirstNode (&Statement->DefaultListHead);
784 Default = QUESTION_DEFAULT_FROM_LINK (Link);
785 RemoveEntryList (&Default->Link);
786
qwang12f4113e12008-11-21 06:59:58 +0000787 FreePool (Default);
qhuang8c60a0612008-10-31 04:41:33 +0000788 }
789
790 //
791 // Free Options List
792 //
793 while (!IsListEmpty (&Statement->OptionListHead)) {
794 Link = GetFirstNode (&Statement->OptionListHead);
795 Option = QUESTION_OPTION_FROM_LINK (Link);
ydong1031585af2012-01-31 07:17:42 +0000796 if (Option->SuppressExpression != NULL) {
797 FreePool (Option->SuppressExpression);
798 }
qhuang8c60a0612008-10-31 04:41:33 +0000799 RemoveEntryList (&Option->Link);
800
qwang12f4113e12008-11-21 06:59:58 +0000801 FreePool (Option);
qhuang8c60a0612008-10-31 04:41:33 +0000802 }
803
804 //
805 // Free Inconsistent List
806 //
807 while (!IsListEmpty (&Statement->InconsistentListHead)) {
808 Link = GetFirstNode (&Statement->InconsistentListHead);
809 Expression = FORM_EXPRESSION_FROM_LINK (Link);
810 RemoveEntryList (&Expression->Link);
811
812 DestroyExpression (Expression);
813 }
814
815 //
816 // Free NoSubmit List
817 //
818 while (!IsListEmpty (&Statement->NoSubmitListHead)) {
819 Link = GetFirstNode (&Statement->NoSubmitListHead);
820 Expression = FORM_EXPRESSION_FROM_LINK (Link);
821 RemoveEntryList (&Expression->Link);
822
823 DestroyExpression (Expression);
824 }
825
Eric Dong1c0d3062013-09-04 04:15:10 +0000826 //
827 // Free WarningIf List
828 //
829 while (!IsListEmpty (&Statement->WarningListHead)) {
830 Link = GetFirstNode (&Statement->WarningListHead);
831 Expression = FORM_EXPRESSION_FROM_LINK (Link);
832 RemoveEntryList (&Expression->Link);
833
834 DestroyExpression (Expression);
835 }
836
ydong1031585af2012-01-31 07:17:42 +0000837 if (Statement->Expression != NULL) {
838 FreePool (Statement->Expression);
839 }
840
qhuang8c60a0612008-10-31 04:41:33 +0000841 if (Statement->VariableName != NULL) {
842 FreePool (Statement->VariableName);
843 }
844 if (Statement->BlockName != NULL) {
845 FreePool (Statement->BlockName);
846 }
lgao4b86b4132010-02-22 06:30:41 +0000847 if (Statement->BufferValue != NULL) {
848 FreePool (Statement->BufferValue);
849 }
ydong10e2100bf2010-12-23 06:47:50 +0000850 if (Statement->Operand == EFI_IFR_STRING_OP || Statement->Operand == EFI_IFR_PASSWORD_OP) {
851 DeleteString(Statement->HiiValue.Value.string, FormSet->HiiHandle);
852 }
qhuang8c60a0612008-10-31 04:41:33 +0000853}
854
855
856/**
857 Free resources of a Form.
858
ydong10e2100bf2010-12-23 06:47:50 +0000859 @param FormSet Pointer of the FormSet
qhuang8c60a0612008-10-31 04:41:33 +0000860 @param Form Pointer of the Form.
861
862**/
863VOID
864DestroyForm (
ydong10e2100bf2010-12-23 06:47:50 +0000865 IN FORM_BROWSER_FORMSET *FormSet,
866 IN OUT FORM_BROWSER_FORM *Form
qhuang8c60a0612008-10-31 04:41:33 +0000867 )
868{
869 LIST_ENTRY *Link;
870 FORM_EXPRESSION *Expression;
871 FORM_BROWSER_STATEMENT *Statement;
ydong10b18e7052011-05-31 00:59:15 +0000872 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
qhuang8c60a0612008-10-31 04:41:33 +0000873
874 //
875 // Free Form Expressions
876 //
877 while (!IsListEmpty (&Form->ExpressionListHead)) {
878 Link = GetFirstNode (&Form->ExpressionListHead);
879 Expression = FORM_EXPRESSION_FROM_LINK (Link);
880 RemoveEntryList (&Expression->Link);
881
882 DestroyExpression (Expression);
883 }
884
885 //
886 // Free Statements/Questions
887 //
888 while (!IsListEmpty (&Form->StatementListHead)) {
889 Link = GetFirstNode (&Form->StatementListHead);
890 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
891 RemoveEntryList (&Statement->Link);
892
ydong10e2100bf2010-12-23 06:47:50 +0000893 DestroyStatement (FormSet, Statement);
qhuang8c60a0612008-10-31 04:41:33 +0000894 }
895
896 //
ydong10b18e7052011-05-31 00:59:15 +0000897 // Free ConfigRequest string.
898 //
899 while (!IsListEmpty (&Form->ConfigRequestHead)) {
900 Link = GetFirstNode (&Form->ConfigRequestHead);
901 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
902 RemoveEntryList (&ConfigInfo->Link);
903
904 FreePool (ConfigInfo->ConfigRequest);
905 FreePool (ConfigInfo);
906 }
907
ydong1031585af2012-01-31 07:17:42 +0000908 if (Form->SuppressExpression != NULL) {
909 FreePool (Form->SuppressExpression);
910 }
911
ydong10b18e7052011-05-31 00:59:15 +0000912 //
qhuang8c60a0612008-10-31 04:41:33 +0000913 // Free this Form
914 //
qwang12f4113e12008-11-21 06:59:58 +0000915 FreePool (Form);
qhuang8c60a0612008-10-31 04:41:33 +0000916}
917
918
919/**
920 Free resources allocated for a FormSet.
921
922 @param FormSet Pointer of the FormSet
923
924**/
925VOID
926DestroyFormSet (
927 IN OUT FORM_BROWSER_FORMSET *FormSet
928 )
929{
930 LIST_ENTRY *Link;
931 FORMSET_STORAGE *Storage;
932 FORMSET_DEFAULTSTORE *DefaultStore;
lgao40c66bc72009-11-12 01:16:12 +0000933 FORM_EXPRESSION *Expression;
qhuang8c60a0612008-10-31 04:41:33 +0000934 FORM_BROWSER_FORM *Form;
935
xdu24c8358c2009-11-13 05:40:21 +0000936 if (FormSet->IfrBinaryData == NULL) {
937 //
938 // Uninitialized FormSet
939 //
940 FreePool (FormSet);
941 return;
942 }
943
qhuang8c60a0612008-10-31 04:41:33 +0000944 //
945 // Free IFR binary buffer
946 //
947 FreePool (FormSet->IfrBinaryData);
948
949 //
950 // Free FormSet Storage
951 //
952 if (FormSet->StorageListHead.ForwardLink != NULL) {
953 while (!IsListEmpty (&FormSet->StorageListHead)) {
954 Link = GetFirstNode (&FormSet->StorageListHead);
955 Storage = FORMSET_STORAGE_FROM_LINK (Link);
956 RemoveEntryList (&Storage->Link);
957
958 DestroyStorage (Storage);
959 }
960 }
961
962 //
963 // Free FormSet Default Store
964 //
965 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
966 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
967 Link = GetFirstNode (&FormSet->DefaultStoreListHead);
968 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);
969 RemoveEntryList (&DefaultStore->Link);
970
qwang12f4113e12008-11-21 06:59:58 +0000971 FreePool (DefaultStore);
qhuang8c60a0612008-10-31 04:41:33 +0000972 }
973 }
974
975 //
lgao40c66bc72009-11-12 01:16:12 +0000976 // Free Formset Expressions
977 //
978 while (!IsListEmpty (&FormSet->ExpressionListHead)) {
979 Link = GetFirstNode (&FormSet->ExpressionListHead);
980 Expression = FORM_EXPRESSION_FROM_LINK (Link);
981 RemoveEntryList (&Expression->Link);
982
983 DestroyExpression (Expression);
984 }
985
986 //
qhuang8c60a0612008-10-31 04:41:33 +0000987 // Free Forms
988 //
989 if (FormSet->FormListHead.ForwardLink != NULL) {
990 while (!IsListEmpty (&FormSet->FormListHead)) {
991 Link = GetFirstNode (&FormSet->FormListHead);
992 Form = FORM_BROWSER_FORM_FROM_LINK (Link);
993 RemoveEntryList (&Form->Link);
994
ydong10e2100bf2010-12-23 06:47:50 +0000995 DestroyForm (FormSet, Form);
qhuang8c60a0612008-10-31 04:41:33 +0000996 }
997 }
998
999 if (FormSet->StatementBuffer != NULL) {
1000 FreePool (FormSet->StatementBuffer);
1001 }
1002 if (FormSet->ExpressionBuffer != NULL) {
1003 FreePool (FormSet->ExpressionBuffer);
1004 }
1005
1006 FreePool (FormSet);
1007}
1008
1009
1010/**
1011 Tell whether this Operand is an Expression OpCode or not
1012
1013 @param Operand Operand of an IFR OpCode.
1014
1015 @retval TRUE This is an Expression OpCode.
1016 @retval FALSE Not an Expression OpCode.
1017
1018**/
1019BOOLEAN
1020IsExpressionOpCode (
1021 IN UINT8 Operand
1022 )
1023{
1024 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||
lgao425737122010-02-25 10:10:59 +00001025 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) ||
1026 ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||
qhuang8c60a0612008-10-31 04:41:33 +00001027 (Operand == EFI_IFR_CATENATE_OP) ||
1028 (Operand == EFI_IFR_TO_LOWER_OP) ||
1029 (Operand == EFI_IFR_TO_UPPER_OP) ||
lgao425737122010-02-25 10:10:59 +00001030 (Operand == EFI_IFR_MAP_OP) ||
rsun3cbf73e52009-11-26 09:26:42 +00001031 (Operand == EFI_IFR_VERSION_OP) ||
1032 (Operand == EFI_IFR_SECURITY_OP)) {
qhuang8c60a0612008-10-31 04:41:33 +00001033 return TRUE;
1034 } else {
1035 return FALSE;
1036 }
1037}
1038
Eric Dong077c7ae2013-12-17 08:33:06 +00001039/**
1040 Tell whether this Operand is an Statement OpCode.
1041
1042 @param Operand Operand of an IFR OpCode.
1043
1044 @retval TRUE This is an Statement OpCode.
1045 @retval FALSE Not an Statement OpCode.
1046
1047**/
1048BOOLEAN
1049IsStatementOpCode (
1050 IN UINT8 Operand
1051 )
1052{
1053 if ((Operand == EFI_IFR_SUBTITLE_OP) ||
1054 (Operand == EFI_IFR_TEXT_OP) ||
1055 (Operand == EFI_IFR_RESET_BUTTON_OP) ||
1056 (Operand == EFI_IFR_REF_OP) ||
1057 (Operand == EFI_IFR_ACTION_OP) ||
1058 (Operand == EFI_IFR_NUMERIC_OP) ||
1059 (Operand == EFI_IFR_ORDERED_LIST_OP) ||
1060 (Operand == EFI_IFR_CHECKBOX_OP) ||
1061 (Operand == EFI_IFR_STRING_OP) ||
1062 (Operand == EFI_IFR_PASSWORD_OP) ||
1063 (Operand == EFI_IFR_DATE_OP) ||
1064 (Operand == EFI_IFR_TIME_OP) ||
1065 (Operand == EFI_IFR_GUID_OP) ||
1066 (Operand == EFI_IFR_ONE_OF_OP)) {
1067 return TRUE;
1068 } else {
1069 return FALSE;
1070 }
1071}
qhuang8c60a0612008-10-31 04:41:33 +00001072
1073/**
1074 Calculate number of Statemens(Questions) and Expression OpCodes.
1075
1076 @param FormSet The FormSet to be counted.
1077 @param NumberOfStatement Number of Statemens(Questions)
1078 @param NumberOfExpression Number of Expression OpCodes
1079
1080**/
1081VOID
1082CountOpCodes (
1083 IN FORM_BROWSER_FORMSET *FormSet,
1084 IN OUT UINT16 *NumberOfStatement,
1085 IN OUT UINT16 *NumberOfExpression
1086 )
1087{
1088 UINT16 StatementCount;
1089 UINT16 ExpressionCount;
1090 UINT8 *OpCodeData;
1091 UINTN Offset;
1092 UINTN OpCodeLen;
1093
1094 Offset = 0;
1095 StatementCount = 0;
1096 ExpressionCount = 0;
1097
1098 while (Offset < FormSet->IfrBinaryLength) {
1099 OpCodeData = FormSet->IfrBinaryData + Offset;
1100 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
1101 Offset += OpCodeLen;
1102
1103 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {
1104 ExpressionCount++;
1105 } else {
1106 StatementCount++;
1107 }
1108 }
1109
1110 *NumberOfStatement = StatementCount;
1111 *NumberOfExpression = ExpressionCount;
1112}
1113
1114
1115
1116/**
1117 Parse opcodes in the formset IFR binary.
1118
1119 @param FormSet Pointer of the FormSet data structure.
1120
1121 @retval EFI_SUCCESS Opcode parse success.
1122 @retval Other Opcode parse fail.
1123
1124**/
1125EFI_STATUS
1126ParseOpCodes (
1127 IN FORM_BROWSER_FORMSET *FormSet
1128 )
1129{
1130 EFI_STATUS Status;
qhuang8c60a0612008-10-31 04:41:33 +00001131 FORM_BROWSER_FORM *CurrentForm;
1132 FORM_BROWSER_STATEMENT *CurrentStatement;
Eric Dong077c7ae2013-12-17 08:33:06 +00001133 FORM_BROWSER_STATEMENT *ParentStatement;
qhuang8c60a0612008-10-31 04:41:33 +00001134 EXPRESSION_OPCODE *ExpressionOpCode;
1135 FORM_EXPRESSION *CurrentExpression;
1136 UINT8 Operand;
1137 UINT8 Scope;
1138 UINTN OpCodeOffset;
1139 UINTN OpCodeLength;
1140 UINT8 *OpCodeData;
1141 UINT8 ScopeOpCode;
1142 FORMSET_STORAGE *Storage;
1143 FORMSET_DEFAULTSTORE *DefaultStore;
1144 QUESTION_DEFAULT *CurrentDefault;
1145 QUESTION_OPTION *CurrentOption;
xdu2d02847d2009-10-26 03:03:47 +00001146 UINT8 Width;
qhuang8c60a0612008-10-31 04:41:33 +00001147 UINT16 NumberOfStatement;
1148 UINT16 NumberOfExpression;
1149 EFI_IMAGE_ID *ImageId;
lgao40c66bc72009-11-12 01:16:12 +00001150 BOOLEAN SuppressForQuestion;
qhuang8c60a0612008-10-31 04:41:33 +00001151 BOOLEAN SuppressForOption;
qhuang8c60a0612008-10-31 04:41:33 +00001152 UINT16 DepthOfDisable;
1153 BOOLEAN OpCodeDisabled;
1154 BOOLEAN SingleOpCodeExpression;
1155 BOOLEAN InScopeDefault;
1156 EFI_HII_VALUE *Value;
lgao425737122010-02-25 10:10:59 +00001157 EFI_IFR_FORM_MAP_METHOD *MapMethod;
1158 UINT8 MapScopeDepth;
1159 LIST_ENTRY *Link;
1160 FORMSET_STORAGE *VarStorage;
1161 LIST_ENTRY *MapExpressionList;
1162 EFI_VARSTORE_ID TempVarstoreId;
ydong1031585af2012-01-31 07:17:42 +00001163 BOOLEAN InScopeDisable;
1164 INTN ConditionalExprCount;
qhuang8c60a0612008-10-31 04:41:33 +00001165
lgao40c66bc72009-11-12 01:16:12 +00001166 SuppressForQuestion = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +00001167 SuppressForOption = FALSE;
ydong1031585af2012-01-31 07:17:42 +00001168 InScopeDisable = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +00001169 DepthOfDisable = 0;
1170 OpCodeDisabled = FALSE;
1171 SingleOpCodeExpression = FALSE;
1172 InScopeDefault = FALSE;
1173 CurrentExpression = NULL;
1174 CurrentDefault = NULL;
1175 CurrentOption = NULL;
qwang12c4105892009-02-06 06:34:43 +00001176 ImageId = NULL;
lgao425737122010-02-25 10:10:59 +00001177 MapMethod = NULL;
1178 MapScopeDepth = 0;
1179 Link = NULL;
1180 VarStorage = NULL;
1181 MapExpressionList = NULL;
1182 TempVarstoreId = 0;
ydong1031585af2012-01-31 07:17:42 +00001183 ConditionalExprCount = 0;
qhuang8c60a0612008-10-31 04:41:33 +00001184
1185 //
1186 // Get the number of Statements and Expressions
1187 //
1188 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
1189
1190 mStatementIndex = 0;
Eric Dong7c6c0642013-08-12 02:19:56 +00001191 mUsedQuestionId = 1;
qhuang8c60a0612008-10-31 04:41:33 +00001192 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
1193 if (FormSet->StatementBuffer == NULL) {
1194 return EFI_OUT_OF_RESOURCES;
1195 }
1196
1197 mExpressionOpCodeIndex = 0;
1198 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));
1199 if (FormSet->ExpressionBuffer == NULL) {
1200 return EFI_OUT_OF_RESOURCES;
1201 }
1202
Eric Dong7c6c0642013-08-12 02:19:56 +00001203 InitializeListHead (&FormSet->StatementListOSF);
qhuang8c60a0612008-10-31 04:41:33 +00001204 InitializeListHead (&FormSet->StorageListHead);
1205 InitializeListHead (&FormSet->DefaultStoreListHead);
1206 InitializeListHead (&FormSet->FormListHead);
lgao448a9d5f2011-09-13 09:32:54 +00001207 InitializeListHead (&FormSet->ExpressionListHead);
lgao425737122010-02-25 10:10:59 +00001208 ResetCurrentExpressionStack ();
1209 ResetMapExpressionListStack ();
qhuang8c60a0612008-10-31 04:41:33 +00001210
1211 CurrentForm = NULL;
1212 CurrentStatement = NULL;
Eric Dong077c7ae2013-12-17 08:33:06 +00001213 ParentStatement = NULL;
qhuang8c60a0612008-10-31 04:41:33 +00001214
1215 ResetScopeStack ();
1216
1217 OpCodeOffset = 0;
1218 while (OpCodeOffset < FormSet->IfrBinaryLength) {
1219 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;
1220
1221 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
1222 OpCodeOffset += OpCodeLength;
1223 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
1224 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;
1225
1226 //
1227 // If scope bit set, push onto scope stack
1228 //
1229 if (Scope != 0) {
1230 PushScope (Operand);
1231 }
1232
1233 if (OpCodeDisabled) {
1234 //
1235 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1236 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1237 //
1238 if (Operand == EFI_IFR_DISABLE_IF_OP) {
1239 DepthOfDisable++;
1240 } else if (Operand == EFI_IFR_END_OP) {
1241 Status = PopScope (&ScopeOpCode);
1242 if (EFI_ERROR (Status)) {
1243 return Status;
1244 }
1245
1246 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {
1247 if (DepthOfDisable == 0) {
ydong1031585af2012-01-31 07:17:42 +00001248 InScopeDisable = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +00001249 OpCodeDisabled = FALSE;
1250 } else {
1251 DepthOfDisable--;
1252 }
1253 }
1254 }
1255 continue;
1256 }
1257
1258 if (IsExpressionOpCode (Operand)) {
1259 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];
1260 mExpressionOpCodeIndex++;
1261
1262 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;
1263 ExpressionOpCode->Operand = Operand;
1264 Value = &ExpressionOpCode->Value;
1265
1266 switch (Operand) {
1267 case EFI_IFR_EQ_ID_VAL_OP:
1268 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1269
1270 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1271 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));
1272 break;
1273
1274 case EFI_IFR_EQ_ID_ID_OP:
1275 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));
1276 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));
1277 break;
1278
ydong10e8ef4282012-01-12 13:03:56 +00001279 case EFI_IFR_EQ_ID_VAL_LIST_OP:
qhuang82654f642009-09-21 14:15:35 +00001280 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1281 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));
1282 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);
qhuang8c60a0612008-10-31 04:41:33 +00001283 break;
1284
1285 case EFI_IFR_TO_STRING_OP:
1286 case EFI_IFR_FIND_OP:
1287 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;
1288 break;
1289
1290 case EFI_IFR_STRING_REF1_OP:
1291 Value->Type = EFI_IFR_TYPE_STRING;
1292 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));
1293 break;
1294
1295 case EFI_IFR_RULE_REF_OP:
1296 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;
1297 break;
1298
1299 case EFI_IFR_SPAN_OP:
1300 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;
1301 break;
1302
1303 case EFI_IFR_THIS_OP:
Eric Dong077c7ae2013-12-17 08:33:06 +00001304 ASSERT (ParentStatement != NULL);
1305 ExpressionOpCode->QuestionId = ParentStatement->QuestionId;
qhuang8c60a0612008-10-31 04:41:33 +00001306 break;
1307
rsun3cbf73e52009-11-26 09:26:42 +00001308 case EFI_IFR_SECURITY_OP:
1309 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));
1310 break;
1311
lgao425737122010-02-25 10:10:59 +00001312 case EFI_IFR_GET_OP:
1313 case EFI_IFR_SET_OP:
1314 CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));
1315 if (TempVarstoreId != 0) {
1316 if (FormSet->StorageListHead.ForwardLink != NULL) {
1317 Link = GetFirstNode (&FormSet->StorageListHead);
1318 while (!IsNull (&FormSet->StorageListHead, Link)) {
1319 VarStorage = FORMSET_STORAGE_FROM_LINK (Link);
1320 if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {
ydong1094f3aae2013-04-16 10:53:22 +00001321 ExpressionOpCode->VarStorage = VarStorage->BrowserStorage;
lgao425737122010-02-25 10:10:59 +00001322 break;
1323 }
1324 Link = GetNextNode (&FormSet->StorageListHead, Link);
1325 }
1326 }
1327 if (ExpressionOpCode->VarStorage == NULL) {
1328 //
1329 // VarStorage is not found.
1330 //
1331 return EFI_INVALID_PARAMETER;
1332 }
1333 }
1334 ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;
1335 switch (ExpressionOpCode->ValueType) {
1336 case EFI_IFR_TYPE_BOOLEAN:
1337 case EFI_IFR_TYPE_NUM_SIZE_8:
1338 ExpressionOpCode->ValueWidth = 1;
1339 break;
1340
1341 case EFI_IFR_TYPE_NUM_SIZE_16:
1342 case EFI_IFR_TYPE_STRING:
1343 ExpressionOpCode->ValueWidth = 2;
1344 break;
1345
1346 case EFI_IFR_TYPE_NUM_SIZE_32:
1347 ExpressionOpCode->ValueWidth = 4;
1348 break;
1349
1350 case EFI_IFR_TYPE_NUM_SIZE_64:
1351 ExpressionOpCode->ValueWidth = 8;
1352 break;
1353
1354 case EFI_IFR_TYPE_DATE:
ydong10c9325702010-09-15 07:48:11 +00001355 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE);
lgao425737122010-02-25 10:10:59 +00001356 break;
1357
1358 case EFI_IFR_TYPE_TIME:
ydong10c9325702010-09-15 07:48:11 +00001359 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);
lgao425737122010-02-25 10:10:59 +00001360 break;
1361
ydong108ca61802011-06-28 06:41:28 +00001362 case EFI_IFR_TYPE_REF:
1363 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);
1364 break;
1365
lgao425737122010-02-25 10:10:59 +00001366 case EFI_IFR_TYPE_OTHER:
1367 case EFI_IFR_TYPE_UNDEFINED:
1368 case EFI_IFR_TYPE_ACTION:
1369 case EFI_IFR_TYPE_BUFFER:
1370 default:
1371 //
1372 // Invalid value type for Get/Set opcode.
1373 //
1374 return EFI_INVALID_PARAMETER;
1375 }
1376 CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID));
1377 CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));
1378 if ((ExpressionOpCode->VarStorage != NULL) &&
1379 (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE ||
1380 ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
1381 ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);
1382 if (ExpressionOpCode->ValueName == NULL) {
1383 //
1384 // String ID is invalid.
1385 //
1386 return EFI_INVALID_PARAMETER;
1387 }
1388 }
1389 break;
1390
qhuang8c60a0612008-10-31 04:41:33 +00001391 case EFI_IFR_QUESTION_REF1_OP:
qhuang82654f642009-09-21 14:15:35 +00001392 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
qhuang8c60a0612008-10-31 04:41:33 +00001393 break;
1394
1395 case EFI_IFR_QUESTION_REF3_OP:
1396 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {
1397 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1398
1399 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {
1400 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));
1401 }
1402 }
1403 break;
1404
1405 //
1406 // constant
1407 //
1408 case EFI_IFR_TRUE_OP:
1409 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1410 Value->Value.b = TRUE;
1411 break;
1412
1413 case EFI_IFR_FALSE_OP:
1414 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1415 Value->Value.b = FALSE;
1416 break;
1417
1418 case EFI_IFR_ONE_OP:
1419 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1420 Value->Value.u8 = 1;
1421 break;
1422
1423 case EFI_IFR_ZERO_OP:
1424 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1425 Value->Value.u8 = 0;
1426 break;
1427
1428 case EFI_IFR_ONES_OP:
1429 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1430 Value->Value.u64 = 0xffffffffffffffffULL;
1431 break;
1432
1433 case EFI_IFR_UINT8_OP:
1434 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1435 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;
1436 break;
1437
1438 case EFI_IFR_UINT16_OP:
1439 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1440 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));
1441 break;
1442
1443 case EFI_IFR_UINT32_OP:
1444 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1445 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));
1446 break;
1447
1448 case EFI_IFR_UINT64_OP:
1449 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1450 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));
1451 break;
1452
1453 case EFI_IFR_UNDEFINED_OP:
xdu2d02847d2009-10-26 03:03:47 +00001454 Value->Type = EFI_IFR_TYPE_UNDEFINED;
qhuang8c60a0612008-10-31 04:41:33 +00001455 break;
1456
1457 case EFI_IFR_VERSION_OP:
1458 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1459 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;
1460 break;
1461
1462 default:
1463 break;
1464 }
lgao425737122010-02-25 10:10:59 +00001465 //
1466 // Create sub expression nested in MAP opcode
1467 //
1468 if (CurrentExpression == NULL && MapScopeDepth > 0) {
1469 CurrentExpression = CreateExpression (CurrentForm);
lgao4771ecec2010-02-27 09:04:11 +00001470 ASSERT (MapExpressionList != NULL);
lgao425737122010-02-25 10:10:59 +00001471 InsertTailList (MapExpressionList, &CurrentExpression->Link);
1472 if (Scope == 0) {
1473 SingleOpCodeExpression = TRUE;
1474 }
1475 }
xdu2f8a1c222009-10-20 03:01:10 +00001476 ASSERT (CurrentExpression != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001477 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);
lgao425737122010-02-25 10:10:59 +00001478 if (Operand == EFI_IFR_MAP_OP) {
1479 //
1480 // Store current Map Expression List.
1481 //
1482 if (MapExpressionList != NULL) {
1483 PushMapExpressionList (MapExpressionList);
1484 }
1485 //
1486 // Initialize new Map Expression List.
1487 //
1488 MapExpressionList = &ExpressionOpCode->MapExpressionList;
1489 InitializeListHead (MapExpressionList);
1490 //
1491 // Store current expression.
1492 //
1493 PushCurrentExpression (CurrentExpression);
1494 CurrentExpression = NULL;
1495 MapScopeDepth ++;
1496 } else if (SingleOpCodeExpression) {
qhuang8c60a0612008-10-31 04:41:33 +00001497 //
1498 // There are two cases to indicate the end of an Expression:
1499 // for single OpCode expression: one Expression OpCode
1500 // for expression consists of more than one OpCode: EFI_IFR_END
1501 //
1502 SingleOpCodeExpression = FALSE;
1503
ydong1031585af2012-01-31 07:17:42 +00001504 if (InScopeDisable && CurrentForm == NULL) {
qhuang8c60a0612008-10-31 04:41:33 +00001505 //
lgao40a1147e2009-04-22 03:18:37 +00001506 // This is DisableIf expression for Form, it should be a constant expression
qhuang8c60a0612008-10-31 04:41:33 +00001507 //
1508 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
1509 if (EFI_ERROR (Status)) {
1510 return Status;
1511 }
qwang12c4105892009-02-06 06:34:43 +00001512
qhuang8c60a0612008-10-31 04:41:33 +00001513 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
1514 return EFI_INVALID_PARAMETER;
1515 }
1516
1517 OpCodeDisabled = CurrentExpression->Result.Value.b;
1518 }
1519
1520 CurrentExpression = NULL;
1521 }
1522
1523 continue;
1524 }
1525
1526 //
1527 // Parse the Opcode
1528 //
1529 switch (Operand) {
1530
1531 case EFI_IFR_FORM_SET_OP:
1532 //
xdu2f8a1c222009-10-20 03:01:10 +00001533 // Check the formset GUID
qhuang8c60a0612008-10-31 04:41:33 +00001534 //
1535 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {
1536 return EFI_INVALID_PARAMETER;
1537 }
1538
1539 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
1540 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
lgao40a1147e2009-04-22 03:18:37 +00001541
lgao4d2285262010-02-02 01:38:00 +00001542 if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
1543 //
1544 // The formset OpCode contains ClassGuid
1545 //
1546 FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);
1547 CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));
1548 }
qhuang8c60a0612008-10-31 04:41:33 +00001549 break;
1550
1551 case EFI_IFR_FORM_OP:
1552 //
1553 // Create a new Form for this FormSet
1554 //
1555 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
jji41ac628e2009-01-19 07:58:58 +00001556 ASSERT (CurrentForm != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001557 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1558 InitializeListHead (&CurrentForm->ExpressionListHead);
1559 InitializeListHead (&CurrentForm->StatementListHead);
ydong10b18e7052011-05-31 00:59:15 +00001560 InitializeListHead (&CurrentForm->ConfigRequestHead);
qhuang8c60a0612008-10-31 04:41:33 +00001561
lgao425737122010-02-25 10:10:59 +00001562 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
qhuang8c60a0612008-10-31 04:41:33 +00001563 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1564 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
1565
ydong1031585af2012-01-31 07:17:42 +00001566 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
1567 if ( ConditionalExprCount > 0) {
lgao40c66bc72009-11-12 01:16:12 +00001568 //
1569 // Form is inside of suppressif
1570 //
ydong1031585af2012-01-31 07:17:42 +00001571 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1572 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1573 ASSERT (CurrentForm->SuppressExpression != NULL);
1574 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1575 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1576 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
lgao40c66bc72009-11-12 01:16:12 +00001577 }
1578
1579 if (Scope != 0) {
1580 //
1581 // Enter scope of a Form, suppressif will be used for Question or Option
1582 //
1583 SuppressForQuestion = TRUE;
1584 }
1585
qhuang8c60a0612008-10-31 04:41:33 +00001586 //
1587 // Insert into Form list of this FormSet
1588 //
1589 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1590 break;
1591
lgao425737122010-02-25 10:10:59 +00001592 case EFI_IFR_FORM_MAP_OP:
1593 //
1594 // Create a new Form for this FormSet
1595 //
1596 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1597 ASSERT (CurrentForm != NULL);
1598 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1599 InitializeListHead (&CurrentForm->ExpressionListHead);
1600 InitializeListHead (&CurrentForm->StatementListHead);
ydong10b18e7052011-05-31 00:59:15 +00001601 InitializeListHead (&CurrentForm->ConfigRequestHead);
lgao425737122010-02-25 10:10:59 +00001602 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1603
1604 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1605 //
1606 // FormMap Form must contain at least one Map Method.
1607 //
1608 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {
1609 return EFI_INVALID_PARAMETER;
1610 }
1611 //
1612 // Try to find the standard form map method.
1613 //
1614 while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {
1615 if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {
1616 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1617 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1618 break;
1619 }
1620 MapMethod ++;
1621 }
1622 //
1623 // If the standard form map method is not found, the first map method title will be used.
1624 //
1625 if (CurrentForm->FormTitle == 0) {
1626 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1627 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1628 }
1629
ydong1031585af2012-01-31 07:17:42 +00001630 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
1631 if ( ConditionalExprCount > 0) {
lgao425737122010-02-25 10:10:59 +00001632 //
1633 // Form is inside of suppressif
1634 //
ydong1031585af2012-01-31 07:17:42 +00001635 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1636 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1637 ASSERT (CurrentForm->SuppressExpression != NULL);
1638 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1639 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1640 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
lgao425737122010-02-25 10:10:59 +00001641 }
1642
1643 if (Scope != 0) {
1644 //
1645 // Enter scope of a Form, suppressif will be used for Question or Option
1646 //
1647 SuppressForQuestion = TRUE;
1648 }
1649
1650 //
1651 // Insert into Form list of this FormSet
1652 //
1653 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1654 break;
1655
qhuang8c60a0612008-10-31 04:41:33 +00001656 //
1657 // Storage
1658 //
1659 case EFI_IFR_VARSTORE_OP:
1660 //
1661 // Create a buffer Storage for this FormSet
1662 //
ydong1094f3aae2013-04-16 10:53:22 +00001663 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_BUFFER, OpCodeData);
qhuang8c60a0612008-10-31 04:41:33 +00001664 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
qhuang8c60a0612008-10-31 04:41:33 +00001665 break;
1666
1667 case EFI_IFR_VARSTORE_NAME_VALUE_OP:
1668 //
1669 // Create a name/value Storage for this FormSet
1670 //
ydong1094f3aae2013-04-16 10:53:22 +00001671 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_NAME_VALUE, OpCodeData);
qhuang8c60a0612008-10-31 04:41:33 +00001672 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
qhuang8c60a0612008-10-31 04:41:33 +00001673 break;
1674
1675 case EFI_IFR_VARSTORE_EFI_OP:
1676 //
1677 // Create a EFI variable Storage for this FormSet
1678 //
ydong10cce62302011-07-12 07:24:36 +00001679 if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) {
Eric Dongc0462ea2013-08-23 05:54:33 +00001680 //
1681 // Create efi varstore with format follow UEFI spec before 2.3.1.
1682 //
ydong1094f3aae2013-04-16 10:53:22 +00001683 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE, OpCodeData);
1684 } else {
Eric Dongc0462ea2013-08-23 05:54:33 +00001685 //
1686 // Create efi varstore with format follow UEFI spec 2.3.1 and later.
1687 //
ydong1094f3aae2013-04-16 10:53:22 +00001688 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER, OpCodeData);
ydong10cce62302011-07-12 07:24:36 +00001689 }
ydong1094f3aae2013-04-16 10:53:22 +00001690 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
qhuang8c60a0612008-10-31 04:41:33 +00001691 break;
1692
1693 //
1694 // DefaultStore
1695 //
1696 case EFI_IFR_DEFAULTSTORE_OP:
1697 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
jji41ac628e2009-01-19 07:58:58 +00001698 ASSERT (DefaultStore != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001699 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
1700
1701 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));
1702 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
1703
1704 //
1705 // Insert to DefaultStore list of this Formset
1706 //
1707 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
1708 break;
1709
1710 //
1711 // Statements
1712 //
1713 case EFI_IFR_SUBTITLE_OP:
1714 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
qwang12bc166db2009-02-02 07:18:59 +00001715 ASSERT (CurrentStatement != NULL);
xdu28b0fc5c2009-10-26 03:05:16 +00001716
qhuang8c60a0612008-10-31 04:41:33 +00001717 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
Eric Dong7c6c0642013-08-12 02:19:56 +00001718 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
qhuang8c60a0612008-10-31 04:41:33 +00001719 break;
1720
1721 case EFI_IFR_TEXT_OP:
1722 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
qwang12bc166db2009-02-02 07:18:59 +00001723 ASSERT (CurrentStatement != NULL);
Eric Dong7c6c0642013-08-12 02:19:56 +00001724 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
qhuang8c60a0612008-10-31 04:41:33 +00001725 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
1726 break;
1727
xdu2f8a1c222009-10-20 03:01:10 +00001728 case EFI_IFR_RESET_BUTTON_OP:
1729 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1730 ASSERT (CurrentStatement != NULL);
Eric Dong7c6c0642013-08-12 02:19:56 +00001731 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
xdu2f8a1c222009-10-20 03:01:10 +00001732 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
1733 break;
1734
qhuang8c60a0612008-10-31 04:41:33 +00001735 //
1736 // Questions
1737 //
1738 case EFI_IFR_ACTION_OP:
1739 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
qwang12bc166db2009-02-02 07:18:59 +00001740 ASSERT (CurrentStatement != NULL);
xdu2d02847d2009-10-26 03:03:47 +00001741 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;
qhuang8c60a0612008-10-31 04:41:33 +00001742
1743 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
1744 //
1745 // No QuestionConfig present, so no configuration string will be processed
1746 //
1747 CurrentStatement->QuestionConfig = 0;
1748 } else {
1749 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
1750 }
1751 break;
1752
qhuang8c60a0612008-10-31 04:41:33 +00001753 case EFI_IFR_REF_OP:
1754 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001755 ASSERT (CurrentStatement != NULL);
ydong108ca61802011-06-28 06:41:28 +00001756 Value = &CurrentStatement->HiiValue;
1757 Value->Type = EFI_IFR_TYPE_REF;
1758 if (OpCodeLength >= sizeof (EFI_IFR_REF)) {
1759 CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
qhuang8c60a0612008-10-31 04:41:33 +00001760
ydong108ca61802011-06-28 06:41:28 +00001761 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
1762 CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
qhuang8c60a0612008-10-31 04:41:33 +00001763
ydong108ca61802011-06-28 06:41:28 +00001764 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
1765 CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
1766
1767 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
1768 CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1769 }
qhuang8c60a0612008-10-31 04:41:33 +00001770 }
1771 }
1772 }
ydong108ca61802011-06-28 06:41:28 +00001773 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);
1774 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001775 break;
1776
1777 case EFI_IFR_ONE_OF_OP:
1778 case EFI_IFR_NUMERIC_OP:
1779 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidy945e3ae2009-05-13 09:24:25 +00001780 ASSERT(CurrentStatement != NULL);
xdu28b0fc5c2009-10-26 03:05:16 +00001781
qhuang8c60a0612008-10-31 04:41:33 +00001782 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
1783 Value = &CurrentStatement->HiiValue;
1784
1785 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
1786 case EFI_IFR_NUMERIC_SIZE_1:
1787 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
1788 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
1789 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
ydong10cd7bfc22010-09-16 04:51:25 +00001790 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);
qhuang8c60a0612008-10-31 04:41:33 +00001791 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1792 break;
1793
1794 case EFI_IFR_NUMERIC_SIZE_2:
1795 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
1796 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
1797 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));
ydong10cd7bfc22010-09-16 04:51:25 +00001798 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);
qhuang8c60a0612008-10-31 04:41:33 +00001799 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1800 break;
1801
1802 case EFI_IFR_NUMERIC_SIZE_4:
1803 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
1804 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
1805 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));
ydong10cd7bfc22010-09-16 04:51:25 +00001806 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);
qhuang8c60a0612008-10-31 04:41:33 +00001807 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1808 break;
1809
1810 case EFI_IFR_NUMERIC_SIZE_8:
1811 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
1812 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
1813 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));
ydong10cd7bfc22010-09-16 04:51:25 +00001814 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);
qhuang8c60a0612008-10-31 04:41:33 +00001815 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1816 break;
1817
1818 default:
1819 break;
1820 }
1821
ydong10b18e7052011-05-31 00:59:15 +00001822 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001823
1824 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {
1825 SuppressForOption = TRUE;
1826 }
1827 break;
1828
1829 case EFI_IFR_ORDERED_LIST_OP:
1830 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001831 ASSERT(CurrentStatement != NULL);
xdu28b0fc5c2009-10-26 03:05:16 +00001832
qhuang8c60a0612008-10-31 04:41:33 +00001833 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;
1834 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;
qhuang8c60a0612008-10-31 04:41:33 +00001835
xdu2d02847d2009-10-26 03:03:47 +00001836 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;
lgao4b86b4132010-02-22 06:30:41 +00001837 CurrentStatement->BufferValue = NULL;
qhuang8c60a0612008-10-31 04:41:33 +00001838
1839 if (Scope != 0) {
1840 SuppressForOption = TRUE;
1841 }
1842 break;
1843
1844 case EFI_IFR_CHECKBOX_OP:
1845 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001846 ASSERT(CurrentStatement != NULL);
xdu28b0fc5c2009-10-26 03:05:16 +00001847
qhuang8c60a0612008-10-31 04:41:33 +00001848 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;
ydong10cd7bfc22010-09-16 04:51:25 +00001849 CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);
qhuang8c60a0612008-10-31 04:41:33 +00001850 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
1851
ydong10b18e7052011-05-31 00:59:15 +00001852 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001853
1854 break;
1855
1856 case EFI_IFR_STRING_OP:
1857 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001858 ASSERT (CurrentStatement != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001859 //
1860 // MinSize is the minimum number of characters that can be accepted for this opcode,
1861 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1862 // The characters are stored as Unicode, so the storage width should multiply 2.
1863 //
1864 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;
1865 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;
1866 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
1867 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;
1868
1869 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1870 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));
ydong10e2100bf2010-12-23 06:47:50 +00001871 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
qhuang8c60a0612008-10-31 04:41:33 +00001872
ydong10b18e7052011-05-31 00:59:15 +00001873 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001874 break;
1875
1876 case EFI_IFR_PASSWORD_OP:
1877 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001878 ASSERT (CurrentStatement != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001879 //
1880 // MinSize is the minimum number of characters that can be accepted for this opcode,
1881 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1882 // The characters are stored as Unicode, so the storage width should multiply 2.
1883 //
1884 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));
1885 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));
1886 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
1887
1888 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1889 CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));
ydong10e2100bf2010-12-23 06:47:50 +00001890 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
qhuang8c60a0612008-10-31 04:41:33 +00001891
ydong10b18e7052011-05-31 00:59:15 +00001892 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001893 break;
1894
1895 case EFI_IFR_DATE_OP:
1896 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001897 ASSERT(CurrentStatement != NULL);
xdu28b0fc5c2009-10-26 03:05:16 +00001898
qhuang8c60a0612008-10-31 04:41:33 +00001899 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;
1900 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
1901
1902 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {
ydong10cd7bfc22010-09-16 04:51:25 +00001903 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);
qhuang8c60a0612008-10-31 04:41:33 +00001904
ydong10b18e7052011-05-31 00:59:15 +00001905 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001906 } else {
1907 //
1908 // Don't assign storage for RTC type of date/time
1909 //
1910 CurrentStatement->Storage = NULL;
1911 CurrentStatement->StorageWidth = 0;
1912 }
1913 break;
1914
1915 case EFI_IFR_TIME_OP:
1916 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
gikidyb347c1b2009-05-15 03:39:01 +00001917 ASSERT(CurrentStatement != NULL);
xdu28b0fc5c2009-10-26 03:05:16 +00001918
qhuang8c60a0612008-10-31 04:41:33 +00001919 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;
1920 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
1921
1922 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {
ydong105ec56d12011-05-17 01:27:05 +00001923 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);
qhuang8c60a0612008-10-31 04:41:33 +00001924
ydong10b18e7052011-05-31 00:59:15 +00001925 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00001926 } else {
1927 //
1928 // Don't assign storage for RTC type of date/time
1929 //
1930 CurrentStatement->Storage = NULL;
1931 CurrentStatement->StorageWidth = 0;
1932 }
1933 break;
1934
1935 //
1936 // Default
1937 //
1938 case EFI_IFR_DEFAULT_OP:
1939 //
1940 // EFI_IFR_DEFAULT appear in scope of a Question,
1941 // It creates a default value for the current question.
1942 // A Question may have more than one Default value which have different default types.
1943 //
1944 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
jji41ac628e2009-01-19 07:58:58 +00001945 ASSERT (CurrentDefault != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001946 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
1947
1948 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
1949 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
ydong1023fe74d2012-12-17 03:30:43 +00001950 if (OpCodeLength > OFFSET_OF (EFI_IFR_DEFAULT, Value)) {
1951 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));
ydong104706ff42012-09-27 11:19:56 +00001952 ExtendValueToU64 (&CurrentDefault->Value);
1953 }
qhuang8c60a0612008-10-31 04:41:33 +00001954
1955 //
1956 // Insert to Default Value list of current Question
1957 //
Eric Dong077c7ae2013-12-17 08:33:06 +00001958 InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);
qhuang8c60a0612008-10-31 04:41:33 +00001959
1960 if (Scope != 0) {
1961 InScopeDefault = TRUE;
1962 }
1963 break;
1964
1965 //
1966 // Option
1967 //
1968 case EFI_IFR_ONE_OF_OPTION_OP:
1969 //
1970 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1971 // It create a selection for use in current Question.
1972 //
1973 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
jji41ac628e2009-01-19 07:58:58 +00001974 ASSERT (CurrentOption != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001975 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
Eric Dong7c6c0642013-08-12 02:19:56 +00001976 CurrentOption->OpCode = (EFI_IFR_ONE_OF_OPTION *) OpCodeData;
qhuang8c60a0612008-10-31 04:41:33 +00001977
1978 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
1979 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
1980 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
ydong10a7f87052013-01-06 06:12:50 +00001981 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
qhuang8c60a0612008-10-31 04:41:33 +00001982 ExtendValueToU64 (&CurrentOption->Value);
1983
ydong1031585af2012-01-31 07:17:42 +00001984 ConditionalExprCount = GetConditionalExpressionCount(ExpressOption);
1985 if ( ConditionalExprCount > 0) {
1986 //
1987 // Form is inside of suppressif
1988 //
1989 CurrentOption->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1990 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1991 ASSERT (CurrentOption->SuppressExpression != NULL);
1992 CurrentOption->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1993 CurrentOption->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1994 CopyMem (CurrentOption->SuppressExpression->Expression, GetConditionalExpressionList(ExpressOption), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
qhuang8c60a0612008-10-31 04:41:33 +00001995 }
1996
Eric Dong077c7ae2013-12-17 08:33:06 +00001997 ASSERT (ParentStatement != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00001998 //
1999 // Insert to Option list of current Question
2000 //
Eric Dong077c7ae2013-12-17 08:33:06 +00002001 InsertTailList (&ParentStatement->OptionListHead, &CurrentOption->Link);
xdu2d02847d2009-10-26 03:03:47 +00002002 //
2003 // Now we know the Storage width of nested Ordered List
2004 //
Eric Dong077c7ae2013-12-17 08:33:06 +00002005 if ((ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (ParentStatement->BufferValue == NULL)) {
xdu2d02847d2009-10-26 03:03:47 +00002006 Width = 1;
2007 switch (CurrentOption->Value.Type) {
2008 case EFI_IFR_TYPE_NUM_SIZE_8:
2009 Width = 1;
2010 break;
2011
2012 case EFI_IFR_TYPE_NUM_SIZE_16:
2013 Width = 2;
2014 break;
2015
2016 case EFI_IFR_TYPE_NUM_SIZE_32:
2017 Width = 4;
2018 break;
2019
2020 case EFI_IFR_TYPE_NUM_SIZE_64:
2021 Width = 8;
2022 break;
2023
2024 default:
2025 //
2026 // Invalid type for Ordered List
2027 //
2028 break;
2029 }
2030
Eric Dong077c7ae2013-12-17 08:33:06 +00002031 ParentStatement->StorageWidth = (UINT16) (ParentStatement->MaxContainers * Width);
2032 ParentStatement->BufferValue = AllocateZeroPool (ParentStatement->StorageWidth);
2033 ParentStatement->ValueType = CurrentOption->Value.Type;
2034 if (ParentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {
2035 ParentStatement->HiiValue.Buffer = ParentStatement->BufferValue;
2036 ParentStatement->HiiValue.BufferLen = ParentStatement->StorageWidth;
ydong10901ba0e2011-11-18 07:07:31 +00002037 }
xdu2d02847d2009-10-26 03:03:47 +00002038
Eric Dong077c7ae2013-12-17 08:33:06 +00002039 InitializeRequestElement (FormSet, ParentStatement, CurrentForm);
xdu2d02847d2009-10-26 03:03:47 +00002040 }
qhuang8c60a0612008-10-31 04:41:33 +00002041 break;
2042
2043 //
2044 // Conditional
2045 //
2046 case EFI_IFR_NO_SUBMIT_IF_OP:
2047 case EFI_IFR_INCONSISTENT_IF_OP:
2048 //
2049 // Create an Expression node
2050 //
2051 CurrentExpression = CreateExpression (CurrentForm);
2052 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));
2053
2054 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {
2055 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;
Eric Dong077c7ae2013-12-17 08:33:06 +00002056 InsertTailList (&ParentStatement->NoSubmitListHead, &CurrentExpression->Link);
qhuang8c60a0612008-10-31 04:41:33 +00002057 } else {
2058 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;
Eric Dong077c7ae2013-12-17 08:33:06 +00002059 InsertTailList (&ParentStatement->InconsistentListHead, &CurrentExpression->Link);
qhuang8c60a0612008-10-31 04:41:33 +00002060 }
lgao40c66bc72009-11-12 01:16:12 +00002061
2062 //
2063 // Take a look at next OpCode to see whether current expression consists
2064 // of single OpCode
2065 //
2066 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2067 SingleOpCodeExpression = TRUE;
2068 }
qhuang8c60a0612008-10-31 04:41:33 +00002069 break;
2070
Eric Dong1c0d3062013-09-04 04:15:10 +00002071 case EFI_IFR_WARNING_IF_OP:
2072 //
2073 // Create an Expression node
2074 //
2075 CurrentExpression = CreateExpression (CurrentForm);
2076 CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *) OpCodeData)->Warning, sizeof (EFI_STRING_ID));
2077 CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeData)->TimeOut;
2078 CurrentExpression->Type = EFI_HII_EXPRESSION_WARNING_IF;
Eric Dong077c7ae2013-12-17 08:33:06 +00002079 InsertTailList (&ParentStatement->WarningListHead, &CurrentExpression->Link);
Eric Dong1c0d3062013-09-04 04:15:10 +00002080
2081 //
2082 // Take a look at next OpCode to see whether current expression consists
2083 // of single OpCode
2084 //
2085 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2086 SingleOpCodeExpression = TRUE;
2087 }
2088 break;
2089
qhuang8c60a0612008-10-31 04:41:33 +00002090 case EFI_IFR_SUPPRESS_IF_OP:
2091 //
2092 // Question and Option will appear in scope of this OpCode
2093 //
2094 CurrentExpression = CreateExpression (CurrentForm);
2095 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;
lgao40c66bc72009-11-12 01:16:12 +00002096
2097 if (CurrentForm == NULL) {
2098 InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);
2099 } else {
2100 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2101 }
qhuang8c60a0612008-10-31 04:41:33 +00002102
2103 if (SuppressForOption) {
ydong1031585af2012-01-31 07:17:42 +00002104 PushConditionalExpression(CurrentExpression, ExpressOption);
lgao40c66bc72009-11-12 01:16:12 +00002105 } else if (SuppressForQuestion) {
ydong1031585af2012-01-31 07:17:42 +00002106 PushConditionalExpression(CurrentExpression, ExpressStatement);
lgao40c66bc72009-11-12 01:16:12 +00002107 } else {
ydong1031585af2012-01-31 07:17:42 +00002108 PushConditionalExpression(CurrentExpression, ExpressForm);
lgao40c66bc72009-11-12 01:16:12 +00002109 }
2110
2111 //
2112 // Take a look at next OpCode to see whether current expression consists
2113 // of single OpCode
2114 //
2115 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2116 SingleOpCodeExpression = TRUE;
qhuang8c60a0612008-10-31 04:41:33 +00002117 }
2118 break;
2119
2120 case EFI_IFR_GRAY_OUT_IF_OP:
2121 //
2122 // Questions will appear in scope of this OpCode
2123 //
2124 CurrentExpression = CreateExpression (CurrentForm);
2125 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;
2126 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
ydong1031585af2012-01-31 07:17:42 +00002127 PushConditionalExpression(CurrentExpression, ExpressStatement);
lgao40c66bc72009-11-12 01:16:12 +00002128
2129 //
2130 // Take a look at next OpCode to see whether current expression consists
2131 // of single OpCode
2132 //
2133 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2134 SingleOpCodeExpression = TRUE;
2135 }
qhuang8c60a0612008-10-31 04:41:33 +00002136 break;
2137
2138 case EFI_IFR_DISABLE_IF_OP:
2139 //
2140 // The DisableIf expression should only rely on constant, so it could be
2141 // evaluated at initialization and it will not be queued
2142 //
2143 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
jji41ac628e2009-01-19 07:58:58 +00002144 ASSERT (CurrentExpression != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00002145 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;
2146 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;
2147 InitializeListHead (&CurrentExpression->OpCodeListHead);
2148
lgao40a1147e2009-04-22 03:18:37 +00002149 if (CurrentForm != NULL) {
2150 //
2151 // This is DisableIf for Question, enqueue it to Form expression list
2152 //
2153 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
ydong1031585af2012-01-31 07:17:42 +00002154 PushConditionalExpression(CurrentExpression, ExpressStatement);
lgao40a1147e2009-04-22 03:18:37 +00002155 }
2156
ydong1031585af2012-01-31 07:17:42 +00002157 OpCodeDisabled = FALSE;
2158 InScopeDisable = TRUE;
qhuang8c60a0612008-10-31 04:41:33 +00002159 //
2160 // Take a look at next OpCode to see whether current expression consists
2161 // of single OpCode
2162 //
2163 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2164 SingleOpCodeExpression = TRUE;
2165 }
2166 break;
2167
2168 //
2169 // Expression
2170 //
2171 case EFI_IFR_VALUE_OP:
2172 CurrentExpression = CreateExpression (CurrentForm);
2173 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;
2174 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2175
2176 if (InScopeDefault) {
2177 //
2178 // Used for default (EFI_IFR_DEFAULT)
2179 //
2180 CurrentDefault->ValueExpression = CurrentExpression;
2181 } else {
2182 //
2183 // If used for a question, then the question will be read-only
2184 //
qwang12bc166db2009-02-02 07:18:59 +00002185 //
2186 // Make sure CurrentStatement is not NULL.
2187 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2188 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2189 //
Eric Dong077c7ae2013-12-17 08:33:06 +00002190 ASSERT (ParentStatement != NULL);
2191 ParentStatement->ValueExpression = CurrentExpression;
qhuang8c60a0612008-10-31 04:41:33 +00002192 }
lgao40c66bc72009-11-12 01:16:12 +00002193
2194 //
2195 // Take a look at next OpCode to see whether current expression consists
2196 // of single OpCode
2197 //
2198 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2199 SingleOpCodeExpression = TRUE;
2200 }
qhuang8c60a0612008-10-31 04:41:33 +00002201 break;
2202
2203 case EFI_IFR_RULE_OP:
2204 CurrentExpression = CreateExpression (CurrentForm);
2205 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;
2206
2207 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;
2208 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
lgao40c66bc72009-11-12 01:16:12 +00002209
2210 //
2211 // Take a look at next OpCode to see whether current expression consists
2212 // of single OpCode
2213 //
2214 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2215 SingleOpCodeExpression = TRUE;
2216 }
qhuang8c60a0612008-10-31 04:41:33 +00002217 break;
2218
lgao425737122010-02-25 10:10:59 +00002219 case EFI_IFR_READ_OP:
2220 CurrentExpression = CreateExpression (CurrentForm);
2221 CurrentExpression->Type = EFI_HII_EXPRESSION_READ;
2222 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2223
2224 //
2225 // Make sure CurrentStatement is not NULL.
2226 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2227 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2228 //
Eric Dong077c7ae2013-12-17 08:33:06 +00002229 ASSERT (ParentStatement != NULL);
2230 ParentStatement->ReadExpression = CurrentExpression;
lgao425737122010-02-25 10:10:59 +00002231
2232 //
2233 // Take a look at next OpCode to see whether current expression consists
2234 // of single OpCode
2235 //
2236 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2237 SingleOpCodeExpression = TRUE;
2238 }
2239 break;
2240
2241 case EFI_IFR_WRITE_OP:
2242 CurrentExpression = CreateExpression (CurrentForm);
2243 CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;
2244 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2245
2246 //
2247 // Make sure CurrentStatement is not NULL.
2248 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2249 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2250 //
Eric Dong077c7ae2013-12-17 08:33:06 +00002251 ASSERT (ParentStatement != NULL);
2252 ParentStatement->WriteExpression = CurrentExpression;
lgao425737122010-02-25 10:10:59 +00002253
2254 //
2255 // Take a look at next OpCode to see whether current expression consists
2256 // of single OpCode
2257 //
2258 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2259 SingleOpCodeExpression = TRUE;
2260 }
2261 break;
2262
qhuang8c60a0612008-10-31 04:41:33 +00002263 //
2264 // Image
2265 //
2266 case EFI_IFR_IMAGE_OP:
2267 //
2268 // Get ScopeOpcode from top of stack
2269 //
2270 PopScope (&ScopeOpCode);
2271 PushScope (ScopeOpCode);
2272
2273 switch (ScopeOpCode) {
2274 case EFI_IFR_FORM_SET_OP:
2275 ImageId = &FormSet->ImageId;
2276 break;
2277
2278 case EFI_IFR_FORM_OP:
lgao425737122010-02-25 10:10:59 +00002279 case EFI_IFR_FORM_MAP_OP:
qwang12d0720b52009-01-20 01:55:11 +00002280 ASSERT (CurrentForm != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00002281 ImageId = &CurrentForm->ImageId;
2282 break;
2283
2284 case EFI_IFR_ONE_OF_OPTION_OP:
2285 ImageId = &CurrentOption->ImageId;
2286 break;
2287
2288 default:
qwang12bc166db2009-02-02 07:18:59 +00002289 //
2290 // Make sure CurrentStatement is not NULL.
2291 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2292 // file is wrongly generated by tools such as VFR Compiler.
2293 //
Eric Dong077c7ae2013-12-17 08:33:06 +00002294 ASSERT (ParentStatement != NULL);
2295 ImageId = &ParentStatement->ImageId;
qhuang8c60a0612008-10-31 04:41:33 +00002296 break;
2297 }
2298
qwang12c4105892009-02-06 06:34:43 +00002299 ASSERT (ImageId != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00002300 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
2301 break;
2302
2303 //
2304 // Refresh
2305 //
2306 case EFI_IFR_REFRESH_OP:
Eric Dong077c7ae2013-12-17 08:33:06 +00002307 ASSERT (ParentStatement != NULL);
2308 ParentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;
qhuang8c60a0612008-10-31 04:41:33 +00002309 break;
2310
2311 //
ydong10211cc6e2011-06-08 08:09:47 +00002312 // Refresh guid.
2313 //
2314 case EFI_IFR_REFRESH_ID_OP:
Eric Dong077c7ae2013-12-17 08:33:06 +00002315 ASSERT (ParentStatement != NULL);
2316 CopyMem (&ParentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));
ydong10211cc6e2011-06-08 08:09:47 +00002317 break;
2318
2319 //
ydong10b00964a2011-06-08 07:27:39 +00002320 // Modal tag
2321 //
2322 case EFI_IFR_MODAL_TAG_OP:
2323 ASSERT (CurrentForm != NULL);
2324 CurrentForm->ModalForm = TRUE;
2325 break;
2326
2327 //
ydong10f67c4382011-11-16 05:23:38 +00002328 // Lock tag, used by form and statement.
2329 //
2330 case EFI_IFR_LOCKED_OP:
2331 //
2332 // Get ScopeOpcode from top of stack
2333 //
2334 PopScope (&ScopeOpCode);
2335 PushScope (ScopeOpCode);
2336 switch (ScopeOpCode) {
2337 case EFI_IFR_FORM_OP:
2338 case EFI_IFR_FORM_MAP_OP:
2339 ASSERT (CurrentForm != NULL);
2340 CurrentForm->Locked = TRUE;
2341 break;
2342
2343 default:
Eric Dong077c7ae2013-12-17 08:33:06 +00002344 ASSERT (ParentStatement != NULL);
2345 ParentStatement->Locked = TRUE;
ydong10f67c4382011-11-16 05:23:38 +00002346 }
2347 break;
2348
2349 //
qhuang8c60a0612008-10-31 04:41:33 +00002350 // Vendor specific
2351 //
Eric Dong7c6c0642013-08-12 02:19:56 +00002352 case EFI_IFR_GUID_OP:
2353 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
qhuang8c60a0612008-10-31 04:41:33 +00002354 break;
2355
2356 //
2357 // Scope End
2358 //
2359 case EFI_IFR_END_OP:
2360 Status = PopScope (&ScopeOpCode);
2361 if (EFI_ERROR (Status)) {
2362 ResetScopeStack ();
2363 return Status;
2364 }
Eric Dong077c7ae2013-12-17 08:33:06 +00002365
2366 //
2367 // Parent statement end tag found, update ParentStatement info.
2368 //
2369 if (IsStatementOpCode(ScopeOpCode) && ParentStatement->Operand == ScopeOpCode) {
2370 ParentStatement = ParentStatement->ParentStatement;
2371 }
qhuang8c60a0612008-10-31 04:41:33 +00002372
2373 switch (ScopeOpCode) {
2374 case EFI_IFR_FORM_SET_OP:
2375 //
2376 // End of FormSet, update FormSet IFR binary length
2377 // to stop parsing substantial OpCodes
2378 //
2379 FormSet->IfrBinaryLength = OpCodeOffset;
2380 break;
2381
2382 case EFI_IFR_FORM_OP:
lgao425737122010-02-25 10:10:59 +00002383 case EFI_IFR_FORM_MAP_OP:
qhuang8c60a0612008-10-31 04:41:33 +00002384 //
2385 // End of Form
2386 //
2387 CurrentForm = NULL;
lgao40c66bc72009-11-12 01:16:12 +00002388 SuppressForQuestion = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +00002389 break;
2390
2391 case EFI_IFR_ONE_OF_OPTION_OP:
2392 //
2393 // End of Option
2394 //
2395 CurrentOption = NULL;
2396 break;
2397
qhuang8c60a0612008-10-31 04:41:33 +00002398 case EFI_IFR_NO_SUBMIT_IF_OP:
2399 case EFI_IFR_INCONSISTENT_IF_OP:
Eric Dong1c0d3062013-09-04 04:15:10 +00002400 case EFI_IFR_WARNING_IF_OP:
qhuang8c60a0612008-10-31 04:41:33 +00002401 //
2402 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2403 //
2404 break;
2405
2406 case EFI_IFR_SUPPRESS_IF_OP:
2407 if (SuppressForOption) {
ydong1031585af2012-01-31 07:17:42 +00002408 PopConditionalExpression(ExpressOption);
lgao40c66bc72009-11-12 01:16:12 +00002409 } else if (SuppressForQuestion) {
ydong1031585af2012-01-31 07:17:42 +00002410 PopConditionalExpression(ExpressStatement);
lgao40c66bc72009-11-12 01:16:12 +00002411 } else {
ydong1031585af2012-01-31 07:17:42 +00002412 PopConditionalExpression(ExpressForm);
qhuang8c60a0612008-10-31 04:41:33 +00002413 }
2414 break;
2415
2416 case EFI_IFR_GRAY_OUT_IF_OP:
ydong1031585af2012-01-31 07:17:42 +00002417 PopConditionalExpression(ExpressStatement);
qhuang8c60a0612008-10-31 04:41:33 +00002418 break;
2419
2420 case EFI_IFR_DISABLE_IF_OP:
ydong1031585af2012-01-31 07:17:42 +00002421 if (CurrentForm != NULL) {
2422 PopConditionalExpression(ExpressStatement);
2423 }
2424 InScopeDisable = FALSE;
qhuang8c60a0612008-10-31 04:41:33 +00002425 OpCodeDisabled = FALSE;
2426 break;
2427
2428 case EFI_IFR_ONE_OF_OP:
2429 case EFI_IFR_ORDERED_LIST_OP:
2430 SuppressForOption = FALSE;
2431 break;
2432
2433 case EFI_IFR_DEFAULT_OP:
2434 InScopeDefault = FALSE;
2435 break;
2436
lgao425737122010-02-25 10:10:59 +00002437 case EFI_IFR_MAP_OP:
2438 //
2439 // Get current Map Expression List.
2440 //
2441 Status = PopMapExpressionList ((VOID **) &MapExpressionList);
2442 if (Status == EFI_ACCESS_DENIED) {
2443 MapExpressionList = NULL;
2444 }
2445 //
2446 // Get current expression.
2447 //
2448 Status = PopCurrentExpression ((VOID **) &CurrentExpression);
2449 ASSERT_EFI_ERROR (Status);
lgao4771ecec2010-02-27 09:04:11 +00002450 ASSERT (MapScopeDepth > 0);
lgao425737122010-02-25 10:10:59 +00002451 MapScopeDepth --;
2452 break;
2453
qhuang8c60a0612008-10-31 04:41:33 +00002454 default:
2455 if (IsExpressionOpCode (ScopeOpCode)) {
ydong1031585af2012-01-31 07:17:42 +00002456 if (InScopeDisable && CurrentForm == NULL) {
qhuang8c60a0612008-10-31 04:41:33 +00002457 //
lgao40a1147e2009-04-22 03:18:37 +00002458 // This is DisableIf expression for Form, it should be a constant expression
qhuang8c60a0612008-10-31 04:41:33 +00002459 //
xdu2f8a1c222009-10-20 03:01:10 +00002460 ASSERT (CurrentExpression != NULL);
qhuang8c60a0612008-10-31 04:41:33 +00002461 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
2462 if (EFI_ERROR (Status)) {
2463 return Status;
2464 }
qwang12a935a0d2009-02-10 09:40:27 +00002465
qhuang8c60a0612008-10-31 04:41:33 +00002466 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
2467 return EFI_INVALID_PARAMETER;
2468 }
2469
2470 OpCodeDisabled = CurrentExpression->Result.Value.b;
2471 //
lgao425737122010-02-25 10:10:59 +00002472 // DisableIf Expression is only used once and not queued, free it
qhuang8c60a0612008-10-31 04:41:33 +00002473 //
2474 DestroyExpression (CurrentExpression);
2475 }
2476
2477 //
2478 // End of current Expression
2479 //
2480 CurrentExpression = NULL;
2481 }
2482 break;
2483 }
2484 break;
2485
2486 default:
2487 break;
2488 }
Eric Dong077c7ae2013-12-17 08:33:06 +00002489
2490 if (IsStatementOpCode(Operand)) {
2491 CurrentStatement->ParentStatement = ParentStatement;
2492 if (Scope != 0) {
2493 //
2494 // Scope != 0, other statements or options may nest in this statement.
2495 // Update the ParentStatement info.
2496 //
2497 ParentStatement = CurrentStatement;
2498 }
2499 }
qhuang8c60a0612008-10-31 04:41:33 +00002500 }
2501
2502 return EFI_SUCCESS;
2503}