3 The definition of CFormPkg's member function
5 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "VfrFormPkg.h"
20 * The definition of CFormPkg's member function
23 SPendingAssign::SPendingAssign (
39 mKey
= new CHAR8
[strlen (Key
) + 1];
46 mMsg
= new CHAR8
[strlen (Msg
) + 1];
53 SPendingAssign::~SPendingAssign (
70 SPendingAssign::SetAddrAndLen (
80 SPendingAssign::AssignValue (
85 memmove (mAddr
, Addr
, (mLen
< Len
? mLen
: Len
));
90 SPendingAssign::GetKey (
106 mBufferNodeQueueHead
= NULL
;
107 mCurrBufferNode
= NULL
;
109 Node
= new SBufferNode
;
113 BufferStart
= new CHAR8
[BufferSize
];
114 if (BufferStart
== NULL
) {
117 BufferEnd
= BufferStart
+ BufferSize
;
119 memset (BufferStart
, 0, BufferSize
);
120 Node
->mBufferStart
= BufferStart
;
121 Node
->mBufferEnd
= BufferEnd
;
122 Node
->mBufferFree
= BufferStart
;
125 mBufferSize
= BufferSize
;
126 mBufferNodeQueueHead
= Node
;
127 mBufferNodeQueueTail
= Node
;
128 mCurrBufferNode
= Node
;
131 CFormPkg::~CFormPkg ()
134 SPendingAssign
*pPNode
;
136 while (mBufferNodeQueueHead
!= NULL
) {
137 pBNode
= mBufferNodeQueueHead
;
138 mBufferNodeQueueHead
= mBufferNodeQueueHead
->mNext
;
139 if (pBNode
->mBufferStart
!= NULL
) {
140 delete pBNode
->mBufferStart
;
144 mBufferNodeQueueTail
= NULL
;
145 mCurrBufferNode
= NULL
;
147 while (PendingAssignList
!= NULL
) {
148 pPNode
= PendingAssignList
;
149 PendingAssignList
= PendingAssignList
->mNext
;
152 PendingAssignList
= NULL
;
156 CFormPkg::CreateNewNode (
162 Node
= new SBufferNode
;
167 Node
->mBufferStart
= new CHAR8
[mBufferSize
];
168 if (Node
->mBufferStart
== NULL
) {
172 memset (Node
->mBufferStart
, 0, mBufferSize
);
173 Node
->mBufferEnd
= Node
->mBufferStart
+ mBufferSize
;
174 Node
->mBufferFree
= Node
->mBufferStart
;
182 CFormPkg::IfrBinBufferGet (
186 CHAR8
*BinBuffer
= NULL
;
187 SBufferNode
*Node
= NULL
;
189 if ((Len
== 0) || (Len
> mBufferSize
)) {
193 if ((mCurrBufferNode
->mBufferFree
+ Len
) <= mCurrBufferNode
->mBufferEnd
) {
194 BinBuffer
= mCurrBufferNode
->mBufferFree
;
195 mCurrBufferNode
->mBufferFree
+= Len
;
197 Node
= CreateNewNode ();
202 if (mBufferNodeQueueTail
== NULL
) {
203 mBufferNodeQueueHead
= mBufferNodeQueueTail
= Node
;
205 mBufferNodeQueueTail
->mNext
= Node
;
206 mBufferNodeQueueTail
= Node
;
208 mCurrBufferNode
= Node
;
213 BinBuffer
= mCurrBufferNode
->mBufferFree
;
214 mCurrBufferNode
->mBufferFree
+= Len
;
224 CFormPkg::GetPkgLength (
236 mReadBufferNode
= mBufferNodeQueueHead
;
237 mReadBufferOffset
= 0;
245 mReadBufferNode
= NULL
;
246 mReadBufferOffset
= 0;
257 if ((Size
== 0) || (Buffer
== NULL
)) {
261 if (mReadBufferNode
== NULL
) {
265 for (Index
= 0; Index
< Size
; Index
++) {
266 if ((mReadBufferNode
->mBufferStart
+ mReadBufferOffset
) < mReadBufferNode
->mBufferFree
) {
267 Buffer
[Index
] = mReadBufferNode
->mBufferStart
[mReadBufferOffset
++];
269 if ((mReadBufferNode
= mReadBufferNode
->mNext
) == NULL
) {
272 mReadBufferOffset
= 0;
282 CFormPkg::BuildPkgHdr (
283 OUT EFI_HII_PACKAGE_HEADER
**PkgHdr
286 if (PkgHdr
== NULL
) {
287 return VFR_RETURN_FATAL_ERROR
;
290 if (((*PkgHdr
) = new EFI_HII_PACKAGE_HEADER
) == NULL
) {
291 return VFR_RETURN_OUT_FOR_RESOURCES
;
294 (*PkgHdr
)->Type
= EFI_HII_PACKAGE_FORM
;
295 (*PkgHdr
)->Length
= mPkgLength
+ sizeof (EFI_HII_PACKAGE_HEADER
);
297 return VFR_RETURN_SUCCESS
;
302 OUT PACKAGE_DATA
&TBuffer
310 if (TBuffer
.Buffer
!= NULL
) {
311 delete TBuffer
.Buffer
;
314 TBuffer
.Size
= mPkgLength
;
315 TBuffer
.Buffer
= NULL
;
316 if (TBuffer
.Size
!= 0) {
317 TBuffer
.Buffer
= new CHAR8
[TBuffer
.Size
];
319 return VFR_RETURN_SUCCESS
;
322 Temp
= TBuffer
.Buffer
;
324 while ((Size
= Read (Buffer
, 1024)) != 0) {
325 memcpy (Temp
, Buffer
, Size
);
329 return VFR_RETURN_SUCCESS
;
336 IN PACKAGE_DATA
*PkgData
339 EFI_VFR_RETURN_CODE Ret
;
342 EFI_HII_PACKAGE_HEADER
*PkgHdr
;
344 if (Output
== NULL
) {
345 return VFR_RETURN_FATAL_ERROR
;
348 if ((Ret
= BuildPkgHdr(&PkgHdr
)) != VFR_RETURN_SUCCESS
) {
351 fwrite (PkgHdr
, sizeof (EFI_HII_PACKAGE_HEADER
), 1, Output
);
354 if (PkgData
== NULL
) {
356 while ((Size
= Read (Buffer
, 1024)) != 0) {
357 fwrite (Buffer
, Size
, 1, Output
);
361 fwrite (PkgData
->Buffer
, PkgData
->Size
, 1, Output
);
364 return VFR_RETURN_SUCCESS
;
368 CFormPkg::_WRITE_PKG_LINE (
371 IN CONST CHAR8
*LineHeader
,
378 if ((pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
382 for (Index
= 0; Index
< BlkSize
; Index
++) {
383 if ((Index
% LineBytes
) == 0) {
384 fprintf (pFile
, "\n%s", LineHeader
);
386 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
391 CFormPkg::_WRITE_PKG_END (
394 IN CONST CHAR8
*LineHeader
,
401 if ((BlkSize
== 0) || (pFile
== NULL
) || (LineHeader
== NULL
) || (BlkBuf
== NULL
)) {
405 for (Index
= 0; Index
< BlkSize
- 1; Index
++) {
406 if ((Index
% LineBytes
) == 0) {
407 fprintf (pFile
, "\n%s", LineHeader
);
409 fprintf (pFile
, "0x%02X, ", (UINT8
)BlkBuf
[Index
]);
412 if ((Index
% LineBytes
) == 0) {
413 fprintf (pFile
, "\n%s", LineHeader
);
415 fprintf (pFile
, "0x%02X\n", (UINT8
)BlkBuf
[Index
]);
418 #define BYTES_PRE_LINE 0x10
419 UINT32 gAdjustOpcodeOffset
= 0;
420 BOOLEAN gNeedAdjustOpcode
= FALSE
;
421 UINT32 gAdjustOpcodeLen
= 0;
427 IN PACKAGE_DATA
*PkgData
430 EFI_VFR_RETURN_CODE Ret
;
431 CHAR8 Buffer
[BYTES_PRE_LINE
* 8];
432 EFI_HII_PACKAGE_HEADER
*PkgHdr
;
433 UINT32 PkgLength
= 0;
436 if ((BaseName
== NULL
) || (pFile
== NULL
)) {
437 return VFR_RETURN_FATAL_ERROR
;
440 fprintf (pFile
, "\nunsigned char %sBin[] = {\n", BaseName
);
442 if ((Ret
= BuildPkgHdr(&PkgHdr
)) != VFR_RETURN_SUCCESS
) {
447 // For framework vfr file, the extension framework header will be added.
449 if (VfrCompatibleMode
) {
450 fprintf (pFile
, " // FRAMEWORK PACKAGE HEADER Length\n");
451 PkgLength
= PkgHdr
->Length
+ sizeof (UINT32
) + 2;
452 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&PkgLength
, sizeof (UINT32
));
453 fprintf (pFile
, "\n\n // FRAMEWORK PACKAGE HEADER Type\n");
455 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&PkgLength
, sizeof (UINT16
));
457 fprintf (pFile
, " // ARRAY LENGTH\n");
458 PkgLength
= PkgHdr
->Length
+ sizeof (UINT32
);
459 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)&PkgLength
, sizeof (UINT32
));
462 fprintf (pFile
, "\n\n // PACKAGE HEADER\n");
463 _WRITE_PKG_LINE(pFile
, BYTES_PRE_LINE
, " ", (CHAR8
*)PkgHdr
, sizeof (EFI_HII_PACKAGE_HEADER
));
464 PkgLength
= sizeof (EFI_HII_PACKAGE_HEADER
);
466 fprintf (pFile
, "\n\n // PACKAGE DATA\n");
468 if (PkgData
== NULL
) {
470 while ((ReadSize
= Read ((CHAR8
*)Buffer
, BYTES_PRE_LINE
* 8)) != 0) {
471 PkgLength
+= ReadSize
;
472 if (PkgLength
< PkgHdr
->Length
) {
473 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", Buffer
, ReadSize
);
475 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", Buffer
, ReadSize
);
480 if (PkgData
->Size
% BYTES_PRE_LINE
!= 0) {
481 PkgLength
= PkgData
->Size
- (PkgData
->Size
% BYTES_PRE_LINE
);
482 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
, PkgLength
);
483 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
+ PkgLength
, PkgData
->Size
% BYTES_PRE_LINE
);
485 PkgLength
= PkgData
->Size
- BYTES_PRE_LINE
;
486 _WRITE_PKG_LINE (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
, PkgLength
);
487 _WRITE_PKG_END (pFile
, BYTES_PRE_LINE
, " ", PkgData
->Buffer
+ PkgLength
, BYTES_PRE_LINE
);
492 fprintf (pFile
, "\n};\n");
494 return VFR_RETURN_SUCCESS
;
498 CFormPkg::AssignPending (
506 SPendingAssign
*pNew
;
508 pNew
= new SPendingAssign (Key
, ValAddr
, ValLen
, LineNo
, Msg
);
510 return VFR_RETURN_OUT_FOR_RESOURCES
;
513 pNew
->mNext
= PendingAssignList
;
514 PendingAssignList
= pNew
;
515 return VFR_RETURN_SUCCESS
;
519 CFormPkg::DoPendingAssign (
525 SPendingAssign
*pNode
;
527 if ((Key
== NULL
) || (ValAddr
== NULL
)) {
531 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
532 if (strcmp (pNode
->mKey
, Key
) == 0) {
533 pNode
->AssignValue (ValAddr
, ValLen
);
539 CFormPkg::HavePendingUnassigned (
543 SPendingAssign
*pNode
;
545 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
546 if (pNode
->mFlag
== PENDING
) {
555 CFormPkg::PendingAssignPrintAll (
559 SPendingAssign
*pNode
;
561 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
562 if (pNode
->mFlag
== PENDING
) {
563 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, pNode
->mKey
, "Error", pNode
->mMsg
);
569 CFormPkg::GetBinBufferNodeForAddr (
570 IN CHAR8
*BinBuffAddr
573 SBufferNode
*TmpNode
;
575 TmpNode
= mBufferNodeQueueHead
;
577 while (TmpNode
!= NULL
) {
578 if (TmpNode
->mBufferStart
<= BinBuffAddr
&& TmpNode
->mBufferFree
>= BinBuffAddr
) {
582 TmpNode
= TmpNode
->mNext
;
589 CFormPkg::GetNodeBefore(
590 IN SBufferNode
*CurrentNode
593 SBufferNode
*FirstNode
= mBufferNodeQueueHead
;
594 SBufferNode
*LastNode
= mBufferNodeQueueHead
;
596 while (FirstNode
!= NULL
) {
597 if (FirstNode
== CurrentNode
) {
601 LastNode
= FirstNode
;
602 FirstNode
= FirstNode
->mNext
;
605 if (FirstNode
== NULL
) {
613 CFormPkg::InsertNodeBefore(
614 IN SBufferNode
*CurrentNode
,
615 IN SBufferNode
*NewNode
618 SBufferNode
*LastNode
= GetNodeBefore (CurrentNode
);
620 if (LastNode
== NULL
) {
621 return VFR_RETURN_MISMATCHED
;
624 NewNode
->mNext
= LastNode
->mNext
;
625 LastNode
->mNext
= NewNode
;
627 return VFR_RETURN_SUCCESS
;
631 CFormPkg::GetBufAddrBaseOnOffset (
635 SBufferNode
*TmpNode
;
637 UINT32 CurrentBufLen
;
641 for (TmpNode
= mBufferNodeQueueHead
; TmpNode
!= NULL
; TmpNode
= TmpNode
->mNext
) {
642 CurrentBufLen
= TmpNode
->mBufferFree
- TmpNode
->mBufferStart
;
643 if (Offset
>= TotalBufLen
&& Offset
< TotalBufLen
+ CurrentBufLen
) {
644 return TmpNode
->mBufferStart
+ (Offset
- TotalBufLen
);
647 TotalBufLen
+= CurrentBufLen
;
654 CFormPkg::AdjustDynamicInsertOpcode (
655 IN CHAR8
*InserPositionAddr
,
656 IN CHAR8
*InsertOpcodeAddr
,
657 IN BOOLEAN CreateOpcodeAfterParsingVfr
660 SBufferNode
*InserPositionNode
;
661 SBufferNode
*InsertOpcodeNode
;
662 SBufferNode
*NewRestoreNodeBegin
;
663 SBufferNode
*NewRestoreNodeEnd
;
664 SBufferNode
*NewLastEndNode
;
665 SBufferNode
*TmpNode
;
666 UINT32 NeedRestoreCodeLen
;
668 NewRestoreNodeEnd
= NULL
;
670 InserPositionNode
= GetBinBufferNodeForAddr(InserPositionAddr
);
671 InsertOpcodeNode
= GetBinBufferNodeForAddr(InsertOpcodeAddr
);
673 if (InserPositionNode
== InsertOpcodeNode
) {
675 // Create New Node to save the restore opcode.
677 NeedRestoreCodeLen
= InsertOpcodeAddr
- InserPositionAddr
;
678 gAdjustOpcodeLen
= NeedRestoreCodeLen
;
679 NewRestoreNodeBegin
= CreateNewNode ();
680 if (NewRestoreNodeBegin
== NULL
) {
681 return VFR_RETURN_OUT_FOR_RESOURCES
;
683 memcpy (NewRestoreNodeBegin
->mBufferFree
, InserPositionAddr
, NeedRestoreCodeLen
);
684 NewRestoreNodeBegin
->mBufferFree
+= NeedRestoreCodeLen
;
687 // Override the restore buffer data.
689 memmove (InserPositionAddr
, InsertOpcodeAddr
, InsertOpcodeNode
->mBufferFree
- InsertOpcodeAddr
);
690 InsertOpcodeNode
->mBufferFree
-= NeedRestoreCodeLen
;
691 memset (InsertOpcodeNode
->mBufferFree
, 0, NeedRestoreCodeLen
);
694 // Create New Node to save the restore opcode.
696 NeedRestoreCodeLen
= InserPositionNode
->mBufferFree
- InserPositionAddr
;
697 gAdjustOpcodeLen
= NeedRestoreCodeLen
;
698 NewRestoreNodeBegin
= CreateNewNode ();
699 if (NewRestoreNodeBegin
== NULL
) {
700 return VFR_RETURN_OUT_FOR_RESOURCES
;
702 memcpy (NewRestoreNodeBegin
->mBufferFree
, InserPositionAddr
, NeedRestoreCodeLen
);
703 NewRestoreNodeBegin
->mBufferFree
+= NeedRestoreCodeLen
;
705 // Override the restore buffer data.
707 InserPositionNode
->mBufferFree
-= NeedRestoreCodeLen
;
709 // Link the restore data to new node.
711 NewRestoreNodeBegin
->mNext
= InserPositionNode
->mNext
;
714 // Count the Adjust opcode len.
716 TmpNode
= InserPositionNode
->mNext
;
717 while (TmpNode
!= InsertOpcodeNode
) {
718 gAdjustOpcodeLen
+= TmpNode
->mBufferFree
- TmpNode
->mBufferStart
;
719 TmpNode
= TmpNode
->mNext
;
723 // Create New Node to save the last node of restore opcode.
725 NeedRestoreCodeLen
= InsertOpcodeAddr
- InsertOpcodeNode
->mBufferStart
;
726 gAdjustOpcodeLen
+= NeedRestoreCodeLen
;
727 if (NeedRestoreCodeLen
> 0) {
728 NewRestoreNodeEnd
= CreateNewNode ();
729 if (NewRestoreNodeEnd
== NULL
) {
730 return VFR_RETURN_OUT_FOR_RESOURCES
;
732 memcpy (NewRestoreNodeEnd
->mBufferFree
, InsertOpcodeNode
->mBufferStart
, NeedRestoreCodeLen
);
733 NewRestoreNodeEnd
->mBufferFree
+= NeedRestoreCodeLen
;
735 // Override the restore buffer data.
737 memmove (InsertOpcodeNode
->mBufferStart
, InsertOpcodeAddr
, InsertOpcodeNode
->mBufferFree
- InsertOpcodeAddr
);
738 InsertOpcodeNode
->mBufferFree
-= InsertOpcodeAddr
- InsertOpcodeNode
->mBufferStart
;
741 // Insert the last restore data node.
743 TmpNode
= GetNodeBefore (InsertOpcodeNode
);
744 if (TmpNode
== InserPositionNode
) {
745 NewRestoreNodeBegin
->mNext
= NewRestoreNodeEnd
;
747 TmpNode
->mNext
= NewRestoreNodeEnd
;
750 // Connect the dynamic opcode node to the node after InserPositionNode.
752 InserPositionNode
->mNext
= InsertOpcodeNode
;
756 if (CreateOpcodeAfterParsingVfr
) {
758 // Th new opcodes were created after Parsing Vfr file,
759 // so the content in mBufferNodeQueueTail must be the new created opcodes.
760 // So connet the NewRestoreNodeBegin to the tail and update the tail node.
762 mBufferNodeQueueTail
->mNext
= NewRestoreNodeBegin
;
763 if (NewRestoreNodeEnd
!= NULL
) {
764 mBufferNodeQueueTail
= NewRestoreNodeEnd
;
766 mBufferNodeQueueTail
= NewRestoreNodeBegin
;
769 if (mBufferNodeQueueTail
->mBufferFree
- mBufferNodeQueueTail
->mBufferStart
> 2) {
771 // End form set opcode all in the mBufferNodeQueueTail node.
773 NewLastEndNode
= CreateNewNode ();
774 if (NewLastEndNode
== NULL
) {
775 return VFR_RETURN_OUT_FOR_RESOURCES
;
777 NewLastEndNode
->mBufferStart
[0] = 0x29;
778 NewLastEndNode
->mBufferStart
[1] = 0x02;
779 NewLastEndNode
->mBufferFree
+= 2;
781 mBufferNodeQueueTail
->mBufferFree
-= 2;
783 mBufferNodeQueueTail
->mNext
= NewRestoreNodeBegin
;
784 if (NewRestoreNodeEnd
!= NULL
) {
785 NewRestoreNodeEnd
->mNext
= NewLastEndNode
;
787 NewRestoreNodeBegin
->mNext
= NewLastEndNode
;
790 mBufferNodeQueueTail
= NewLastEndNode
;
791 } else if (mBufferNodeQueueTail
->mBufferFree
- mBufferNodeQueueTail
->mBufferStart
== 2) {
792 TmpNode
= GetNodeBefore(mBufferNodeQueueTail
);
793 TmpNode
->mNext
= NewRestoreNodeBegin
;
794 if (NewRestoreNodeEnd
!= NULL
) {
795 NewRestoreNodeEnd
->mNext
= mBufferNodeQueueTail
;
797 NewRestoreNodeBegin
->mNext
= mBufferNodeQueueTail
;
801 mCurrBufferNode
= mBufferNodeQueueTail
;
802 return VFR_RETURN_SUCCESS
;
806 CFormPkg::DeclarePendingQuestion (
807 IN CVfrVarDataTypeDB
&lCVfrVarDataTypeDB
,
808 IN CVfrDataStorage
&lCVfrDataStorage
,
809 IN CVfrQuestionDB
&lCVfrQuestionDB
,
810 IN EFI_GUID
*LocalFormSetGuid
,
812 OUT CHAR8
**InsertOpcodeAddr
815 SPendingAssign
*pNode
;
818 CHAR8 FName
[MAX_NAME_LEN
];
822 EFI_VFR_RETURN_CODE ReturnCode
;
823 EFI_VFR_VARSTORE_TYPE VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
824 EFI_VARSTORE_ID VarStoreId
= EFI_VARSTORE_ID_INVALID
;
827 // Declare all questions as Numeric in DisableIf True
831 DIObj
.SetLineNo (LineNo
);
832 *InsertOpcodeAddr
= DIObj
.GetObjBinAddr ();
835 CIfrTrue
TObj (LineNo
);
837 // Declare Numeric qeustion for each undefined question.
838 for (pNode
= PendingAssignList
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
839 if (pNode
->mFlag
== PENDING
) {
841 EFI_VARSTORE_INFO Info
;
842 EFI_QUESTION_ID QId
= EFI_QUESTION_ID_INVALID
;
844 CNObj
.SetLineNo (LineNo
);
845 CNObj
.SetPrompt (0x0);
849 // Register this question, assume it is normal question, not date or time question
851 VarStr
= pNode
->mKey
;
852 ReturnCode
= lCVfrQuestionDB
.RegisterQuestion (NULL
, VarStr
, QId
);
853 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
854 gCVfrErrorHandle
.HandleError (ReturnCode
, pNode
->mLineNo
, pNode
->mKey
);
859 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr
, QId
);
862 // Get Question Info, framework vfr VarName == StructName
864 ReturnCode
= lCVfrVarDataTypeDB
.ExtractFieldNameAndArrary (VarStr
, FName
, ArrayIdx
);
865 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
866 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, pNode
->mKey
, "Error", "Var string is not the valid C variable");
872 ReturnCode
= lCVfrDataStorage
.GetVarStoreId (FName
, &Info
.mVarStoreId
);
873 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
874 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, FName
, "Error", "Var Store Type is not defined");
877 VarStoreType
= lCVfrDataStorage
.GetVarStoreType (Info
.mVarStoreId
);
879 if (*VarStr
== '\0' && ArrayIdx
!= INVALID_ARRAY_INDEX
) {
880 ReturnCode
= lCVfrDataStorage
.GetNameVarStoreInfo (&Info
, ArrayIdx
);
882 if (VarStoreType
== EFI_VFR_VARSTORE_EFI
) {
883 ReturnCode
= lCVfrDataStorage
.GetEfiVarStoreInfo (&Info
);
884 } else if (VarStoreType
== EFI_VFR_VARSTORE_BUFFER
) {
885 VarStr
= pNode
->mKey
;
886 //convert VarStr with store name to VarStr with structure name
887 ReturnCode
= lCVfrDataStorage
.GetBufferVarStoreDataTypeName (Info
.mVarStoreId
, &SName
);
888 if (ReturnCode
== VFR_RETURN_SUCCESS
) {
889 NewStr
= new CHAR8
[strlen (VarStr
) + strlen (SName
) + 1];
891 strcpy (NewStr
, SName
);
892 strcat (NewStr
, VarStr
+ strlen (FName
));
893 ReturnCode
= lCVfrVarDataTypeDB
.GetDataFieldInfo (NewStr
, Info
.mInfo
.mVarOffset
, Info
.mVarType
, Info
.mVarTotalSize
);
897 ReturnCode
= VFR_RETURN_UNSUPPORTED
;
900 if (ReturnCode
!= VFR_RETURN_SUCCESS
) {
901 gCVfrErrorHandle
.HandleError (ReturnCode
, pNode
->mLineNo
, pNode
->mKey
);
905 CNObj
.SetQuestionId (QId
);
906 CNObj
.SetVarStoreInfo (&Info
);
908 // Numeric doesn't support BOOLEAN data type.
909 // BOOLEAN type has the same data size to UINT8.
911 if (Info
.mVarType
== EFI_IFR_TYPE_BOOLEAN
) {
912 Info
.mVarType
= EFI_IFR_TYPE_NUM_SIZE_8
;
914 CNObj
.SetFlags (0, Info
.mVarType
);
916 // Use maximum value not to limit the vaild value for the undefined question.
918 switch (Info
.mVarType
) {
919 case EFI_IFR_TYPE_NUM_SIZE_64
:
920 CNObj
.SetMinMaxStepData ((UINT64
) 0, (UINT64
) -1 , (UINT64
) 0);
923 case EFI_IFR_TYPE_NUM_SIZE_32
:
924 CNObj
.SetMinMaxStepData ((UINT32
) 0, (UINT32
) -1 , (UINT32
) 0);
927 case EFI_IFR_TYPE_NUM_SIZE_16
:
928 CNObj
.SetMinMaxStepData ((UINT16
) 0, (UINT16
) -1 , (UINT16
) 0);
931 case EFI_IFR_TYPE_NUM_SIZE_8
:
932 CNObj
.SetMinMaxStepData ((UINT8
) 0, (UINT8
) -1 , (UINT8
) 0);
938 CNObj
.ShrinkBinSize (ShrinkSize
);
941 // For undefined Efi VarStore type question
942 // Append the extended guided opcode to contain VarName
944 if (VarStoreType
== EFI_VFR_VARSTORE_EFI
|| VfrCompatibleMode
) {
945 CIfrVarEqName
CVNObj (QId
, Info
.mInfo
.mVarName
);
946 CVNObj
.SetLineNo (LineNo
);
953 CEObj
.SetLineNo (LineNo
);
961 SEObj
.SetLineNo (LineNo
);
963 return VFR_RETURN_SUCCESS
;
968 SIfrRecord::SIfrRecord (
974 mLineNo
= 0xFFFFFFFF;
975 mOffset
= 0xFFFFFFFF;
979 SIfrRecord::~SIfrRecord (
983 if (mIfrBinBuf
!= NULL
) {
987 mLineNo
= 0xFFFFFFFF;
988 mOffset
= 0xFFFFFFFF;
993 CIfrRecordInfoDB::CIfrRecordInfoDB (
998 mRecordCount
= EFI_IFR_RECORDINFO_IDX_START
;
999 mIfrRecordListHead
= NULL
;
1000 mIfrRecordListTail
= NULL
;
1001 mAllDefaultTypeCount
= 0;
1002 for (UINT8 i
= 0; i
< EFI_HII_MAX_SUPPORT_DEFAULT_TYPE
; i
++) {
1003 mAllDefaultIdArray
[i
] = 0xffff;
1007 CIfrRecordInfoDB::~CIfrRecordInfoDB (
1013 while (mIfrRecordListHead
!= NULL
) {
1014 pNode
= mIfrRecordListHead
;
1015 mIfrRecordListHead
= mIfrRecordListHead
->mNext
;
1021 CIfrRecordInfoDB::GetRecordInfoFromIdx (
1026 SIfrRecord
*pNode
= NULL
;
1028 if (RecordIdx
== EFI_IFR_RECORDINFO_IDX_INVALUD
) {
1032 for (Idx
= (EFI_IFR_RECORDINFO_IDX_START
+ 1), pNode
= mIfrRecordListHead
;
1033 (Idx
!= RecordIdx
) && (pNode
!= NULL
);
1034 Idx
++, pNode
= pNode
->mNext
)
1041 CIfrRecordInfoDB::IfrRecordRegister (
1043 IN CHAR8
*IfrBinBuf
,
1050 if (mSwitch
== FALSE
) {
1051 return EFI_IFR_RECORDINFO_IDX_INVALUD
;
1054 if ((pNew
= new SIfrRecord
) == NULL
) {
1055 return EFI_IFR_RECORDINFO_IDX_INVALUD
;
1058 if (mIfrRecordListHead
== NULL
) {
1059 mIfrRecordListHead
= pNew
;
1060 mIfrRecordListTail
= pNew
;
1062 mIfrRecordListTail
->mNext
= pNew
;
1063 mIfrRecordListTail
= pNew
;
1067 return mRecordCount
;
1071 CIfrRecordInfoDB::IfrRecordInfoUpdate (
1072 IN UINT32 RecordIdx
,
1082 if ((pNode
= GetRecordInfoFromIdx (RecordIdx
)) == NULL
) {
1088 // Line number is not specified explicitly, try to use line number of previous opcode
1090 Prev
= GetRecordInfoFromIdx (RecordIdx
- 1);
1092 LineNo
= Prev
->mLineNo
;
1096 pNode
->mLineNo
= LineNo
;
1097 pNode
->mOffset
= Offset
;
1098 pNode
->mBinBufLen
= BinBufLen
;
1099 pNode
->mIfrBinBuf
= BinBuf
;
1104 CIfrRecordInfoDB::IfrRecordOutput (
1105 OUT PACKAGE_DATA
&TBuffer
1111 if (TBuffer
.Buffer
!= NULL
) {
1112 delete TBuffer
.Buffer
;
1116 TBuffer
.Buffer
= NULL
;
1119 if (mSwitch
== FALSE
) {
1123 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1124 TBuffer
.Size
+= pNode
->mBinBufLen
;
1127 if (TBuffer
.Size
!= 0) {
1128 TBuffer
.Buffer
= new CHAR8
[TBuffer
.Size
];
1133 Temp
= TBuffer
.Buffer
;
1135 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1136 if (pNode
->mIfrBinBuf
!= NULL
) {
1137 memcpy (Temp
, pNode
->mIfrBinBuf
, pNode
->mBinBufLen
);
1138 Temp
+= pNode
->mBinBufLen
;
1146 CIfrRecordInfoDB::IfrRecordOutput (
1155 if (mSwitch
== FALSE
) {
1165 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1166 if (pNode
->mLineNo
== LineNo
|| LineNo
== 0) {
1167 fprintf (File
, ">%08X: ", pNode
->mOffset
);
1168 TotalSize
+= pNode
->mBinBufLen
;
1169 if (pNode
->mIfrBinBuf
!= NULL
) {
1170 for (Index
= 0; Index
< pNode
->mBinBufLen
; Index
++) {
1171 fprintf (File
, "%02X ", (UINT8
)(pNode
->mIfrBinBuf
[Index
]));
1174 fprintf (File
, "\n");
1179 fprintf (File
, "\nTotal Size of all record is 0x%08X\n", TotalSize
);
1184 // for framework vfr file
1185 // adjust opcode sequence for uefi IFR format
1186 // adjust inconsistent and varstore into the right position.
1189 CIfrRecordInfoDB::CheckQuestionOpCode (
1194 case EFI_IFR_CHECKBOX_OP
:
1195 case EFI_IFR_NUMERIC_OP
:
1196 case EFI_IFR_PASSWORD_OP
:
1197 case EFI_IFR_ONE_OF_OP
:
1198 case EFI_IFR_ACTION_OP
:
1199 case EFI_IFR_STRING_OP
:
1200 case EFI_IFR_DATE_OP
:
1201 case EFI_IFR_TIME_OP
:
1202 case EFI_IFR_ORDERED_LIST_OP
:
1203 case EFI_IFR_REF_OP
:
1211 CIfrRecordInfoDB::CheckIdOpCode (
1216 case EFI_IFR_EQ_ID_VAL_OP
:
1217 case EFI_IFR_EQ_ID_ID_OP
:
1218 case EFI_IFR_EQ_ID_VAL_LIST_OP
:
1219 case EFI_IFR_QUESTION_REF1_OP
:
1227 CIfrRecordInfoDB::GetOpcodeQuestionId (
1228 IN EFI_IFR_OP_HEADER
*OpHead
1231 EFI_IFR_QUESTION_HEADER
*QuestionHead
;
1233 QuestionHead
= (EFI_IFR_QUESTION_HEADER
*) (OpHead
+ 1);
1235 return QuestionHead
->QuestionId
;
1239 CIfrRecordInfoDB::GetRecordInfoFromOffset (
1243 SIfrRecord
*pNode
= NULL
;
1245 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1246 if (pNode
->mOffset
== Offset
) {
1255 Add just the op code position.
1257 Case1 (CreateOpcodeAfterParsingVfr == FALSE): The dynamic opcodes were created before the formset opcode,
1258 so pDynamicOpcodeNodes is before mIfrRecordListTail.
1262 |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|
1266 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + mIfrRecordListTail|
1268 Case2 (CreateOpcodeAfterParsingVfr == TRUE): The dynamic opcodes were created after paring the vfr file,
1269 so new records are appennded to the end of OriginalIfrRecordListTail.
1273 |mIfrRecordListHead + ...+ pAdjustNode + ... + OriginalIfrRecordListTail + pDynamicOpcodeNodes|
1277 |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + ... + OriginalIfrRecordListTail|
1280 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
1284 CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (
1285 IN BOOLEAN CreateOpcodeAfterParsingVfr
1288 UINT32 OpcodeOffset
;
1289 SIfrRecord
*pNode
, *pPreNode
;
1290 SIfrRecord
*pAdjustNode
, *pNodeBeforeAdjust
;
1291 SIfrRecord
*pNodeBeforeDynamic
;
1294 pNodeBeforeDynamic
= NULL
;
1298 // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,
1299 // and the node before pDynamicOpcodeNode.
1301 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1302 if (OpcodeOffset
== gAdjustOpcodeOffset
) {
1303 pAdjustNode
= pNode
;
1304 pNodeBeforeAdjust
= pPreNode
;
1305 } else if (OpcodeOffset
== gAdjustOpcodeOffset
+ gAdjustOpcodeLen
) {
1306 pNodeBeforeDynamic
= pPreNode
;
1308 if (pNode
->mNext
!= NULL
) {
1311 OpcodeOffset
+= pNode
->mBinBufLen
;
1315 // Check the nodes whether exist.
1317 if (pNodeBeforeDynamic
== NULL
|| pAdjustNode
== NULL
) {
1322 // Adjust the node. pPreNode save the Node before mIfrRecordListTail
1324 pNodeBeforeAdjust
->mNext
= pNodeBeforeDynamic
->mNext
;
1325 if (CreateOpcodeAfterParsingVfr
) {
1327 // mIfrRecordListTail is the end of pDynamicNode (Case2).
1329 mIfrRecordListTail
->mNext
= pAdjustNode
;
1330 mIfrRecordListTail
= pNodeBeforeDynamic
;
1331 mIfrRecordListTail
->mNext
= NULL
;
1334 //pPreNode is the end of pDynamicNode(Case1).
1336 pPreNode
->mNext
= pAdjustNode
;
1337 pNodeBeforeDynamic
->mNext
= mIfrRecordListTail
;
1344 Update the record info(the position in the record list, offset and mIfrBinBuf) for new created record.
1346 @param CreateOpcodeAfterParsingVfr Whether create the dynamic opcode after parsing the VFR file.
1350 CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (
1351 IN BOOLEAN CreateOpcodeAfterParsingVfr
1354 SIfrRecord
*pRecord
;
1357 // Base on the original offset info to update the record list.
1359 if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr
)) {
1360 gCVfrErrorHandle
.PrintMsg (0, "Error", "Can not find the adjust offset in the record.");
1364 // Base on the opcode binary length to recalculate the offset for each opcode.
1366 IfrAdjustOffsetForRecord();
1369 // Base on the offset to find the binary address.
1371 pRecord
= GetRecordInfoFromOffset(gAdjustOpcodeOffset
);
1372 while (pRecord
!= NULL
) {
1373 pRecord
->mIfrBinBuf
= gCFormPkg
.GetBufAddrBaseOnOffset(pRecord
->mOffset
);
1374 pRecord
= pRecord
->mNext
;
1380 CIfrRecordInfoDB::IfrAdjustOffsetForRecord (
1384 UINT32 OpcodeOffset
;
1388 for (pNode
= mIfrRecordListHead
; pNode
!= NULL
; pNode
= pNode
->mNext
) {
1389 pNode
->mOffset
= OpcodeOffset
;
1390 OpcodeOffset
+= pNode
->mBinBufLen
;
1395 CIfrRecordInfoDB::IfrRecordAdjust (
1399 SIfrRecord
*pNode
, *preNode
;
1400 SIfrRecord
*uNode
, *tNode
;
1401 EFI_IFR_OP_HEADER
*OpHead
, *tOpHead
;
1402 EFI_QUESTION_ID QuestionId
;
1404 UINT32 QuestionScope
;
1405 UINT32 OpcodeOffset
;
1406 CHAR8 ErrorMsg
[MAX_STRING_LEN
] = {0, };
1407 EFI_VFR_RETURN_CODE Status
;
1410 // Init local variable
1412 Status
= VFR_RETURN_SUCCESS
;
1413 pNode
= mIfrRecordListHead
;
1416 while (pNode
!= NULL
) {
1417 OpHead
= (EFI_IFR_OP_HEADER
*) pNode
->mIfrBinBuf
;
1420 // make sure the inconsistent opcode in question scope
1422 if (QuestionScope
> 0) {
1423 QuestionScope
+= OpHead
->Scope
;
1424 if (OpHead
->OpCode
== EFI_IFR_END_OP
) {
1429 if (CheckQuestionOpCode (OpHead
->OpCode
)) {
1433 // for the inconsistent opcode not in question scope, adjust it
1435 if (OpHead
->OpCode
== EFI_IFR_INCONSISTENT_IF_OP
&& QuestionScope
== 0) {
1437 // for inconsistent opcode not in question scope
1441 // Count inconsistent opcode Scope
1443 StackCount
= OpHead
->Scope
;
1444 QuestionId
= EFI_QUESTION_ID_INVALID
;
1446 while (tNode
!= NULL
&& StackCount
> 0) {
1447 tNode
= tNode
->mNext
;
1448 tOpHead
= (EFI_IFR_OP_HEADER
*) tNode
->mIfrBinBuf
;
1450 // Calculate Scope Number
1452 StackCount
+= tOpHead
->Scope
;
1453 if (tOpHead
->OpCode
== EFI_IFR_END_OP
) {
1457 // by IdEqual opcode to get QuestionId
1459 if (QuestionId
== EFI_QUESTION_ID_INVALID
&&
1460 CheckIdOpCode (tOpHead
->OpCode
)) {
1461 QuestionId
= *(EFI_QUESTION_ID
*) (tOpHead
+ 1);
1464 if (tNode
== NULL
|| QuestionId
== EFI_QUESTION_ID_INVALID
) {
1466 // report error; not found
1468 sprintf (ErrorMsg
, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId
);
1469 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", ErrorMsg
);
1470 Status
= VFR_RETURN_MISMATCHED
;
1474 // extract inconsistent opcode list
1475 // pNode is Incosistent opcode, tNode is End Opcode
1479 // insert inconsistent opcode list into the right question scope by questionid
1481 for (uNode
= mIfrRecordListHead
; uNode
!= NULL
; uNode
= uNode
->mNext
) {
1482 tOpHead
= (EFI_IFR_OP_HEADER
*) uNode
->mIfrBinBuf
;
1483 if (CheckQuestionOpCode (tOpHead
->OpCode
) &&
1484 (QuestionId
== GetOpcodeQuestionId (tOpHead
))) {
1489 // insert inconsistent opcode list and check LATE_CHECK flag
1491 if (uNode
!= NULL
) {
1492 if ((((EFI_IFR_QUESTION_HEADER
*)(tOpHead
+ 1))->Flags
& 0x20) != 0) {
1494 // if LATE_CHECK flag is set, change inconsistent to nosumbit
1496 OpHead
->OpCode
= EFI_IFR_NO_SUBMIT_IF_OP
;
1500 // skip the default storage for Date and Time
1502 if ((uNode
->mNext
!= NULL
) && (*uNode
->mNext
->mIfrBinBuf
== EFI_IFR_DEFAULT_OP
)) {
1503 uNode
= uNode
->mNext
;
1506 preNode
->mNext
= tNode
->mNext
;
1507 tNode
->mNext
= uNode
->mNext
;
1508 uNode
->mNext
= pNode
;
1510 // reset pNode to head list, scan the whole list again.
1512 pNode
= mIfrRecordListHead
;
1518 // not found matched question id, report error
1520 sprintf (ErrorMsg
, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId
);
1521 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", ErrorMsg
);
1522 Status
= VFR_RETURN_MISMATCHED
;
1525 } else if (OpHead
->OpCode
== EFI_IFR_VARSTORE_OP
||
1526 OpHead
->OpCode
== EFI_IFR_VARSTORE_EFI_OP
) {
1528 // for new added group of varstore opcode
1531 while (tNode
->mNext
!= NULL
) {
1532 tOpHead
= (EFI_IFR_OP_HEADER
*) tNode
->mNext
->mIfrBinBuf
;
1533 if (tOpHead
->OpCode
!= EFI_IFR_VARSTORE_OP
&&
1534 tOpHead
->OpCode
!= EFI_IFR_VARSTORE_EFI_OP
) {
1537 tNode
= tNode
->mNext
;
1540 if (tNode
->mNext
== NULL
) {
1542 // invalid IfrCode, IfrCode end by EndOpCode
1544 gCVfrErrorHandle
.PrintMsg (0, NULL
, "Error", "No found End Opcode in the end");
1545 Status
= VFR_RETURN_MISMATCHED
;
1549 if (tOpHead
->OpCode
!= EFI_IFR_END_OP
) {
1551 // not new added varstore, which are not needed to be adjust.
1554 pNode
= tNode
->mNext
;
1558 // move new added varstore opcode to the position befor form opcode
1559 // varstore opcode between pNode and tNode
1563 // search form opcode from begin
1565 for (uNode
= mIfrRecordListHead
; uNode
->mNext
!= NULL
; uNode
= uNode
->mNext
) {
1566 tOpHead
= (EFI_IFR_OP_HEADER
*) uNode
->mNext
->mIfrBinBuf
;
1567 if (tOpHead
->OpCode
== EFI_IFR_FORM_OP
) {
1572 // Insert varstore opcode beform form opcode if form opcode is found
1574 if (uNode
->mNext
!= NULL
) {
1575 preNode
->mNext
= tNode
->mNext
;
1576 tNode
->mNext
= uNode
->mNext
;
1577 uNode
->mNext
= pNode
;
1579 // reset pNode to head list, scan the whole list again.
1581 pNode
= mIfrRecordListHead
;
1587 // not found form, continue scan IfrRecord list
1590 pNode
= tNode
->mNext
;
1599 pNode
= pNode
->mNext
;
1603 // Update Ifr Opcode Offset
1605 if (Status
== VFR_RETURN_SUCCESS
) {
1606 IfrAdjustOffsetForRecord ();
1612 When the Varstore of the question is EFI_VFR_VARSTORE_BUFFER and the default value is not
1613 given by expression, should save the default info for the Buffer VarStore.
1615 @param DefaultId The default id.
1616 @param pQuestionNode Point to the question opcode node.
1617 @param Value The default value.
1620 CIfrRecordInfoDB::IfrAddDefaultToBufferConfig (
1621 IN UINT16 DefaultId
,
1622 IN SIfrRecord
*pQuestionNode
,
1623 IN EFI_IFR_TYPE_VALUE Value
1626 CHAR8
*VarStoreName
= NULL
;
1627 EFI_VFR_VARSTORE_TYPE VarStoreType
= EFI_VFR_VARSTORE_INVALID
;
1628 EFI_GUID
*VarGuid
= NULL
;
1629 EFI_VARSTORE_INFO VarInfo
;
1630 EFI_IFR_QUESTION_HEADER
*QuestionHead
;
1631 EFI_IFR_OP_HEADER
*pQuestionOpHead
;
1633 pQuestionOpHead
= (EFI_IFR_OP_HEADER
*) pQuestionNode
->mIfrBinBuf
;
1634 QuestionHead
= (EFI_IFR_QUESTION_HEADER
*) (pQuestionOpHead
+ 1);
1637 // Get the Var Store name and type.
1639 gCVfrDataStorage
.GetVarStoreName (QuestionHead
->VarStoreId
, &VarStoreName
);
1640 VarGuid
= gCVfrDataStorage
.GetVarStoreGuid (QuestionHead
->VarStoreId
);
1641 VarStoreType
= gCVfrDataStorage
.GetVarStoreType (QuestionHead
->VarStoreId
);
1644 // Only for Buffer storage need to save the default info in the storage.
1645 // Other type storage, just return.
1647 if (VarStoreType
!= EFI_VFR_VARSTORE_BUFFER
) {
1650 VarInfo
.mInfo
.mVarOffset
= QuestionHead
->VarStoreInfo
.VarOffset
;
1651 VarInfo
.mVarStoreId
= QuestionHead
->VarStoreId
;
1655 // Get the buffer storage info about this question.
1657 gCVfrDataStorage
.GetBufferVarStoreFieldInfo (&VarInfo
);
1662 gCVfrDefaultStore
.BufferVarStoreAltConfigAdd (
1673 Record the number and default id of all defaultstore opcode.
1677 CIfrRecordInfoDB::IfrGetDefaultStoreInfo (
1682 EFI_IFR_OP_HEADER
*pOpHead
;
1683 EFI_IFR_DEFAULTSTORE
*DefaultStore
;
1685 pNode
= mIfrRecordListHead
;
1686 mAllDefaultTypeCount
= 0;
1688 while (pNode
!= NULL
) {
1689 pOpHead
= (EFI_IFR_OP_HEADER
*) pNode
->mIfrBinBuf
;
1691 if (pOpHead
->OpCode
== EFI_IFR_DEFAULTSTORE_OP
){
1692 DefaultStore
= (EFI_IFR_DEFAULTSTORE
*) pNode
->mIfrBinBuf
;
1693 mAllDefaultIdArray
[mAllDefaultTypeCount
++] = DefaultStore
->DefaultId
;
1695 pNode
= pNode
->mNext
;
1700 Create new default opcode record.
1702 @param Size The new default opcode size.
1703 @param DefaultId The new default id.
1704 @param Type The new default type.
1705 @param LineNo The line number of the new record.
1706 @param Value The new default value.
1710 CIfrRecordInfoDB::IfrCreateDefaultRecord(
1712 IN UINT16 DefaultId
,
1715 IN EFI_IFR_TYPE_VALUE Value
1719 CIfrDefault2
*DObj2
;
1724 if (Type
== EFI_IFR_TYPE_OTHER
) {
1725 DObj2
= new CIfrDefault2 (Size
);
1726 DObj2
->SetDefaultId(DefaultId
);
1727 DObj2
->SetType(Type
);
1728 DObj2
->SetLineNo(LineNo
);
1729 DObj2
->SetScope (1);
1732 DObj
= new CIfrDefault (Size
);
1733 DObj
->SetDefaultId(DefaultId
);
1734 DObj
->SetType(Type
);
1735 DObj
->SetLineNo(LineNo
);
1736 DObj
->SetValue (Value
);
1742 Create new default opcode for question base on the QuestionDefaultInfo.
1744 @param pQuestionNode Point to the question opcode Node.
1745 @param QuestionDefaultInfo Point to the QuestionDefaultInfo for current question.
1749 CIfrRecordInfoDB::IfrCreateDefaultForQuestion (
1750 IN SIfrRecord
*pQuestionNode
,
1751 IN QuestionDefaultRecord
*QuestionDefaultInfo
1754 EFI_IFR_OP_HEADER
*pOpHead
;
1755 EFI_IFR_DEFAULT
*Default
;
1758 SIfrRecord
*pDefaultNode
;
1765 EFI_IFR_ONE_OF_OPTION
*DefaultOptionOpcode
;
1766 EFI_IFR_TYPE_VALUE CheckBoxDefaultValue
;
1768 CheckBoxDefaultValue
.b
= 1;
1769 pOpHead
= (EFI_IFR_OP_HEADER
*) pQuestionNode
->mIfrBinBuf
;
1775 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1777 gAdjustOpcodeOffset
= pQuestionNode
->mNext
->mOffset
;
1780 // For oneof, the default with smallest default id is given by the option flag.
1781 // So create the missing defaults base on the oneof option value(mDefaultValueRecord).
1783 if (pOpHead
->OpCode
== EFI_IFR_ONE_OF_OP
&& !QuestionDefaultInfo
->mIsDefaultOpcode
) {
1784 DefaultOptionOpcode
= (EFI_IFR_ONE_OF_OPTION
*)QuestionDefaultInfo
->mDefaultValueRecord
->mIfrBinBuf
;
1785 DefaultSize
= QuestionDefaultInfo
->mDefaultValueRecord
->mBinBufLen
- OFFSET_OF (EFI_IFR_ONE_OF_OPTION
, Value
);
1786 DefaultSize
+= OFFSET_OF (EFI_IFR_DEFAULT
, Value
);
1787 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1788 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1789 IfrCreateDefaultRecord (DefaultSize
, mAllDefaultIdArray
[i
], DefaultOptionOpcode
->Type
, pQuestionNode
->mLineNo
, DefaultOptionOpcode
->Value
);
1791 // Save the new created default in the buffer storage.
1793 IfrAddDefaultToBufferConfig (mAllDefaultIdArray
[i
], pQuestionNode
, DefaultOptionOpcode
->Value
);
1801 // For checkbox, the default with smallest default id is given by the question flag.
1802 // And create the missing defaults with true value.
1804 if (pOpHead
-> OpCode
== EFI_IFR_CHECKBOX_OP
&& !QuestionDefaultInfo
->mIsDefaultOpcode
) {
1805 DefaultSize
= OFFSET_OF (EFI_IFR_DEFAULT
, Value
) + sizeof (BOOLEAN
);
1806 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1807 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1808 IfrCreateDefaultRecord (DefaultSize
, mAllDefaultIdArray
[i
], EFI_IFR_TYPE_BOOLEAN
, pQuestionNode
->mLineNo
, CheckBoxDefaultValue
);
1810 // Save the new created default.
1812 IfrAddDefaultToBufferConfig (mAllDefaultIdArray
[i
], pQuestionNode
, CheckBoxDefaultValue
);
1820 // The default with smallest default id is given by the default opcode.
1821 // So create the missing defaults base on the value in the default opcode.
1825 // pDefaultNode point to the mDefaultValueRecord in QuestionDefaultInfo.
1827 pDefaultNode
= QuestionDefaultInfo
->mDefaultValueRecord
;
1828 Default
= (EFI_IFR_DEFAULT
*)pDefaultNode
->mIfrBinBuf
;
1830 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1832 gAdjustOpcodeOffset
= pDefaultNode
->mNext
->mOffset
;
1834 if (Default
->Type
== EFI_IFR_TYPE_OTHER
) {
1836 // EFI_IFR_DEFAULT_2 opcode.
1838 // Point to the first expression opcode.
1840 pSNode
= pDefaultNode
->mNext
;
1843 // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)
1845 while (pSNode
!= NULL
&& pSNode
->mNext
!= NULL
&& ScopeCount
!= 0) {
1846 pOpHead
= (EFI_IFR_OP_HEADER
*) pSNode
->mIfrBinBuf
;
1847 if (pOpHead
->Scope
== 1) {
1850 if (pOpHead
->OpCode
== EFI_IFR_END_OP
) {
1854 pSNode
= pSNode
->mNext
;
1858 // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
1860 gAdjustOpcodeOffset
= pSNode
->mOffset
;
1862 // Create new default opcode node for missing default.
1864 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1865 OpcodeNumber
= OpcodeCount
;
1866 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1867 IfrCreateDefaultRecord (Default
->Header
.Length
, mAllDefaultIdArray
[i
], Default
->Type
, pENode
->mLineNo
, Default
->Value
);
1869 // Point to the first expression opcode node.
1871 pSNode
= pDefaultNode
->mNext
;
1873 // Create the expression opcode and end opcode for the new created EFI_IFR_DEFAULT_2 opcode.
1875 while (pSNode
!= NULL
&& pSNode
->mNext
!= NULL
&& OpcodeNumber
-- != 0) {
1876 pOpHead
= (EFI_IFR_OP_HEADER
*) pSNode
->mIfrBinBuf
;
1877 Obj
= new CIfrObj (pOpHead
->OpCode
, NULL
, pSNode
->mBinBufLen
, FALSE
);
1878 Obj
->SetLineNo (pSNode
->mLineNo
);
1879 ObjBinBuf
= Obj
->GetObjBinAddr();
1880 memcpy (ObjBinBuf
, pSNode
->mIfrBinBuf
, (UINTN
)pSNode
->mBinBufLen
);
1882 pSNode
= pSNode
->mNext
;
1888 // EFI_IFR_DEFAULT opcode.
1890 // Create new default opcode node for missing default.
1892 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1893 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1894 IfrCreateDefaultRecord (Default
->Header
.Length
, mAllDefaultIdArray
[i
], Default
->Type
, pDefaultNode
->mLineNo
, Default
->Value
);
1896 // Save the new created default in the buffer storage..
1898 IfrAddDefaultToBufferConfig (mAllDefaultIdArray
[i
], pQuestionNode
, Default
->Value
);
1905 Parse the default information in a question, get the QuestionDefaultInfo.
1907 @param pQuestionNode Point to the question record Node.
1908 @param QuestionDefaultInfo On return, point to the QuestionDefaultInfo.
1911 CIfrRecordInfoDB::IfrParseDefaulInfoInQuestion(
1912 IN SIfrRecord
*pQuestionNode
,
1913 OUT QuestionDefaultRecord
*QuestionDefaultInfo
1917 EFI_IFR_ONE_OF_OPTION
*OneofOptionOpcode
;
1918 EFI_IFR_OP_HEADER
*pSOpHead
;
1919 EFI_IFR_CHECKBOX
*CheckBoxOpcode
;
1920 EFI_IFR_DEFAULT
*DefaultOpcode
;
1921 BOOLEAN IsOneOfOpcode
;
1922 UINT16 SmallestDefaultId
;
1925 SmallestDefaultId
= 0xffff;
1926 IsOneOfOpcode
= FALSE
;
1928 pSNode
= pQuestionNode
;
1931 // Parse all the opcodes in the Question.
1933 while (pSNode
!= NULL
) {
1934 pSOpHead
= (EFI_IFR_OP_HEADER
*) pSNode
->mIfrBinBuf
;
1936 // For a question, its scope bit must be set, the scope exists until it reaches a corresponding EFI_IFR_END_OP.
1937 // Scopes may be nested within other scopes.
1938 // When finishing parsing a question, the scope count must be zero.
1940 if (pSOpHead
->Scope
== 1) {
1943 if (pSOpHead
->OpCode
== EFI_IFR_END_OP
) {
1947 // Check whether finishing parsing a question.
1949 if (ScopeCount
== 0) {
1954 // Record the default information in the question.
1956 switch (pSOpHead
->OpCode
) {
1957 case EFI_IFR_ONE_OF_OP
:
1958 IsOneOfOpcode
= TRUE
;
1960 case EFI_IFR_CHECKBOX_OP
:
1962 // The default info of check box may be given by flag.
1963 // So need to check the flag of check box.
1965 CheckBoxOpcode
= (EFI_IFR_CHECKBOX
*)pSNode
->mIfrBinBuf
;
1966 if ((CheckBoxOpcode
->Flags
& EFI_IFR_CHECKBOX_DEFAULT
) != 0) {
1968 // Check whether need to update the smallest default id.
1970 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_STANDARD
) {
1971 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_STANDARD
;
1974 // Update the QuestionDefaultInfo.
1976 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1977 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_STANDARD
) {
1978 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1979 QuestionDefaultInfo
->mDefaultNumber
++;
1980 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
1986 if ((CheckBoxOpcode
->Flags
& EFI_IFR_CHECKBOX_DEFAULT_MFG
) != 0) {
1988 // Check whether need to update the smallest default id.
1990 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1991 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_MANUFACTURING
;
1994 // Update the QuestionDefaultInfo.
1996 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
1997 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
1998 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
1999 QuestionDefaultInfo
->mDefaultNumber
++;
2000 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2007 case EFI_IFR_ONE_OF_OPTION_OP
:
2008 if (!IsOneOfOpcode
) {
2010 // Only check the option in oneof.
2014 OneofOptionOpcode
= (EFI_IFR_ONE_OF_OPTION
*)pSNode
->mIfrBinBuf
;
2015 if ((OneofOptionOpcode
->Flags
& EFI_IFR_OPTION_DEFAULT
) != 0) {
2017 // The option is used as the standard default.
2018 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2020 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_STANDARD
) {
2021 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_STANDARD
;
2022 QuestionDefaultInfo
->mDefaultValueRecord
= pSNode
;
2025 // Update the IsDefaultIdExist array in QuestionDefaultInfo.
2027 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
2028 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_STANDARD
) {
2029 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2030 QuestionDefaultInfo
->mDefaultNumber
++;
2031 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2037 if ((OneofOptionOpcode
->Flags
& EFI_IFR_OPTION_DEFAULT_MFG
) != 0) {
2039 // This option is used as the manufacture default.
2040 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2042 if (SmallestDefaultId
> EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2043 SmallestDefaultId
= EFI_HII_DEFAULT_CLASS_MANUFACTURING
;
2044 QuestionDefaultInfo
->mDefaultValueRecord
= pSNode
;
2047 // Update the QuestionDefaultInfo.
2049 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++) {
2050 if (mAllDefaultIdArray
[i
] == EFI_HII_DEFAULT_CLASS_MANUFACTURING
) {
2051 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2052 QuestionDefaultInfo
->mDefaultNumber
++;
2053 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2060 case EFI_IFR_DEFAULT_OP
:
2061 DefaultOpcode
= (EFI_IFR_DEFAULT
*) pSNode
->mIfrBinBuf
;
2063 // Check whether need to update the smallest default id and QuestionDefaultInfo.
2065 if (SmallestDefaultId
>= DefaultOpcode
->DefaultId
) {
2066 SmallestDefaultId
= DefaultOpcode
->DefaultId
;
2067 QuestionDefaultInfo
->mDefaultValueRecord
= pSNode
;
2068 QuestionDefaultInfo
->mIsDefaultOpcode
= TRUE
;
2071 // Update the QuestionDefaultInfo.
2073 for (UINT8 i
= 0; i
< mAllDefaultTypeCount
; i
++){
2074 if (mAllDefaultIdArray
[i
] == ((EFI_IFR_DEFAULT
*)pSNode
->mIfrBinBuf
)->DefaultId
) {
2075 if (!QuestionDefaultInfo
->mIsDefaultIdExist
[i
]) {
2076 QuestionDefaultInfo
->mDefaultNumber
++;
2077 QuestionDefaultInfo
->mIsDefaultIdExist
[i
] = TRUE
;
2087 // Parse next opcode in this question.
2089 pSNode
= pSNode
->mNext
;
2094 Check or add default for question if need.
2096 This function will check the default info for question.
2097 If the question has default, but the default number < defaultstore opcode number.
2098 will do following two action :
2100 1. if (AutoDefault) will add default for question to support all kinds of defaults.
2101 2. if (CheckDefault) will generate an error to tell user the question misses some default value.
2103 We assume that the two options can not be TRUE at same time.
2104 If they are TRUE at same time, only do the action corresponding to AutoDefault option.
2106 @param AutoDefault Add default for question if needed
2107 @param CheckDefault Check the default info, if missing default, generates an error.
2111 CIfrRecordInfoDB::IfrCheckAddDefaultRecord (
2112 BOOLEAN AutoDefault
,
2113 BOOLEAN CheckDefault
2117 SIfrRecord
*pTailNode
;
2118 SIfrRecord
*pStartAdjustNode
;
2119 EFI_IFR_OP_HEADER
*pOpHead
;
2120 QuestionDefaultRecord QuestionDefaultInfo
;
2121 UINT8 MissingDefaultCount
;
2122 CHAR8 Msg
[MAX_STRING_LEN
] = {0, };
2124 pNode
= mIfrRecordListHead
;
2127 // Record the number and default id of all defaultstore opcode.
2129 IfrGetDefaultStoreInfo ();
2131 while (pNode
!= NULL
) {
2132 pOpHead
= (EFI_IFR_OP_HEADER
*) pNode
->mIfrBinBuf
;
2134 // Check whether is question opcode.
2136 if (CheckQuestionOpCode (pOpHead
->OpCode
)) {
2138 // Initialize some local variables here, because they vary with question.
2139 // Record the mIfrRecordListTail for each question, because may create default node for question after mIfrRecordListTail.
2141 memset (&QuestionDefaultInfo
, 0, sizeof (QuestionDefaultRecord
));
2142 pTailNode
= mIfrRecordListTail
;
2144 // Get the QuestionDefaultInfo for current question.
2146 IfrParseDefaulInfoInQuestion (pNode
, &QuestionDefaultInfo
);
2148 if (QuestionDefaultInfo
.mDefaultNumber
!= mAllDefaultTypeCount
&& QuestionDefaultInfo
.mDefaultNumber
!= 0) {
2151 // Create default for question which misses default.
2153 IfrCreateDefaultForQuestion (pNode
, &QuestionDefaultInfo
);
2156 // Adjust the buffer content.
2157 // pStartAdjustNode->mIfrBinBuf points to the insert position.
2158 // pTailNode->mNext->mIfrBinBuf points to the inset opcodes.
2160 pStartAdjustNode
=GetRecordInfoFromOffset (gAdjustOpcodeOffset
);
2161 gCFormPkg
.AdjustDynamicInsertOpcode (pStartAdjustNode
->mIfrBinBuf
, pTailNode
->mNext
->mIfrBinBuf
, TRUE
);
2164 // Update the record info.
2166 IfrUpdateRecordInfoForDynamicOpcode (TRUE
);
2167 } else if (CheckDefault
) {
2169 // Generate an error for question which misses default.
2171 MissingDefaultCount
= mAllDefaultTypeCount
- QuestionDefaultInfo
.mDefaultNumber
;
2172 sprintf (Msg
, "The question misses %d default, the question's opcode is %d", MissingDefaultCount
, pOpHead
->OpCode
);
2173 gCVfrErrorHandle
.PrintMsg (pNode
->mLineNo
, NULL
, "Error", Msg
);
2178 // parse next opcode.
2180 pNode
= pNode
->mNext
;
2184 CIfrRecordInfoDB gCIfrRecordInfoDB
;
2187 CIfrObj::_EMIT_PENDING_OBJ (
2191 CHAR8
*ObjBinBuf
= NULL
;
2196 if (!mDelayEmit
|| !gCreateOp
) {
2200 mPkgOffset
= gCFormPkg
.GetPkgLength ();
2202 // update data buffer to package data
2204 ObjBinBuf
= gCFormPkg
.IfrBinBufferGet (mObjBinLen
);
2205 if (ObjBinBuf
!= NULL
) {
2206 memmove (ObjBinBuf
, mObjBinBuf
, mObjBinLen
);
2210 // update bin buffer to package data buffer
2212 if (mObjBinBuf
!= NULL
) {
2214 mObjBinBuf
= ObjBinBuf
;
2221 * The definition of CIfrObj's member function
2226 } gOpcodeSizesScopeTable
[] = {
2227 { 0, 0 }, // EFI_IFR_INVALID - 0x00
2228 { sizeof (EFI_IFR_FORM
), 1 }, // EFI_IFR_FORM_OP
2229 { sizeof (EFI_IFR_SUBTITLE
), 1 }, // EFI_IFR_SUBTITLE_OP
2230 { sizeof (EFI_IFR_TEXT
), 0 }, // EFI_IFR_TEXT_OP
2231 { sizeof (EFI_IFR_IMAGE
), 0 }, // EFI_IFR_IMAGE_OP
2232 { sizeof (EFI_IFR_ONE_OF
), 1 }, // EFI_IFR_ONE_OF_OP - 0x05
2233 { sizeof (EFI_IFR_CHECKBOX
), 1}, // EFI_IFR_CHECKBOX_OP
2234 { sizeof (EFI_IFR_NUMERIC
), 1 }, // EFI_IFR_NUMERIC_OP
2235 { sizeof (EFI_IFR_PASSWORD
), 1 }, // EFI_IFR_PASSWORD_OP
2236 { sizeof (EFI_IFR_ONE_OF_OPTION
), 0 }, // EFI_IFR_ONE_OF_OPTION_OP
2237 { sizeof (EFI_IFR_SUPPRESS_IF
), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A
2238 { sizeof (EFI_IFR_LOCKED
), 0 }, // EFI_IFR_LOCKED_OP
2239 { sizeof (EFI_IFR_ACTION
), 1 }, // EFI_IFR_ACTION_OP
2240 { sizeof (EFI_IFR_RESET_BUTTON
), 1 }, // EFI_IFR_RESET_BUTTON_OP
2241 { sizeof (EFI_IFR_FORM_SET
), 1 }, // EFI_IFR_FORM_SET_OP -0xE
2242 { sizeof (EFI_IFR_REF
), 0 }, // EFI_IFR_REF_OP
2243 { sizeof (EFI_IFR_NO_SUBMIT_IF
), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10
2244 { sizeof (EFI_IFR_INCONSISTENT_IF
), 1 }, // EFI_IFR_INCONSISTENT_IF_OP
2245 { sizeof (EFI_IFR_EQ_ID_VAL
), 0 }, // EFI_IFR_EQ_ID_VAL_OP
2246 { sizeof (EFI_IFR_EQ_ID_ID
), 0 }, // EFI_IFR_EQ_ID_ID_OP
2247 { sizeof (EFI_IFR_EQ_ID_VAL_LIST
), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14
2248 { sizeof (EFI_IFR_AND
), 0 }, // EFI_IFR_AND_OP
2249 { sizeof (EFI_IFR_OR
), 0 }, // EFI_IFR_OR_OP
2250 { sizeof (EFI_IFR_NOT
), 0 }, // EFI_IFR_NOT_OP
2251 { sizeof (EFI_IFR_RULE
), 1 }, // EFI_IFR_RULE_OP
2252 { sizeof (EFI_IFR_GRAY_OUT_IF
), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19
2253 { sizeof (EFI_IFR_DATE
), 1 }, // EFI_IFR_DATE_OP
2254 { sizeof (EFI_IFR_TIME
), 1 }, // EFI_IFR_TIME_OP
2255 { sizeof (EFI_IFR_STRING
), 1 }, // EFI_IFR_STRING_OP
2256 { sizeof (EFI_IFR_REFRESH
), 0 }, // EFI_IFR_REFRESH_OP
2257 { sizeof (EFI_IFR_DISABLE_IF
), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E
2259 { sizeof (EFI_IFR_TO_LOWER
), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20
2260 { sizeof (EFI_IFR_TO_UPPER
), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21
2261 { sizeof (EFI_IFR_MAP
), 1 }, // EFI_IFR_MAP - 0x22
2262 { sizeof (EFI_IFR_ORDERED_LIST
), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23
2263 { sizeof (EFI_IFR_VARSTORE
), 0 }, // EFI_IFR_VARSTORE_OP
2264 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE
), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
2265 { sizeof (EFI_IFR_VARSTORE_EFI
), 0 }, // EFI_IFR_VARSTORE_EFI_OP
2266 { sizeof (EFI_IFR_VARSTORE_DEVICE
), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP
2267 { sizeof (EFI_IFR_VERSION
), 0 }, // EFI_IFR_VERSION_OP - 0x28
2268 { sizeof (EFI_IFR_END
), 0 }, // EFI_IFR_END_OP
2269 { sizeof (EFI_IFR_MATCH
), 0 }, // EFI_IFR_MATCH_OP - 0x2A
2270 { sizeof (EFI_IFR_GET
), 0 }, // EFI_IFR_GET - 0x2B
2271 { sizeof (EFI_IFR_SET
), 0 }, // EFI_IFR_SET - 0x2C
2272 { sizeof (EFI_IFR_READ
), 0 }, // EFI_IFR_READ - 0x2D
2273 { sizeof (EFI_IFR_WRITE
), 0 }, // EFI_IFR_WRITE - 0x2E
2274 { sizeof (EFI_IFR_EQUAL
), 0 }, // EFI_IFR_EQUAL_OP - 0x2F
2275 { sizeof (EFI_IFR_NOT_EQUAL
), 0 }, // EFI_IFR_NOT_EQUAL_OP
2276 { sizeof (EFI_IFR_GREATER_THAN
), 0 }, // EFI_IFR_GREATER_THAN_OP
2277 { sizeof (EFI_IFR_GREATER_EQUAL
), 0 }, // EFI_IFR_GREATER_EQUAL_OP
2278 { sizeof (EFI_IFR_LESS_THAN
), 0 }, // EFI_IFR_LESS_THAN_OP
2279 { sizeof (EFI_IFR_LESS_EQUAL
), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34
2280 { sizeof (EFI_IFR_BITWISE_AND
), 0 }, // EFI_IFR_BITWISE_AND_OP
2281 { sizeof (EFI_IFR_BITWISE_OR
), 0 }, // EFI_IFR_BITWISE_OR_OP
2282 { sizeof (EFI_IFR_BITWISE_NOT
), 0 }, // EFI_IFR_BITWISE_NOT_OP
2283 { sizeof (EFI_IFR_SHIFT_LEFT
), 0 }, // EFI_IFR_SHIFT_LEFT_OP
2284 { sizeof (EFI_IFR_SHIFT_RIGHT
), 0 }, // EFI_IFR_SHIFT_RIGHT_OP
2285 { sizeof (EFI_IFR_ADD
), 0 }, // EFI_IFR_ADD_OP - 0x3A
2286 { sizeof (EFI_IFR_SUBTRACT
), 0 }, // EFI_IFR_SUBTRACT_OP
2287 { sizeof (EFI_IFR_MULTIPLY
), 0 }, // EFI_IFR_MULTIPLY_OP
2288 { sizeof (EFI_IFR_DIVIDE
), 0 }, // EFI_IFR_DIVIDE_OP
2289 { sizeof (EFI_IFR_MODULO
), 0 }, // EFI_IFR_MODULO_OP - 0x3E
2290 { sizeof (EFI_IFR_RULE_REF
), 0 }, // EFI_IFR_RULE_REF_OP
2291 { sizeof (EFI_IFR_QUESTION_REF1
), 0 }, // EFI_IFR_QUESTION_REF1_OP
2292 { sizeof (EFI_IFR_QUESTION_REF2
), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41
2293 { sizeof (EFI_IFR_UINT8
), 0}, // EFI_IFR_UINT8
2294 { sizeof (EFI_IFR_UINT16
), 0}, // EFI_IFR_UINT16
2295 { sizeof (EFI_IFR_UINT32
), 0}, // EFI_IFR_UINT32
2296 { sizeof (EFI_IFR_UINT64
), 0}, // EFI_IFR_UTNT64
2297 { sizeof (EFI_IFR_TRUE
), 0 }, // EFI_IFR_TRUE_OP - 0x46
2298 { sizeof (EFI_IFR_FALSE
), 0 }, // EFI_IFR_FALSE_OP
2299 { sizeof (EFI_IFR_TO_UINT
), 0 }, // EFI_IFR_TO_UINT_OP
2300 { sizeof (EFI_IFR_TO_STRING
), 0 }, // EFI_IFR_TO_STRING_OP
2301 { sizeof (EFI_IFR_TO_BOOLEAN
), 0 }, // EFI_IFR_TO_BOOLEAN_OP
2302 { sizeof (EFI_IFR_MID
), 0 }, // EFI_IFR_MID_OP
2303 { sizeof (EFI_IFR_FIND
), 0 }, // EFI_IFR_FIND_OP
2304 { sizeof (EFI_IFR_TOKEN
), 0 }, // EFI_IFR_TOKEN_OP
2305 { sizeof (EFI_IFR_STRING_REF1
), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E
2306 { sizeof (EFI_IFR_STRING_REF2
), 0 }, // EFI_IFR_STRING_REF2_OP
2307 { sizeof (EFI_IFR_CONDITIONAL
), 0 }, // EFI_IFR_CONDITIONAL_OP
2308 { sizeof (EFI_IFR_QUESTION_REF3
), 0 }, // EFI_IFR_QUESTION_REF3_OP
2309 { sizeof (EFI_IFR_ZERO
), 0 }, // EFI_IFR_ZERO_OP
2310 { sizeof (EFI_IFR_ONE
), 0 }, // EFI_IFR_ONE_OP
2311 { sizeof (EFI_IFR_ONES
), 0 }, // EFI_IFR_ONES_OP
2312 { sizeof (EFI_IFR_UNDEFINED
), 0 }, // EFI_IFR_UNDEFINED_OP
2313 { sizeof (EFI_IFR_LENGTH
), 0 }, // EFI_IFR_LENGTH_OP
2314 { sizeof (EFI_IFR_DUP
), 0 }, // EFI_IFR_DUP_OP - 0x57
2315 { sizeof (EFI_IFR_THIS
), 0 }, // EFI_IFR_THIS_OP
2316 { sizeof (EFI_IFR_SPAN
), 0 }, // EFI_IFR_SPAN_OP
2317 { sizeof (EFI_IFR_VALUE
), 1 }, // EFI_IFR_VALUE_OP
2318 { sizeof (EFI_IFR_DEFAULT
), 0 }, // EFI_IFR_DEFAULT_OP
2319 { sizeof (EFI_IFR_DEFAULTSTORE
), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C
2320 { sizeof (EFI_IFR_FORM_MAP
), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D
2321 { sizeof (EFI_IFR_CATENATE
), 0 }, // EFI_IFR_CATENATE_OP
2322 { sizeof (EFI_IFR_GUID
), 0 }, // EFI_IFR_GUID_OP
2323 { sizeof (EFI_IFR_SECURITY
), 0 }, // EFI_IFR_SECURITY_OP - 0x60
2324 { sizeof (EFI_IFR_MODAL_TAG
), 0}, // EFI_IFR_MODAL_TAG_OP - 0x61
2325 { sizeof (EFI_IFR_REFRESH_ID
), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62
2326 { sizeof (EFI_IFR_WARNING_IF
), 1}, // EFI_IFR_WARNING_IF_OP - 0x63
2327 { sizeof (EFI_IFR_MATCH2
), 0 }, // EFI_IFR_MATCH2_OP - 0x64
2330 #ifdef CIFROBJ_DEUBG
2333 } gIfrObjPrintDebugTable
[] = {
2334 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",
2335 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",
2336 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",
2337 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",
2338 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",
2339 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",
2340 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",
2341 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",
2342 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",
2343 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",
2344 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
2345 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",
2346 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",
2347 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",
2348 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",
2349 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",
2350 "EFI_IFR_SECURITY", "EFI_IFR_MODAL_TAG", "EFI_IFR_REFRESH_ID", "EFI_IFR_WARNING_IF", "EFI_IFR_MATCH2",
2354 CIFROBJ_DEBUG_PRINT (
2358 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable
[OpCode
].mIfrName
);
2362 #define CIFROBJ_DEBUG_PRINT(OpCode)
2366 BOOLEAN gCreateOp
= TRUE
;
2372 IN BOOLEAN DelayEmit
2375 mDelayEmit
= DelayEmit
;
2376 mPkgOffset
= gCFormPkg
.GetPkgLength ();
2377 mObjBinLen
= (ObjBinLen
== 0) ? gOpcodeSizesScopeTable
[OpCode
].mSize
: ObjBinLen
;
2378 mObjBinBuf
= ((DelayEmit
== FALSE
) && (gCreateOp
== TRUE
)) ? gCFormPkg
.IfrBinBufferGet (mObjBinLen
) : new CHAR8
[EFI_IFR_MAX_LENGTH
];
2379 mRecordIdx
= (gCreateOp
== TRUE
) ? gCIfrRecordInfoDB
.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf
, mObjBinLen
, mPkgOffset
) : EFI_IFR_RECORDINFO_IDX_INVALUD
;
2381 if (IfrObj
!= NULL
) {
2382 *IfrObj
= mObjBinBuf
;
2385 CIFROBJ_DEBUG_PRINT (OpCode
);
2392 if ((mDelayEmit
== TRUE
) && ((gCreateOp
== TRUE
))) {
2393 _EMIT_PENDING_OBJ ();
2396 gCIfrRecordInfoDB
.IfrRecordInfoUpdate (mRecordIdx
, mLineNo
, mObjBinBuf
, mObjBinLen
, mPkgOffset
);
2400 * The definition of CIfrObj's member function
2402 UINT8 gScopeCount
= 0;
2404 CIfrOpHeader::CIfrOpHeader (
2408 ) : mHeader ((EFI_IFR_OP_HEADER
*)StartAddr
)
2410 mHeader
->OpCode
= OpCode
;
2411 mHeader
->Length
= (Length
== 0) ? gOpcodeSizesScopeTable
[OpCode
].mSize
: Length
;
2412 mHeader
->Scope
= (gOpcodeSizesScopeTable
[OpCode
].mScope
+ gScopeCount
> 0) ? 1 : 0;
2415 CIfrOpHeader::CIfrOpHeader (
2416 IN CIfrOpHeader
&OpHdr
2419 mHeader
= OpHdr
.mHeader
;
2422 UINT32
CIfrFormId::FormIdBitMap
[EFI_FREE_FORM_ID_BITMAP_SIZE
] = {0, };