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