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