]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
Update question validation logic, move the check pointer from after user input to...
[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 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 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 Tell whether this Operand is an Statement OpCode.
1044
1045 @param Operand Operand of an IFR OpCode.
1046
1047 @retval TRUE This is an Statement OpCode.
1048 @retval FALSE Not an Statement OpCode.
1049
1050 **/
1051 BOOLEAN
1052 IsStatementOpCode (
1053 IN UINT8 Operand
1054 )
1055 {
1056 if ((Operand == EFI_IFR_SUBTITLE_OP) ||
1057 (Operand == EFI_IFR_TEXT_OP) ||
1058 (Operand == EFI_IFR_RESET_BUTTON_OP) ||
1059 (Operand == EFI_IFR_REF_OP) ||
1060 (Operand == EFI_IFR_ACTION_OP) ||
1061 (Operand == EFI_IFR_NUMERIC_OP) ||
1062 (Operand == EFI_IFR_ORDERED_LIST_OP) ||
1063 (Operand == EFI_IFR_CHECKBOX_OP) ||
1064 (Operand == EFI_IFR_STRING_OP) ||
1065 (Operand == EFI_IFR_PASSWORD_OP) ||
1066 (Operand == EFI_IFR_DATE_OP) ||
1067 (Operand == EFI_IFR_TIME_OP) ||
1068 (Operand == EFI_IFR_GUID_OP) ||
1069 (Operand == EFI_IFR_ONE_OF_OP)) {
1070 return TRUE;
1071 } else {
1072 return FALSE;
1073 }
1074 }
1075
1076 /**
1077 Calculate number of Statemens(Questions) and Expression OpCodes.
1078
1079 @param FormSet The FormSet to be counted.
1080 @param NumberOfStatement Number of Statemens(Questions)
1081 @param NumberOfExpression Number of Expression OpCodes
1082
1083 **/
1084 VOID
1085 CountOpCodes (
1086 IN FORM_BROWSER_FORMSET *FormSet,
1087 IN OUT UINT16 *NumberOfStatement,
1088 IN OUT UINT16 *NumberOfExpression
1089 )
1090 {
1091 UINT16 StatementCount;
1092 UINT16 ExpressionCount;
1093 UINT8 *OpCodeData;
1094 UINTN Offset;
1095 UINTN OpCodeLen;
1096
1097 Offset = 0;
1098 StatementCount = 0;
1099 ExpressionCount = 0;
1100
1101 while (Offset < FormSet->IfrBinaryLength) {
1102 OpCodeData = FormSet->IfrBinaryData + Offset;
1103 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
1104 Offset += OpCodeLen;
1105
1106 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {
1107 ExpressionCount++;
1108 } else {
1109 StatementCount++;
1110 }
1111 }
1112
1113 *NumberOfStatement = StatementCount;
1114 *NumberOfExpression = ExpressionCount;
1115 }
1116
1117
1118
1119 /**
1120 Parse opcodes in the formset IFR binary.
1121
1122 @param FormSet Pointer of the FormSet data structure.
1123
1124 @retval EFI_SUCCESS Opcode parse success.
1125 @retval Other Opcode parse fail.
1126
1127 **/
1128 EFI_STATUS
1129 ParseOpCodes (
1130 IN FORM_BROWSER_FORMSET *FormSet
1131 )
1132 {
1133 EFI_STATUS Status;
1134 FORM_BROWSER_FORM *CurrentForm;
1135 FORM_BROWSER_STATEMENT *CurrentStatement;
1136 FORM_BROWSER_STATEMENT *ParentStatement;
1137 EXPRESSION_OPCODE *ExpressionOpCode;
1138 FORM_EXPRESSION *CurrentExpression;
1139 UINT8 Operand;
1140 UINT8 Scope;
1141 UINTN OpCodeOffset;
1142 UINTN OpCodeLength;
1143 UINT8 *OpCodeData;
1144 UINT8 ScopeOpCode;
1145 FORMSET_STORAGE *Storage;
1146 FORMSET_DEFAULTSTORE *DefaultStore;
1147 QUESTION_DEFAULT *CurrentDefault;
1148 QUESTION_OPTION *CurrentOption;
1149 UINT8 Width;
1150 UINT16 NumberOfStatement;
1151 UINT16 NumberOfExpression;
1152 EFI_IMAGE_ID *ImageId;
1153 BOOLEAN SuppressForQuestion;
1154 BOOLEAN SuppressForOption;
1155 UINT16 DepthOfDisable;
1156 BOOLEAN OpCodeDisabled;
1157 BOOLEAN SingleOpCodeExpression;
1158 BOOLEAN InScopeDefault;
1159 EFI_HII_VALUE *Value;
1160 EFI_IFR_FORM_MAP_METHOD *MapMethod;
1161 UINT8 MapScopeDepth;
1162 LIST_ENTRY *Link;
1163 FORMSET_STORAGE *VarStorage;
1164 LIST_ENTRY *MapExpressionList;
1165 EFI_VARSTORE_ID TempVarstoreId;
1166 BOOLEAN InScopeDisable;
1167 INTN ConditionalExprCount;
1168
1169 SuppressForQuestion = FALSE;
1170 SuppressForOption = FALSE;
1171 InScopeDisable = FALSE;
1172 DepthOfDisable = 0;
1173 OpCodeDisabled = FALSE;
1174 SingleOpCodeExpression = FALSE;
1175 InScopeDefault = FALSE;
1176 CurrentExpression = NULL;
1177 CurrentDefault = NULL;
1178 CurrentOption = NULL;
1179 ImageId = NULL;
1180 MapMethod = NULL;
1181 MapScopeDepth = 0;
1182 Link = NULL;
1183 VarStorage = NULL;
1184 MapExpressionList = NULL;
1185 TempVarstoreId = 0;
1186 ConditionalExprCount = 0;
1187
1188 //
1189 // Get the number of Statements and Expressions
1190 //
1191 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
1192
1193 mStatementIndex = 0;
1194 mUsedQuestionId = 1;
1195 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
1196 if (FormSet->StatementBuffer == NULL) {
1197 return EFI_OUT_OF_RESOURCES;
1198 }
1199
1200 mExpressionOpCodeIndex = 0;
1201 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));
1202 if (FormSet->ExpressionBuffer == NULL) {
1203 return EFI_OUT_OF_RESOURCES;
1204 }
1205
1206 InitializeListHead (&FormSet->StatementListOSF);
1207 InitializeListHead (&FormSet->StorageListHead);
1208 InitializeListHead (&FormSet->DefaultStoreListHead);
1209 InitializeListHead (&FormSet->FormListHead);
1210 InitializeListHead (&FormSet->ExpressionListHead);
1211 ResetCurrentExpressionStack ();
1212 ResetMapExpressionListStack ();
1213
1214 CurrentForm = NULL;
1215 CurrentStatement = NULL;
1216 ParentStatement = NULL;
1217
1218 ResetScopeStack ();
1219
1220 OpCodeOffset = 0;
1221 while (OpCodeOffset < FormSet->IfrBinaryLength) {
1222 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;
1223
1224 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
1225 OpCodeOffset += OpCodeLength;
1226 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
1227 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;
1228
1229 //
1230 // If scope bit set, push onto scope stack
1231 //
1232 if (Scope != 0) {
1233 PushScope (Operand);
1234 }
1235
1236 if (OpCodeDisabled) {
1237 //
1238 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1239 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1240 //
1241 if (Operand == EFI_IFR_DISABLE_IF_OP) {
1242 DepthOfDisable++;
1243 } else if (Operand == EFI_IFR_END_OP) {
1244 Status = PopScope (&ScopeOpCode);
1245 if (EFI_ERROR (Status)) {
1246 return Status;
1247 }
1248
1249 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {
1250 if (DepthOfDisable == 0) {
1251 InScopeDisable = FALSE;
1252 OpCodeDisabled = FALSE;
1253 } else {
1254 DepthOfDisable--;
1255 }
1256 }
1257 }
1258 continue;
1259 }
1260
1261 if (IsExpressionOpCode (Operand)) {
1262 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];
1263 mExpressionOpCodeIndex++;
1264
1265 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;
1266 ExpressionOpCode->Operand = Operand;
1267 Value = &ExpressionOpCode->Value;
1268
1269 switch (Operand) {
1270 case EFI_IFR_EQ_ID_VAL_OP:
1271 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1272
1273 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1274 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));
1275 break;
1276
1277 case EFI_IFR_EQ_ID_ID_OP:
1278 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));
1279 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));
1280 break;
1281
1282 case EFI_IFR_EQ_ID_VAL_LIST_OP:
1283 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1284 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));
1285 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);
1286 break;
1287
1288 case EFI_IFR_TO_STRING_OP:
1289 case EFI_IFR_FIND_OP:
1290 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;
1291 break;
1292
1293 case EFI_IFR_STRING_REF1_OP:
1294 Value->Type = EFI_IFR_TYPE_STRING;
1295 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));
1296 break;
1297
1298 case EFI_IFR_RULE_REF_OP:
1299 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;
1300 break;
1301
1302 case EFI_IFR_SPAN_OP:
1303 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;
1304 break;
1305
1306 case EFI_IFR_THIS_OP:
1307 ASSERT (ParentStatement != NULL);
1308 ExpressionOpCode->QuestionId = ParentStatement->QuestionId;
1309 break;
1310
1311 case EFI_IFR_SECURITY_OP:
1312 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));
1313 break;
1314
1315 case EFI_IFR_GET_OP:
1316 case EFI_IFR_SET_OP:
1317 CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));
1318 if (TempVarstoreId != 0) {
1319 if (FormSet->StorageListHead.ForwardLink != NULL) {
1320 Link = GetFirstNode (&FormSet->StorageListHead);
1321 while (!IsNull (&FormSet->StorageListHead, Link)) {
1322 VarStorage = FORMSET_STORAGE_FROM_LINK (Link);
1323 if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {
1324 ExpressionOpCode->VarStorage = VarStorage->BrowserStorage;
1325 break;
1326 }
1327 Link = GetNextNode (&FormSet->StorageListHead, Link);
1328 }
1329 }
1330 if (ExpressionOpCode->VarStorage == NULL) {
1331 //
1332 // VarStorage is not found.
1333 //
1334 return EFI_INVALID_PARAMETER;
1335 }
1336 }
1337 ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;
1338 switch (ExpressionOpCode->ValueType) {
1339 case EFI_IFR_TYPE_BOOLEAN:
1340 case EFI_IFR_TYPE_NUM_SIZE_8:
1341 ExpressionOpCode->ValueWidth = 1;
1342 break;
1343
1344 case EFI_IFR_TYPE_NUM_SIZE_16:
1345 case EFI_IFR_TYPE_STRING:
1346 ExpressionOpCode->ValueWidth = 2;
1347 break;
1348
1349 case EFI_IFR_TYPE_NUM_SIZE_32:
1350 ExpressionOpCode->ValueWidth = 4;
1351 break;
1352
1353 case EFI_IFR_TYPE_NUM_SIZE_64:
1354 ExpressionOpCode->ValueWidth = 8;
1355 break;
1356
1357 case EFI_IFR_TYPE_DATE:
1358 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE);
1359 break;
1360
1361 case EFI_IFR_TYPE_TIME:
1362 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);
1363 break;
1364
1365 case EFI_IFR_TYPE_REF:
1366 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);
1367 break;
1368
1369 case EFI_IFR_TYPE_OTHER:
1370 case EFI_IFR_TYPE_UNDEFINED:
1371 case EFI_IFR_TYPE_ACTION:
1372 case EFI_IFR_TYPE_BUFFER:
1373 default:
1374 //
1375 // Invalid value type for Get/Set opcode.
1376 //
1377 return EFI_INVALID_PARAMETER;
1378 }
1379 CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID));
1380 CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));
1381 if ((ExpressionOpCode->VarStorage != NULL) &&
1382 (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE ||
1383 ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
1384 ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);
1385 if (ExpressionOpCode->ValueName == NULL) {
1386 //
1387 // String ID is invalid.
1388 //
1389 return EFI_INVALID_PARAMETER;
1390 }
1391 }
1392 break;
1393
1394 case EFI_IFR_QUESTION_REF1_OP:
1395 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1396 break;
1397
1398 case EFI_IFR_QUESTION_REF3_OP:
1399 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {
1400 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1401
1402 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {
1403 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));
1404 }
1405 }
1406 break;
1407
1408 //
1409 // constant
1410 //
1411 case EFI_IFR_TRUE_OP:
1412 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1413 Value->Value.b = TRUE;
1414 break;
1415
1416 case EFI_IFR_FALSE_OP:
1417 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1418 Value->Value.b = FALSE;
1419 break;
1420
1421 case EFI_IFR_ONE_OP:
1422 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1423 Value->Value.u8 = 1;
1424 break;
1425
1426 case EFI_IFR_ZERO_OP:
1427 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1428 Value->Value.u8 = 0;
1429 break;
1430
1431 case EFI_IFR_ONES_OP:
1432 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1433 Value->Value.u64 = 0xffffffffffffffffULL;
1434 break;
1435
1436 case EFI_IFR_UINT8_OP:
1437 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1438 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;
1439 break;
1440
1441 case EFI_IFR_UINT16_OP:
1442 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1443 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));
1444 break;
1445
1446 case EFI_IFR_UINT32_OP:
1447 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1448 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));
1449 break;
1450
1451 case EFI_IFR_UINT64_OP:
1452 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1453 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));
1454 break;
1455
1456 case EFI_IFR_UNDEFINED_OP:
1457 Value->Type = EFI_IFR_TYPE_UNDEFINED;
1458 break;
1459
1460 case EFI_IFR_VERSION_OP:
1461 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1462 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;
1463 break;
1464
1465 default:
1466 break;
1467 }
1468 //
1469 // Create sub expression nested in MAP opcode
1470 //
1471 if (CurrentExpression == NULL && MapScopeDepth > 0) {
1472 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
1473 ASSERT (MapExpressionList != NULL);
1474 InsertTailList (MapExpressionList, &CurrentExpression->Link);
1475 if (Scope == 0) {
1476 SingleOpCodeExpression = TRUE;
1477 }
1478 }
1479 ASSERT (CurrentExpression != NULL);
1480 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);
1481 if (Operand == EFI_IFR_MAP_OP) {
1482 //
1483 // Store current Map Expression List.
1484 //
1485 if (MapExpressionList != NULL) {
1486 PushMapExpressionList (MapExpressionList);
1487 }
1488 //
1489 // Initialize new Map Expression List.
1490 //
1491 MapExpressionList = &ExpressionOpCode->MapExpressionList;
1492 InitializeListHead (MapExpressionList);
1493 //
1494 // Store current expression.
1495 //
1496 PushCurrentExpression (CurrentExpression);
1497 CurrentExpression = NULL;
1498 MapScopeDepth ++;
1499 } else if (SingleOpCodeExpression) {
1500 //
1501 // There are two cases to indicate the end of an Expression:
1502 // for single OpCode expression: one Expression OpCode
1503 // for expression consists of more than one OpCode: EFI_IFR_END
1504 //
1505 SingleOpCodeExpression = FALSE;
1506
1507 if (InScopeDisable && CurrentForm == NULL) {
1508 //
1509 // This is DisableIf expression for Form, it should be a constant expression
1510 //
1511 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
1512 if (EFI_ERROR (Status)) {
1513 return Status;
1514 }
1515
1516 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
1517 return EFI_INVALID_PARAMETER;
1518 }
1519
1520 OpCodeDisabled = CurrentExpression->Result.Value.b;
1521 }
1522
1523 CurrentExpression = NULL;
1524 }
1525
1526 continue;
1527 }
1528
1529 //
1530 // Parse the Opcode
1531 //
1532 switch (Operand) {
1533
1534 case EFI_IFR_FORM_SET_OP:
1535 //
1536 // Check the formset GUID
1537 //
1538 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {
1539 return EFI_INVALID_PARAMETER;
1540 }
1541
1542 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
1543 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
1544
1545 if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
1546 //
1547 // The formset OpCode contains ClassGuid
1548 //
1549 FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);
1550 CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));
1551 }
1552 break;
1553
1554 case EFI_IFR_FORM_OP:
1555 //
1556 // Create a new Form for this FormSet
1557 //
1558 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1559 ASSERT (CurrentForm != NULL);
1560 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1561 InitializeListHead (&CurrentForm->ExpressionListHead);
1562 InitializeListHead (&CurrentForm->StatementListHead);
1563 InitializeListHead (&CurrentForm->ConfigRequestHead);
1564
1565 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1566 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1567 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
1568
1569 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
1570 if ( ConditionalExprCount > 0) {
1571 //
1572 // Form is inside of suppressif
1573 //
1574 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1575 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1576 ASSERT (CurrentForm->SuppressExpression != NULL);
1577 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1578 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1579 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
1580 }
1581
1582 if (Scope != 0) {
1583 //
1584 // Enter scope of a Form, suppressif will be used for Question or Option
1585 //
1586 SuppressForQuestion = TRUE;
1587 }
1588
1589 //
1590 // Insert into Form list of this FormSet
1591 //
1592 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1593 break;
1594
1595 case EFI_IFR_FORM_MAP_OP:
1596 //
1597 // Create a new Form for this FormSet
1598 //
1599 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1600 ASSERT (CurrentForm != NULL);
1601 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1602 InitializeListHead (&CurrentForm->ExpressionListHead);
1603 InitializeListHead (&CurrentForm->StatementListHead);
1604 InitializeListHead (&CurrentForm->ConfigRequestHead);
1605 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1606
1607 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1608 //
1609 // FormMap Form must contain at least one Map Method.
1610 //
1611 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {
1612 return EFI_INVALID_PARAMETER;
1613 }
1614 //
1615 // Try to find the standard form map method.
1616 //
1617 while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {
1618 if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {
1619 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1620 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1621 break;
1622 }
1623 MapMethod ++;
1624 }
1625 //
1626 // If the standard form map method is not found, the first map method title will be used.
1627 //
1628 if (CurrentForm->FormTitle == 0) {
1629 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1630 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1631 }
1632
1633 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
1634 if ( ConditionalExprCount > 0) {
1635 //
1636 // Form is inside of suppressif
1637 //
1638 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1639 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1640 ASSERT (CurrentForm->SuppressExpression != NULL);
1641 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1642 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1643 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
1644 }
1645
1646 if (Scope != 0) {
1647 //
1648 // Enter scope of a Form, suppressif will be used for Question or Option
1649 //
1650 SuppressForQuestion = TRUE;
1651 }
1652
1653 //
1654 // Insert into Form list of this FormSet
1655 //
1656 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1657 break;
1658
1659 //
1660 // Storage
1661 //
1662 case EFI_IFR_VARSTORE_OP:
1663 //
1664 // Create a buffer Storage for this FormSet
1665 //
1666 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_BUFFER, OpCodeData);
1667 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1668 break;
1669
1670 case EFI_IFR_VARSTORE_NAME_VALUE_OP:
1671 //
1672 // Create a name/value Storage for this FormSet
1673 //
1674 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_NAME_VALUE, OpCodeData);
1675 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1676 break;
1677
1678 case EFI_IFR_VARSTORE_EFI_OP:
1679 //
1680 // Create a EFI variable Storage for this FormSet
1681 //
1682 if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) {
1683 //
1684 // Create efi varstore with format follow UEFI spec before 2.3.1.
1685 //
1686 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE, OpCodeData);
1687 } else {
1688 //
1689 // Create efi varstore with format follow UEFI spec 2.3.1 and later.
1690 //
1691 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER, OpCodeData);
1692 }
1693 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1694 break;
1695
1696 //
1697 // DefaultStore
1698 //
1699 case EFI_IFR_DEFAULTSTORE_OP:
1700 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
1701 ASSERT (DefaultStore != NULL);
1702 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
1703
1704 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));
1705 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
1706
1707 //
1708 // Insert to DefaultStore list of this Formset
1709 //
1710 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
1711 break;
1712
1713 //
1714 // Statements
1715 //
1716 case EFI_IFR_SUBTITLE_OP:
1717 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1718 ASSERT (CurrentStatement != NULL);
1719
1720 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
1721 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
1722 break;
1723
1724 case EFI_IFR_TEXT_OP:
1725 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1726 ASSERT (CurrentStatement != NULL);
1727 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
1728 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
1729 break;
1730
1731 case EFI_IFR_RESET_BUTTON_OP:
1732 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1733 ASSERT (CurrentStatement != NULL);
1734 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
1735 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
1736 break;
1737
1738 //
1739 // Questions
1740 //
1741 case EFI_IFR_ACTION_OP:
1742 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1743 ASSERT (CurrentStatement != NULL);
1744 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;
1745
1746 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
1747 //
1748 // No QuestionConfig present, so no configuration string will be processed
1749 //
1750 CurrentStatement->QuestionConfig = 0;
1751 } else {
1752 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
1753 }
1754 break;
1755
1756 case EFI_IFR_REF_OP:
1757 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1758 ASSERT (CurrentStatement != NULL);
1759 Value = &CurrentStatement->HiiValue;
1760 Value->Type = EFI_IFR_TYPE_REF;
1761 if (OpCodeLength >= sizeof (EFI_IFR_REF)) {
1762 CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
1763
1764 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
1765 CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1766
1767 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
1768 CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
1769
1770 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
1771 CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1772 }
1773 }
1774 }
1775 }
1776 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);
1777 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1778 break;
1779
1780 case EFI_IFR_ONE_OF_OP:
1781 case EFI_IFR_NUMERIC_OP:
1782 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1783 ASSERT(CurrentStatement != NULL);
1784
1785 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
1786 Value = &CurrentStatement->HiiValue;
1787
1788 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
1789 case EFI_IFR_NUMERIC_SIZE_1:
1790 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
1791 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
1792 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
1793 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);
1794 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1795 break;
1796
1797 case EFI_IFR_NUMERIC_SIZE_2:
1798 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
1799 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
1800 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));
1801 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);
1802 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1803 break;
1804
1805 case EFI_IFR_NUMERIC_SIZE_4:
1806 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
1807 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
1808 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));
1809 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);
1810 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1811 break;
1812
1813 case EFI_IFR_NUMERIC_SIZE_8:
1814 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
1815 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
1816 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));
1817 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);
1818 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1819 break;
1820
1821 default:
1822 break;
1823 }
1824
1825 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1826
1827 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {
1828 SuppressForOption = TRUE;
1829 }
1830 break;
1831
1832 case EFI_IFR_ORDERED_LIST_OP:
1833 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1834 ASSERT(CurrentStatement != NULL);
1835
1836 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;
1837 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;
1838
1839 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;
1840 CurrentStatement->BufferValue = NULL;
1841
1842 if (Scope != 0) {
1843 SuppressForOption = TRUE;
1844 }
1845 break;
1846
1847 case EFI_IFR_CHECKBOX_OP:
1848 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1849 ASSERT(CurrentStatement != NULL);
1850
1851 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;
1852 CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);
1853 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
1854
1855 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1856
1857 break;
1858
1859 case EFI_IFR_STRING_OP:
1860 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1861 ASSERT (CurrentStatement != NULL);
1862 //
1863 // MinSize is the minimum number of characters that can be accepted for this opcode,
1864 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1865 // The characters are stored as Unicode, so the storage width should multiply 2.
1866 //
1867 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;
1868 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;
1869 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
1870 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;
1871
1872 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1873 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));
1874 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
1875
1876 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1877 break;
1878
1879 case EFI_IFR_PASSWORD_OP:
1880 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1881 ASSERT (CurrentStatement != NULL);
1882 //
1883 // MinSize is the minimum number of characters that can be accepted for this opcode,
1884 // MaxSize is the maximum number of characters that can be accepted for this opcode.
1885 // The characters are stored as Unicode, so the storage width should multiply 2.
1886 //
1887 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));
1888 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));
1889 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
1890
1891 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
1892 CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));
1893 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
1894
1895 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1896 break;
1897
1898 case EFI_IFR_DATE_OP:
1899 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1900 ASSERT(CurrentStatement != NULL);
1901
1902 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;
1903 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
1904
1905 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {
1906 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);
1907
1908 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1909 } else {
1910 //
1911 // Don't assign storage for RTC type of date/time
1912 //
1913 CurrentStatement->Storage = NULL;
1914 CurrentStatement->StorageWidth = 0;
1915 }
1916 break;
1917
1918 case EFI_IFR_TIME_OP:
1919 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1920 ASSERT(CurrentStatement != NULL);
1921
1922 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;
1923 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
1924
1925 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {
1926 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);
1927
1928 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1929 } else {
1930 //
1931 // Don't assign storage for RTC type of date/time
1932 //
1933 CurrentStatement->Storage = NULL;
1934 CurrentStatement->StorageWidth = 0;
1935 }
1936 break;
1937
1938 //
1939 // Default
1940 //
1941 case EFI_IFR_DEFAULT_OP:
1942 //
1943 // EFI_IFR_DEFAULT appear in scope of a Question,
1944 // It creates a default value for the current question.
1945 // A Question may have more than one Default value which have different default types.
1946 //
1947 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
1948 ASSERT (CurrentDefault != NULL);
1949 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
1950
1951 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
1952 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
1953 if (OpCodeLength > OFFSET_OF (EFI_IFR_DEFAULT, Value)) {
1954 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));
1955 ExtendValueToU64 (&CurrentDefault->Value);
1956 }
1957
1958 //
1959 // Insert to Default Value list of current Question
1960 //
1961 InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);
1962
1963 if (Scope != 0) {
1964 InScopeDefault = TRUE;
1965 }
1966 break;
1967
1968 //
1969 // Option
1970 //
1971 case EFI_IFR_ONE_OF_OPTION_OP:
1972 //
1973 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
1974 // It create a selection for use in current Question.
1975 //
1976 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
1977 ASSERT (CurrentOption != NULL);
1978 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
1979 CurrentOption->OpCode = (EFI_IFR_ONE_OF_OPTION *) OpCodeData;
1980
1981 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
1982 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
1983 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
1984 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
1985 ExtendValueToU64 (&CurrentOption->Value);
1986
1987 ConditionalExprCount = GetConditionalExpressionCount(ExpressOption);
1988 if ( ConditionalExprCount > 0) {
1989 //
1990 // Form is inside of suppressif
1991 //
1992 CurrentOption->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1993 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1994 ASSERT (CurrentOption->SuppressExpression != NULL);
1995 CurrentOption->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1996 CurrentOption->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1997 CopyMem (CurrentOption->SuppressExpression->Expression, GetConditionalExpressionList(ExpressOption), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
1998 }
1999
2000 ASSERT (ParentStatement != NULL);
2001 //
2002 // Insert to Option list of current Question
2003 //
2004 InsertTailList (&ParentStatement->OptionListHead, &CurrentOption->Link);
2005 //
2006 // Now we know the Storage width of nested Ordered List
2007 //
2008 if ((ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (ParentStatement->BufferValue == NULL)) {
2009 Width = 1;
2010 switch (CurrentOption->Value.Type) {
2011 case EFI_IFR_TYPE_NUM_SIZE_8:
2012 Width = 1;
2013 break;
2014
2015 case EFI_IFR_TYPE_NUM_SIZE_16:
2016 Width = 2;
2017 break;
2018
2019 case EFI_IFR_TYPE_NUM_SIZE_32:
2020 Width = 4;
2021 break;
2022
2023 case EFI_IFR_TYPE_NUM_SIZE_64:
2024 Width = 8;
2025 break;
2026
2027 default:
2028 //
2029 // Invalid type for Ordered List
2030 //
2031 break;
2032 }
2033
2034 ParentStatement->StorageWidth = (UINT16) (ParentStatement->MaxContainers * Width);
2035 ParentStatement->BufferValue = AllocateZeroPool (ParentStatement->StorageWidth);
2036 ParentStatement->ValueType = CurrentOption->Value.Type;
2037 if (ParentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {
2038 ParentStatement->HiiValue.Buffer = ParentStatement->BufferValue;
2039 ParentStatement->HiiValue.BufferLen = ParentStatement->StorageWidth;
2040 }
2041
2042 InitializeRequestElement (FormSet, ParentStatement, CurrentForm);
2043 }
2044 break;
2045
2046 //
2047 // Conditional
2048 //
2049 case EFI_IFR_NO_SUBMIT_IF_OP:
2050 case EFI_IFR_INCONSISTENT_IF_OP:
2051 //
2052 // Create an Expression node
2053 //
2054 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2055 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));
2056
2057 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {
2058 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;
2059 InsertTailList (&ParentStatement->NoSubmitListHead, &CurrentExpression->Link);
2060 } else {
2061 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;
2062 InsertTailList (&ParentStatement->InconsistentListHead, &CurrentExpression->Link);
2063 }
2064
2065 //
2066 // Take a look at next OpCode to see whether current expression consists
2067 // of single OpCode
2068 //
2069 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2070 SingleOpCodeExpression = TRUE;
2071 }
2072 break;
2073
2074 case EFI_IFR_WARNING_IF_OP:
2075 //
2076 // Create an Expression node
2077 //
2078 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2079 CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *) OpCodeData)->Warning, sizeof (EFI_STRING_ID));
2080 CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeData)->TimeOut;
2081 CurrentExpression->Type = EFI_HII_EXPRESSION_WARNING_IF;
2082 InsertTailList (&ParentStatement->WarningListHead, &CurrentExpression->Link);
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_SUPPRESS_IF_OP:
2094 //
2095 // Question and Option will appear in scope of this OpCode
2096 //
2097 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2098 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;
2099
2100 if (CurrentForm == NULL) {
2101 InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);
2102 } else {
2103 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2104 }
2105
2106 if (SuppressForOption) {
2107 PushConditionalExpression(CurrentExpression, ExpressOption);
2108 } else if (SuppressForQuestion) {
2109 PushConditionalExpression(CurrentExpression, ExpressStatement);
2110 } else {
2111 PushConditionalExpression(CurrentExpression, ExpressForm);
2112 }
2113
2114 //
2115 // Take a look at next OpCode to see whether current expression consists
2116 // of single OpCode
2117 //
2118 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2119 SingleOpCodeExpression = TRUE;
2120 }
2121 break;
2122
2123 case EFI_IFR_GRAY_OUT_IF_OP:
2124 //
2125 // Questions will appear in scope of this OpCode
2126 //
2127 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2128 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;
2129 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2130 PushConditionalExpression(CurrentExpression, ExpressStatement);
2131
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 case EFI_IFR_DISABLE_IF_OP:
2142 //
2143 // The DisableIf expression should only rely on constant, so it could be
2144 // evaluated at initialization and it will not be queued
2145 //
2146 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
2147 ASSERT (CurrentExpression != NULL);
2148 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;
2149 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;
2150 InitializeListHead (&CurrentExpression->OpCodeListHead);
2151
2152 if (CurrentForm != NULL) {
2153 //
2154 // This is DisableIf for Question, enqueue it to Form expression list
2155 //
2156 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2157 PushConditionalExpression(CurrentExpression, ExpressStatement);
2158 }
2159
2160 OpCodeDisabled = FALSE;
2161 InScopeDisable = TRUE;
2162 //
2163 // Take a look at next OpCode to see whether current expression consists
2164 // of single OpCode
2165 //
2166 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2167 SingleOpCodeExpression = TRUE;
2168 }
2169 break;
2170
2171 //
2172 // Expression
2173 //
2174 case EFI_IFR_VALUE_OP:
2175 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2176 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;
2177 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2178
2179 if (InScopeDefault) {
2180 //
2181 // Used for default (EFI_IFR_DEFAULT)
2182 //
2183 CurrentDefault->ValueExpression = CurrentExpression;
2184 } else {
2185 //
2186 // If used for a question, then the question will be read-only
2187 //
2188 //
2189 // Make sure CurrentStatement is not NULL.
2190 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2191 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2192 //
2193 ASSERT (ParentStatement != NULL);
2194 ParentStatement->ValueExpression = CurrentExpression;
2195 }
2196
2197 //
2198 // Take a look at next OpCode to see whether current expression consists
2199 // of single OpCode
2200 //
2201 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2202 SingleOpCodeExpression = TRUE;
2203 }
2204 break;
2205
2206 case EFI_IFR_RULE_OP:
2207 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2208 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;
2209
2210 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;
2211 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2212
2213 //
2214 // Take a look at next OpCode to see whether current expression consists
2215 // of single OpCode
2216 //
2217 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2218 SingleOpCodeExpression = TRUE;
2219 }
2220 break;
2221
2222 case EFI_IFR_READ_OP:
2223 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2224 CurrentExpression->Type = EFI_HII_EXPRESSION_READ;
2225 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2226
2227 //
2228 // Make sure CurrentStatement is not NULL.
2229 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2230 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2231 //
2232 ASSERT (ParentStatement != NULL);
2233 ParentStatement->ReadExpression = CurrentExpression;
2234
2235 //
2236 // Take a look at next OpCode to see whether current expression consists
2237 // of single OpCode
2238 //
2239 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2240 SingleOpCodeExpression = TRUE;
2241 }
2242 break;
2243
2244 case EFI_IFR_WRITE_OP:
2245 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2246 CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;
2247 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2248
2249 //
2250 // Make sure CurrentStatement is not NULL.
2251 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2252 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2253 //
2254 ASSERT (ParentStatement != NULL);
2255 ParentStatement->WriteExpression = CurrentExpression;
2256
2257 //
2258 // Take a look at next OpCode to see whether current expression consists
2259 // of single OpCode
2260 //
2261 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2262 SingleOpCodeExpression = TRUE;
2263 }
2264 break;
2265
2266 //
2267 // Image
2268 //
2269 case EFI_IFR_IMAGE_OP:
2270 //
2271 // Get ScopeOpcode from top of stack
2272 //
2273 PopScope (&ScopeOpCode);
2274 PushScope (ScopeOpCode);
2275
2276 switch (ScopeOpCode) {
2277 case EFI_IFR_FORM_SET_OP:
2278 ImageId = &FormSet->ImageId;
2279 break;
2280
2281 case EFI_IFR_FORM_OP:
2282 case EFI_IFR_FORM_MAP_OP:
2283 ASSERT (CurrentForm != NULL);
2284 ImageId = &CurrentForm->ImageId;
2285 break;
2286
2287 case EFI_IFR_ONE_OF_OPTION_OP:
2288 ImageId = &CurrentOption->ImageId;
2289 break;
2290
2291 default:
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.
2296 //
2297 ASSERT (ParentStatement != NULL);
2298 ImageId = &ParentStatement->ImageId;
2299 break;
2300 }
2301
2302 ASSERT (ImageId != NULL);
2303 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
2304 break;
2305
2306 //
2307 // Refresh
2308 //
2309 case EFI_IFR_REFRESH_OP:
2310 ASSERT (ParentStatement != NULL);
2311 ParentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;
2312 break;
2313
2314 //
2315 // Refresh guid.
2316 //
2317 case EFI_IFR_REFRESH_ID_OP:
2318 ASSERT (ParentStatement != NULL);
2319 CopyMem (&ParentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));
2320 break;
2321
2322 //
2323 // Modal tag
2324 //
2325 case EFI_IFR_MODAL_TAG_OP:
2326 ASSERT (CurrentForm != NULL);
2327 CurrentForm->ModalForm = TRUE;
2328 break;
2329
2330 //
2331 // Lock tag, used by form and statement.
2332 //
2333 case EFI_IFR_LOCKED_OP:
2334 //
2335 // Get ScopeOpcode from top of stack
2336 //
2337 PopScope (&ScopeOpCode);
2338 PushScope (ScopeOpCode);
2339 switch (ScopeOpCode) {
2340 case EFI_IFR_FORM_OP:
2341 case EFI_IFR_FORM_MAP_OP:
2342 ASSERT (CurrentForm != NULL);
2343 CurrentForm->Locked = TRUE;
2344 break;
2345
2346 default:
2347 ASSERT (ParentStatement != NULL);
2348 ParentStatement->Locked = TRUE;
2349 }
2350 break;
2351
2352 //
2353 // Vendor specific
2354 //
2355 case EFI_IFR_GUID_OP:
2356 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
2357 break;
2358
2359 //
2360 // Scope End
2361 //
2362 case EFI_IFR_END_OP:
2363 Status = PopScope (&ScopeOpCode);
2364 if (EFI_ERROR (Status)) {
2365 ResetScopeStack ();
2366 return Status;
2367 }
2368
2369 //
2370 // Parent statement end tag found, update ParentStatement info.
2371 //
2372 if (IsStatementOpCode(ScopeOpCode) && (ParentStatement != NULL) && (ParentStatement->Operand == ScopeOpCode)) {
2373 ParentStatement = ParentStatement->ParentStatement;
2374 }
2375
2376 switch (ScopeOpCode) {
2377 case EFI_IFR_FORM_SET_OP:
2378 //
2379 // End of FormSet, update FormSet IFR binary length
2380 // to stop parsing substantial OpCodes
2381 //
2382 FormSet->IfrBinaryLength = OpCodeOffset;
2383 break;
2384
2385 case EFI_IFR_FORM_OP:
2386 case EFI_IFR_FORM_MAP_OP:
2387 //
2388 // End of Form
2389 //
2390 CurrentForm = NULL;
2391 SuppressForQuestion = FALSE;
2392 break;
2393
2394 case EFI_IFR_ONE_OF_OPTION_OP:
2395 //
2396 // End of Option
2397 //
2398 CurrentOption = NULL;
2399 break;
2400
2401 case EFI_IFR_NO_SUBMIT_IF_OP:
2402 case EFI_IFR_INCONSISTENT_IF_OP:
2403 case EFI_IFR_WARNING_IF_OP:
2404 //
2405 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2406 //
2407 break;
2408
2409 case EFI_IFR_SUPPRESS_IF_OP:
2410 if (SuppressForOption) {
2411 PopConditionalExpression(ExpressOption);
2412 } else if (SuppressForQuestion) {
2413 PopConditionalExpression(ExpressStatement);
2414 } else {
2415 PopConditionalExpression(ExpressForm);
2416 }
2417 break;
2418
2419 case EFI_IFR_GRAY_OUT_IF_OP:
2420 PopConditionalExpression(ExpressStatement);
2421 break;
2422
2423 case EFI_IFR_DISABLE_IF_OP:
2424 if (CurrentForm != NULL) {
2425 PopConditionalExpression(ExpressStatement);
2426 }
2427 InScopeDisable = FALSE;
2428 OpCodeDisabled = FALSE;
2429 break;
2430
2431 case EFI_IFR_ONE_OF_OP:
2432 case EFI_IFR_ORDERED_LIST_OP:
2433 SuppressForOption = FALSE;
2434 break;
2435
2436 case EFI_IFR_DEFAULT_OP:
2437 InScopeDefault = FALSE;
2438 break;
2439
2440 case EFI_IFR_MAP_OP:
2441 //
2442 // Get current Map Expression List.
2443 //
2444 Status = PopMapExpressionList ((VOID **) &MapExpressionList);
2445 if (Status == EFI_ACCESS_DENIED) {
2446 MapExpressionList = NULL;
2447 }
2448 //
2449 // Get current expression.
2450 //
2451 Status = PopCurrentExpression ((VOID **) &CurrentExpression);
2452 ASSERT_EFI_ERROR (Status);
2453 ASSERT (MapScopeDepth > 0);
2454 MapScopeDepth --;
2455 break;
2456
2457 default:
2458 if (IsExpressionOpCode (ScopeOpCode)) {
2459 if (InScopeDisable && CurrentForm == NULL) {
2460 //
2461 // This is DisableIf expression for Form, it should be a constant expression
2462 //
2463 ASSERT (CurrentExpression != NULL);
2464 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
2465 if (EFI_ERROR (Status)) {
2466 return Status;
2467 }
2468
2469 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {
2470 return EFI_INVALID_PARAMETER;
2471 }
2472
2473 OpCodeDisabled = CurrentExpression->Result.Value.b;
2474 //
2475 // DisableIf Expression is only used once and not queued, free it
2476 //
2477 DestroyExpression (CurrentExpression);
2478 }
2479
2480 //
2481 // End of current Expression
2482 //
2483 CurrentExpression = NULL;
2484 }
2485 break;
2486 }
2487 break;
2488
2489 default:
2490 break;
2491 }
2492
2493 if (IsStatementOpCode(Operand)) {
2494 CurrentStatement->ParentStatement = ParentStatement;
2495 if (Scope != 0) {
2496 //
2497 // Scope != 0, other statements or options may nest in this statement.
2498 // Update the ParentStatement info.
2499 //
2500 ParentStatement = CurrentStatement;
2501 }
2502 }
2503 }
2504
2505 return EFI_SUCCESS;
2506 }