]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
Refine code to fix potential code bug.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / IfrParse.c
1 /** @file
2 Parser for IFR binary encoding.
3
4 Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "Setup.h"
16
17 UINT16 mStatementIndex;
18 UINT16 mExpressionOpCodeIndex;
19 EFI_QUESTION_ID mUsedQuestionId;
20 BOOLEAN mInScopeSubtitle;
21 extern LIST_ENTRY gBrowserStorageList;
22 /**
23 Initialize Statement header members.
24
25 @param OpCodeData Pointer of the raw OpCode data.
26 @param FormSet Pointer of the current FormSe.
27 @param Form Pointer of the current Form.
28
29 @return The Statement.
30
31 **/
32 FORM_BROWSER_STATEMENT *
33 CreateStatement (
34 IN UINT8 *OpCodeData,
35 IN OUT FORM_BROWSER_FORMSET *FormSet,
36 IN OUT FORM_BROWSER_FORM *Form
37 )
38 {
39 FORM_BROWSER_STATEMENT *Statement;
40 EFI_IFR_STATEMENT_HEADER *StatementHdr;
41 INTN ConditionalExprCount;
42
43 if (Form == NULL) {
44 //
45 // Only guid op may out side the form level.
46 //
47 ASSERT (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_GUID_OP);
48 }
49
50 Statement = &FormSet->StatementBuffer[mStatementIndex];
51 mStatementIndex++;
52
53 InitializeListHead (&Statement->DefaultListHead);
54 InitializeListHead (&Statement->OptionListHead);
55 InitializeListHead (&Statement->InconsistentListHead);
56 InitializeListHead (&Statement->NoSubmitListHead);
57 InitializeListHead (&Statement->WarningListHead);
58
59 Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;
60
61 Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
62 Statement->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;
63
64 StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
65 CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
66 CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));
67
68 ConditionalExprCount = GetConditionalExpressionCount(ExpressStatement);
69 if (ConditionalExprCount > 0) {
70 //
71 // Form is inside of suppressif
72 //
73
74 Statement->Expression = (FORM_EXPRESSION_LIST *) AllocatePool(
75 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
76 ASSERT (Statement->Expression != NULL);
77 Statement->Expression->Count = (UINTN) ConditionalExprCount;
78 Statement->Expression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
79 CopyMem (Statement->Expression->Expression, GetConditionalExpressionList(ExpressStatement), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
80 }
81
82 Statement->InSubtitle = mInScopeSubtitle;
83
84 //
85 // Insert this Statement into current Form
86 //
87 if (Form == NULL) {
88 InsertTailList (&FormSet->StatementListOSF, &Statement->Link);
89 } else {
90 InsertTailList (&Form->StatementListHead, &Statement->Link);
91 }
92 return Statement;
93 }
94
95 /**
96 Convert a numeric value to a Unicode String and insert it to String Package.
97 This string is used as the Unicode Name for the EFI Variable. This is to support
98 the deprecated vareqval opcode.
99
100 @param FormSet The FormSet.
101 @param Statement The numeric question whose VarStoreInfo.VarName is the
102 numeric value which is used to produce the Unicode Name
103 for the EFI Variable.
104
105 If the Statement is NULL, the ASSERT.
106 If the opcode is not Numeric, then ASSERT.
107
108 @retval EFI_SUCCESS The funtion always succeeds.
109 **/
110 EFI_STATUS
111 UpdateCheckBoxStringToken (
112 IN CONST FORM_BROWSER_FORMSET *FormSet,
113 IN FORM_BROWSER_STATEMENT *Statement
114 )
115 {
116 CHAR16 Str[MAXIMUM_VALUE_CHARACTERS];
117 EFI_STRING_ID Id;
118
119 ASSERT (Statement != NULL);
120 ASSERT (Statement->Operand == EFI_IFR_NUMERIC_OP);
121
122 UnicodeValueToString (Str, 0, Statement->VarStoreInfo.VarName, MAXIMUM_VALUE_CHARACTERS - 1);
123
124 Id = HiiSetString (FormSet->HiiHandle, 0, Str, NULL);
125 if (Id == 0) {
126 return EFI_OUT_OF_RESOURCES;
127 }
128
129 Statement->VarStoreInfo.VarName = Id;
130
131 return EFI_SUCCESS;
132 }
133
134 /**
135 Check if the next opcode is the EFI_IFR_EXTEND_OP_VAREQNAME.
136
137 @param OpCodeData The current opcode.
138
139 @retval TRUE Yes.
140 @retval FALSE No.
141 **/
142 BOOLEAN
143 IsNextOpCodeGuidedVarEqName (
144 IN UINT8 *OpCodeData
145 )
146 {
147 //
148 // Get next opcode
149 //
150 OpCodeData += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
151 if (*OpCodeData == EFI_IFR_GUID_OP) {
152 if (CompareGuid (&gEfiIfrFrameworkGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
153 //
154 // Specific GUIDed opcodes to support IFR generated from Framework HII VFR
155 //
156 if ((((EFI_IFR_GUID_VAREQNAME *) OpCodeData)->ExtendOpCode) == EFI_IFR_EXTEND_OP_VAREQNAME) {
157 return TRUE;
158 }
159 }
160 }
161
162 return FALSE;
163 }
164
165 /**
166 Initialize Question's members.
167
168 @param OpCodeData Pointer of the raw OpCode data.
169 @param FormSet Pointer of the current FormSet.
170 @param Form Pointer of the current Form.
171
172 @return The Question.
173
174 **/
175 FORM_BROWSER_STATEMENT *
176 CreateQuestion (
177 IN UINT8 *OpCodeData,
178 IN OUT FORM_BROWSER_FORMSET *FormSet,
179 IN OUT FORM_BROWSER_FORM *Form
180 )
181 {
182 FORM_BROWSER_STATEMENT *Statement;
183 EFI_IFR_QUESTION_HEADER *QuestionHdr;
184 LIST_ENTRY *Link;
185 FORMSET_STORAGE *Storage;
186 NAME_VALUE_NODE *NameValueNode;
187 EFI_STATUS Status;
188 BOOLEAN Find;
189
190 Statement = CreateStatement (OpCodeData, FormSet, Form);
191 if (Statement == NULL) {
192 return NULL;
193 }
194
195 QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
196 CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));
197 CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));
198 CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));
199
200 Statement->QuestionFlags = QuestionHdr->Flags;
201
202 if (Statement->VarStoreId == 0) {
203 //
204 // VarStoreId of zero indicates no variable storage
205 //
206 return Statement;
207 }
208
209 //
210 // Take a look at next OpCode to see whether it is a GUIDed opcode to support
211 // Framework Compatibility
212 //
213 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
214 if ((*OpCodeData == EFI_IFR_NUMERIC_OP) && IsNextOpCodeGuidedVarEqName (OpCodeData)) {
215 Status = UpdateCheckBoxStringToken (FormSet, Statement);
216 if (EFI_ERROR (Status)) {
217 return NULL;
218 }
219 }
220 }
221
222 //
223 // Find Storage for this Question
224 //
225 Link = GetFirstNode (&FormSet->StorageListHead);
226 while (!IsNull (&FormSet->StorageListHead, Link)) {
227 Storage = FORMSET_STORAGE_FROM_LINK (Link);
228
229 if (Storage->VarStoreId == Statement->VarStoreId) {
230 Statement->Storage = Storage->BrowserStorage;
231 break;
232 }
233
234 Link = GetNextNode (&FormSet->StorageListHead, Link);
235 }
236 ASSERT (Statement->Storage != NULL);
237
238 //
239 // Initialilze varname for Name/Value or EFI Variable
240 //
241 if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||
242 (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
243 Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);
244 ASSERT (Statement->VariableName != NULL);
245
246 if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
247 //
248 // Check whether old string node already exist.
249 //
250 Find = FALSE;
251 if (!IsListEmpty(&Statement->Storage->NameValueListHead)) {
252 Link = GetFirstNode (&Statement->Storage->NameValueListHead);
253 while (!IsNull (&Statement->Storage->NameValueListHead, Link)) {
254 NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);
255
256 if (StrCmp (Statement->VariableName, NameValueNode->Name) == 0) {
257 Find = TRUE;
258 break;
259 }
260
261 Link = GetNextNode (&Statement->Storage->NameValueListHead, Link);
262 }
263 }
264
265 if (!Find) {
266 //
267 // Insert to Name/Value varstore list
268 //
269 NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));
270 ASSERT (NameValueNode != NULL);
271 NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;
272 NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);
273 ASSERT (NameValueNode->Name != NULL);
274 NameValueNode->Value = AllocateZeroPool (0x10);
275 ASSERT (NameValueNode->Value != NULL);
276 NameValueNode->EditValue = AllocateZeroPool (0x10);
277 ASSERT (NameValueNode->EditValue != NULL);
278
279 InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);
280 }
281 }
282 }
283
284 return Statement;
285 }
286
287
288 /**
289 Allocate a FORM_EXPRESSION node.
290
291 @param Form The Form associated with this Expression
292
293 @return Pointer to a FORM_EXPRESSION data structure.
294
295 **/
296 FORM_EXPRESSION *
297 CreateExpression (
298 IN OUT FORM_BROWSER_FORM *Form
299 )
300 {
301 FORM_EXPRESSION *Expression;
302
303 Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
304 ASSERT (Expression != NULL);
305 Expression->Signature = FORM_EXPRESSION_SIGNATURE;
306 InitializeListHead (&Expression->OpCodeListHead);
307
308 return Expression;
309 }
310
311 /**
312 Create ConfigHdr string for a storage.
313
314 @param FormSet Pointer of the current FormSet
315 @param Storage Pointer of the storage
316
317 @retval EFI_SUCCESS Initialize ConfigHdr success
318
319 **/
320 EFI_STATUS
321 InitializeConfigHdr (
322 IN FORM_BROWSER_FORMSET *FormSet,
323 IN OUT BROWSER_STORAGE *Storage
324 )
325 {
326 CHAR16 *Name;
327
328 if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
329 Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
330 Name = Storage->Name;
331 } else {
332 Name = NULL;
333 }
334
335 Storage->ConfigHdr = HiiConstructConfigHdr (
336 &Storage->Guid,
337 Name,
338 FormSet->DriverHandle
339 );
340
341 if (Storage->ConfigHdr == NULL) {
342 return EFI_NOT_FOUND;
343 }
344
345 return EFI_SUCCESS;
346 }
347
348 /**
349 Find the global storage link base on the input storate type, name and guid.
350
351 For EFI_HII_VARSTORE_EFI_VARIABLE and EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER,
352 same guid + name = same storage
353
354 For EFI_HII_VARSTORE_NAME_VALUE:
355 same guid + HiiHandle = same storage
356
357 For EFI_HII_VARSTORE_BUFFER:
358 same guid + name + HiiHandle = same storage
359
360 @param StorageType Storage type.
361 @param StorageGuid Storage guid.
362 @param StorageName Storage Name.
363 @param HiiHandle HiiHandle for this varstore.
364
365 @return Pointer to a GLOBAL_STORAGE data structure.
366
367 **/
368 BROWSER_STORAGE *
369 FindStorageInList (
370 IN UINT8 StorageType,
371 IN EFI_GUID *StorageGuid,
372 IN CHAR16 *StorageName,
373 IN EFI_HII_HANDLE HiiHandle
374 )
375 {
376 LIST_ENTRY *Link;
377 BROWSER_STORAGE *BrowserStorage;
378
379 Link = GetFirstNode (&gBrowserStorageList);
380 while (!IsNull (&gBrowserStorageList, Link)) {
381 BrowserStorage = BROWSER_STORAGE_FROM_LINK (Link);
382
383 if ((BrowserStorage->Type == StorageType) && CompareGuid (&BrowserStorage->Guid, StorageGuid)) {
384 if (StorageType == EFI_HII_VARSTORE_NAME_VALUE && BrowserStorage->HiiHandle == HiiHandle) {
385 return BrowserStorage;
386 }
387
388 if (StrCmp (BrowserStorage->Name, StorageName) == 0) {
389 if (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE || StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
390 return BrowserStorage;
391 } else if (StorageType == EFI_HII_VARSTORE_BUFFER && BrowserStorage->HiiHandle == HiiHandle) {
392 return BrowserStorage;
393 }
394 }
395 }
396
397 //
398 // Get Next Storage.
399 //
400 Link = GetNextNode (&gBrowserStorageList, Link);
401 }
402
403 return NULL;
404 }
405
406 /**
407 Intialize the Global Storage.
408
409 @param BrowserStorage Pointer to the global storage.
410 @param StorageType Storage type.
411 @param OpCodeData Binary data for this opcode.
412
413 **/
414 VOID
415 IntializeBrowserStorage (
416 IN BROWSER_STORAGE *BrowserStorage,
417 IN UINT8 StorageType,
418 IN UINT8 *OpCodeData
419 )
420 {
421 switch (StorageType) {
422 case EFI_HII_VARSTORE_BUFFER:
423 CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));
424 CopyMem (&BrowserStorage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));
425
426 BrowserStorage->Buffer = AllocateZeroPool (BrowserStorage->Size);
427 BrowserStorage->EditBuffer = AllocateZeroPool (BrowserStorage->Size);
428 break;
429
430 case EFI_HII_VARSTORE_EFI_VARIABLE:
431 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
432 CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));
433 CopyMem (&BrowserStorage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));
434 CopyMem (&BrowserStorage->Size, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Size, sizeof (UINT16));
435
436 if (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
437 BrowserStorage->Buffer = AllocateZeroPool (BrowserStorage->Size);
438 BrowserStorage->EditBuffer = AllocateZeroPool (BrowserStorage->Size);
439 }
440 break;
441
442 case EFI_HII_VARSTORE_NAME_VALUE:
443 CopyMem (&BrowserStorage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));
444
445 InitializeListHead (&BrowserStorage->NameValueListHead);
446 break;
447
448 default:
449 break;
450 }
451 }
452
453 /**
454 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
455
456 @param FormSet Pointer of the current FormSet
457 @param StorageType Storage type.
458 @param OpCodeData Binary data for this opcode.
459
460 @return Pointer to a FORMSET_STORAGE data structure.
461
462 **/
463 FORMSET_STORAGE *
464 CreateStorage (
465 IN FORM_BROWSER_FORMSET *FormSet,
466 IN UINT8 StorageType,
467 IN UINT8 *OpCodeData
468 )
469 {
470 FORMSET_STORAGE *Storage;
471 CHAR16 *UnicodeString;
472 UINT16 Index;
473 BROWSER_STORAGE *BrowserStorage;
474 EFI_GUID *StorageGuid;
475 CHAR8 *StorageName;
476
477 UnicodeString = NULL;
478 StorageName = NULL;
479 switch (StorageType) {
480 case EFI_HII_VARSTORE_BUFFER:
481 StorageGuid = (EFI_GUID *) (CHAR8*) &((EFI_IFR_VARSTORE *) OpCodeData)->Guid;
482 StorageName = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;
483 break;
484
485 case EFI_HII_VARSTORE_EFI_VARIABLE:
486 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
487 StorageGuid = (EFI_GUID *) (CHAR8*) &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid;
488 StorageName = (CHAR8 *) ((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Name;
489 break;
490
491 default:
492 ASSERT (StorageType == EFI_HII_VARSTORE_NAME_VALUE);
493 StorageGuid = &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid;
494 break;
495 }
496
497 if (StorageType != EFI_HII_VARSTORE_NAME_VALUE) {
498 ASSERT (StorageName != NULL);
499
500 UnicodeString = AllocateZeroPool (AsciiStrSize (StorageName) * 2);
501 ASSERT (UnicodeString != NULL);
502 for (Index = 0; StorageName[Index] != 0; Index++) {
503 UnicodeString[Index] = (CHAR16) StorageName[Index];
504 }
505 }
506
507 Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));
508 ASSERT (Storage != NULL);
509 Storage->Signature = FORMSET_STORAGE_SIGNATURE;
510 InsertTailList (&FormSet->StorageListHead, &Storage->Link);
511
512 BrowserStorage = FindStorageInList(StorageType, StorageGuid, UnicodeString, FormSet->HiiHandle);
513 if (BrowserStorage == NULL) {
514 BrowserStorage = AllocateZeroPool (sizeof (BROWSER_STORAGE));
515 ASSERT (BrowserStorage != NULL);
516
517 BrowserStorage->Signature = BROWSER_STORAGE_SIGNATURE;
518 InsertTailList (&gBrowserStorageList, &BrowserStorage->Link);
519
520 IntializeBrowserStorage (BrowserStorage, StorageType, OpCodeData);
521 BrowserStorage->Type = StorageType;
522 if (StorageType != EFI_HII_VARSTORE_NAME_VALUE) {
523 BrowserStorage->Name = UnicodeString;
524 }
525
526 BrowserStorage->HiiHandle = FormSet->HiiHandle;
527 InitializeConfigHdr (FormSet, BrowserStorage);
528
529 BrowserStorage->Initialized = FALSE;
530 }
531
532 Storage->BrowserStorage = BrowserStorage;
533 Storage->ConfigRequest = AllocateCopyPool (StrSize (BrowserStorage->ConfigHdr), BrowserStorage->ConfigHdr);
534 Storage->SpareStrLen = 0;
535
536 return Storage;
537 }
538
539 /**
540 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>
541
542 @param FormSet Pointer of the current FormSet.
543 @param Question The Question to be initialized.
544 @param Form Pointer of the current form.
545
546 @retval EFI_SUCCESS Function success.
547 @retval EFI_INVALID_PARAMETER No storage associated with the Question.
548
549 **/
550 EFI_STATUS
551 InitializeRequestElement (
552 IN OUT FORM_BROWSER_FORMSET *FormSet,
553 IN OUT FORM_BROWSER_STATEMENT *Question,
554 IN OUT FORM_BROWSER_FORM *Form
555 )
556 {
557 BROWSER_STORAGE *Storage;
558 FORMSET_STORAGE *FormsetStorage;
559 UINTN StrLen;
560 UINTN StringSize;
561 CHAR16 *NewStr;
562 CHAR16 RequestElement[30];
563 LIST_ENTRY *Link;
564 BOOLEAN Find;
565 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
566
567 Storage = Question->Storage;
568 if (Storage == NULL) {
569 return EFI_INVALID_PARAMETER;
570 }
571
572 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
573 //
574 // <ConfigRequest> is unnecessary for EFI variable storage,
575 // GetVariable()/SetVariable() will be used to retrieve/save values
576 //
577 return EFI_SUCCESS;
578 }
579
580 //
581 // Prepare <RequestElement>
582 //
583 if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
584 Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
585 StrLen = UnicodeSPrint (
586 RequestElement,
587 30 * sizeof (CHAR16),
588 L"&OFFSET=%x&WIDTH=%x",
589 Question->VarStoreInfo.VarOffset,
590 Question->StorageWidth
591 );
592 Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);
593 } else {
594 StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);
595 }
596
597 if ((Question->Operand == EFI_IFR_PASSWORD_OP) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {
598 //
599 // Password with CALLBACK flag is stored in encoded format,
600 // so don't need to append it to <ConfigRequest>
601 //
602 return EFI_SUCCESS;
603 }
604
605 //
606 // Find Formset Storage for this Question
607 //
608 FormsetStorage = NULL;
609 Link = GetFirstNode (&FormSet->StorageListHead);
610 while (!IsNull (&FormSet->StorageListHead, Link)) {
611 FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);
612
613 if (FormsetStorage->VarStoreId == Question->VarStoreId) {
614 break;
615 }
616
617 Link = GetNextNode (&FormSet->StorageListHead, Link);
618 }
619 ASSERT (FormsetStorage != NULL);
620
621 //
622 // Append <RequestElement> to <ConfigRequest>
623 //
624 if (StrLen > FormsetStorage->SpareStrLen) {
625 //
626 // Old String buffer is not sufficient for RequestElement, allocate a new one
627 //
628 StringSize = (FormsetStorage->ConfigRequest != NULL) ? StrSize (FormsetStorage->ConfigRequest) : sizeof (CHAR16);
629 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));
630 ASSERT (NewStr != NULL);
631 if (FormsetStorage->ConfigRequest != NULL) {
632 CopyMem (NewStr, FormsetStorage->ConfigRequest, StringSize);
633 FreePool (FormsetStorage->ConfigRequest);
634 }
635 FormsetStorage->ConfigRequest = NewStr;
636 FormsetStorage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
637 }
638
639 StrCat (FormsetStorage->ConfigRequest, RequestElement);
640 FormsetStorage->ElementCount++;
641 FormsetStorage->SpareStrLen -= StrLen;
642
643 //
644 // Update the Config Request info saved in the form.
645 //
646 ConfigInfo = NULL;
647 Find = FALSE;
648 Link = GetFirstNode (&Form->ConfigRequestHead);
649 while (!IsNull (&Form->ConfigRequestHead, Link)) {
650 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
651
652 if (ConfigInfo != NULL && ConfigInfo->Storage == Storage) {
653 Find = TRUE;
654 break;
655 }
656
657 Link = GetNextNode (&Form->ConfigRequestHead, Link);
658 }
659
660 if (!Find) {
661 ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST));
662 ASSERT (ConfigInfo != NULL);
663 ConfigInfo->Signature = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE;
664 ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr);
665 ConfigInfo->SpareStrLen = 0;
666 ConfigInfo->Storage = Storage;
667 InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link);
668 }
669
670 //
671 // Append <RequestElement> to <ConfigRequest>
672 //
673 if (StrLen > ConfigInfo->SpareStrLen) {
674 //
675 // Old String buffer is not sufficient for RequestElement, allocate a new one
676 //
677 StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);
678 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));
679 ASSERT (NewStr != NULL);
680 if (ConfigInfo->ConfigRequest != NULL) {
681 CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);
682 FreePool (ConfigInfo->ConfigRequest);
683 }
684 ConfigInfo->ConfigRequest = NewStr;
685 ConfigInfo->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
686 }
687
688 StrCat (ConfigInfo->ConfigRequest, RequestElement);
689 ConfigInfo->ElementCount++;
690 ConfigInfo->SpareStrLen -= StrLen;
691 return EFI_SUCCESS;
692 }
693
694
695 /**
696 Free resources of a Expression.
697
698 @param FormSet Pointer of the Expression
699
700 **/
701 VOID
702 DestroyExpression (
703 IN FORM_EXPRESSION *Expression
704 )
705 {
706 LIST_ENTRY *Link;
707 EXPRESSION_OPCODE *OpCode;
708 LIST_ENTRY *SubExpressionLink;
709 FORM_EXPRESSION *SubExpression;
710
711 while (!IsListEmpty (&Expression->OpCodeListHead)) {
712 Link = GetFirstNode (&Expression->OpCodeListHead);
713 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);
714 RemoveEntryList (&OpCode->Link);
715
716 if (OpCode->ValueList != NULL) {
717 FreePool (OpCode->ValueList);
718 }
719
720 if (OpCode->ValueName != NULL) {
721 FreePool (OpCode->ValueName);
722 }
723
724 if (OpCode->MapExpressionList.ForwardLink != NULL) {
725 while (!IsListEmpty (&OpCode->MapExpressionList)) {
726 SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);
727 SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);
728 RemoveEntryList(&SubExpression->Link);
729 DestroyExpression (SubExpression);
730 }
731 }
732 }
733
734 //
735 // Free this Expression
736 //
737 FreePool (Expression);
738 }
739
740 /**
741 Free resources of a storage.
742
743 @param Storage Pointer of the storage
744
745 **/
746 VOID
747 DestroyStorage (
748 IN FORMSET_STORAGE *Storage
749 )
750 {
751 if (Storage == NULL) {
752 return;
753 }
754
755 if (Storage->ConfigRequest != NULL) {
756 FreePool (Storage->ConfigRequest);
757 }
758
759 FreePool (Storage);
760 }
761
762
763 /**
764 Free resources of a Statement.
765
766 @param FormSet Pointer of the FormSet
767 @param Statement Pointer of the Statement
768
769 **/
770 VOID
771 DestroyStatement (
772 IN FORM_BROWSER_FORMSET *FormSet,
773 IN OUT FORM_BROWSER_STATEMENT *Statement
774 )
775 {
776 LIST_ENTRY *Link;
777 QUESTION_DEFAULT *Default;
778 QUESTION_OPTION *Option;
779 FORM_EXPRESSION *Expression;
780
781 //
782 // Free Default value List
783 //
784 while (!IsListEmpty (&Statement->DefaultListHead)) {
785 Link = GetFirstNode (&Statement->DefaultListHead);
786 Default = QUESTION_DEFAULT_FROM_LINK (Link);
787 RemoveEntryList (&Default->Link);
788
789 FreePool (Default);
790 }
791
792 //
793 // Free Options List
794 //
795 while (!IsListEmpty (&Statement->OptionListHead)) {
796 Link = GetFirstNode (&Statement->OptionListHead);
797 Option = QUESTION_OPTION_FROM_LINK (Link);
798 if (Option->SuppressExpression != NULL) {
799 FreePool (Option->SuppressExpression);
800 }
801 RemoveEntryList (&Option->Link);
802
803 FreePool (Option);
804 }
805
806 //
807 // Free Inconsistent List
808 //
809 while (!IsListEmpty (&Statement->InconsistentListHead)) {
810 Link = GetFirstNode (&Statement->InconsistentListHead);
811 Expression = FORM_EXPRESSION_FROM_LINK (Link);
812 RemoveEntryList (&Expression->Link);
813
814 DestroyExpression (Expression);
815 }
816
817 //
818 // Free NoSubmit List
819 //
820 while (!IsListEmpty (&Statement->NoSubmitListHead)) {
821 Link = GetFirstNode (&Statement->NoSubmitListHead);
822 Expression = FORM_EXPRESSION_FROM_LINK (Link);
823 RemoveEntryList (&Expression->Link);
824
825 DestroyExpression (Expression);
826 }
827
828 //
829 // Free WarningIf List
830 //
831 while (!IsListEmpty (&Statement->WarningListHead)) {
832 Link = GetFirstNode (&Statement->WarningListHead);
833 Expression = FORM_EXPRESSION_FROM_LINK (Link);
834 RemoveEntryList (&Expression->Link);
835
836 DestroyExpression (Expression);
837 }
838
839 if (Statement->Expression != NULL) {
840 FreePool (Statement->Expression);
841 }
842
843 if (Statement->VariableName != NULL) {
844 FreePool (Statement->VariableName);
845 }
846 if (Statement->BlockName != NULL) {
847 FreePool (Statement->BlockName);
848 }
849 if (Statement->BufferValue != NULL) {
850 FreePool (Statement->BufferValue);
851 }
852 if (Statement->Operand == EFI_IFR_STRING_OP || Statement->Operand == EFI_IFR_PASSWORD_OP) {
853 DeleteString(Statement->HiiValue.Value.string, FormSet->HiiHandle);
854 }
855 }
856
857
858 /**
859 Free resources of a Form.
860
861 @param FormSet Pointer of the FormSet
862 @param Form Pointer of the Form.
863
864 **/
865 VOID
866 DestroyForm (
867 IN FORM_BROWSER_FORMSET *FormSet,
868 IN OUT FORM_BROWSER_FORM *Form
869 )
870 {
871 LIST_ENTRY *Link;
872 FORM_EXPRESSION *Expression;
873 FORM_BROWSER_STATEMENT *Statement;
874 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
875
876 //
877 // Free Form Expressions
878 //
879 while (!IsListEmpty (&Form->ExpressionListHead)) {
880 Link = GetFirstNode (&Form->ExpressionListHead);
881 Expression = FORM_EXPRESSION_FROM_LINK (Link);
882 RemoveEntryList (&Expression->Link);
883
884 DestroyExpression (Expression);
885 }
886
887 //
888 // Free Statements/Questions
889 //
890 while (!IsListEmpty (&Form->StatementListHead)) {
891 Link = GetFirstNode (&Form->StatementListHead);
892 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
893 RemoveEntryList (&Statement->Link);
894
895 DestroyStatement (FormSet, Statement);
896 }
897
898 //
899 // Free ConfigRequest string.
900 //
901 while (!IsListEmpty (&Form->ConfigRequestHead)) {
902 Link = GetFirstNode (&Form->ConfigRequestHead);
903 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
904 RemoveEntryList (&ConfigInfo->Link);
905
906 FreePool (ConfigInfo->ConfigRequest);
907 FreePool (ConfigInfo);
908 }
909
910 if (Form->SuppressExpression != NULL) {
911 FreePool (Form->SuppressExpression);
912 }
913
914 //
915 // Free this Form
916 //
917 FreePool (Form);
918 }
919
920
921 /**
922 Free resources allocated for a FormSet.
923
924 @param FormSet Pointer of the FormSet
925
926 **/
927 VOID
928 DestroyFormSet (
929 IN OUT FORM_BROWSER_FORMSET *FormSet
930 )
931 {
932 LIST_ENTRY *Link;
933 FORMSET_STORAGE *Storage;
934 FORMSET_DEFAULTSTORE *DefaultStore;
935 FORM_EXPRESSION *Expression;
936 FORM_BROWSER_FORM *Form;
937
938 if (FormSet->IfrBinaryData == NULL) {
939 //
940 // Uninitialized FormSet
941 //
942 FreePool (FormSet);
943 return;
944 }
945
946 //
947 // Free IFR binary buffer
948 //
949 FreePool (FormSet->IfrBinaryData);
950
951 //
952 // Free FormSet Storage
953 //
954 if (FormSet->StorageListHead.ForwardLink != NULL) {
955 while (!IsListEmpty (&FormSet->StorageListHead)) {
956 Link = GetFirstNode (&FormSet->StorageListHead);
957 Storage = FORMSET_STORAGE_FROM_LINK (Link);
958 RemoveEntryList (&Storage->Link);
959
960 DestroyStorage (Storage);
961 }
962 }
963
964 //
965 // Free FormSet Default Store
966 //
967 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
968 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
969 Link = GetFirstNode (&FormSet->DefaultStoreListHead);
970 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);
971 RemoveEntryList (&DefaultStore->Link);
972
973 FreePool (DefaultStore);
974 }
975 }
976
977 //
978 // Free Formset Expressions
979 //
980 while (!IsListEmpty (&FormSet->ExpressionListHead)) {
981 Link = GetFirstNode (&FormSet->ExpressionListHead);
982 Expression = FORM_EXPRESSION_FROM_LINK (Link);
983 RemoveEntryList (&Expression->Link);
984
985 DestroyExpression (Expression);
986 }
987
988 //
989 // Free Forms
990 //
991 if (FormSet->FormListHead.ForwardLink != NULL) {
992 while (!IsListEmpty (&FormSet->FormListHead)) {
993 Link = GetFirstNode (&FormSet->FormListHead);
994 Form = FORM_BROWSER_FORM_FROM_LINK (Link);
995 RemoveEntryList (&Form->Link);
996
997 DestroyForm (FormSet, Form);
998 }
999 }
1000
1001 if (FormSet->StatementBuffer != NULL) {
1002 FreePool (FormSet->StatementBuffer);
1003 }
1004 if (FormSet->ExpressionBuffer != NULL) {
1005 FreePool (FormSet->ExpressionBuffer);
1006 }
1007
1008 FreePool (FormSet);
1009 }
1010
1011
1012 /**
1013 Tell whether this Operand is an Expression OpCode or not
1014
1015 @param Operand Operand of an IFR OpCode.
1016
1017 @retval TRUE This is an Expression OpCode.
1018 @retval FALSE Not an Expression OpCode.
1019
1020 **/
1021 BOOLEAN
1022 IsExpressionOpCode (
1023 IN UINT8 Operand
1024 )
1025 {
1026 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||
1027 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) ||
1028 ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||
1029 (Operand == EFI_IFR_CATENATE_OP) ||
1030 (Operand == EFI_IFR_TO_LOWER_OP) ||
1031 (Operand == EFI_IFR_TO_UPPER_OP) ||
1032 (Operand == EFI_IFR_MAP_OP) ||
1033 (Operand == EFI_IFR_VERSION_OP) ||
1034 (Operand == EFI_IFR_SECURITY_OP)) {
1035 return TRUE;
1036 } else {
1037 return FALSE;
1038 }
1039 }
1040
1041
1042 /**
1043 Calculate number of Statemens(Questions) and Expression OpCodes.
1044
1045 @param FormSet The FormSet to be counted.
1046 @param NumberOfStatement Number of Statemens(Questions)
1047 @param NumberOfExpression Number of Expression OpCodes
1048
1049 **/
1050 VOID
1051 CountOpCodes (
1052 IN FORM_BROWSER_FORMSET *FormSet,
1053 IN OUT UINT16 *NumberOfStatement,
1054 IN OUT UINT16 *NumberOfExpression
1055 )
1056 {
1057 UINT16 StatementCount;
1058 UINT16 ExpressionCount;
1059 UINT8 *OpCodeData;
1060 UINTN Offset;
1061 UINTN OpCodeLen;
1062
1063 Offset = 0;
1064 StatementCount = 0;
1065 ExpressionCount = 0;
1066
1067 while (Offset < FormSet->IfrBinaryLength) {
1068 OpCodeData = FormSet->IfrBinaryData + Offset;
1069 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
1070 Offset += OpCodeLen;
1071
1072 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {
1073 ExpressionCount++;
1074 } else {
1075 StatementCount++;
1076 }
1077 }
1078
1079 *NumberOfStatement = StatementCount;
1080 *NumberOfExpression = ExpressionCount;
1081 }
1082
1083
1084
1085 /**
1086 Parse opcodes in the formset IFR binary.
1087
1088 @param FormSet Pointer of the FormSet data structure.
1089
1090 @retval EFI_SUCCESS Opcode parse success.
1091 @retval Other Opcode parse fail.
1092
1093 **/
1094 EFI_STATUS
1095 ParseOpCodes (
1096 IN FORM_BROWSER_FORMSET *FormSet
1097 )
1098 {
1099 EFI_STATUS Status;
1100 FORM_BROWSER_FORM *CurrentForm;
1101 FORM_BROWSER_STATEMENT *CurrentStatement;
1102 EXPRESSION_OPCODE *ExpressionOpCode;
1103 FORM_EXPRESSION *CurrentExpression;
1104 UINT8 Operand;
1105 UINT8 Scope;
1106 UINTN OpCodeOffset;
1107 UINTN OpCodeLength;
1108 UINT8 *OpCodeData;
1109 UINT8 ScopeOpCode;
1110 FORMSET_STORAGE *Storage;
1111 FORMSET_DEFAULTSTORE *DefaultStore;
1112 QUESTION_DEFAULT *CurrentDefault;
1113 QUESTION_OPTION *CurrentOption;
1114 UINT8 Width;
1115 UINT16 NumberOfStatement;
1116 UINT16 NumberOfExpression;
1117 EFI_IMAGE_ID *ImageId;
1118 BOOLEAN SuppressForQuestion;
1119 BOOLEAN SuppressForOption;
1120 UINT16 DepthOfDisable;
1121 BOOLEAN OpCodeDisabled;
1122 BOOLEAN SingleOpCodeExpression;
1123 BOOLEAN InScopeDefault;
1124 EFI_HII_VALUE *Value;
1125 EFI_IFR_FORM_MAP_METHOD *MapMethod;
1126 UINT8 MapScopeDepth;
1127 LIST_ENTRY *Link;
1128 FORMSET_STORAGE *VarStorage;
1129 LIST_ENTRY *MapExpressionList;
1130 EFI_VARSTORE_ID TempVarstoreId;
1131 BOOLEAN InScopeDisable;
1132 INTN ConditionalExprCount;
1133
1134 mInScopeSubtitle = FALSE;
1135 SuppressForQuestion = FALSE;
1136 SuppressForOption = FALSE;
1137 InScopeDisable = FALSE;
1138 DepthOfDisable = 0;
1139 OpCodeDisabled = FALSE;
1140 SingleOpCodeExpression = FALSE;
1141 InScopeDefault = FALSE;
1142 CurrentExpression = NULL;
1143 CurrentDefault = NULL;
1144 CurrentOption = NULL;
1145 ImageId = NULL;
1146 MapMethod = NULL;
1147 MapScopeDepth = 0;
1148 Link = NULL;
1149 VarStorage = NULL;
1150 MapExpressionList = NULL;
1151 TempVarstoreId = 0;
1152 ConditionalExprCount = 0;
1153
1154 //
1155 // Get the number of Statements and Expressions
1156 //
1157 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
1158
1159 mStatementIndex = 0;
1160 mUsedQuestionId = 1;
1161 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
1162 if (FormSet->StatementBuffer == NULL) {
1163 return EFI_OUT_OF_RESOURCES;
1164 }
1165
1166 mExpressionOpCodeIndex = 0;
1167 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));
1168 if (FormSet->ExpressionBuffer == NULL) {
1169 return EFI_OUT_OF_RESOURCES;
1170 }
1171
1172 InitializeListHead (&FormSet->StatementListOSF);
1173 InitializeListHead (&FormSet->StorageListHead);
1174 InitializeListHead (&FormSet->DefaultStoreListHead);
1175 InitializeListHead (&FormSet->FormListHead);
1176 InitializeListHead (&FormSet->ExpressionListHead);
1177 ResetCurrentExpressionStack ();
1178 ResetMapExpressionListStack ();
1179
1180 CurrentForm = NULL;
1181 CurrentStatement = NULL;
1182
1183 ResetScopeStack ();
1184
1185 OpCodeOffset = 0;
1186 while (OpCodeOffset < FormSet->IfrBinaryLength) {
1187 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;
1188
1189 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
1190 OpCodeOffset += OpCodeLength;
1191 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
1192 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;
1193
1194 //
1195 // If scope bit set, push onto scope stack
1196 //
1197 if (Scope != 0) {
1198 PushScope (Operand);
1199 }
1200
1201 if (OpCodeDisabled) {
1202 //
1203 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1204 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1205 //
1206 if (Operand == EFI_IFR_DISABLE_IF_OP) {
1207 DepthOfDisable++;
1208 } else if (Operand == EFI_IFR_END_OP) {
1209 Status = PopScope (&ScopeOpCode);
1210 if (EFI_ERROR (Status)) {
1211 return Status;
1212 }
1213
1214 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {
1215 if (DepthOfDisable == 0) {
1216 InScopeDisable = FALSE;
1217 OpCodeDisabled = FALSE;
1218 } else {
1219 DepthOfDisable--;
1220 }
1221 }
1222 }
1223 continue;
1224 }
1225
1226 if (IsExpressionOpCode (Operand)) {
1227 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];
1228 mExpressionOpCodeIndex++;
1229
1230 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;
1231 ExpressionOpCode->Operand = Operand;
1232 Value = &ExpressionOpCode->Value;
1233
1234 switch (Operand) {
1235 case EFI_IFR_EQ_ID_VAL_OP:
1236 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1237
1238 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1239 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));
1240 break;
1241
1242 case EFI_IFR_EQ_ID_ID_OP:
1243 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));
1244 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));
1245 break;
1246
1247 case EFI_IFR_EQ_ID_VAL_LIST_OP:
1248 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1249 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));
1250 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);
1251 break;
1252
1253 case EFI_IFR_TO_STRING_OP:
1254 case EFI_IFR_FIND_OP:
1255 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;
1256 break;
1257
1258 case EFI_IFR_STRING_REF1_OP:
1259 Value->Type = EFI_IFR_TYPE_STRING;
1260 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));
1261 break;
1262
1263 case EFI_IFR_RULE_REF_OP:
1264 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;
1265 break;
1266
1267 case EFI_IFR_SPAN_OP:
1268 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;
1269 break;
1270
1271 case EFI_IFR_THIS_OP:
1272 ASSERT (CurrentStatement != NULL);
1273 ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;
1274 break;
1275
1276 case EFI_IFR_SECURITY_OP:
1277 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));
1278 break;
1279
1280 case EFI_IFR_GET_OP:
1281 case EFI_IFR_SET_OP:
1282 CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));
1283 if (TempVarstoreId != 0) {
1284 if (FormSet->StorageListHead.ForwardLink != NULL) {
1285 Link = GetFirstNode (&FormSet->StorageListHead);
1286 while (!IsNull (&FormSet->StorageListHead, Link)) {
1287 VarStorage = FORMSET_STORAGE_FROM_LINK (Link);
1288 if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {
1289 ExpressionOpCode->VarStorage = VarStorage->BrowserStorage;
1290 break;
1291 }
1292 Link = GetNextNode (&FormSet->StorageListHead, Link);
1293 }
1294 }
1295 if (ExpressionOpCode->VarStorage == NULL) {
1296 //
1297 // VarStorage is not found.
1298 //
1299 return EFI_INVALID_PARAMETER;
1300 }
1301 }
1302 ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;
1303 switch (ExpressionOpCode->ValueType) {
1304 case EFI_IFR_TYPE_BOOLEAN:
1305 case EFI_IFR_TYPE_NUM_SIZE_8:
1306 ExpressionOpCode->ValueWidth = 1;
1307 break;
1308
1309 case EFI_IFR_TYPE_NUM_SIZE_16:
1310 case EFI_IFR_TYPE_STRING:
1311 ExpressionOpCode->ValueWidth = 2;
1312 break;
1313
1314 case EFI_IFR_TYPE_NUM_SIZE_32:
1315 ExpressionOpCode->ValueWidth = 4;
1316 break;
1317
1318 case EFI_IFR_TYPE_NUM_SIZE_64:
1319 ExpressionOpCode->ValueWidth = 8;
1320 break;
1321
1322 case EFI_IFR_TYPE_DATE:
1323 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE);
1324 break;
1325
1326 case EFI_IFR_TYPE_TIME:
1327 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);
1328 break;
1329
1330 case EFI_IFR_TYPE_REF:
1331 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);
1332 break;
1333
1334 case EFI_IFR_TYPE_OTHER:
1335 case EFI_IFR_TYPE_UNDEFINED:
1336 case EFI_IFR_TYPE_ACTION:
1337 case EFI_IFR_TYPE_BUFFER:
1338 default:
1339 //
1340 // Invalid value type for Get/Set opcode.
1341 //
1342 return EFI_INVALID_PARAMETER;
1343 }
1344 CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID));
1345 CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));
1346 if ((ExpressionOpCode->VarStorage != NULL) &&
1347 (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE ||
1348 ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
1349 ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);
1350 if (ExpressionOpCode->ValueName == NULL) {
1351 //
1352 // String ID is invalid.
1353 //
1354 return EFI_INVALID_PARAMETER;
1355 }
1356 }
1357 break;
1358
1359 case EFI_IFR_QUESTION_REF1_OP:
1360 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1361 break;
1362
1363 case EFI_IFR_QUESTION_REF3_OP:
1364 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {
1365 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1366
1367 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {
1368 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));
1369 }
1370 }
1371 break;
1372
1373 //
1374 // constant
1375 //
1376 case EFI_IFR_TRUE_OP:
1377 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1378 Value->Value.b = TRUE;
1379 break;
1380
1381 case EFI_IFR_FALSE_OP:
1382 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1383 Value->Value.b = FALSE;
1384 break;
1385
1386 case EFI_IFR_ONE_OP:
1387 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1388 Value->Value.u8 = 1;
1389 break;
1390
1391 case EFI_IFR_ZERO_OP:
1392 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1393 Value->Value.u8 = 0;
1394 break;
1395
1396 case EFI_IFR_ONES_OP:
1397 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1398 Value->Value.u64 = 0xffffffffffffffffULL;
1399 break;
1400
1401 case EFI_IFR_UINT8_OP:
1402 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1403 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;
1404 break;
1405
1406 case EFI_IFR_UINT16_OP:
1407 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1408 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));
1409 break;
1410
1411 case EFI_IFR_UINT32_OP:
1412 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1413 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));
1414 break;
1415
1416 case EFI_IFR_UINT64_OP:
1417 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1418 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));
1419 break;
1420
1421 case EFI_IFR_UNDEFINED_OP:
1422 Value->Type = EFI_IFR_TYPE_UNDEFINED;
1423 break;
1424
1425 case EFI_IFR_VERSION_OP:
1426 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1427 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;
1428 break;
1429
1430 default:
1431 break;
1432 }
1433 //
1434 // Create sub expression nested in MAP opcode
1435 //
1436 if (CurrentExpression == NULL && MapScopeDepth > 0) {
1437 CurrentExpression = CreateExpression (CurrentForm);
1438 ASSERT (MapExpressionList != NULL);
1439 InsertTailList (MapExpressionList, &CurrentExpression->Link);
1440 if (Scope == 0) {
1441 SingleOpCodeExpression = TRUE;
1442 }
1443 }
1444 ASSERT (CurrentExpression != NULL);
1445 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);
1446 if (Operand == EFI_IFR_MAP_OP) {
1447 //
1448 // Store current Map Expression List.
1449 //
1450 if (MapExpressionList != NULL) {
1451 PushMapExpressionList (MapExpressionList);
1452 }
1453 //
1454 // Initialize new Map Expression List.
1455 //
1456 MapExpressionList = &ExpressionOpCode->MapExpressionList;
1457 InitializeListHead (MapExpressionList);
1458 //
1459 // Store current expression.
1460 //
1461 PushCurrentExpression (CurrentExpression);
1462 CurrentExpression = NULL;
1463 MapScopeDepth ++;
1464 } else if (SingleOpCodeExpression) {
1465 //
1466 // There are two cases to indicate the end of an Expression:
1467 // for single OpCode expression: one Expression OpCode
1468 // for expression consists of more than one OpCode: EFI_IFR_END
1469 //
1470 SingleOpCodeExpression = FALSE;
1471
1472 if (InScopeDisable && CurrentForm == NULL) {
1473 //
1474 // This is DisableIf expression for Form, it should be a constant expression
1475 //
1476 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
1477 if (EFI_ERROR (Status)) {
1478 return Status;
1479 }
1480
1481 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
1482 return EFI_INVALID_PARAMETER;
1483 }
1484
1485 OpCodeDisabled = CurrentExpression->Result.Value.b;
1486 }
1487
1488 CurrentExpression = NULL;
1489 }
1490
1491 continue;
1492 }
1493
1494 //
1495 // Parse the Opcode
1496 //
1497 switch (Operand) {
1498
1499 case EFI_IFR_FORM_SET_OP:
1500 //
1501 // Check the formset GUID
1502 //
1503 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {
1504 return EFI_INVALID_PARAMETER;
1505 }
1506
1507 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
1508 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
1509
1510 if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
1511 //
1512 // The formset OpCode contains ClassGuid
1513 //
1514 FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);
1515 CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));
1516 }
1517 break;
1518
1519 case EFI_IFR_FORM_OP:
1520 //
1521 // Create a new Form for this FormSet
1522 //
1523 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1524 ASSERT (CurrentForm != NULL);
1525 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1526 InitializeListHead (&CurrentForm->ExpressionListHead);
1527 InitializeListHead (&CurrentForm->StatementListHead);
1528 InitializeListHead (&CurrentForm->ConfigRequestHead);
1529
1530 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1531 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1532 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
1533
1534 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
1535 if ( ConditionalExprCount > 0) {
1536 //
1537 // Form is inside of suppressif
1538 //
1539 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1540 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1541 ASSERT (CurrentForm->SuppressExpression != NULL);
1542 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1543 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1544 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
1545 }
1546
1547 if (Scope != 0) {
1548 //
1549 // Enter scope of a Form, suppressif will be used for Question or Option
1550 //
1551 SuppressForQuestion = TRUE;
1552 }
1553
1554 //
1555 // Insert into Form list of this FormSet
1556 //
1557 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1558 break;
1559
1560 case EFI_IFR_FORM_MAP_OP:
1561 //
1562 // Create a new Form for this FormSet
1563 //
1564 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1565 ASSERT (CurrentForm != NULL);
1566 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1567 InitializeListHead (&CurrentForm->ExpressionListHead);
1568 InitializeListHead (&CurrentForm->StatementListHead);
1569 InitializeListHead (&CurrentForm->ConfigRequestHead);
1570 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1571
1572 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1573 //
1574 // FormMap Form must contain at least one Map Method.
1575 //
1576 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {
1577 return EFI_INVALID_PARAMETER;
1578 }
1579 //
1580 // Try to find the standard form map method.
1581 //
1582 while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {
1583 if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {
1584 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1585 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1586 break;
1587 }
1588 MapMethod ++;
1589 }
1590 //
1591 // If the standard form map method is not found, the first map method title will be used.
1592 //
1593 if (CurrentForm->FormTitle == 0) {
1594 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1595 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1596 }
1597
1598 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
1599 if ( ConditionalExprCount > 0) {
1600 //
1601 // Form is inside of suppressif
1602 //
1603 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1604 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1605 ASSERT (CurrentForm->SuppressExpression != NULL);
1606 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1607 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1608 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
1609 }
1610
1611 if (Scope != 0) {
1612 //
1613 // Enter scope of a Form, suppressif will be used for Question or Option
1614 //
1615 SuppressForQuestion = TRUE;
1616 }
1617
1618 //
1619 // Insert into Form list of this FormSet
1620 //
1621 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1622 break;
1623
1624 //
1625 // Storage
1626 //
1627 case EFI_IFR_VARSTORE_OP:
1628 //
1629 // Create a buffer Storage for this FormSet
1630 //
1631 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_BUFFER, OpCodeData);
1632 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1633 break;
1634
1635 case EFI_IFR_VARSTORE_NAME_VALUE_OP:
1636 //
1637 // Create a name/value Storage for this FormSet
1638 //
1639 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_NAME_VALUE, OpCodeData);
1640 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1641 break;
1642
1643 case EFI_IFR_VARSTORE_EFI_OP:
1644 //
1645 // Create a EFI variable Storage for this FormSet
1646 //
1647 if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) {
1648 //
1649 // Create efi varstore with format follow UEFI spec before 2.3.1.
1650 //
1651 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE, OpCodeData);
1652 } else {
1653 //
1654 // Create efi varstore with format follow UEFI spec 2.3.1 and later.
1655 //
1656 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER, OpCodeData);
1657 }
1658 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1659 break;
1660
1661 //
1662 // DefaultStore
1663 //
1664 case EFI_IFR_DEFAULTSTORE_OP:
1665 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
1666 ASSERT (DefaultStore != NULL);
1667 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
1668
1669 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));
1670 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
1671
1672 //
1673 // Insert to DefaultStore list of this Formset
1674 //
1675 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
1676 break;
1677
1678 //
1679 // Statements
1680 //
1681 case EFI_IFR_SUBTITLE_OP:
1682 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1683 ASSERT (CurrentStatement != NULL);
1684
1685 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
1686 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
1687 if (Scope != 0) {
1688 mInScopeSubtitle = TRUE;
1689 }
1690 break;
1691
1692 case EFI_IFR_TEXT_OP:
1693 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1694 ASSERT (CurrentStatement != NULL);
1695 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
1696 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
1697 break;
1698
1699 case EFI_IFR_RESET_BUTTON_OP:
1700 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1701 ASSERT (CurrentStatement != NULL);
1702 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
1703 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
1704 break;
1705
1706 //
1707 // Questions
1708 //
1709 case EFI_IFR_ACTION_OP:
1710 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1711 ASSERT (CurrentStatement != NULL);
1712 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;
1713
1714 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
1715 //
1716 // No QuestionConfig present, so no configuration string will be processed
1717 //
1718 CurrentStatement->QuestionConfig = 0;
1719 } else {
1720 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
1721 }
1722 break;
1723
1724 case EFI_IFR_REF_OP:
1725 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1726 ASSERT (CurrentStatement != NULL);
1727 Value = &CurrentStatement->HiiValue;
1728 Value->Type = EFI_IFR_TYPE_REF;
1729 if (OpCodeLength >= sizeof (EFI_IFR_REF)) {
1730 CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
1731
1732 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
1733 CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1734
1735 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
1736 CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
1737
1738 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
1739 CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1740 }
1741 }
1742 }
1743 }
1744 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);
1745 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1746 break;
1747
1748 case EFI_IFR_ONE_OF_OP:
1749 case EFI_IFR_NUMERIC_OP:
1750 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1751 ASSERT(CurrentStatement != NULL);
1752
1753 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
1754 Value = &CurrentStatement->HiiValue;
1755
1756 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
1757 case EFI_IFR_NUMERIC_SIZE_1:
1758 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
1759 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
1760 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
1761 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);
1762 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1763 break;
1764
1765 case EFI_IFR_NUMERIC_SIZE_2:
1766 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
1767 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
1768 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));
1769 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);
1770 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1771 break;
1772
1773 case EFI_IFR_NUMERIC_SIZE_4:
1774 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
1775 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
1776 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));
1777 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);
1778 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1779 break;
1780
1781 case EFI_IFR_NUMERIC_SIZE_8:
1782 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
1783 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
1784 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));
1785 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);
1786 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1787 break;
1788
1789 default:
1790 break;
1791 }
1792
1793 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1794
1795 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {
1796 SuppressForOption = TRUE;
1797 }
1798 break;
1799
1800 case EFI_IFR_ORDERED_LIST_OP:
1801 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1802 ASSERT(CurrentStatement != NULL);
1803
1804 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;
1805 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;
1806
1807 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;
1808 CurrentStatement->BufferValue = NULL;
1809
1810 if (Scope != 0) {
1811 SuppressForOption = TRUE;
1812 }
1813 break;
1814
1815 case EFI_IFR_CHECKBOX_OP:
1816 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1817 ASSERT(CurrentStatement != NULL);
1818
1819 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;
1820 CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);
1821 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
1822
1823 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1824
1825 break;
1826
1827 case EFI_IFR_STRING_OP:
1828 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1829 ASSERT (CurrentStatement != NULL);
1830 //
1831 // MinSize is the minimum number of characters that can be accepted for this opcode,
1832 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1833 // The characters are stored as Unicode, so the storage width should multiply 2.
1834 //
1835 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;
1836 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;
1837 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
1838 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;
1839
1840 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1841 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));
1842 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
1843
1844 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1845 break;
1846
1847 case EFI_IFR_PASSWORD_OP:
1848 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1849 ASSERT (CurrentStatement != NULL);
1850 //
1851 // MinSize is the minimum number of characters that can be accepted for this opcode,
1852 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1853 // The characters are stored as Unicode, so the storage width should multiply 2.
1854 //
1855 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));
1856 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));
1857 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
1858
1859 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1860 CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));
1861 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
1862
1863 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1864 break;
1865
1866 case EFI_IFR_DATE_OP:
1867 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1868 ASSERT(CurrentStatement != NULL);
1869
1870 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;
1871 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
1872
1873 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {
1874 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);
1875
1876 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1877 } else {
1878 //
1879 // Don't assign storage for RTC type of date/time
1880 //
1881 CurrentStatement->Storage = NULL;
1882 CurrentStatement->StorageWidth = 0;
1883 }
1884 break;
1885
1886 case EFI_IFR_TIME_OP:
1887 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1888 ASSERT(CurrentStatement != NULL);
1889
1890 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;
1891 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
1892
1893 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {
1894 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);
1895
1896 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1897 } else {
1898 //
1899 // Don't assign storage for RTC type of date/time
1900 //
1901 CurrentStatement->Storage = NULL;
1902 CurrentStatement->StorageWidth = 0;
1903 }
1904 break;
1905
1906 //
1907 // Default
1908 //
1909 case EFI_IFR_DEFAULT_OP:
1910 //
1911 // EFI_IFR_DEFAULT appear in scope of a Question,
1912 // It creates a default value for the current question.
1913 // A Question may have more than one Default value which have different default types.
1914 //
1915 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
1916 ASSERT (CurrentDefault != NULL);
1917 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
1918
1919 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
1920 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
1921 if (OpCodeLength > OFFSET_OF (EFI_IFR_DEFAULT, Value)) {
1922 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));
1923 ExtendValueToU64 (&CurrentDefault->Value);
1924 }
1925
1926 //
1927 // Insert to Default Value list of current Question
1928 //
1929 InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);
1930
1931 if (Scope != 0) {
1932 InScopeDefault = TRUE;
1933 }
1934 break;
1935
1936 //
1937 // Option
1938 //
1939 case EFI_IFR_ONE_OF_OPTION_OP:
1940 //
1941 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1942 // It create a selection for use in current Question.
1943 //
1944 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
1945 ASSERT (CurrentOption != NULL);
1946 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
1947 CurrentOption->OpCode = (EFI_IFR_ONE_OF_OPTION *) OpCodeData;
1948
1949 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
1950 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
1951 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
1952 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
1953 ExtendValueToU64 (&CurrentOption->Value);
1954
1955 ConditionalExprCount = GetConditionalExpressionCount(ExpressOption);
1956 if ( ConditionalExprCount > 0) {
1957 //
1958 // Form is inside of suppressif
1959 //
1960 CurrentOption->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1961 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1962 ASSERT (CurrentOption->SuppressExpression != NULL);
1963 CurrentOption->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1964 CurrentOption->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1965 CopyMem (CurrentOption->SuppressExpression->Expression, GetConditionalExpressionList(ExpressOption), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
1966 }
1967
1968 //
1969 // Insert to Option list of current Question
1970 //
1971 InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);
1972
1973 //
1974 // Now we know the Storage width of nested Ordered List
1975 //
1976 ASSERT (CurrentStatement != NULL);
1977 if ((CurrentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (CurrentStatement->BufferValue == NULL)) {
1978 Width = 1;
1979 switch (CurrentOption->Value.Type) {
1980 case EFI_IFR_TYPE_NUM_SIZE_8:
1981 Width = 1;
1982 break;
1983
1984 case EFI_IFR_TYPE_NUM_SIZE_16:
1985 Width = 2;
1986 break;
1987
1988 case EFI_IFR_TYPE_NUM_SIZE_32:
1989 Width = 4;
1990 break;
1991
1992 case EFI_IFR_TYPE_NUM_SIZE_64:
1993 Width = 8;
1994 break;
1995
1996 default:
1997 //
1998 // Invalid type for Ordered List
1999 //
2000 break;
2001 }
2002
2003 CurrentStatement->StorageWidth = (UINT16) (CurrentStatement->MaxContainers * Width);
2004 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);
2005 CurrentStatement->ValueType = CurrentOption->Value.Type;
2006 if (CurrentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {
2007 CurrentStatement->HiiValue.Buffer = CurrentStatement->BufferValue;
2008 CurrentStatement->HiiValue.BufferLen = CurrentStatement->StorageWidth;
2009 }
2010
2011 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
2012 }
2013 break;
2014
2015 //
2016 // Conditional
2017 //
2018 case EFI_IFR_NO_SUBMIT_IF_OP:
2019 case EFI_IFR_INCONSISTENT_IF_OP:
2020 //
2021 // Create an Expression node
2022 //
2023 CurrentExpression = CreateExpression (CurrentForm);
2024 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));
2025
2026 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {
2027 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;
2028 InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);
2029 } else {
2030 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;
2031 InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);
2032 }
2033
2034 //
2035 // Take a look at next OpCode to see whether current expression consists
2036 // of single OpCode
2037 //
2038 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2039 SingleOpCodeExpression = TRUE;
2040 }
2041 break;
2042
2043 case EFI_IFR_WARNING_IF_OP:
2044 //
2045 // Create an Expression node
2046 //
2047 CurrentExpression = CreateExpression (CurrentForm);
2048 CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *) OpCodeData)->Warning, sizeof (EFI_STRING_ID));
2049 CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeData)->TimeOut;
2050 CurrentExpression->Type = EFI_HII_EXPRESSION_WARNING_IF;
2051 InsertTailList (&CurrentStatement->WarningListHead, &CurrentExpression->Link);
2052
2053 //
2054 // Take a look at next OpCode to see whether current expression consists
2055 // of single OpCode
2056 //
2057 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2058 SingleOpCodeExpression = TRUE;
2059 }
2060 break;
2061
2062 case EFI_IFR_SUPPRESS_IF_OP:
2063 //
2064 // Question and Option will appear in scope of this OpCode
2065 //
2066 CurrentExpression = CreateExpression (CurrentForm);
2067 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;
2068
2069 if (CurrentForm == NULL) {
2070 InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);
2071 } else {
2072 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2073 }
2074
2075 if (SuppressForOption) {
2076 PushConditionalExpression(CurrentExpression, ExpressOption);
2077 } else if (SuppressForQuestion) {
2078 PushConditionalExpression(CurrentExpression, ExpressStatement);
2079 } else {
2080 PushConditionalExpression(CurrentExpression, ExpressForm);
2081 }
2082
2083 //
2084 // Take a look at next OpCode to see whether current expression consists
2085 // of single OpCode
2086 //
2087 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2088 SingleOpCodeExpression = TRUE;
2089 }
2090 break;
2091
2092 case EFI_IFR_GRAY_OUT_IF_OP:
2093 //
2094 // Questions will appear in scope of this OpCode
2095 //
2096 CurrentExpression = CreateExpression (CurrentForm);
2097 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;
2098 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2099 PushConditionalExpression(CurrentExpression, ExpressStatement);
2100
2101 //
2102 // Take a look at next OpCode to see whether current expression consists
2103 // of single OpCode
2104 //
2105 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2106 SingleOpCodeExpression = TRUE;
2107 }
2108 break;
2109
2110 case EFI_IFR_DISABLE_IF_OP:
2111 //
2112 // The DisableIf expression should only rely on constant, so it could be
2113 // evaluated at initialization and it will not be queued
2114 //
2115 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
2116 ASSERT (CurrentExpression != NULL);
2117 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;
2118 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;
2119 InitializeListHead (&CurrentExpression->OpCodeListHead);
2120
2121 if (CurrentForm != NULL) {
2122 //
2123 // This is DisableIf for Question, enqueue it to Form expression list
2124 //
2125 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2126 PushConditionalExpression(CurrentExpression, ExpressStatement);
2127 }
2128
2129 OpCodeDisabled = FALSE;
2130 InScopeDisable = TRUE;
2131 //
2132 // Take a look at next OpCode to see whether current expression consists
2133 // of single OpCode
2134 //
2135 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2136 SingleOpCodeExpression = TRUE;
2137 }
2138 break;
2139
2140 //
2141 // Expression
2142 //
2143 case EFI_IFR_VALUE_OP:
2144 CurrentExpression = CreateExpression (CurrentForm);
2145 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;
2146 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2147
2148 if (InScopeDefault) {
2149 //
2150 // Used for default (EFI_IFR_DEFAULT)
2151 //
2152 CurrentDefault->ValueExpression = CurrentExpression;
2153 } else {
2154 //
2155 // If used for a question, then the question will be read-only
2156 //
2157 //
2158 // Make sure CurrentStatement is not NULL.
2159 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2160 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2161 //
2162 ASSERT (CurrentStatement != NULL);
2163 CurrentStatement->ValueExpression = CurrentExpression;
2164 }
2165
2166 //
2167 // Take a look at next OpCode to see whether current expression consists
2168 // of single OpCode
2169 //
2170 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2171 SingleOpCodeExpression = TRUE;
2172 }
2173 break;
2174
2175 case EFI_IFR_RULE_OP:
2176 CurrentExpression = CreateExpression (CurrentForm);
2177 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;
2178
2179 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;
2180 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2181
2182 //
2183 // Take a look at next OpCode to see whether current expression consists
2184 // of single OpCode
2185 //
2186 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2187 SingleOpCodeExpression = TRUE;
2188 }
2189 break;
2190
2191 case EFI_IFR_READ_OP:
2192 CurrentExpression = CreateExpression (CurrentForm);
2193 CurrentExpression->Type = EFI_HII_EXPRESSION_READ;
2194 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2195
2196 //
2197 // Make sure CurrentStatement is not NULL.
2198 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2199 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2200 //
2201 ASSERT (CurrentStatement != NULL);
2202 CurrentStatement->ReadExpression = CurrentExpression;
2203
2204 //
2205 // Take a look at next OpCode to see whether current expression consists
2206 // of single OpCode
2207 //
2208 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2209 SingleOpCodeExpression = TRUE;
2210 }
2211 break;
2212
2213 case EFI_IFR_WRITE_OP:
2214 CurrentExpression = CreateExpression (CurrentForm);
2215 CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;
2216 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2217
2218 //
2219 // Make sure CurrentStatement is not NULL.
2220 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2221 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2222 //
2223 ASSERT (CurrentStatement != NULL);
2224 CurrentStatement->WriteExpression = CurrentExpression;
2225
2226 //
2227 // Take a look at next OpCode to see whether current expression consists
2228 // of single OpCode
2229 //
2230 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2231 SingleOpCodeExpression = TRUE;
2232 }
2233 break;
2234
2235 //
2236 // Image
2237 //
2238 case EFI_IFR_IMAGE_OP:
2239 //
2240 // Get ScopeOpcode from top of stack
2241 //
2242 PopScope (&ScopeOpCode);
2243 PushScope (ScopeOpCode);
2244
2245 switch (ScopeOpCode) {
2246 case EFI_IFR_FORM_SET_OP:
2247 ImageId = &FormSet->ImageId;
2248 break;
2249
2250 case EFI_IFR_FORM_OP:
2251 case EFI_IFR_FORM_MAP_OP:
2252 ASSERT (CurrentForm != NULL);
2253 ImageId = &CurrentForm->ImageId;
2254 break;
2255
2256 case EFI_IFR_ONE_OF_OPTION_OP:
2257 ImageId = &CurrentOption->ImageId;
2258 break;
2259
2260 default:
2261 //
2262 // Make sure CurrentStatement is not NULL.
2263 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2264 // file is wrongly generated by tools such as VFR Compiler.
2265 //
2266 ASSERT (CurrentStatement != NULL);
2267 ImageId = &CurrentStatement->ImageId;
2268 break;
2269 }
2270
2271 ASSERT (ImageId != NULL);
2272 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
2273 break;
2274
2275 //
2276 // Refresh
2277 //
2278 case EFI_IFR_REFRESH_OP:
2279 ASSERT (CurrentStatement != NULL);
2280 CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;
2281 break;
2282
2283 //
2284 // Refresh guid.
2285 //
2286 case EFI_IFR_REFRESH_ID_OP:
2287 ASSERT (CurrentStatement != NULL);
2288 CopyMem (&CurrentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));
2289 break;
2290
2291 //
2292 // Modal tag
2293 //
2294 case EFI_IFR_MODAL_TAG_OP:
2295 ASSERT (CurrentForm != NULL);
2296 CurrentForm->ModalForm = TRUE;
2297 break;
2298
2299 //
2300 // Lock tag, used by form and statement.
2301 //
2302 case EFI_IFR_LOCKED_OP:
2303 //
2304 // Get ScopeOpcode from top of stack
2305 //
2306 PopScope (&ScopeOpCode);
2307 PushScope (ScopeOpCode);
2308 switch (ScopeOpCode) {
2309 case EFI_IFR_FORM_OP:
2310 case EFI_IFR_FORM_MAP_OP:
2311 ASSERT (CurrentForm != NULL);
2312 CurrentForm->Locked = TRUE;
2313 break;
2314
2315 default:
2316 ASSERT (CurrentStatement != NULL);
2317 CurrentStatement->Locked = TRUE;
2318 }
2319 break;
2320
2321 //
2322 // Vendor specific
2323 //
2324 case EFI_IFR_GUID_OP:
2325 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
2326 break;
2327
2328 //
2329 // Scope End
2330 //
2331 case EFI_IFR_END_OP:
2332 Status = PopScope (&ScopeOpCode);
2333 if (EFI_ERROR (Status)) {
2334 ResetScopeStack ();
2335 return Status;
2336 }
2337
2338 switch (ScopeOpCode) {
2339 case EFI_IFR_FORM_SET_OP:
2340 //
2341 // End of FormSet, update FormSet IFR binary length
2342 // to stop parsing substantial OpCodes
2343 //
2344 FormSet->IfrBinaryLength = OpCodeOffset;
2345 break;
2346
2347 case EFI_IFR_FORM_OP:
2348 case EFI_IFR_FORM_MAP_OP:
2349 //
2350 // End of Form
2351 //
2352 CurrentForm = NULL;
2353 SuppressForQuestion = FALSE;
2354 break;
2355
2356 case EFI_IFR_ONE_OF_OPTION_OP:
2357 //
2358 // End of Option
2359 //
2360 CurrentOption = NULL;
2361 break;
2362
2363 case EFI_IFR_SUBTITLE_OP:
2364 mInScopeSubtitle = FALSE;
2365 break;
2366
2367 case EFI_IFR_NO_SUBMIT_IF_OP:
2368 case EFI_IFR_INCONSISTENT_IF_OP:
2369 case EFI_IFR_WARNING_IF_OP:
2370 //
2371 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2372 //
2373 break;
2374
2375 case EFI_IFR_SUPPRESS_IF_OP:
2376 if (SuppressForOption) {
2377 PopConditionalExpression(ExpressOption);
2378 } else if (SuppressForQuestion) {
2379 PopConditionalExpression(ExpressStatement);
2380 } else {
2381 PopConditionalExpression(ExpressForm);
2382 }
2383 break;
2384
2385 case EFI_IFR_GRAY_OUT_IF_OP:
2386 PopConditionalExpression(ExpressStatement);
2387 break;
2388
2389 case EFI_IFR_DISABLE_IF_OP:
2390 if (CurrentForm != NULL) {
2391 PopConditionalExpression(ExpressStatement);
2392 }
2393 InScopeDisable = FALSE;
2394 OpCodeDisabled = FALSE;
2395 break;
2396
2397 case EFI_IFR_ONE_OF_OP:
2398 case EFI_IFR_ORDERED_LIST_OP:
2399 SuppressForOption = FALSE;
2400 break;
2401
2402 case EFI_IFR_DEFAULT_OP:
2403 InScopeDefault = FALSE;
2404 break;
2405
2406 case EFI_IFR_MAP_OP:
2407 //
2408 // Get current Map Expression List.
2409 //
2410 Status = PopMapExpressionList ((VOID **) &MapExpressionList);
2411 if (Status == EFI_ACCESS_DENIED) {
2412 MapExpressionList = NULL;
2413 }
2414 //
2415 // Get current expression.
2416 //
2417 Status = PopCurrentExpression ((VOID **) &CurrentExpression);
2418 ASSERT_EFI_ERROR (Status);
2419 ASSERT (MapScopeDepth > 0);
2420 MapScopeDepth --;
2421 break;
2422
2423 default:
2424 if (IsExpressionOpCode (ScopeOpCode)) {
2425 if (InScopeDisable && CurrentForm == NULL) {
2426 //
2427 // This is DisableIf expression for Form, it should be a constant expression
2428 //
2429 ASSERT (CurrentExpression != NULL);
2430 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
2431 if (EFI_ERROR (Status)) {
2432 return Status;
2433 }
2434
2435 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
2436 return EFI_INVALID_PARAMETER;
2437 }
2438
2439 OpCodeDisabled = CurrentExpression->Result.Value.b;
2440 //
2441 // DisableIf Expression is only used once and not queued, free it
2442 //
2443 DestroyExpression (CurrentExpression);
2444 }
2445
2446 //
2447 // End of current Expression
2448 //
2449 CurrentExpression = NULL;
2450 }
2451 break;
2452 }
2453 break;
2454
2455 default:
2456 break;
2457 }
2458 }
2459
2460 return EFI_SUCCESS;
2461 }