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