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