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