]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
MdeModulePkg/SetupBrowser: Fix the typo in the comment
[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 FormSet.
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 HiiToLower(RequestElement);
719 Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);
720 } else {
721 StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);
722 }
723
724 if ((Question->Operand == EFI_IFR_PASSWORD_OP) && ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK)) {
725 //
726 // Password with CALLBACK flag is stored in encoded format,
727 // so don't need to append it to <ConfigRequest>
728 //
729 return EFI_SUCCESS;
730 }
731
732 //
733 // Find Formset Storage for this Question
734 //
735 FormsetStorage = GetFstStgFromVarId(FormSet, Question->VarStoreId);
736 ASSERT (FormsetStorage != NULL);
737 StringSize = (FormsetStorage->ConfigRequest != NULL) ? StrSize (FormsetStorage->ConfigRequest) : sizeof (CHAR16);
738 MaxLen = StringSize / sizeof (CHAR16) + FormsetStorage->SpareStrLen;
739
740 //
741 // Append <RequestElement> to <ConfigRequest>
742 //
743 if (StrLen > FormsetStorage->SpareStrLen) {
744 //
745 // Old String buffer is not sufficient for RequestElement, allocate a new one
746 //
747 MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;
748 NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));
749 ASSERT (NewStr != NULL);
750 if (FormsetStorage->ConfigRequest != NULL) {
751 CopyMem (NewStr, FormsetStorage->ConfigRequest, StringSize);
752 FreePool (FormsetStorage->ConfigRequest);
753 }
754 FormsetStorage->ConfigRequest = NewStr;
755 FormsetStorage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
756 }
757
758 StrCatS (FormsetStorage->ConfigRequest, MaxLen, RequestElement);
759 FormsetStorage->ElementCount++;
760 FormsetStorage->SpareStrLen -= StrLen;
761
762 //
763 // Update the Config Request info saved in the form.
764 //
765 ConfigInfo = NULL;
766 Find = FALSE;
767 Link = GetFirstNode (&Form->ConfigRequestHead);
768 while (!IsNull (&Form->ConfigRequestHead, Link)) {
769 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
770
771 if (ConfigInfo != NULL && ConfigInfo->Storage == FormsetStorage->BrowserStorage) {
772 Find = TRUE;
773 break;
774 }
775
776 Link = GetNextNode (&Form->ConfigRequestHead, Link);
777 }
778
779 if (!Find) {
780 ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST));
781 ASSERT (ConfigInfo != NULL);
782 ConfigInfo->Signature = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE;
783 ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (FormsetStorage->ConfigHdr), FormsetStorage->ConfigHdr);
784 ASSERT (ConfigInfo->ConfigRequest != NULL);
785 ConfigInfo->SpareStrLen = 0;
786 ConfigInfo->Storage = FormsetStorage->BrowserStorage;
787 InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link);
788 }
789 StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16);
790 MaxLen = StringSize / sizeof (CHAR16) + ConfigInfo->SpareStrLen;
791
792 //
793 // Append <RequestElement> to <ConfigRequest>
794 //
795 if (StrLen > ConfigInfo->SpareStrLen) {
796 //
797 // Old String buffer is not sufficient for RequestElement, allocate a new one
798 //
799 MaxLen = StringSize / sizeof (CHAR16) + CONFIG_REQUEST_STRING_INCREMENTAL;
800 NewStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));
801 ASSERT (NewStr != NULL);
802 if (ConfigInfo->ConfigRequest != NULL) {
803 CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize);
804 FreePool (ConfigInfo->ConfigRequest);
805 }
806 ConfigInfo->ConfigRequest = NewStr;
807 ConfigInfo->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;
808 }
809
810 StrCatS (ConfigInfo->ConfigRequest, MaxLen, RequestElement);
811 ConfigInfo->ElementCount++;
812 ConfigInfo->SpareStrLen -= StrLen;
813 return EFI_SUCCESS;
814 }
815
816
817 /**
818 Free resources of a Expression.
819
820 @param FormSet Pointer of the Expression
821
822 **/
823 VOID
824 DestroyExpression (
825 IN FORM_EXPRESSION *Expression
826 )
827 {
828 LIST_ENTRY *Link;
829 EXPRESSION_OPCODE *OpCode;
830 LIST_ENTRY *SubExpressionLink;
831 FORM_EXPRESSION *SubExpression;
832
833 while (!IsListEmpty (&Expression->OpCodeListHead)) {
834 Link = GetFirstNode (&Expression->OpCodeListHead);
835 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);
836 RemoveEntryList (&OpCode->Link);
837
838 if (OpCode->ValueList != NULL) {
839 FreePool (OpCode->ValueList);
840 }
841
842 if (OpCode->ValueName != NULL) {
843 FreePool (OpCode->ValueName);
844 }
845
846 if (OpCode->MapExpressionList.ForwardLink != NULL) {
847 while (!IsListEmpty (&OpCode->MapExpressionList)) {
848 SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);
849 SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);
850 RemoveEntryList(&SubExpression->Link);
851 DestroyExpression (SubExpression);
852 }
853 }
854 }
855
856 //
857 // Free this Expression
858 //
859 FreePool (Expression);
860 }
861
862 /**
863 Free resources of a storage.
864
865 @param Storage Pointer of the storage
866
867 **/
868 VOID
869 DestroyStorage (
870 IN FORMSET_STORAGE *Storage
871 )
872 {
873 if (Storage == NULL) {
874 return;
875 }
876
877 if (Storage->ConfigRequest != NULL) {
878 FreePool (Storage->ConfigRequest);
879 }
880
881 FreePool (Storage);
882 }
883
884
885 /**
886 Free resources of a Statement.
887
888 @param FormSet Pointer of the FormSet
889 @param Statement Pointer of the Statement
890
891 **/
892 VOID
893 DestroyStatement (
894 IN FORM_BROWSER_FORMSET *FormSet,
895 IN OUT FORM_BROWSER_STATEMENT *Statement
896 )
897 {
898 LIST_ENTRY *Link;
899 QUESTION_DEFAULT *Default;
900 QUESTION_OPTION *Option;
901 FORM_EXPRESSION *Expression;
902
903 //
904 // Free Default value List
905 //
906 while (!IsListEmpty (&Statement->DefaultListHead)) {
907 Link = GetFirstNode (&Statement->DefaultListHead);
908 Default = QUESTION_DEFAULT_FROM_LINK (Link);
909 RemoveEntryList (&Default->Link);
910
911 if (Default->Value.Buffer != NULL) {
912 FreePool (Default->Value.Buffer);
913 }
914 FreePool (Default);
915 }
916
917 //
918 // Free Options List
919 //
920 while (!IsListEmpty (&Statement->OptionListHead)) {
921 Link = GetFirstNode (&Statement->OptionListHead);
922 Option = QUESTION_OPTION_FROM_LINK (Link);
923 if (Option->SuppressExpression != NULL) {
924 FreePool (Option->SuppressExpression);
925 }
926 RemoveEntryList (&Option->Link);
927
928 FreePool (Option);
929 }
930
931 //
932 // Free Inconsistent List
933 //
934 while (!IsListEmpty (&Statement->InconsistentListHead)) {
935 Link = GetFirstNode (&Statement->InconsistentListHead);
936 Expression = FORM_EXPRESSION_FROM_LINK (Link);
937 RemoveEntryList (&Expression->Link);
938
939 DestroyExpression (Expression);
940 }
941
942 //
943 // Free NoSubmit List
944 //
945 while (!IsListEmpty (&Statement->NoSubmitListHead)) {
946 Link = GetFirstNode (&Statement->NoSubmitListHead);
947 Expression = FORM_EXPRESSION_FROM_LINK (Link);
948 RemoveEntryList (&Expression->Link);
949
950 DestroyExpression (Expression);
951 }
952
953 //
954 // Free WarningIf List
955 //
956 while (!IsListEmpty (&Statement->WarningListHead)) {
957 Link = GetFirstNode (&Statement->WarningListHead);
958 Expression = FORM_EXPRESSION_FROM_LINK (Link);
959 RemoveEntryList (&Expression->Link);
960
961 DestroyExpression (Expression);
962 }
963
964 if (Statement->Expression != NULL) {
965 FreePool (Statement->Expression);
966 }
967
968 if (Statement->VariableName != NULL) {
969 FreePool (Statement->VariableName);
970 }
971 if (Statement->BlockName != NULL) {
972 FreePool (Statement->BlockName);
973 }
974 if (Statement->BufferValue != NULL) {
975 FreePool (Statement->BufferValue);
976 }
977 if (Statement->Operand == EFI_IFR_STRING_OP || Statement->Operand == EFI_IFR_PASSWORD_OP) {
978 DeleteString(Statement->HiiValue.Value.string, FormSet->HiiHandle);
979 }
980 }
981
982
983 /**
984 Free resources of a Form.
985
986 @param FormSet Pointer of the FormSet
987 @param Form Pointer of the Form.
988
989 **/
990 VOID
991 DestroyForm (
992 IN FORM_BROWSER_FORMSET *FormSet,
993 IN OUT FORM_BROWSER_FORM *Form
994 )
995 {
996 LIST_ENTRY *Link;
997 FORM_EXPRESSION *Expression;
998 FORM_BROWSER_STATEMENT *Statement;
999 FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
1000
1001 //
1002 // Free Form Expressions
1003 //
1004 while (!IsListEmpty (&Form->ExpressionListHead)) {
1005 Link = GetFirstNode (&Form->ExpressionListHead);
1006 Expression = FORM_EXPRESSION_FROM_LINK (Link);
1007 RemoveEntryList (&Expression->Link);
1008
1009 DestroyExpression (Expression);
1010 }
1011
1012 //
1013 // Free Statements/Questions
1014 //
1015 while (!IsListEmpty (&Form->StatementListHead)) {
1016 Link = GetFirstNode (&Form->StatementListHead);
1017 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
1018 RemoveEntryList (&Statement->Link);
1019
1020 DestroyStatement (FormSet, Statement);
1021 }
1022
1023 //
1024 // Free ConfigRequest string.
1025 //
1026 while (!IsListEmpty (&Form->ConfigRequestHead)) {
1027 Link = GetFirstNode (&Form->ConfigRequestHead);
1028 ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
1029 RemoveEntryList (&ConfigInfo->Link);
1030
1031 FreePool (ConfigInfo->ConfigRequest);
1032 FreePool (ConfigInfo);
1033 }
1034
1035 if (Form->SuppressExpression != NULL) {
1036 FreePool (Form->SuppressExpression);
1037 }
1038
1039 UiFreeMenuList (&Form->FormViewListHead);
1040
1041 //
1042 // Free this Form
1043 //
1044 FreePool (Form);
1045 }
1046
1047
1048 /**
1049 Free resources allocated for a FormSet.
1050
1051 @param FormSet Pointer of the FormSet
1052
1053 **/
1054 VOID
1055 DestroyFormSet (
1056 IN OUT FORM_BROWSER_FORMSET *FormSet
1057 )
1058 {
1059 LIST_ENTRY *Link;
1060 FORMSET_STORAGE *Storage;
1061 FORMSET_DEFAULTSTORE *DefaultStore;
1062 FORM_EXPRESSION *Expression;
1063 FORM_BROWSER_FORM *Form;
1064
1065 if (FormSet->IfrBinaryData == NULL) {
1066 //
1067 // Uninitialized FormSet
1068 //
1069 FreePool (FormSet);
1070 return;
1071 }
1072
1073 //
1074 // Free IFR binary buffer
1075 //
1076 FreePool (FormSet->IfrBinaryData);
1077
1078 //
1079 // Free FormSet Storage
1080 //
1081 if (FormSet->StorageListHead.ForwardLink != NULL) {
1082 while (!IsListEmpty (&FormSet->StorageListHead)) {
1083 Link = GetFirstNode (&FormSet->StorageListHead);
1084 Storage = FORMSET_STORAGE_FROM_LINK (Link);
1085 RemoveEntryList (&Storage->Link);
1086
1087 DestroyStorage (Storage);
1088 }
1089 }
1090
1091 //
1092 // Free FormSet Default Store
1093 //
1094 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
1095 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
1096 Link = GetFirstNode (&FormSet->DefaultStoreListHead);
1097 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);
1098 RemoveEntryList (&DefaultStore->Link);
1099
1100 FreePool (DefaultStore);
1101 }
1102 }
1103
1104 //
1105 // Free Formset Expressions
1106 //
1107 while (!IsListEmpty (&FormSet->ExpressionListHead)) {
1108 Link = GetFirstNode (&FormSet->ExpressionListHead);
1109 Expression = FORM_EXPRESSION_FROM_LINK (Link);
1110 RemoveEntryList (&Expression->Link);
1111
1112 DestroyExpression (Expression);
1113 }
1114
1115 //
1116 // Free Forms
1117 //
1118 if (FormSet->FormListHead.ForwardLink != NULL) {
1119 while (!IsListEmpty (&FormSet->FormListHead)) {
1120 Link = GetFirstNode (&FormSet->FormListHead);
1121 Form = FORM_BROWSER_FORM_FROM_LINK (Link);
1122 RemoveEntryList (&Form->Link);
1123
1124 DestroyForm (FormSet, Form);
1125 }
1126 }
1127
1128 if (FormSet->StatementBuffer != NULL) {
1129 FreePool (FormSet->StatementBuffer);
1130 }
1131 if (FormSet->ExpressionBuffer != NULL) {
1132 FreePool (FormSet->ExpressionBuffer);
1133 }
1134
1135 FreePool (FormSet);
1136 }
1137
1138
1139 /**
1140 Tell whether this Operand is an Expression OpCode or not
1141
1142 @param Operand Operand of an IFR OpCode.
1143
1144 @retval TRUE This is an Expression OpCode.
1145 @retval FALSE Not an Expression OpCode.
1146
1147 **/
1148 BOOLEAN
1149 IsExpressionOpCode (
1150 IN UINT8 Operand
1151 )
1152 {
1153 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||
1154 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) ||
1155 ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||
1156 (Operand == EFI_IFR_CATENATE_OP) ||
1157 (Operand == EFI_IFR_TO_LOWER_OP) ||
1158 (Operand == EFI_IFR_TO_UPPER_OP) ||
1159 (Operand == EFI_IFR_MAP_OP) ||
1160 (Operand == EFI_IFR_VERSION_OP) ||
1161 (Operand == EFI_IFR_SECURITY_OP) ||
1162 (Operand == EFI_IFR_MATCH2_OP)) {
1163 return TRUE;
1164 } else {
1165 return FALSE;
1166 }
1167 }
1168
1169 /**
1170 Tell whether this Operand is an Statement OpCode.
1171
1172 @param Operand Operand of an IFR OpCode.
1173
1174 @retval TRUE This is an Statement OpCode.
1175 @retval FALSE Not an Statement OpCode.
1176
1177 **/
1178 BOOLEAN
1179 IsStatementOpCode (
1180 IN UINT8 Operand
1181 )
1182 {
1183 if ((Operand == EFI_IFR_SUBTITLE_OP) ||
1184 (Operand == EFI_IFR_TEXT_OP) ||
1185 (Operand == EFI_IFR_RESET_BUTTON_OP) ||
1186 (Operand == EFI_IFR_REF_OP) ||
1187 (Operand == EFI_IFR_ACTION_OP) ||
1188 (Operand == EFI_IFR_NUMERIC_OP) ||
1189 (Operand == EFI_IFR_ORDERED_LIST_OP) ||
1190 (Operand == EFI_IFR_CHECKBOX_OP) ||
1191 (Operand == EFI_IFR_STRING_OP) ||
1192 (Operand == EFI_IFR_PASSWORD_OP) ||
1193 (Operand == EFI_IFR_DATE_OP) ||
1194 (Operand == EFI_IFR_TIME_OP) ||
1195 (Operand == EFI_IFR_GUID_OP) ||
1196 (Operand == EFI_IFR_ONE_OF_OP)) {
1197 return TRUE;
1198 } else {
1199 return FALSE;
1200 }
1201 }
1202
1203 /**
1204 Tell whether this Operand is an known OpCode.
1205
1206 @param Operand Operand of an IFR OpCode.
1207
1208 @retval TRUE This is an Statement OpCode.
1209 @retval FALSE Not an Statement OpCode.
1210
1211 **/
1212 BOOLEAN
1213 IsUnKnownOpCode (
1214 IN UINT8 Operand
1215 )
1216 {
1217 return Operand > EFI_IFR_MATCH2_OP ? TRUE : FALSE;
1218 }
1219
1220 /**
1221 Calculate number of Statemens(Questions) and Expression OpCodes.
1222
1223 @param FormSet The FormSet to be counted.
1224 @param NumberOfStatement Number of Statemens(Questions)
1225 @param NumberOfExpression Number of Expression OpCodes
1226
1227 **/
1228 VOID
1229 CountOpCodes (
1230 IN FORM_BROWSER_FORMSET *FormSet,
1231 IN OUT UINT16 *NumberOfStatement,
1232 IN OUT UINT16 *NumberOfExpression
1233 )
1234 {
1235 UINT16 StatementCount;
1236 UINT16 ExpressionCount;
1237 UINT8 *OpCodeData;
1238 UINTN Offset;
1239 UINTN OpCodeLen;
1240
1241 Offset = 0;
1242 StatementCount = 0;
1243 ExpressionCount = 0;
1244
1245 while (Offset < FormSet->IfrBinaryLength) {
1246 OpCodeData = FormSet->IfrBinaryData + Offset;
1247 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
1248 Offset += OpCodeLen;
1249
1250 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {
1251 ExpressionCount++;
1252 } else {
1253 StatementCount++;
1254 }
1255 }
1256
1257 *NumberOfStatement = StatementCount;
1258 *NumberOfExpression = ExpressionCount;
1259 }
1260
1261
1262
1263 /**
1264 Parse opcodes in the formset IFR binary.
1265
1266 @param FormSet Pointer of the FormSet data structure.
1267
1268 @retval EFI_SUCCESS Opcode parse success.
1269 @retval Other Opcode parse fail.
1270
1271 **/
1272 EFI_STATUS
1273 ParseOpCodes (
1274 IN FORM_BROWSER_FORMSET *FormSet
1275 )
1276 {
1277 EFI_STATUS Status;
1278 FORM_BROWSER_FORM *CurrentForm;
1279 FORM_BROWSER_STATEMENT *CurrentStatement;
1280 FORM_BROWSER_STATEMENT *ParentStatement;
1281 EXPRESSION_OPCODE *ExpressionOpCode;
1282 FORM_EXPRESSION *CurrentExpression;
1283 UINT8 Operand;
1284 UINT8 Scope;
1285 UINTN OpCodeOffset;
1286 UINTN OpCodeLength;
1287 UINT8 *OpCodeData;
1288 UINT8 ScopeOpCode;
1289 FORMSET_STORAGE *Storage;
1290 FORMSET_DEFAULTSTORE *DefaultStore;
1291 QUESTION_DEFAULT *CurrentDefault;
1292 QUESTION_OPTION *CurrentOption;
1293 UINT8 Width;
1294 UINT16 NumberOfStatement;
1295 UINT16 NumberOfExpression;
1296 EFI_IMAGE_ID *ImageId;
1297 BOOLEAN SuppressForQuestion;
1298 BOOLEAN SuppressForOption;
1299 UINT16 DepthOfDisable;
1300 BOOLEAN OpCodeDisabled;
1301 BOOLEAN SingleOpCodeExpression;
1302 BOOLEAN InScopeDefault;
1303 EFI_HII_VALUE *Value;
1304 EFI_IFR_FORM_MAP_METHOD *MapMethod;
1305 UINT8 MapScopeDepth;
1306 LIST_ENTRY *Link;
1307 FORMSET_STORAGE *VarStorage;
1308 LIST_ENTRY *MapExpressionList;
1309 EFI_VARSTORE_ID TempVarstoreId;
1310 BOOLEAN InScopeDisable;
1311 INTN ConditionalExprCount;
1312 BOOLEAN InUnknownScope;
1313 UINT8 UnknownDepth;
1314
1315 SuppressForQuestion = FALSE;
1316 SuppressForOption = FALSE;
1317 InScopeDisable = FALSE;
1318 DepthOfDisable = 0;
1319 OpCodeDisabled = FALSE;
1320 SingleOpCodeExpression = FALSE;
1321 InScopeDefault = FALSE;
1322 CurrentExpression = NULL;
1323 CurrentDefault = NULL;
1324 CurrentOption = NULL;
1325 ImageId = NULL;
1326 MapMethod = NULL;
1327 MapScopeDepth = 0;
1328 Link = NULL;
1329 VarStorage = NULL;
1330 MapExpressionList = NULL;
1331 TempVarstoreId = 0;
1332 ConditionalExprCount = 0;
1333 InUnknownScope = FALSE;
1334 UnknownDepth = 0;
1335
1336 //
1337 // Get the number of Statements and Expressions
1338 //
1339 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
1340
1341 mStatementIndex = 0;
1342 mUsedQuestionId = 1;
1343 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
1344 if (FormSet->StatementBuffer == NULL) {
1345 return EFI_OUT_OF_RESOURCES;
1346 }
1347
1348 mExpressionOpCodeIndex = 0;
1349 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));
1350 if (FormSet->ExpressionBuffer == NULL) {
1351 return EFI_OUT_OF_RESOURCES;
1352 }
1353
1354 InitializeListHead (&FormSet->StatementListOSF);
1355 InitializeListHead (&FormSet->StorageListHead);
1356 InitializeListHead (&FormSet->SaveFailStorageListHead);
1357 InitializeListHead (&FormSet->DefaultStoreListHead);
1358 InitializeListHead (&FormSet->FormListHead);
1359 InitializeListHead (&FormSet->ExpressionListHead);
1360 ResetCurrentExpressionStack ();
1361 ResetMapExpressionListStack ();
1362
1363 CurrentForm = NULL;
1364 CurrentStatement = NULL;
1365 ParentStatement = NULL;
1366
1367 ResetScopeStack ();
1368
1369 OpCodeOffset = 0;
1370 while (OpCodeOffset < FormSet->IfrBinaryLength) {
1371 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;
1372
1373 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
1374 OpCodeOffset += OpCodeLength;
1375 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
1376 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;
1377
1378 if (InUnknownScope) {
1379 if (Operand == EFI_IFR_END_OP) {
1380 UnknownDepth --;
1381
1382 if (UnknownDepth == 0) {
1383 InUnknownScope = FALSE;
1384 }
1385 } else {
1386 if (Scope != 0) {
1387 UnknownDepth ++;
1388 }
1389 }
1390
1391 continue;
1392 }
1393
1394 if (IsUnKnownOpCode(Operand)) {
1395 if (Scope != 0) {
1396 InUnknownScope = TRUE;
1397 UnknownDepth ++;
1398 }
1399
1400 continue;
1401 }
1402
1403 //
1404 // If scope bit set, push onto scope stack
1405 //
1406 if (Scope != 0) {
1407 PushScope (Operand);
1408 }
1409
1410 if (OpCodeDisabled) {
1411 //
1412 // DisableIf Expression is evaluated to be TRUE, try to find its end.
1413 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END
1414 //
1415 if (Operand == EFI_IFR_DISABLE_IF_OP) {
1416 DepthOfDisable++;
1417 } else if (Operand == EFI_IFR_END_OP) {
1418 Status = PopScope (&ScopeOpCode);
1419 if (EFI_ERROR (Status)) {
1420 return Status;
1421 }
1422
1423 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {
1424 if (DepthOfDisable == 0) {
1425 InScopeDisable = FALSE;
1426 OpCodeDisabled = FALSE;
1427 } else {
1428 DepthOfDisable--;
1429 }
1430 }
1431 }
1432 continue;
1433 }
1434
1435 if (IsExpressionOpCode (Operand)) {
1436 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];
1437 mExpressionOpCodeIndex++;
1438
1439 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;
1440 ExpressionOpCode->Operand = Operand;
1441 Value = &ExpressionOpCode->Value;
1442
1443 switch (Operand) {
1444 case EFI_IFR_EQ_ID_VAL_OP:
1445 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1446
1447 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1448 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));
1449 break;
1450
1451 case EFI_IFR_EQ_ID_ID_OP:
1452 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));
1453 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));
1454 break;
1455
1456 case EFI_IFR_EQ_ID_VAL_LIST_OP:
1457 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1458 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ListLength, sizeof (UINT16));
1459 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->ValueList);
1460 break;
1461
1462 case EFI_IFR_TO_STRING_OP:
1463 case EFI_IFR_FIND_OP:
1464 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;
1465 break;
1466
1467 case EFI_IFR_STRING_REF1_OP:
1468 Value->Type = EFI_IFR_TYPE_STRING;
1469 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));
1470 break;
1471
1472 case EFI_IFR_RULE_REF_OP:
1473 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;
1474 break;
1475
1476 case EFI_IFR_SPAN_OP:
1477 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;
1478 break;
1479
1480 case EFI_IFR_THIS_OP:
1481 ASSERT (ParentStatement != NULL);
1482 ExpressionOpCode->QuestionId = ParentStatement->QuestionId;
1483 break;
1484
1485 case EFI_IFR_SECURITY_OP:
1486 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_SECURITY *) OpCodeData)->Permissions, sizeof (EFI_GUID));
1487 break;
1488
1489 case EFI_IFR_MATCH2_OP:
1490 CopyMem (&ExpressionOpCode->Guid, &((EFI_IFR_MATCH2 *) OpCodeData)->SyntaxType, sizeof (EFI_GUID));
1491 break;
1492
1493 case EFI_IFR_GET_OP:
1494 case EFI_IFR_SET_OP:
1495 CopyMem (&TempVarstoreId, &((EFI_IFR_GET *) OpCodeData)->VarStoreId, sizeof (TempVarstoreId));
1496 if (TempVarstoreId != 0) {
1497 if (FormSet->StorageListHead.ForwardLink != NULL) {
1498 Link = GetFirstNode (&FormSet->StorageListHead);
1499 while (!IsNull (&FormSet->StorageListHead, Link)) {
1500 VarStorage = FORMSET_STORAGE_FROM_LINK (Link);
1501 if (VarStorage->VarStoreId == ((EFI_IFR_GET *) OpCodeData)->VarStoreId) {
1502 ExpressionOpCode->VarStorage = VarStorage->BrowserStorage;
1503 break;
1504 }
1505 Link = GetNextNode (&FormSet->StorageListHead, Link);
1506 }
1507 }
1508 if (ExpressionOpCode->VarStorage == NULL) {
1509 //
1510 // VarStorage is not found.
1511 //
1512 return EFI_INVALID_PARAMETER;
1513 }
1514 }
1515 ExpressionOpCode->ValueType = ((EFI_IFR_GET *) OpCodeData)->VarStoreType;
1516 switch (ExpressionOpCode->ValueType) {
1517 case EFI_IFR_TYPE_BOOLEAN:
1518 case EFI_IFR_TYPE_NUM_SIZE_8:
1519 ExpressionOpCode->ValueWidth = 1;
1520 break;
1521
1522 case EFI_IFR_TYPE_NUM_SIZE_16:
1523 case EFI_IFR_TYPE_STRING:
1524 ExpressionOpCode->ValueWidth = 2;
1525 break;
1526
1527 case EFI_IFR_TYPE_NUM_SIZE_32:
1528 ExpressionOpCode->ValueWidth = 4;
1529 break;
1530
1531 case EFI_IFR_TYPE_NUM_SIZE_64:
1532 ExpressionOpCode->ValueWidth = 8;
1533 break;
1534
1535 case EFI_IFR_TYPE_DATE:
1536 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_DATE);
1537 break;
1538
1539 case EFI_IFR_TYPE_TIME:
1540 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);
1541 break;
1542
1543 case EFI_IFR_TYPE_REF:
1544 ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);
1545 break;
1546
1547 case EFI_IFR_TYPE_OTHER:
1548 case EFI_IFR_TYPE_UNDEFINED:
1549 case EFI_IFR_TYPE_ACTION:
1550 case EFI_IFR_TYPE_BUFFER:
1551 default:
1552 //
1553 // Invalid value type for Get/Set opcode.
1554 //
1555 return EFI_INVALID_PARAMETER;
1556 }
1557 CopyMem (&ExpressionOpCode->VarStoreInfo.VarName, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarName, sizeof (EFI_STRING_ID));
1558 CopyMem (&ExpressionOpCode->VarStoreInfo.VarOffset, &((EFI_IFR_GET *) OpCodeData)->VarStoreInfo.VarOffset, sizeof (UINT16));
1559 if ((ExpressionOpCode->VarStorage != NULL) &&
1560 (ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_NAME_VALUE ||
1561 ExpressionOpCode->VarStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
1562 ExpressionOpCode->ValueName = GetToken (ExpressionOpCode->VarStoreInfo.VarName, FormSet->HiiHandle);
1563 if (ExpressionOpCode->ValueName == NULL) {
1564 //
1565 // String ID is invalid.
1566 //
1567 return EFI_INVALID_PARAMETER;
1568 }
1569 }
1570 break;
1571
1572 case EFI_IFR_QUESTION_REF1_OP:
1573 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1574 break;
1575
1576 case EFI_IFR_QUESTION_REF3_OP:
1577 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {
1578 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1579
1580 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {
1581 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));
1582 }
1583 }
1584 break;
1585
1586 //
1587 // constant
1588 //
1589 case EFI_IFR_TRUE_OP:
1590 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1591 Value->Value.b = TRUE;
1592 break;
1593
1594 case EFI_IFR_FALSE_OP:
1595 Value->Type = EFI_IFR_TYPE_BOOLEAN;
1596 Value->Value.b = FALSE;
1597 break;
1598
1599 case EFI_IFR_ONE_OP:
1600 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1601 Value->Value.u8 = 1;
1602 break;
1603
1604 case EFI_IFR_ZERO_OP:
1605 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1606 Value->Value.u8 = 0;
1607 break;
1608
1609 case EFI_IFR_ONES_OP:
1610 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1611 Value->Value.u64 = 0xffffffffffffffffULL;
1612 break;
1613
1614 case EFI_IFR_UINT8_OP:
1615 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1616 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;
1617 break;
1618
1619 case EFI_IFR_UINT16_OP:
1620 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1621 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));
1622 break;
1623
1624 case EFI_IFR_UINT32_OP:
1625 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1626 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));
1627 break;
1628
1629 case EFI_IFR_UINT64_OP:
1630 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1631 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));
1632 break;
1633
1634 case EFI_IFR_UNDEFINED_OP:
1635 Value->Type = EFI_IFR_TYPE_UNDEFINED;
1636 break;
1637
1638 case EFI_IFR_VERSION_OP:
1639 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1640 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;
1641 break;
1642
1643 default:
1644 break;
1645 }
1646 //
1647 // Create sub expression nested in MAP opcode
1648 //
1649 if (CurrentExpression == NULL && MapScopeDepth > 0) {
1650 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
1651 ASSERT (MapExpressionList != NULL);
1652 InsertTailList (MapExpressionList, &CurrentExpression->Link);
1653 if (Scope == 0) {
1654 SingleOpCodeExpression = TRUE;
1655 }
1656 }
1657 ASSERT (CurrentExpression != NULL);
1658 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);
1659 if (Operand == EFI_IFR_MAP_OP) {
1660 //
1661 // Store current Map Expression List.
1662 //
1663 if (MapExpressionList != NULL) {
1664 PushMapExpressionList (MapExpressionList);
1665 }
1666 //
1667 // Initialize new Map Expression List.
1668 //
1669 MapExpressionList = &ExpressionOpCode->MapExpressionList;
1670 InitializeListHead (MapExpressionList);
1671 //
1672 // Store current expression.
1673 //
1674 PushCurrentExpression (CurrentExpression);
1675 CurrentExpression = NULL;
1676 MapScopeDepth ++;
1677 } else if (SingleOpCodeExpression) {
1678 //
1679 // There are two cases to indicate the end of an Expression:
1680 // for single OpCode expression: one Expression OpCode
1681 // for expression consists of more than one OpCode: EFI_IFR_END
1682 //
1683 SingleOpCodeExpression = FALSE;
1684
1685 if (InScopeDisable && CurrentForm == NULL) {
1686 //
1687 // This is DisableIf expression for Form, it should be a constant expression
1688 //
1689 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
1690 if (EFI_ERROR (Status)) {
1691 return Status;
1692 }
1693
1694 OpCodeDisabled = IsTrue(&CurrentExpression->Result);
1695 }
1696
1697 CurrentExpression = NULL;
1698 }
1699
1700 continue;
1701 }
1702
1703 //
1704 // Parse the Opcode
1705 //
1706 switch (Operand) {
1707
1708 case EFI_IFR_FORM_SET_OP:
1709 //
1710 // Check the formset GUID
1711 //
1712 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {
1713 return EFI_INVALID_PARAMETER;
1714 }
1715
1716 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
1717 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
1718 FormSet->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;//save the opcode address of formset
1719
1720 if (OpCodeLength > OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
1721 //
1722 // The formset OpCode contains ClassGuid
1723 //
1724 FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);
1725 CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));
1726 }
1727 break;
1728
1729 case EFI_IFR_FORM_OP:
1730 //
1731 // Create a new Form for this FormSet
1732 //
1733 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1734 ASSERT (CurrentForm != NULL);
1735 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1736 InitializeListHead (&CurrentForm->ExpressionListHead);
1737 InitializeListHead (&CurrentForm->StatementListHead);
1738 InitializeListHead (&CurrentForm->ConfigRequestHead);
1739 InitializeListHead (&CurrentForm->FormViewListHead);
1740
1741 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1742 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1743 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
1744
1745 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
1746 if ( ConditionalExprCount > 0) {
1747 //
1748 // Form is inside of suppressif
1749 //
1750 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1751 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1752 ASSERT (CurrentForm->SuppressExpression != NULL);
1753 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1754 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1755 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
1756 }
1757
1758 if (Scope != 0) {
1759 //
1760 // Enter scope of a Form, suppressif will be used for Question or Option
1761 //
1762 SuppressForQuestion = TRUE;
1763 }
1764
1765 //
1766 // Insert into Form list of this FormSet
1767 //
1768 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1769 break;
1770
1771 case EFI_IFR_FORM_MAP_OP:
1772 //
1773 // Create a new Form for this FormSet
1774 //
1775 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
1776 ASSERT (CurrentForm != NULL);
1777 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
1778 InitializeListHead (&CurrentForm->ExpressionListHead);
1779 InitializeListHead (&CurrentForm->StatementListHead);
1780 InitializeListHead (&CurrentForm->ConfigRequestHead);
1781 InitializeListHead (&CurrentForm->FormViewListHead);
1782
1783 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
1784
1785 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1786 //
1787 // FormMap Form must contain at least one Map Method.
1788 //
1789 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {
1790 return EFI_INVALID_PARAMETER;
1791 }
1792 //
1793 // Try to find the standard form map method.
1794 //
1795 while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {
1796 if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {
1797 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1798 CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
1799 break;
1800 }
1801 MapMethod ++;
1802 }
1803 //
1804 // If the standard form map method is not found, the first map method title will be used.
1805 //
1806 if (CurrentForm->FormTitle == 0) {
1807 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));
1808 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));
1809 }
1810
1811 ConditionalExprCount = GetConditionalExpressionCount(ExpressForm);
1812 if ( ConditionalExprCount > 0) {
1813 //
1814 // Form is inside of suppressif
1815 //
1816 CurrentForm->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
1817 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
1818 ASSERT (CurrentForm->SuppressExpression != NULL);
1819 CurrentForm->SuppressExpression->Count = (UINTN) ConditionalExprCount;
1820 CurrentForm->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
1821 CopyMem (CurrentForm->SuppressExpression->Expression, GetConditionalExpressionList(ExpressForm), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
1822 }
1823
1824 if (Scope != 0) {
1825 //
1826 // Enter scope of a Form, suppressif will be used for Question or Option
1827 //
1828 SuppressForQuestion = TRUE;
1829 }
1830
1831 //
1832 // Insert into Form list of this FormSet
1833 //
1834 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);
1835 break;
1836
1837 //
1838 // Storage
1839 //
1840 case EFI_IFR_VARSTORE_OP:
1841 //
1842 // Create a buffer Storage for this FormSet
1843 //
1844 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_BUFFER, OpCodeData);
1845 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1846 break;
1847
1848 case EFI_IFR_VARSTORE_NAME_VALUE_OP:
1849 //
1850 // Create a name/value Storage for this FormSet
1851 //
1852 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_NAME_VALUE, OpCodeData);
1853 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1854 break;
1855
1856 case EFI_IFR_VARSTORE_EFI_OP:
1857 //
1858 // Create a EFI variable Storage for this FormSet
1859 //
1860 if (OpCodeLength < sizeof (EFI_IFR_VARSTORE_EFI)) {
1861 //
1862 // Create efi varstore with format follow UEFI spec before 2.3.1.
1863 //
1864 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE, OpCodeData);
1865 } else {
1866 //
1867 // Create efi varstore with format follow UEFI spec 2.3.1 and later.
1868 //
1869 Storage = CreateStorage (FormSet, EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER, OpCodeData);
1870 }
1871 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));
1872 break;
1873
1874 //
1875 // DefaultStore
1876 //
1877 case EFI_IFR_DEFAULTSTORE_OP:
1878 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));
1879 ASSERT (DefaultStore != NULL);
1880 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;
1881
1882 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));
1883 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));
1884
1885 //
1886 // Insert to DefaultStore list of this Formset
1887 //
1888 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);
1889 break;
1890
1891 //
1892 // Statements
1893 //
1894 case EFI_IFR_SUBTITLE_OP:
1895 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1896 ASSERT (CurrentStatement != NULL);
1897
1898 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
1899 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
1900 break;
1901
1902 case EFI_IFR_TEXT_OP:
1903 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1904 ASSERT (CurrentStatement != NULL);
1905 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
1906 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
1907 break;
1908
1909 case EFI_IFR_RESET_BUTTON_OP:
1910 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
1911 ASSERT (CurrentStatement != NULL);
1912 CurrentStatement->FakeQuestionId = mUsedQuestionId++;
1913 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
1914 break;
1915
1916 //
1917 // Questions
1918 //
1919 case EFI_IFR_ACTION_OP:
1920 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1921 ASSERT (CurrentStatement != NULL);
1922 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_ACTION;
1923
1924 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {
1925 //
1926 // No QuestionConfig present, so no configuration string will be processed
1927 //
1928 CurrentStatement->QuestionConfig = 0;
1929 } else {
1930 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));
1931 }
1932 break;
1933
1934 case EFI_IFR_REF_OP:
1935 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1936 ASSERT (CurrentStatement != NULL);
1937 Value = &CurrentStatement->HiiValue;
1938 Value->Type = EFI_IFR_TYPE_REF;
1939 if (OpCodeLength >= sizeof (EFI_IFR_REF)) {
1940 CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
1941
1942 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
1943 CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
1944
1945 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
1946 CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
1947
1948 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
1949 CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
1950 }
1951 }
1952 }
1953 }
1954 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);
1955 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
1956 break;
1957
1958 case EFI_IFR_ONE_OF_OP:
1959 case EFI_IFR_NUMERIC_OP:
1960 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
1961 ASSERT(CurrentStatement != NULL);
1962
1963 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;
1964 Value = &CurrentStatement->HiiValue;
1965
1966 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {
1967 case EFI_IFR_NUMERIC_SIZE_1:
1968 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;
1969 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;
1970 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;
1971 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8);
1972 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
1973 break;
1974
1975 case EFI_IFR_NUMERIC_SIZE_2:
1976 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));
1977 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));
1978 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));
1979 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16);
1980 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
1981 break;
1982
1983 case EFI_IFR_NUMERIC_SIZE_4:
1984 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));
1985 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));
1986 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));
1987 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32);
1988 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;
1989 break;
1990
1991 case EFI_IFR_NUMERIC_SIZE_8:
1992 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));
1993 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));
1994 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));
1995 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64);
1996 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1997 break;
1998
1999 default:
2000 break;
2001 }
2002
2003 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
2004
2005 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) {
2006 SuppressForOption = TRUE;
2007 }
2008 break;
2009
2010 case EFI_IFR_ORDERED_LIST_OP:
2011 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
2012 ASSERT(CurrentStatement != NULL);
2013
2014 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;
2015 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;
2016
2017 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BUFFER;
2018 CurrentStatement->BufferValue = NULL;
2019
2020 if (Scope != 0) {
2021 SuppressForOption = TRUE;
2022 }
2023 break;
2024
2025 case EFI_IFR_CHECKBOX_OP:
2026 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
2027 ASSERT(CurrentStatement != NULL);
2028
2029 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;
2030 CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN);
2031 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;
2032
2033 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
2034
2035 break;
2036
2037 case EFI_IFR_STRING_OP:
2038 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
2039 ASSERT (CurrentStatement != NULL);
2040 //
2041 // MinSize is the minimum number of characters that can be accepted for this opcode,
2042 // MaxSize is the maximum number of characters that can be accepted for this opcode.
2043 // The characters are stored as Unicode, so the storage width should multiply 2.
2044 //
2045 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;
2046 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;
2047 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
2048 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;
2049
2050 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
2051 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16));
2052 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
2053
2054 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
2055 break;
2056
2057 case EFI_IFR_PASSWORD_OP:
2058 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
2059 ASSERT (CurrentStatement != NULL);
2060 //
2061 // MinSize is the minimum number of characters that can be accepted for this opcode,
2062 // MaxSize is the maximum number of characters that can be accepted for this opcode.
2063 // The characters are stored as Unicode, so the storage width should multiply 2.
2064 //
2065 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));
2066 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));
2067 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (CHAR16));
2068
2069 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;
2070 CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16)));
2071 CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle);
2072
2073 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
2074 break;
2075
2076 case EFI_IFR_DATE_OP:
2077 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
2078 ASSERT(CurrentStatement != NULL);
2079
2080 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;
2081 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;
2082
2083 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {
2084 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE);
2085
2086 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
2087 } else {
2088 //
2089 // Don't assign storage for RTC type of date/time
2090 //
2091 CurrentStatement->Storage = NULL;
2092 CurrentStatement->StorageWidth = 0;
2093 }
2094 break;
2095
2096 case EFI_IFR_TIME_OP:
2097 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
2098 ASSERT(CurrentStatement != NULL);
2099
2100 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;
2101 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;
2102
2103 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {
2104 CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME);
2105
2106 InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
2107 } else {
2108 //
2109 // Don't assign storage for RTC type of date/time
2110 //
2111 CurrentStatement->Storage = NULL;
2112 CurrentStatement->StorageWidth = 0;
2113 }
2114 break;
2115
2116 //
2117 // Default
2118 //
2119 case EFI_IFR_DEFAULT_OP:
2120 //
2121 // EFI_IFR_DEFAULT appear in scope of a Question,
2122 // It creates a default value for the current question.
2123 // A Question may have more than one Default value which have different default types.
2124 //
2125 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
2126 ASSERT (CurrentDefault != NULL);
2127 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
2128
2129 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;
2130 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));
2131 if (CurrentDefault->Value.Type == EFI_IFR_TYPE_BUFFER) {
2132 CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));
2133 CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_DEFAULT *) OpCodeData)->Value);
2134 ASSERT (CurrentDefault->Value.Buffer != NULL);
2135 } else {
2136 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_DEFAULT, Value));
2137 ExtendValueToU64 (&CurrentDefault->Value);
2138 }
2139
2140 //
2141 // Insert to Default Value list of current Question
2142 //
2143 InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);
2144
2145 if (Scope != 0) {
2146 InScopeDefault = TRUE;
2147 }
2148 break;
2149
2150 //
2151 // Option
2152 //
2153 case EFI_IFR_ONE_OF_OPTION_OP:
2154 ASSERT (ParentStatement != NULL);
2155 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)) {
2156 //
2157 // It's keep the default value for ordered list opcode.
2158 //
2159 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));
2160 ASSERT (CurrentDefault != NULL);
2161 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;
2162
2163 CurrentDefault->Value.Type = EFI_IFR_TYPE_BUFFER;
2164 if ((((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {
2165 CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
2166 } else {
2167 CurrentDefault->DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
2168 }
2169
2170 CurrentDefault->Value.BufferLen = (UINT16) (OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
2171 CurrentDefault->Value.Buffer = AllocateCopyPool (CurrentDefault->Value.BufferLen, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value);
2172 ASSERT (CurrentDefault->Value.Buffer != NULL);
2173
2174 //
2175 // Insert to Default Value list of current Question
2176 //
2177 InsertTailList (&ParentStatement->DefaultListHead, &CurrentDefault->Link);
2178 break;
2179 }
2180
2181 //
2182 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.
2183 // It create a selection for use in current Question.
2184 //
2185 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
2186 ASSERT (CurrentOption != NULL);
2187 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
2188 CurrentOption->OpCode = (EFI_IFR_ONE_OF_OPTION *) OpCodeData;
2189
2190 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
2191 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
2192 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));
2193 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, OpCodeLength - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
2194 ExtendValueToU64 (&CurrentOption->Value);
2195
2196 ConditionalExprCount = GetConditionalExpressionCount(ExpressOption);
2197 if ( ConditionalExprCount > 0) {
2198 //
2199 // Form is inside of suppressif
2200 //
2201 CurrentOption->SuppressExpression = (FORM_EXPRESSION_LIST *) AllocatePool(
2202 (UINTN) (sizeof(FORM_EXPRESSION_LIST) + ((ConditionalExprCount -1) * sizeof(FORM_EXPRESSION *))));
2203 ASSERT (CurrentOption->SuppressExpression != NULL);
2204 CurrentOption->SuppressExpression->Count = (UINTN) ConditionalExprCount;
2205 CurrentOption->SuppressExpression->Signature = FORM_EXPRESSION_LIST_SIGNATURE;
2206 CopyMem (CurrentOption->SuppressExpression->Expression, GetConditionalExpressionList(ExpressOption), (UINTN) (sizeof (FORM_EXPRESSION *) * ConditionalExprCount));
2207 }
2208
2209 //
2210 // Insert to Option list of current Question
2211 //
2212 InsertTailList (&ParentStatement->OptionListHead, &CurrentOption->Link);
2213 //
2214 // Now we know the Storage width of nested Ordered List
2215 //
2216 if ((ParentStatement->Operand == EFI_IFR_ORDERED_LIST_OP) && (ParentStatement->BufferValue == NULL)) {
2217 Width = 1;
2218 switch (CurrentOption->Value.Type) {
2219 case EFI_IFR_TYPE_NUM_SIZE_8:
2220 Width = 1;
2221 break;
2222
2223 case EFI_IFR_TYPE_NUM_SIZE_16:
2224 Width = 2;
2225 break;
2226
2227 case EFI_IFR_TYPE_NUM_SIZE_32:
2228 Width = 4;
2229 break;
2230
2231 case EFI_IFR_TYPE_NUM_SIZE_64:
2232 Width = 8;
2233 break;
2234
2235 default:
2236 //
2237 // Invalid type for Ordered List
2238 //
2239 break;
2240 }
2241
2242 ParentStatement->StorageWidth = (UINT16) (ParentStatement->MaxContainers * Width);
2243 ParentStatement->BufferValue = AllocateZeroPool (ParentStatement->StorageWidth);
2244 ParentStatement->ValueType = CurrentOption->Value.Type;
2245 if (ParentStatement->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {
2246 ParentStatement->HiiValue.Buffer = ParentStatement->BufferValue;
2247 ParentStatement->HiiValue.BufferLen = ParentStatement->StorageWidth;
2248 }
2249
2250 InitializeRequestElement (FormSet, ParentStatement, CurrentForm);
2251 }
2252 break;
2253
2254 //
2255 // Conditional
2256 //
2257 case EFI_IFR_NO_SUBMIT_IF_OP:
2258 case EFI_IFR_INCONSISTENT_IF_OP:
2259 //
2260 // Create an Expression node
2261 //
2262 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2263 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));
2264
2265 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {
2266 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;
2267 InsertTailList (&ParentStatement->NoSubmitListHead, &CurrentExpression->Link);
2268 } else {
2269 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;
2270 InsertTailList (&ParentStatement->InconsistentListHead, &CurrentExpression->Link);
2271 }
2272
2273 //
2274 // Take a look at next OpCode to see whether current expression consists
2275 // of single OpCode
2276 //
2277 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2278 SingleOpCodeExpression = TRUE;
2279 }
2280 break;
2281
2282 case EFI_IFR_WARNING_IF_OP:
2283 //
2284 // Create an Expression node
2285 //
2286 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2287 CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *) OpCodeData)->Warning, sizeof (EFI_STRING_ID));
2288 CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeData)->TimeOut;
2289 CurrentExpression->Type = EFI_HII_EXPRESSION_WARNING_IF;
2290 InsertTailList (&ParentStatement->WarningListHead, &CurrentExpression->Link);
2291
2292 //
2293 // Take a look at next OpCode to see whether current expression consists
2294 // of single OpCode
2295 //
2296 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2297 SingleOpCodeExpression = TRUE;
2298 }
2299 break;
2300
2301 case EFI_IFR_SUPPRESS_IF_OP:
2302 //
2303 // Question and Option will appear in scope of this OpCode
2304 //
2305 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2306 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;
2307
2308 if (CurrentForm == NULL) {
2309 InsertTailList (&FormSet->ExpressionListHead, &CurrentExpression->Link);
2310 } else {
2311 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2312 }
2313
2314 if (SuppressForOption) {
2315 PushConditionalExpression(CurrentExpression, ExpressOption);
2316 } else if (SuppressForQuestion) {
2317 PushConditionalExpression(CurrentExpression, ExpressStatement);
2318 } else {
2319 PushConditionalExpression(CurrentExpression, ExpressForm);
2320 }
2321
2322 //
2323 // Take a look at next OpCode to see whether current expression consists
2324 // of single OpCode
2325 //
2326 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2327 SingleOpCodeExpression = TRUE;
2328 }
2329 break;
2330
2331 case EFI_IFR_GRAY_OUT_IF_OP:
2332 //
2333 // Questions will appear in scope of this OpCode
2334 //
2335 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2336 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;
2337 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2338 PushConditionalExpression(CurrentExpression, ExpressStatement);
2339
2340 //
2341 // Take a look at next OpCode to see whether current expression consists
2342 // of single OpCode
2343 //
2344 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2345 SingleOpCodeExpression = TRUE;
2346 }
2347 break;
2348
2349 case EFI_IFR_DISABLE_IF_OP:
2350 //
2351 // The DisableIf expression should only rely on constant, so it could be
2352 // evaluated at initialization and it will not be queued
2353 //
2354 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));
2355 ASSERT (CurrentExpression != NULL);
2356 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;
2357 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;
2358 InitializeListHead (&CurrentExpression->OpCodeListHead);
2359
2360 if (CurrentForm != NULL) {
2361 //
2362 // This is DisableIf for Question, enqueue it to Form expression list
2363 //
2364 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2365 PushConditionalExpression(CurrentExpression, ExpressStatement);
2366 }
2367
2368 OpCodeDisabled = FALSE;
2369 InScopeDisable = TRUE;
2370 //
2371 // Take a look at next OpCode to see whether current expression consists
2372 // of single OpCode
2373 //
2374 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2375 SingleOpCodeExpression = TRUE;
2376 }
2377 break;
2378
2379 //
2380 // Expression
2381 //
2382 case EFI_IFR_VALUE_OP:
2383 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2384 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;
2385 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2386
2387 if (InScopeDefault) {
2388 //
2389 // Used for default (EFI_IFR_DEFAULT)
2390 //
2391 CurrentDefault->ValueExpression = CurrentExpression;
2392 } else {
2393 //
2394 // If used for a question, then the question will be read-only
2395 //
2396 //
2397 // Make sure CurrentStatement is not NULL.
2398 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2399 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2400 //
2401 ASSERT (ParentStatement != NULL);
2402 ParentStatement->ValueExpression = CurrentExpression;
2403 }
2404
2405 //
2406 // Take a look at next OpCode to see whether current expression consists
2407 // of single OpCode
2408 //
2409 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2410 SingleOpCodeExpression = TRUE;
2411 }
2412 break;
2413
2414 case EFI_IFR_RULE_OP:
2415 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2416 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;
2417
2418 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;
2419 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2420
2421 //
2422 // Take a look at next OpCode to see whether current expression consists
2423 // of single OpCode
2424 //
2425 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2426 SingleOpCodeExpression = TRUE;
2427 }
2428 break;
2429
2430 case EFI_IFR_READ_OP:
2431 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2432 CurrentExpression->Type = EFI_HII_EXPRESSION_READ;
2433 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2434
2435 //
2436 // Make sure CurrentStatement is not NULL.
2437 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2438 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2439 //
2440 ASSERT (ParentStatement != NULL);
2441 ParentStatement->ReadExpression = CurrentExpression;
2442
2443 //
2444 // Take a look at next OpCode to see whether current expression consists
2445 // of single OpCode
2446 //
2447 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2448 SingleOpCodeExpression = TRUE;
2449 }
2450 break;
2451
2452 case EFI_IFR_WRITE_OP:
2453 CurrentExpression = CreateExpression (CurrentForm, OpCodeData);
2454 CurrentExpression->Type = EFI_HII_EXPRESSION_WRITE;
2455 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);
2456
2457 //
2458 // Make sure CurrentStatement is not NULL.
2459 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2460 // file is wrongly generated by tools such as VFR Compiler. There may be a bug in VFR Compiler.
2461 //
2462 ASSERT (ParentStatement != NULL);
2463 ParentStatement->WriteExpression = CurrentExpression;
2464
2465 //
2466 // Take a look at next OpCode to see whether current expression consists
2467 // of single OpCode
2468 //
2469 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {
2470 SingleOpCodeExpression = TRUE;
2471 }
2472 break;
2473
2474 //
2475 // Image
2476 //
2477 case EFI_IFR_IMAGE_OP:
2478 //
2479 // Get ScopeOpcode from top of stack
2480 //
2481 PopScope (&ScopeOpCode);
2482 PushScope (ScopeOpCode);
2483
2484 switch (ScopeOpCode) {
2485 case EFI_IFR_FORM_SET_OP:
2486 ImageId = &FormSet->ImageId;
2487 break;
2488
2489 case EFI_IFR_FORM_OP:
2490 case EFI_IFR_FORM_MAP_OP:
2491 ASSERT (CurrentForm != NULL);
2492 ImageId = &CurrentForm->ImageId;
2493 break;
2494
2495 case EFI_IFR_ONE_OF_OPTION_OP:
2496 ASSERT (CurrentOption != NULL);
2497 ImageId = &CurrentOption->ImageId;
2498 break;
2499
2500 default:
2501 //
2502 // Make sure CurrentStatement is not NULL.
2503 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR
2504 // file is wrongly generated by tools such as VFR Compiler.
2505 //
2506 ASSERT (ParentStatement != NULL);
2507 ImageId = &ParentStatement->ImageId;
2508 break;
2509 }
2510
2511 ASSERT (ImageId != NULL);
2512 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));
2513 break;
2514
2515 //
2516 // Refresh
2517 //
2518 case EFI_IFR_REFRESH_OP:
2519 ASSERT (ParentStatement != NULL);
2520 ParentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;
2521 break;
2522
2523 //
2524 // Refresh guid.
2525 //
2526 case EFI_IFR_REFRESH_ID_OP:
2527 //
2528 // Get ScopeOpcode from top of stack
2529 //
2530 PopScope (&ScopeOpCode);
2531 PushScope (ScopeOpCode);
2532
2533 switch (ScopeOpCode) {
2534 case EFI_IFR_FORM_OP:
2535 case EFI_IFR_FORM_MAP_OP:
2536 ASSERT (CurrentForm != NULL);
2537 CopyMem (&CurrentForm->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));
2538 break;
2539
2540 default:
2541 ASSERT (ParentStatement != NULL);
2542 CopyMem (&ParentStatement->RefreshGuid, &((EFI_IFR_REFRESH_ID *) OpCodeData)->RefreshEventGroupId, sizeof (EFI_GUID));
2543 break;
2544 }
2545 break;
2546
2547 //
2548 // Modal tag
2549 //
2550 case EFI_IFR_MODAL_TAG_OP:
2551 ASSERT (CurrentForm != NULL);
2552 CurrentForm->ModalForm = TRUE;
2553 break;
2554
2555 //
2556 // Lock tag, used by form and statement.
2557 //
2558 case EFI_IFR_LOCKED_OP:
2559 //
2560 // Get ScopeOpcode from top of stack
2561 //
2562 PopScope (&ScopeOpCode);
2563 PushScope (ScopeOpCode);
2564 switch (ScopeOpCode) {
2565 case EFI_IFR_FORM_OP:
2566 case EFI_IFR_FORM_MAP_OP:
2567 ASSERT (CurrentForm != NULL);
2568 CurrentForm->Locked = TRUE;
2569 break;
2570
2571 default:
2572 ASSERT (ParentStatement != NULL);
2573 ParentStatement->Locked = TRUE;
2574 }
2575 break;
2576
2577 //
2578 // Vendor specific
2579 //
2580 case EFI_IFR_GUID_OP:
2581 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
2582 break;
2583
2584 //
2585 // Scope End
2586 //
2587 case EFI_IFR_END_OP:
2588 Status = PopScope (&ScopeOpCode);
2589 if (EFI_ERROR (Status)) {
2590 ResetScopeStack ();
2591 return Status;
2592 }
2593
2594 //
2595 // Parent statement end tag found, update ParentStatement info.
2596 //
2597 if (IsStatementOpCode(ScopeOpCode) && (ParentStatement != NULL) && (ParentStatement->Operand == ScopeOpCode)) {
2598 ParentStatement = ParentStatement->ParentStatement;
2599 }
2600
2601 switch (ScopeOpCode) {
2602 case EFI_IFR_FORM_SET_OP:
2603 //
2604 // End of FormSet, update FormSet IFR binary length
2605 // to stop parsing substantial OpCodes
2606 //
2607 FormSet->IfrBinaryLength = OpCodeOffset;
2608 break;
2609
2610 case EFI_IFR_FORM_OP:
2611 case EFI_IFR_FORM_MAP_OP:
2612 //
2613 // End of Form
2614 //
2615 CurrentForm = NULL;
2616 SuppressForQuestion = FALSE;
2617 break;
2618
2619 case EFI_IFR_ONE_OF_OPTION_OP:
2620 //
2621 // End of Option
2622 //
2623 CurrentOption = NULL;
2624 break;
2625
2626 case EFI_IFR_NO_SUBMIT_IF_OP:
2627 case EFI_IFR_INCONSISTENT_IF_OP:
2628 case EFI_IFR_WARNING_IF_OP:
2629 //
2630 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF
2631 //
2632 break;
2633
2634 case EFI_IFR_SUPPRESS_IF_OP:
2635 if (SuppressForOption) {
2636 PopConditionalExpression(ExpressOption);
2637 } else if (SuppressForQuestion) {
2638 PopConditionalExpression(ExpressStatement);
2639 } else {
2640 PopConditionalExpression(ExpressForm);
2641 }
2642 break;
2643
2644 case EFI_IFR_GRAY_OUT_IF_OP:
2645 PopConditionalExpression(ExpressStatement);
2646 break;
2647
2648 case EFI_IFR_DISABLE_IF_OP:
2649 if (CurrentForm != NULL) {
2650 PopConditionalExpression(ExpressStatement);
2651 }
2652 InScopeDisable = FALSE;
2653 OpCodeDisabled = FALSE;
2654 break;
2655
2656 case EFI_IFR_ONE_OF_OP:
2657 case EFI_IFR_ORDERED_LIST_OP:
2658 SuppressForOption = FALSE;
2659 break;
2660
2661 case EFI_IFR_DEFAULT_OP:
2662 InScopeDefault = FALSE;
2663 break;
2664
2665 case EFI_IFR_MAP_OP:
2666 //
2667 // Get current Map Expression List.
2668 //
2669 Status = PopMapExpressionList ((VOID **) &MapExpressionList);
2670 if (Status == EFI_ACCESS_DENIED) {
2671 MapExpressionList = NULL;
2672 }
2673 //
2674 // Get current expression.
2675 //
2676 Status = PopCurrentExpression ((VOID **) &CurrentExpression);
2677 ASSERT_EFI_ERROR (Status);
2678 ASSERT (MapScopeDepth > 0);
2679 MapScopeDepth --;
2680 break;
2681
2682 default:
2683 if (IsExpressionOpCode (ScopeOpCode)) {
2684 if (InScopeDisable && CurrentForm == NULL) {
2685 //
2686 // This is DisableIf expression for Form, it should be a constant expression
2687 //
2688 ASSERT (CurrentExpression != NULL);
2689 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);
2690 if (EFI_ERROR (Status)) {
2691 return Status;
2692 }
2693
2694 OpCodeDisabled = IsTrue (&CurrentExpression->Result);
2695
2696 //
2697 // DisableIf Expression is only used once and not queued, free it
2698 //
2699 DestroyExpression (CurrentExpression);
2700 }
2701
2702 //
2703 // End of current Expression
2704 //
2705 CurrentExpression = NULL;
2706 }
2707 break;
2708 }
2709 break;
2710
2711 default:
2712 break;
2713 }
2714
2715 if (IsStatementOpCode(Operand)) {
2716 CurrentStatement->ParentStatement = ParentStatement;
2717 if (Scope != 0) {
2718 //
2719 // Scope != 0, other statements or options may nest in this statement.
2720 // Update the ParentStatement info.
2721 //
2722 ParentStatement = CurrentStatement;
2723 }
2724 }
2725 }
2726
2727 return EFI_SUCCESS;
2728 }