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