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