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