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