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