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