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