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