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