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